/** * Constructor. * @param proximity the proximity matrix to store the distance measure of * dissimilarity. To save space, we only need the lower half of matrix. */ public UPGMALinkage(double[][] proximity) { init(proximity); n = new int[proximity.length]; for (int i = 0; i < n.length; i++) n[i] = 1; }
/** * Returns the distance/dissimilarity between two clusters/objects, which * are indexed by integers. */ public float d(int i, int j) { return proximity[index(i, j)]; }
switch (linkageType) { case WARD: link = new WardLinkage(proximity); break; case COMPLETE: link = new CompleteLinkage(proximity); break; case SINGLE: link = new SingleLinkage(proximity); break; case UPGMA: link = new UPGMALinkage(proximity); break; case UPGMC: link = new UPGMCLinkage(proximity); break; case WPGMA: link = new WPGMALinkage(proximity); break; case WPGMC: link = new WPGMCLinkage(proximity); break; default: link = new SingleLinkage(proximity); break;
@Override public void merge(int i, int j) { for (int k = 0; k < i; k++) { proximity[index(i, k)] = (d(i, k) + d(j, k)) / 2 - d(j, i) / 4; } for (int k = i+1; k < j; k++) { proximity[index(k, i)] = (d(k, i) + d(j, k)) / 2 - d(j, i) / 4; } for (int k = j+1; k < size; k++) { proximity[index(k, i)] = (d(k, i) + d(k, j)) / 2 - d(j, i) / 4; } } }
@Override public void merge(int i, int j) { float nij = n[i] + n[j]; for (int k = 0; k < i; k++) { proximity[index(i, k)] = (d(i, k) * n[i] + d(j, k) * n[j] - d(j, i) * n[i] * n[j] / nij) / nij; } for (int k = i+1; k < j; k++) { proximity[index(k, i)] = (d(k, i) * n[i] + d(j, k) * n[j] - d(j, i) * n[i] * n[j] / nij) / nij; } for (int k = j+1; k < size; k++) { proximity[index(k, i)] = (d(k, i) * n[i] + d(k, j) * n[j] - d(j, i) * n[i] * n[j] / nij) / nij; } n[i] += n[j]; } }
@Override public void merge(int i, int j) { float nij = n[i] + n[j]; for (int k = 0; k < i; k++) { proximity[index(i, k)] = (d(i, k) * (n[i] + n[k]) + d(j, k) * (n[j] + n[k]) - d(j, i) * n[k]) / (nij + n[k]); } for (int k = i+1; k < j; k++) { proximity[index(k, i)] = (d(k, i) * (n[i] + n[k]) + d(j, k) * (n[j] + n[k]) - d(j, i) * n[k]) / (nij + n[k]); } for (int k = j+1; k < size; k++) { proximity[index(k, i)] = (d(k, i) * (n[i] + n[k]) + d(k, j) * (n[j] + n[k]) - d(j, i) * n[k]) / (nij + n[k]); } n[i] += n[j]; } }
/** * Find nearest neighbor of a given point. */ private void findNeighbor(int p) { // if no neighbors available, set flag for UpdatePoint to find if (npoints == 1) { neighbor[p] = p; distance[p] = Float.MAX_VALUE; return; } // find first point unequal to p itself int first = 0; if (p == points[first]) { first = 1; } neighbor[p] = points[first]; distance[p] = linkage.d(p, neighbor[p]); // now test whether each other point is closer for (int i = first + 1; i < npoints; i++) { int q = points[i]; if (q != p) { float d = linkage.d(p, q); if (d < distance[p]) { distance[p] = d; neighbor[p] = q; } } } }
/** * Constructor. * @param proximity the proximity matrix to store the distance measure of * dissimilarity. To save space, we only need the lower half of matrix. */ public WPGMALinkage(double[][] proximity) { init(proximity); }
/** * Constructor. * @param proximity the proximity matrix to store the distance measure of * dissimilarity. To save space, we only need the lower half of matrix. */ public CompleteLinkage(double[][] proximity) { init(proximity); }
/** * Constructor. * @param proximity the proximity matrix to store the distance measure of * dissimilarity. To save space, we only need the lower half of matrix. */ public WPGMCLinkage(double[][] proximity) { init(proximity); for (int i = 0; i < this.proximity.length; i++) { this.proximity[i] *= this.proximity[i]; } }
/** * Constructor. * @param proximity The proximity matrix to store the distance measure of * dissimilarity. To save space, we only need the lower half of matrix. */ public SingleLinkage(double[][] proximity) { init(proximity); }
/** * Constructor. * @param proximity the proximity matrix to store the distance measure of * dissimilarity. To save space, we only need the lower half of matrix. */ public WardLinkage(double[][] proximity) { init(proximity); n = new int[proximity.length]; for (int i = 0; i < n.length; i++) { n[i] = 1; } for (int i = 0; i < this.proximity.length; i++) { this.proximity[i] *= this.proximity[i]; } }
/** * Constructor. * @param proximity the proximity matrix to store the distance measure of * dissimilarity. To save space, we only need the lower half of matrix. */ public UPGMCLinkage(double[][] proximity) { init(proximity); n = new int[proximity.length]; for (int i = 0; i < n.length; i++) { n[i] = 1; } for (int i = 0; i < this.proximity.length; i++) { this.proximity[i] *= this.proximity[i]; } }
float nbd = Float.MAX_VALUE; for (int j = i + 1; j < npoints; j++) { float d = linkage.d(points[i], points[j]); if (d < nbd) { nbr = j;
/** * All distances to point have changed, check if our structures are ok * Note that although we completely recompute the neighbors of p, * we don't explicitly call findNeighbor, since that would double * the number of distance computations made by this routine. * Also, like deletion, we don't change any other point's neighbor to p. */ public void updatePoint(int p) { neighbor[p] = p; // flag for not yet found any distance[p] = Float.MAX_VALUE; for (int i = 0; i < npoints; i++) { int q = points[i]; if (q != p) { float d = linkage.d(p, q); if (d < distance[p]) { distance[p] = d; neighbor[p] = q; } if (neighbor[q] == p) { if (d > distance[q]) { findNeighbor(q); } else { distance[q] = d; } } } } }
/** * Single distance has changed, check if our structures are ok. */ public void updateDistance(int p, int q) { float d = linkage.d(p, q); if (d < distance[p]) { distance[p] = q; neighbor[p] = q; } else if (neighbor[p] == q && d > distance[p]) { findNeighbor(p); } if (d < distance[q]) { distance[q] = p; neighbor[q] = p; } else if (neighbor[q] == p && d > distance[q]) { findNeighbor(q); } } }