/*
  * Should return path from initial node to terminal;
  * Means getting new path-backtracker
  */
 public Counter bfs(int initNode, int terminalNode) {
   Counter shortestPaths = new Counter();
   Counter currentNodes = new Counter();
   Counter newNodes = new Counter();
   shortestPaths.add(initNode, 0);
   newNodes.add(initNode, 0);
   while (!newNodes.isEmpty()) {
     currentNodes = new Counter(newNodes);
     newNodes = new Counter();
     for (int r : currentNodes.keySet()) {
       Counter row = this.getRow(r);
       for (int c : row.keySet()) {
         // Weighted case: later paths can be shorter than first path
         double pathLength = currentNodes.get(r) + row.get(c);
         if (pathLength < shortestPaths.getPath(c)) {
           newNodes.put(c, pathLength);
           shortestPaths.put(c, pathLength);
         }
       }
     }
     if (shortestPaths.getPath(terminalNode) < Double.MAX_VALUE / 2.0) {
       break;
     }
   }
   return shortestPaths;
 }
 public void add(int r, int c, double v) {
   Counter newRow = new Counter();
   newRow.add(c, v);
   this.addRow(r, newRow);
   rows.add(r);
   cols.add(c);
 }
 public static Counter ConstrainedEig(SparseMatrix mat, SparseMatrix orthogMat) {
   double trimEps = 0;
   int iterLimit = 10000;
   long start;
   long end;
   Counter vector = new Counter();
   int vecLen = mat.colDim;
   for (int i = 0; i < vecLen; i++) {
     //			vector.add(i, 1.0/Math.sqrt(vecLen));
     vector.add(i, Math.random() - 0.5);
   }
   Counter oldVector = new Counter();
   //		vector = mat.multiply(vector);
   //		for(int r: orthogMat.rows){
   //			Counter orthogRow = orthogMat.getRow(r);
   //			vector.orthogonalize(orthogRow);
   ////			System.out.println(vector.dot(orthogRow));
   //		}
   double norm = 0;
   double sim = 0;
   double diff = 1.0;
   double diffNeg = 1.0;
   int t = 0;
   start = System.currentTimeMillis();
   while (diff > Math.pow(10.0, -16.0) && diffNeg > Math.pow(10.0, -16.0) && t < iterLimit) {
     t += 1;
     //			vector.trimKeys(trimEps);
     oldVector = new Counter(vector);
     vector = mat.multiply(vector);
     for (int r : orthogMat.rows) {
       Counter orthogRow = orthogMat.getRow(r);
       //				System.out.println("before: "+vector.dot(orthogRow));
       vector.orthogonalize(orthogRow);
       //				System.out.println("after: "+vector.dot(orthogRow));
     }
     norm = 0;
     norm = vector.norm();
     vector.multiply(1.0 / norm);
     diff = 0;
     diffNeg = 0;
     Set<Integer> vecOldUnion = vector.concreteKeySet();
     vecOldUnion.addAll(oldVector.concreteKeySet());
     for (int i : vecOldUnion) {
       //			for(int i = 0; i < mat.colDim; i++){
       diff += (oldVector.get(i) - vector.get(i)) * (oldVector.get(i) - vector.get(i));
       diffNeg += (oldVector.get(i) + vector.get(i)) * (oldVector.get(i) + vector.get(i));
     }
     sim = vector.dot(oldVector);
     //			System.out.println(diff+" "+diffNeg+" "+sim+" "+norm+"
     // "+vector.dot(orthogMat.getRow(0)));
     //			System.out.println(vector.toString());
     // System.out.println(oldVector.toString());
   }
   System.out.println(norm + " " + orthogMat.rows.size() + " " + sim);
   //		System.out.println(mat.toStringValues());
   end = System.currentTimeMillis();
   System.out.println("Time: " + (end - start) + " iterations: " + t);
   return vector;
 }
 public static Counter TopEig(SparseMatrix mat) {
   double trimEps = 0.0;
   int iterLimit = 1000;
   long start;
   long end;
   Counter vector = new Counter();
   int vecLen = mat.colDim;
   //		for(int i = 0; i < vecLen; i++){
   //			vector.add(i, Math.random()-0.5);
   //		}
   for (int i = 0; i < vecLen; i++) {
     vector.add(i, 1.0 / (double) vecLen);
   }
   Counter oldVector = new Counter(vector);
   vector = mat.multiply(vector);
   double diff = 1;
   int t = 0;
   start = System.currentTimeMillis();
   while (diff > Math.pow(10.0, -10.0) && (diff < 3.99999 || diff > 4.00001) && t < iterLimit) {
     t += 1;
     vector.trimKeys(trimEps);
     vector = mat.multiply(vector);
     double norm = 0;
     for (int i : vector.keySet()) {
       norm += vector.get(i) * vector.get(i);
       //				norm += Math.abs(vector.get(i));
     }
     norm = Math.sqrt(norm);
     vector.multiply(1.0 / norm);
     diff = 0;
     Set<Integer> vecOldUnion = vector.concreteKeySet();
     vecOldUnion.addAll(oldVector.concreteKeySet());
     for (int i : vecOldUnion) {
       diff += (oldVector.get(i) - vector.get(i)) * (oldVector.get(i) - vector.get(i));
     }
     System.out.println(diff + " " + norm);
     //			System.out.println(vector.toString());
     // System.out.println(oldVector.toString());
     oldVector = new Counter(vector);
   }
   //		System.out.println(mat.toStringValues());
   end = System.currentTimeMillis();
   System.out.println("Time: " + (end - start) + " iterations: " + t);
   return vector;
 }