@Override protected AGNES<O> makeInstance() { return new AGNES<>(distanceFunction, linkage); } }
@Override public TypeInformation[] getInputTypeRestriction() { // The input relation must match our distance function: return TypeUtil.array(getDistanceFunction().getInputTypeRestriction()); }
protected void findBest(int size, double[] scratch, double[] bestd, int[] besti, int j) { final int jbase = AGNES.triangleSize(j); // The distance has increased, we may no longer be the best merge. double bestdj = Double.POSITIVE_INFINITY; int bestij = -1; for(int i = 0, o = jbase; i < j; i++, o++) { if(besti[i] < 0) { continue; } if(scratch[o] < bestdj) { bestdj = scratch[o]; bestij = i; } } for(int i = j + 1, o = jbase + j + j; i < size; o += i, i++) { // assert(o == AGNES.triangleSize(i) + j); if(besti[i] < 0) { continue; } if(scratch[o] < bestdj) { bestdj = scratch[o]; bestij = i; } } bestd[j] = bestdj; besti[j] = bestij; }
DistanceQuery<O> dq = db.getDistanceQuery(relation, getDistanceFunction()); initializeDistanceMatrix(mat, dq, linkage); end = shrinkActiveSet(ix, builder, end, // findMerge(end, mat, builder)); LOG.incrementProcessed(prog);
DistanceQuery<O> dq = db.getDistanceQuery(relation, getDistanceFunction()); ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs()); final int size = ids.size(); double[] scratch = new double[triangleSize(size)]; DBIDArrayIter ix = ids.iter(), iy = ids.iter(); boolean square = WardLinkageMethod.class.isInstance(linkage) && !(SquaredEuclideanDistanceFunction.class.isInstance(getDistanceFunction())); initializeDistanceMatrix(scratch, dq, ix, iy, square); int wsize = size; for(int i = 1; i < size; i++) { int x = findMerge(wsize, scratch, ix, iy, builder); if(x == wsize - 1) { --wsize;
/** * Execute the cluster merge. * * @param end Active set size * @param mat Matrix paradigm * @param builder Hierarchy builder * @param mindist Distance that was used for merging * @param x First matrix position * @param y Second matrix position */ protected void merge(int end, MatrixParadigm mat, PointerHierarchyRepresentationBuilder builder, double mindist, int x, int y) { // Avoid allocating memory, by reusing existing iterators: final DBIDArrayIter ix = mat.ix.seek(x), iy = mat.iy.seek(y); if(LOG.isDebuggingFine()) { LOG.debugFine("Merging: " + DBIDUtil.toString(ix) + " -> " + DBIDUtil.toString(iy) + " " + mindist); } // Perform merge in data structure: x -> y assert (y < x); // Since y < x, prefer keeping y, dropping x. builder.add(ix, linkage.restore(mindist, getDistanceFunction().isSquared()), iy); // Update cluster size for y: final int sizex = builder.getSize(ix), sizey = builder.getSize(iy); builder.setSize(iy, sizex + sizey); updateMatrix(end, mat, builder, mindist, x, y, sizex, sizey); }
AGNES.initializeDistanceMatrix(mat, dq, linkage); DBIDArrayIter ix = mat.ix; for(int i = 1, end = size; i < size; i++) { end = AGNES.shrinkActiveSet(ix, builder, end, // findMerge(end, mat, bestd, besti, builder)); LOG.incrementProcessed(prog);
/** * Run the algorithm on a database. * * @param db Database * @param relation Relation to process. * @return Hierarchical result */ public PointerPrototypeHierarchyRepresentationResult run(Database db, Relation<O> relation) { DistanceQuery<O> dq = DatabaseUtil.precomputedDistanceQuery(db, relation, getDistanceFunction(), LOG); final DBIDs ids = relation.getDBIDs(); final int size = ids.size(); // Initialize space for result: PointerHierarchyRepresentationBuilder builder = new PointerHierarchyRepresentationBuilder(ids, dq.getDistanceFunction().isSquared()); Int2ObjectOpenHashMap<ModifiableDBIDs> clusters = new Int2ObjectOpenHashMap<>(size); // Allocate working space: MatrixParadigm mat = new MatrixParadigm(ids); ArrayModifiableDBIDs prots = DBIDUtil.newArray(MatrixParadigm.triangleSize(size)); initializeMatrices(mat, prots, dq); DBIDArrayMIter protiter = prots.iter(); FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("MiniMax clustering", size - 1, LOG) : null; DBIDArrayIter ix = mat.ix; for(int i = 1, end = size; i < size; i++) { end = AGNES.shrinkActiveSet(ix, builder, end, // findMerge(end, mat, protiter, builder, clusters, dq)); LOG.incrementProcessed(progress); } LOG.ensureCompleted(progress); return (PointerPrototypeHierarchyRepresentationResult) builder.complete(); }
continue; assert(xbase == triangleSize(ox)); for(int oy = 0; oy < ox; oy++) { merge(size, scratch, ix, iy, builder, mindist, x, y); return x;
double[] scratch = new double[AGNES.triangleSize(size)]; DBIDArrayIter ix = ids.iter(), iy = ids.iter(); AGNES.initializeDistanceMatrix(scratch, dq, ix, iy, square);
merge(end, mat, builder, mindist, x, y); return x;
/** * Execute the cluster merge. * * @param size Data set size * @param scratch Scratch space. * @param ix First iterator * @param iy Second iterator * @param builder Hierarchy builder * @param mindist Distance that was used for merging * @param x First matrix position * @param y Second matrix position */ protected void merge(int size, double[] scratch, DBIDArrayIter ix, DBIDArrayIter iy, PointerHierarchyRepresentationBuilder builder, double mindist, int x, int y) { // Avoid allocating memory, by reusing existing iterators: ix.seek(x); iy.seek(y); if(LOG.isDebuggingFine()) { LOG.debugFine("Merging: " + DBIDUtil.toString(ix) + " -> " + DBIDUtil.toString(iy) + " " + mindist); } // Perform merge in data structure: x -> y assert(y < x); // Since y < x, prefer keeping y, dropping x. builder.add(ix, mindist, iy); // Update cluster size for y: final int sizex = builder.getSize(ix), sizey = builder.getSize(iy); builder.setSize(iy, sizex + sizey); // Note: this changes iy. updateMatrix(size, scratch, iy, builder, mindist, x, y, sizex, sizey); }
DistanceQuery<O> dq = db.getDistanceQuery(relation, getDistanceFunction()); initializeDistanceMatrix(mat, dq, linkage); end = shrinkActiveSet(ix, builder, end, // findMerge(end, mat, builder)); LOG.incrementProcessed(prog);
/** * Execute the cluster merge. * * @param end Active set size * @param mat Matrix paradigm * @param builder Hierarchy builder * @param mindist Distance that was used for merging * @param x First matrix position * @param y Second matrix position */ protected void merge(int end, MatrixParadigm mat, PointerHierarchyRepresentationBuilder builder, double mindist, int x, int y) { // Avoid allocating memory, by reusing existing iterators: final DBIDArrayIter ix = mat.ix.seek(x), iy = mat.iy.seek(y); if(LOG.isDebuggingFine()) { LOG.debugFine("Merging: " + DBIDUtil.toString(ix) + " -> " + DBIDUtil.toString(iy) + " " + mindist); } // Perform merge in data structure: x -> y assert (y < x); // Since y < x, prefer keeping y, dropping x. builder.add(ix, linkage.restore(mindist, getDistanceFunction().isSquared()), iy); // Update cluster size for y: final int sizex = builder.getSize(ix), sizey = builder.getSize(iy); builder.setSize(iy, sizex + sizey); updateMatrix(end, mat, builder, mindist, x, y, sizex, sizey); }
AGNES.initializeDistanceMatrix(mat, dq, linkage); DBIDArrayIter ix = mat.ix; for(int i = 1, end = size; i < size; i++) { end = AGNES.shrinkActiveSet(ix, builder, end, // findMerge(end, mat, bestd, besti, builder)); LOG.incrementProcessed(prog);
/** * Run the algorithm on a database. * * @param db Database * @param relation Relation to process. * @return Hierarchical result */ public PointerPrototypeHierarchyRepresentationResult run(Database db, Relation<O> relation) { DistanceQuery<O> dq = DatabaseUtil.precomputedDistanceQuery(db, relation, getDistanceFunction(), LOG); final DBIDs ids = relation.getDBIDs(); final int size = ids.size(); // Initialize space for result: PointerHierarchyRepresentationBuilder builder = new PointerHierarchyRepresentationBuilder(ids, dq.getDistanceFunction().isSquared()); Int2ObjectOpenHashMap<ModifiableDBIDs> clusters = new Int2ObjectOpenHashMap<>(size); // Allocate working space: MatrixParadigm mat = new MatrixParadigm(ids); ArrayModifiableDBIDs prots = DBIDUtil.newArray(MatrixParadigm.triangleSize(size)); initializeMatrices(mat, prots, dq); DBIDArrayMIter protiter = prots.iter(); FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("MiniMax clustering", size - 1, LOG) : null; DBIDArrayIter ix = mat.ix; for(int i = 1, end = size; i < size; i++) { end = AGNES.shrinkActiveSet(ix, builder, end, // findMerge(end, mat, protiter, builder, clusters, dq)); LOG.incrementProcessed(progress); } LOG.ensureCompleted(progress); return (PointerPrototypeHierarchyRepresentationResult) builder.complete(); }
merge(end, mat, builder, mindist, x, y); return x;
DBIDArrayIter ix = mat.ix; for(int i = 1, end = size; i < size; i++) { end = AGNES.shrinkActiveSet(ix, builder, end, // findMerge(end, mat, protiter, builder, clusters, bestd, besti, dq)); LOG.incrementProcessed(prog);
@Override protected AGNES<O> makeInstance() { return new AGNES<>(distanceFunction, linkage); } }
@Override public TypeInformation[] getInputTypeRestriction() { // The input relation must match our distance function: return TypeUtil.array(getDistanceFunction().getInputTypeRestriction()); }