// assumes m > n public double apply(int first, int second, double third) { // System.out.println("m = " + m); // System.out.println("n = " + n); // System.out.println("first = " + first); if (m_col_mode) { // m == 2nd if (first != m) { // System.out.println("m = " + m); // System.out.println("n = " + n); // System.out.println("first = " + first); // System.out.println("val = " + m_parent.get(first, n) ); m_parent.set(first, n, m_parent.get(first, n) + third); } } else { // m == first if (second > n) { // System.out.println("m = " + m); // System.out.println("n = " + n); // System.out.println("first = " + first); // System.out.println("second = " + second); // System.out.println("val = " + m_parent.get(second, n) ); m_parent.set(second, n, m_parent.get(second, n) + third); } else if (second < n) { // System.out.println("m = " + m); // System.out.println("n = " + n); // System.out.println("first = " + first); // System.out.println("second = " + second); // System.out.println("val = " + m_parent.get(n, second) ); m_parent.set(n, second, m_parent.get(n, second) + third); } } return 0.; }
@Override public double[] solve(final double[] bIn) { if (bIn.length != rows()) { throw new IllegalArgumentException(); } final DoubleMatrix2D b = new DenseDoubleMatrix2D(rows(), 1); for (int i = 0; i < rows(); ++i) { b.set(i, 0, bIn[i]); } final DoubleMatrix2D a = new DenseDoubleMatrix2D(u); final DoubleMatrix2D p = Algebra.ZERO.solve(a, b); final double[] r = new double[cols()]; for (int i = 0; i < r.length; ++i) { r[i] = p.get(i, 0); } return r; }
/** * Generates a clusterer by the mean of spectral clustering algorithm. * * @param data set of instances serving as training data * @exception Exception if the clusterer has not been generated successfully */ public void buildClusterer(Instances data) throws java.lang.Exception { m_Sequences = new Instances(data); int n = data.numInstances(); int k = data.numAttributes(); DoubleMatrix2D w; if (useSparseMatrix) w = DoubleFactory2D.sparse.make(n, n); else w = DoubleFactory2D.dense.make(n, n); double[][] v1 = new double[n][]; for (int i = 0; i < n; i++) v1[i] = data.instance(i).toDoubleArray(); v = DoubleFactory2D.dense.make(v1); double sigma_sq = sigma * sigma; // Sets up similarity matrix for (int i = 0; i < n; i++) for (int j = i; j < n; j++) { /*double dist = distnorm2(v.viewRow(i), v.viewRow(j)); if((r == -1) || (dist < r)) { double sim = Math.exp(- (dist * dist) / (2 * sigma_sq)); w.set(i, j, sim); w.set(j, i, sim); }*/ /* String [] key = {data.instance(i).stringValue(0), data.instance(j).stringValue(0)}; System.out.println(key[0]); System.out.println(key[1]); System.out.println(simScoreMap.containsKey(key)); Double simValue = simScoreMap.get(key);*/ double sim = sim_matrix[i][j]; w.set(i, j, sim); w.set(j, i, sim); } // Partitions points int[][] p = partition(w, alpha_star); // Deploys results numOfClusters = p.length; cluster = new int[n]; for (int i = 0; i < p.length; i++) for (int j = 0; j < p[i].length; j++) cluster[p[i][j]] = i; // System.out.println("Final partition:"); // UtilsJS.printMatrix(p); // System.out.println("Cluster:\n"); // UtilsJS.printArray(cluster); this.numOfClusters = cluster[Utils.maxIndex(cluster)] + 1; // System.out.println("Num clusters:\t"+this.numOfClusters); }
/** * Returns the best cut of a graph w.r.t. the degree of dissimilarity between points of different * partitions and the degree of similarity between points of the same partition. * * @param W the weight matrix of the graph * @return an array of two elements, each of these contains the points of a partition */ protected static int[][] bestCut(DoubleMatrix2D W) { int n = W.columns(); // Builds the diagonal matrices D and D^(-1/2) (represented as their diagonals) DoubleMatrix1D d = DoubleFactory1D.dense.make(n); DoubleMatrix1D d_minus_1_2 = DoubleFactory1D.dense.make(n); for (int i = 0; i < n; i++) { double d_i = W.viewRow(i).zSum(); d.set(i, d_i); d_minus_1_2.set(i, 1 / Math.sqrt(d_i)); } DoubleMatrix2D D = DoubleFactory2D.sparse.diagonal(d); // System.out.println("DoubleMatrix2D :\n"+D.toString()); DoubleMatrix2D X = D.copy(); // System.out.println("DoubleMatrix2D copy :\n"+X.toString()); // X = D^(-1/2) * (D - W) * D^(-1/2) X.assign(W, Functions.minus); // System.out.println("DoubleMatrix2D X: (D-W) :\n"+X.toString()); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) X.set(i, j, X.get(i, j) * d_minus_1_2.get(i) * d_minus_1_2.get(j)); // Computes the eigenvalues and the eigenvectors of X EigenvalueDecomposition e = new EigenvalueDecomposition(X); DoubleMatrix1D lambda = e.getRealEigenvalues(); // Selects the eigenvector z_2 associated with the second smallest eigenvalue // Creates a map that contains the pairs <index, eigenvalue> AbstractIntDoubleMap map = new OpenIntDoubleHashMap(n); for (int i = 0; i < n; i++) map.put(i, Math.abs(lambda.get(i))); IntArrayList list = new IntArrayList(); // Sorts the map on the value map.keysSortedByValue(list); // Gets the index of the second smallest element int i_2 = list.get(1); // y_2 = D^(-1/2) * z_2 DoubleMatrix1D y_2 = e.getV().viewColumn(i_2).copy(); y_2.assign(d_minus_1_2, Functions.mult); // Creates a map that contains the pairs <i, y_2[i]> map.clear(); for (int i = 0; i < n; i++) map.put(i, y_2.get(i)); // Sorts the map on the value map.keysSortedByValue(list); // Search the element in the map previuosly ordered that minimizes the cut // of the partition double best_cut = Double.POSITIVE_INFINITY; int[][] partition = new int[2][]; // The array v contains all the elements of the graph ordered by their // projection on vector y_2 int[] v = list.elements(); // For each admissible splitting point i for (int i = 1; i < n; i++) { // The array a contains all the elements that have a projection on vector // y_2 less or equal to the one of i-th element // The array b contains the remaining elements int[] a = new int[i]; int[] b = new int[n - i]; System.arraycopy(v, 0, a, 0, i); System.arraycopy(v, i, b, 0, n - i); double cut = Ncut(W, a, b, v); if (cut < best_cut) { best_cut = cut; partition[0] = a; partition[1] = b; } } // System.out.println("Partition:"); // UtilsJS.printMatrix(partition); return partition; }
public void newmanCluster(ItemRegistry registry) { DoubleMatrix2D distance_matrix = DoubleFactory2D.sparse.make( registry.getGraph().getNodeCount(), registry.getGraph().getNodeCount()); DoubleMatrix1D a_matrix = DoubleFactory1D.dense.make(registry.getGraph().getNodeCount(), 0.); Map<String, Cluster> cluster_map = new HashMap<String, Cluster>(); // construct the leaf node distance matrix Iterator edge_iter = registry.getGraph().getEdges(); m_total_distances = 0.; while (edge_iter.hasNext()) { Edge edge = (Edge) edge_iter.next(); Cluster clust1 = (Cluster) edge.getFirstNode(); Cluster clust2 = (Cluster) edge.getSecondNode(); if (cluster_map.get(clust1.getAttribute("id")) == null) { cluster_map.put(clust1.getAttribute("id"), clust1); } if (cluster_map.get(clust2.getAttribute("id")) == null) { cluster_map.put(clust2.getAttribute("id"), clust2); } int n = Integer.parseInt(clust1.getAttribute("id")); int m = Integer.parseInt(clust2.getAttribute("id")); // make reciprocal (big values = good in newman, but not in our case) double dist = 1 / clust1.getCenter().distance(clust2.getCenter()); distance_matrix.set(Math.max(n, m), Math.min(n, m), dist); // m_total_distances += dist; // a_matrix.setQuick( n, a_matrix.getQuick( n ) + dist ); // a_matrix.setQuick( m, a_matrix.getQuick( m ) + dist ); m_total_distances += 1; a_matrix.setQuick(n, a_matrix.getQuick(n) + 1); a_matrix.setQuick(m, a_matrix.getQuick(m) + 1); } // System.out.println(distance_matrix); // System.out.println(count_matrix); // agglomerate nodes until we reach a root node (or nodes) boolean done = false; int trash = 0; QFinder qfinder = new QFinder(); qfinder.a_matrix = a_matrix; QMerger qmerger = new QMerger(); while (!done) { // find the minimum cluster distance qfinder.reset(); distance_matrix.forEachNonZero(qfinder); // done = true; // System.out.println(distance_matrix); // System.out.println(count_matrix); if (qfinder.getVal() == -Double.MAX_VALUE) { break; } // add a parent cluster to the graph Cluster clust1 = cluster_map.get("" + qfinder.getM()); Cluster clust2 = cluster_map.get("" + qfinder.getN()); while (clust1.getParent() != null) { clust1 = clust1.getParent(); } while (clust2.getParent() != null) { clust2 = clust2.getParent(); } trash++; double dist = Math.max(clust1.getHeight(), clust2.getHeight()); Cluster new_cluster = new DefaultCluster( (float) (clust1.getCenter().getX() + clust2.getCenter().getX()) / 2.f, (float) (clust1.getCenter().getY() + clust2.getCenter().getY()) / 2.f, (float) Math.sqrt( clust1.getRadius() * clust1.getRadius() + clust2.getRadius() * clust2.getRadius()), clust1, clust2, dist); registry.getGraph().addNode(new_cluster); // merge the clusters distances / counts int M = Math.max(qfinder.getM(), qfinder.getN()); int N = Math.min(qfinder.getM(), qfinder.getN()); a_matrix.set(N, a_matrix.getQuick(M) + a_matrix.getQuick(N)); a_matrix.set(M, 0); // System.out.println("M = "+M+" N = "+N + " VAL=" + minfinder.getVal() ); qmerger.setM(M); qmerger.setN(N); qmerger.setParent(distance_matrix); qmerger.setMode(true); // System.out.println(distance_matrix.viewPart( 0, M, distance_matrix.rows(), 1)); distance_matrix.viewPart(0, M, distance_matrix.rows(), 1).forEachNonZero(qmerger); qmerger.setMode(false); // System.out.println(distance_matrix.viewPart( M, 0, 1, M )); distance_matrix.viewPart(M, 0, 1, M).forEachNonZero(qmerger); // System.out.println(distance_matrix); // System.out.println(count_matrix); // free any superfluous memory randomly ~ (1/20) times if (Math.random() > 0.95) { distance_matrix.trimToSize(); } } }
public void shortestDistance(ItemRegistry registry) { // System.out.println(""+registry.getGraph().getNodeCount()); DoubleMatrix2D distance_matrix = DoubleFactory2D.sparse.make( registry.getGraph().getNodeCount(), registry.getGraph().getNodeCount()); DoubleMatrix2D count_matrix = DoubleFactory2D.sparse.make( registry.getGraph().getNodeCount(), registry.getGraph().getNodeCount()); Map<String, Cluster> cluster_map = new HashMap<String, Cluster>(); // construct the leaf node distance matrix Iterator edge_iter = registry.getGraph().getEdges(); while (edge_iter.hasNext()) { Edge edge = (Edge) edge_iter.next(); Cluster clust1 = (Cluster) edge.getFirstNode(); Cluster clust2 = (Cluster) edge.getSecondNode(); if (cluster_map.get(clust1.getAttribute("id")) == null) { cluster_map.put(clust1.getAttribute("id"), clust1); } if (cluster_map.get(clust2.getAttribute("id")) == null) { cluster_map.put(clust2.getAttribute("id"), clust2); } int n = Integer.parseInt(clust1.getAttribute("id")); int m = Integer.parseInt(clust2.getAttribute("id")); double dist = clust1.getCenter().distance(clust2.getCenter()); distance_matrix.set(Math.max(n, m), Math.min(n, m), dist); count_matrix.set(Math.max(n, m), Math.min(n, m), 1); } // System.out.println(distance_matrix); // System.out.println(count_matrix); // agglomerate nodes until we reach a root node (or nodes) boolean done = false; MinFinder minfinder = new MinFinder(); minfinder.count_matrix = count_matrix; Merger merger = new Merger(); while (!done) { // find the minimum cluster distance minfinder.reset(); distance_matrix.forEachNonZero(minfinder); // done = true; // System.out.println(distance_matrix); // System.out.println(count_matrix); if (minfinder.getVal() == Double.MAX_VALUE) { break; } // add a parent cluster to the graph Cluster clust1 = cluster_map.get("" + minfinder.getM()); Cluster clust2 = cluster_map.get("" + minfinder.getN()); while (clust1.getParent() != null) { clust1 = clust1.getParent(); } while (clust2.getParent() != null) { clust2 = clust2.getParent(); } // System.out.println("HERE!"); Cluster new_cluster = new DefaultCluster( (float) (clust1.getCenter().getX() + clust2.getCenter().getX()) / 2.f, (float) (clust1.getCenter().getY() + clust2.getCenter().getY()) / 2.f, (float) Math.sqrt( clust1.getRadius() * clust1.getRadius() + clust2.getRadius() * clust2.getRadius()), clust1, clust2, minfinder.getVal()); registry.getGraph().addNode(new_cluster); // merge the clusters distances / counts int M = Math.max(minfinder.getM(), minfinder.getN()); int N = Math.min(minfinder.getM(), minfinder.getN()); // System.out.println("M = "+M+" N = "+N + " VAL=" + minfinder.getVal() ); merger.setM(M); merger.setN(N); merger.setParent(distance_matrix); merger.setMode(true); // System.out.println(distance_matrix.viewPart( 0, M, distance_matrix.rows(), 1)); distance_matrix.viewPart(0, M, distance_matrix.rows(), 1).forEachNonZero(merger); merger.setMode(false); // System.out.println(distance_matrix.viewPart( M, 0, 1, M )); distance_matrix.viewPart(M, 0, 1, M).forEachNonZero(merger); merger.setParent(count_matrix); merger.setMode(true); count_matrix.viewPart(0, M, count_matrix.rows(), 1).forEachNonZero(merger); merger.setMode(false); count_matrix.viewPart(M, 0, 1, M).forEachNonZero(merger); // System.out.println(distance_matrix); // System.out.println(count_matrix); // free any superfluous memory randomly ~ (1/20) times if (Math.random() > 0.95) { distance_matrix.trimToSize(); } } }