/** * Excess of mass measure. * * @return Excess of mass */ public double totalStability() { double stability = excessOfMass(); double cstab = 0.; for(TempCluster child : children) { cstab += Math.abs(child.totalStability()); } return stability > cstab ? stability : -cstab; }
/** * Cluster containing two existing clusters. * * @param dist Distance * @param a First cluster * @param b Second cluster */ public TempCluster(double dist, TempCluster a, TempCluster b) { this.dist = dist; this.children.add(a); this.children.add(b); this.childrenTotal = a.totalElements() + b.totalElements(); this.aggregate = this.childrenTotal / dist; }
if(cclus.isSpurious(minClSize)) { noise.addDBIDs(cclus.members); toplevel.add(new TempCluster(dist, clead)); if(!oSpurious && !cSpurious) { cclus = cclus != null ? cclus : new TempCluster(cdist, clead); oclus = oclus != null ? oclus : new TempCluster(odist, olead); nclus = new TempCluster(dist, oclus, cclus); nclus = oclus.grow(dist, cclus, clead); nclus = cclus.grow(dist, oclus, olead); nclus = oclus.grow(dist, cclus, clead).resetAggregate(); nclus = cclus.grow(dist, oclus, olead).resetAggregate(); nclus = new TempCluster(dist, clead, olead);
if(cclus.isSpurious(minClSize)) { noise.addDBIDs(cclus.members); toplevel.add(new TempCluster(dist, clead)); if(!oSpurious && !cSpurious) { cclus = cclus != null ? cclus : new TempCluster(cdist, clead); oclus = oclus != null ? oclus : new TempCluster(odist, olead); nclus = new TempCluster(dist, oclus, cclus); nclus = oclus.grow(dist, cclus, clead); nclus = cclus.grow(dist, oclus, olead); nclus = oclus.grow(dist, cclus, clead).resetAggregate(); nclus = cclus.grow(dist, oclus, olead).resetAggregate(); nclus = new TempCluster(dist, clead, olead);
if(cclus.isSpurious(minClSize)) { noise.addDBIDs(cclus.members); toplevel.add(new TempCluster(dist, clead)); if(!oSpurious && !cSpurious) { cclus = cclus != null ? cclus : new TempCluster(cdist, clead); oclus = oclus != null ? oclus : new TempCluster(odist, olead); nclus = new TempCluster(dist, oclus, cclus); nclus = oclus.grow(dist, cclus, clead); nclus = cclus.grow(dist, oclus, olead); nclus = oclus.grow(dist, cclus, clead).resetAggregate(); nclus = cclus.grow(dist, oclus, olead).resetAggregate(); nclus = new TempCluster(dist, clead, olead);
/** * Recursive flattening of clusters. * * @param clustering Output clustering * @param cur Current temporary cluster * @param clus Output cluster * @param flatten Flag to indicate everything below should be flattened. * @param hierarchical Hierarchical output */ private void collectChildren(Clustering<DendrogramModel> clustering, TempCluster cur, Cluster<DendrogramModel> clus, boolean flatten, boolean hierarchical) { for(TempCluster child : cur.children) { if(flatten || child.totalStability() < 0) { members.addDBIDs(child.members); collectChildren(clustering, child, clus, flatten, hierarchical); } else { child.finalizeCluster(clustering, clus, true, hierarchical); } } } }
/** * Recursive flattening of clusters. * * @param clustering Output clustering * @param cur Current temporary cluster * @param clus Output cluster * @param flatten Flag to indicate everything below should be flattened. */ private void collectChildren(TempCluster temp, Clustering<DendrogramModel> clustering, TempCluster cur, Cluster<DendrogramModel> clus, boolean flatten) { for(TempCluster child : cur.children) { if(flatten || child.totalStability() < 0) { temp.members.addDBIDs(child.members); collectChildren(temp, clustering, child, clus, flatten); } else { finalizeCluster(child, clustering, clus, true); } } } }
/** * Make the cluster for the given object * * @param clustering Parent clustering * @param parent Parent cluster (for hierarchical output) * @param flatten Flag to flatten all clusters below. * @param hierarchical Hierarchical outpu */ private void finalizeCluster(Clustering<DendrogramModel> clustering, Cluster<DendrogramModel> parent, boolean flatten, boolean hierarchical) { final String name = "C_" + FormatUtil.NF6.format(dist); Cluster<DendrogramModel> clus = new Cluster<>(name, members, new DendrogramModel(dist)); if(hierarchical && parent != null) { // Hierarchical output clustering.addChildCluster(parent, clus); } else { clustering.addToplevelCluster(clus); } collectChildren(clustering, this, clus, flatten, hierarchical); members = null; children = null; }
/** * Recursive flattening of clusters. * * @param clustering Output clustering * @param cur Current temporary cluster * @param clus Output cluster * @param flatten Flag to indicate everything below should be flattened. */ private void collectChildren(TempCluster temp, Clustering<DendrogramModel> clustering, TempCluster cur, Cluster<DendrogramModel> clus, boolean flatten) { for(TempCluster child : cur.children) { if(flatten || child.totalStability() < 0) { temp.members.addDBIDs(child.members); collectChildren(temp, clustering, child, clus, flatten); } else { finalizeCluster(child, clustering, clus, true); } } } }
/** * Cluster containing two existing clusters. * * @param dist Distance * @param a First cluster * @param b Second cluster */ public TempCluster(double dist, TempCluster a, TempCluster b) { this.dist = dist; this.children.add(a); this.children.add(b); this.childrenTotal = a.totalElements() + b.totalElements(); this.aggregate = this.childrenTotal / dist; }
/** * Cluster containing two existing clusters. * * @param dist Distance * @param a First cluster * @param b Second cluster */ public TempCluster(double dist, TempCluster a, TempCluster b) { this.dist = dist; this.children.add(a); this.children.add(b); this.childrenTotal = a.totalElements() + b.totalElements(); this.aggregate = this.childrenTotal / dist; }
/** * Spurious, also for non-materialized clusters. * * @param clus Cluster, may be {@code null} for 1-element clusters. * @param isCore Core property * @return {@code true} if spurious. */ private boolean isSpurious(TempCluster clus, boolean isCore) { return clus != null ? clus.isSpurious(minClSize) : (minClSize > 1 || !isCore); }
/** * Spurious, also for non-materialized clusters. * * @param clus Cluster, may be {@code null} for 1-element clusters. * @param isCore Core property * @return {@code true} if spurious. */ private boolean isSpurious(TempCluster clus, boolean isCore) { return clus != null ? clus.isSpurious(minClSize) : (minClSize > 1 || !isCore); }
/** * Excess of mass measure. * * @return Excess of mass */ public double totalStability() { double stability = excessOfMass(); double cstab = 0.; for(TempCluster child : children) { cstab += Math.abs(child.totalStability()); } return stability > cstab ? stability : -cstab; }
/** * Spurious, also for non-materialized clusters. * * @param clus Cluster, may be {@code null} for 1-element clusters. * @param isCore Core property * @return {@code true} if spurious. */ private boolean isSpurious(TempCluster clus, boolean isCore) { return clus != null ? clus.isSpurious(minClSize) : (minClSize > 1 || !isCore); }
/** * Excess of mass measure. * * @return Excess of mass */ public double excessOfMass() { return aggregate - totalElements() / dist; }
/** * Excess of mass measure. * * @return Excess of mass */ public double excessOfMass() { return aggregate - totalElements() / dist; }
/** * Reset the aggregate (for spurious clusters). * * @return {@code this} */ public TempCluster resetAggregate() { aggregate = totalElements() / dist; return this; }
/** * Excess of mass measure. * * @return Excess of mass */ public double totalStability() { double stability = excessOfMass(); double cstab = 0.; for(TempCluster child : children) { cstab += Math.abs(child.totalStability()); } return stability > cstab ? stability : -cstab; }
/** * Excess of mass measure. * * @return Excess of mass */ public double excessOfMass() { return aggregate - totalElements() / dist; }