package org.jgrasstools.gears.utils.clustering;
public abstract class GvmSpace {
//TODO use within cluster
public static double nonNegative(double v) {
return v < 0.0 ? 0.0 : v;
}
public abstract Object newOrigin();
public abstract Object newCopy(Object pt);
public abstract double magnitudeSqr(Object pt);
public abstract double sum(Object pt);
//not used directly in algorithm, but useful - override for good performance
public double magnitude(Object pt) {
return Math.sqrt(magnitudeSqr(pt));
}
//not used directly in algorithm, but useful - override for good performance
public double distance(Object pt1, Object pt2) {
Object p = newCopy(pt1);
subtract(p, pt2);
return magnitude(p);
}
//naive implementation that must be overridden for good performance
// m - total mass (not zero)
// pt - aggregate point (prescaled by mass)
// ptSqr - aggregate point squared (prescaled by mass)
public double variance(double m, Object pt, Object ptSqr) {
Object x = newCopy(ptSqr);
// // Var is E(X^2) - E(X)^2, but squaring pt1 introduces an extra factor which is the total mass, so:
subtractScaledSqr(x, 1 / m, pt);
return sum(x);
}
//naive implementation that must be overridden for good performance
// m1 - established total mass
// pt1 - aggregate point (prescaled by mass)
// ptSqr1 - aggregate point squared (prescaled by mass)
// m2 - mass of candidate point
// pt2 - candidate point (not prescaled by mass)
// Note: (m1 + m2) never zero
public double variance(double m1, Object pt1, Object ptSqr1, double m2, Object pt2) {
// compute the total mass
double m0 = m1 + m2;
// compute the new sum
Object pt0 = newCopy(pt1);
addScaled(pt0, m2, pt2);
// compute the new sum of squares
Object ptSqr0 = newCopy(ptSqr1);
addScaledSqr(ptSqr0, m2, pt2);
// compute the variance
return variance(m0, pt0, ptSqr0);
}
//naive implementation that must be overridden for good performance
// m1 - established total mass
// pt1 - aggregate point (prescaled by mass)
// ptSqr1 - aggregate point squared (prescaled by mass)
// m2 - mass of candidate cluster
// pt2 - candidate cluster point (prescaled by mass)
// ptSqr2 - candidate cluster point squared (prescaled by mass)
// Note: (m1 + m2) never zero
public double variance(double m1, Object pt1, Object ptSqr1, double m2, Object pt2, Object ptSqr2) {
// compute the total mass
double m0 = m1 + m2;
// compute the new sum
Object pt0 = newCopy(pt1);
add(pt0, pt2);
// compute the new sum of squares
Object ptSqr0 = newCopy(ptSqr1);
add(ptSqr0, ptSqr2);
// compute the variance
return variance(m0, pt0, ptSqr0);
}
public abstract void setToOrigin(Object pt);
public abstract void setTo(Object dstPt, Object srcPt);
public abstract void setToScaled(Object dstPt, double m, Object srcPt);
public abstract void setToScaledSqr(Object dstPt, double m, Object srcPt);
public abstract void add(Object dstPt, Object srcPt);
public abstract void addScaled(Object dstPt, double m, Object srcPt);
public abstract void addScaledSqr(Object dstPt, double m, Object srcPt);
public abstract void subtract(Object dstPt, Object srcPt);
public abstract void subtractScaled(Object dstPt, double m, Object srcPt);
public abstract void subtractScaledSqr(Object dstPt, double m, Object srcPt);
public abstract void scale(Object dstPt, double m);
public abstract void square(Object pt);
public String toString(Object pt) {
return pt == null ? "null" : pt.toString();
}
}