예제 #1
0
    // 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.;
    }
예제 #2
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;
  }
예제 #5
0
  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();
      }
    }
  }
예제 #6
0
  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();
      }
    }
  }