package tr.gov.ulakbim.jDenetX.clusterers.denstream; import tr.gov.ulakbim.jDenetX.cluster.CFCluster; import weka.core.Instance; public class MicroCluster extends CFCluster { private long lastEditT = -1; private long creationTimestamp = -1; private double lambda; private Timestamp currentTimestamp; public MicroCluster(double[] center, int dimensions, long creationTimestamp, double lambda, Timestamp currentTimestamp) { super(center, dimensions); this.creationTimestamp = creationTimestamp; this.lastEditT = creationTimestamp; this.lambda = lambda; this.currentTimestamp = currentTimestamp; } public MicroCluster(Instance instance, int dimensions, long timestamp, double lambda, Timestamp currentTimestamp) { this(instance.toDoubleArray(), dimensions, timestamp, lambda, currentTimestamp); } public void insert(Instance instance, long timestamp) { N++; super.setWeight(super.getWeight() + 1); this.lastEditT = timestamp; for (int i = 0; i < instance.numValues(); i++) { LS[i] += instance.value(i); SS[i] += instance.value(i) * instance.value(i); } } public long getLastEditTimestamp() { return lastEditT; } private double[] calcCF2(long dt) { double[] cf2 = new double[SS.length]; for (int i = 0; i < SS.length; i++) { cf2[i] = Math.pow(2, -lambda * dt) * SS[i]; } return cf2; } private double[] calcCF1(long dt) { double[] cf1 = new double[LS.length]; for (int i = 0; i < LS.length; i++) { cf1[i] = Math.pow(2, -lambda * dt) * LS[i]; } return cf1; } @Override public double getWeight() { return getWeight(currentTimestamp.getTimestamp()); } private double getWeight(long timestamp) { long dt = timestamp - lastEditT; return (N * Math.pow(2, -lambda * dt)); } public long getCreationTime() { return creationTimestamp; } @Override public double[] getCenter() { return getCenter(currentTimestamp.getTimestamp()); } private double[] getCenter(long timestamp) { long dt = timestamp - lastEditT; double w = getWeight(timestamp); double[] res = new double[LS.length]; for (int i = 0; i < LS.length; i++) { res[i] = LS[i]; res[i] *= Math.pow(2, -lambda * dt); res[i] /= w; } return res; } @Override public double getRadius() { return getRadius(currentTimestamp.getTimestamp()) * 1.6; } public double getRadius(long timestamp) { long dt = timestamp - lastEditT; double[] cf1 = calcCF1(dt); double[] cf2 = calcCF2(dt); double w = getWeight(timestamp); double max = 0; double sum = 0; for (int i = 0; i < SS.length; i++) { double x1 = cf2[i] / w; double x2 = Math.pow(cf1[i] / w, 2); //sum += Math.pow(x1 - x2,2); sum += (x1 - x2); if (Math.sqrt(x1 - x2) > max) { max = Math.sqrt(x1 - x2); } } return max; //return Math.sqrt(Math.sqrt(sum)); //return Math.sqrt(sum); } @Override public MicroCluster copy() { MicroCluster copy = new MicroCluster(this.LS.clone(), this.LS.length, this.getCreationTime(), this.lambda, this.currentTimestamp); copy.setWeight(this.N + 1); copy.N = this.N; copy.SS = this.SS.clone(); copy.LS = this.LS.clone(); copy.lastEditT = this.lastEditT; // MicroCluster copy = (MicroCluster)super.copy(); return copy; } @Override public double getInclusionProbability(Instance instance) { if (getCenterDistance(instance) <= getRadius()) { return 1.0; } return 0.0; } }