public SparseMatrix getRedundant() {
   SparseMatrix redMat = new SparseMatrix(this).multiply(this);
   int oldCard = 0;
   int card = redMat.cardinality();
   int i = 0;
   // for(int r = 0; r < rowDim; r++){
   // if(true){//transMat.hasRow(r)){
   // transMat.add(r, r, 1.0);
   // }
   // if(true){//tcMat.hasRow(r)){
   // tcMat.add(r, r, 1.0);
   // }
   // }
   while (card > oldCard) {
     // System.out.println("iter: "+i);
     i++;
     oldCard = card;
     redMat = redMat.add(redMat.multiply(this));
     card = redMat.cardinality();
     // System.out.println(tcMat.toString());
   }
   return redMat;
 }
 public SparseMatrix transitiveClosure() {
   SparseMatrix tcMat = new SparseMatrix(this);
   SparseMatrix transMat = new SparseMatrix(this);
   int oldCard = 0;
   int card = tcMat.cardinality();
   int i = 0;
   // for(int r = 0; r < rowDim; r++){
   // if(true){//transMat.hasRow(r)){
   // transMat.add(r, r, 1.0);
   // }
   // if(true){//tcMat.hasRow(r)){
   // tcMat.add(r, r, 1.0);
   // }
   // }
   while (card > oldCard) {
     // System.out.println("iter: "+i);
     i++;
     oldCard = card;
     tcMat = tcMat.add(tcMat.multiply(transMat));
     card = tcMat.cardinality();
     // System.out.println(tcMat.toString());
   }
   return tcMat;
 }
  public static void main(String[] args) {
    long start;
    long end;
    int card;
    double seconds;
    double megaTEPs;
    System.out.println("Working");
    Random rand = new Random();
    int dim = 16384;
    int num = dim * 10;
    SparseMatrix testMat = new SparseMatrix(dim, dim);
    for (int i = 0; i < num; i++) {
      if ((i % (1024 * 32 * 20) == 0)) System.out.println(i + " of " + num);
      int r = rand.nextInt(dim);
      int c = rand.nextInt(dim);
      //		    int r = (i+2659)*3571%dim;
      //		    int c = (i+2659)*2081%dim;
      testMat.add(r, c, 1.0);
      testMat.add(c, r, 1.0);
      //			testMat.add(r, r, 1.0);
      //			testMat.add(c, c, 1.0);
      //			testMat.set(r, c, 1.0);
      //			testMat.set(c, r, 1.0);
    }
    boolean isSymm = true;
    int sum = 0;
    for (int r = 0; r < dim; r++) {
      for (int c = 0; c < dim; c++) {
        double val = testMat.get(r, c);
        sum += val;
        if (val > 0.0) {
          if (testMat.get(c, r) == 0) {
            isSymm = false;
          }
        }
      }
    }
    System.out.println(sum + " " + testMat.cardinality() + " " + isSymm);
    //		SparseMatrix testMat2 = new SparseMatrix(dim, dim);
    //		for (int i = 0; i < num; i++) {
    //			int r = rand.nextInt(dim);
    //			int c = rand.nextInt(dim);testMat
    //			testMat2.add(r, c, 1.0);
    //		}
    // start = System.currentTimeMillis();
    // SparseMatrix testMat3 = testMat.multiply(testMat2);
    // end = System.currentTimeMillis();
    // System.out.println("Time: "+(end-start));
    // System.out.println(testMat.cardinality()+" "+testMat.add(testMat2).cardinality()+"
    // "+testMat3.cardinality());

    //		start = System.currentTimeMillis();
    //		SparseMatrix apspRes = new SparseMatrix(testMat.rowDim, testMat.colDim);
    //		int T = 1;testMat
    //		for (int iter = 0; iter < T; iter++) {
    //			apspRes = testMat.apsp();
    //		}
    //		end = System.currentTimeMillis();
    //		System.out.println("Time: " + (end - start));
    //		card = testMat.cardinality();
    //		seconds = (double) (end - start) / 1000.0;
    //		megaTEPs = card / seconds * dim / 1000000.0;
    //		System.out.println("megaTEPs: " + megaTEPs);
    //		System.out.println(testMat.toString());
    //		System.out.println(apspRes.toString());

    // start = System.currentTimeMillis();
    // Counter bfsRes = new Counter();
    // int iterMax = dim;
    // for(int iter = 0; iter < iterMax; iter++){
    // int init = iter;
    // bfsRes = testMat.bfs(init);
    // // System.out.println(bfsRes.toString());
    // }
    // end = System.currentTimeMillis();
    // System.out.println("Time: "+(end-start));
    // card = testMat.cardinality();
    // seconds = (double)(end-start)/1000.0;
    // megaTEPs = card/seconds*iterMax/1000000.0;
    // System.out.println("megaTEPs: "+megaTEPs);
    // System.out.println(init);
    // System.out.println(testMat.toString());
    // System.out.println(bfsRes.toString());

    //		SparseMatrix testMatStoch = testMat.stochasticizeRows();
    //		double beta = 0.85;
    //		ArrayList<Double> vector = new ArrayList<Double>();
    //		for(int i = 0; i < dim; i++){
    //			vector.add(0.0);
    //			if(i == 0) vector.set(i,1.0);
    //		}
    //		ArrayList<Double> seedVector = new ArrayList<Double>(vector);
    //		double svCard = 0;
    //		for(int i = 0; i < dim; i++){
    //			svCard += seedVector.get(i);
    //		}
    //		ArrayList<Double> oldVector = new ArrayList<Double>(vector);
    //		vector = (ArrayList<Double>) testMatStoch.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 < 200){
    //			t += 1;
    //			vector = (ArrayList<Double>) testMatStoch.multiply(vector);
    //			double norm = 0;
    //			for(int i = 0; i < dim; i++){
    ////				norm += vector.get(i)*vector.get(i);
    //				norm += Math.abs(vector.get(i));
    //			}
    ////			norm = Math.sqrt(norm);
    //			for(int i = 0; i < dim; i++){r
    ////				vector.set(i,
    // beta*vector.get(i)/norm+(1-beta)*seedVector.get(i));///Math.max(norm,1.0));
    //				vector.set(i, beta*vector.get(i)+(1-beta)*seedVector.get(i));///Math.max(norm,1.0));
    //			}
    //			diff = 0;
    //			for(int i = 0; i < dim; i++){
    //				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 ArrayList<Double>(vector);
    //		}
    ////		System.out.println(testMatStoch.toStringValues());
    //		end = System.currentTimeMillis();
    //		System.out.println("Time: "+(end-start)+" iterations: "+t);

    //		Counter sv = new Counter();
    //		sv.set(rand.nextInt(dim),1.0);
    //		sv.set(0, 1.0);
    //		SparseMatrix.PersonalizedPageRank(sv, testMat);

    //		SparseMatrix laplacian = testMat.makeLaplacian();
    //		SparseMatrix normedLap = laplacian.stochasticizeRows();
    //		for(int i = 0; i < testMat.rowDim; i++){
    //			testMat.add(i,i,100.0);
    //		}
    //		SparseMatrix normedTest = testMat.stochasticizeRows();
    //		testMat = testMat.symmetric();
    SparseMatrix orthogMat = new SparseMatrix(0, testMat.colDim);
    Counter topEig = SparseMatrix.ConstrainedEig(testMat, orthogMat);
    //		Counter topEig = SparseMatrix.TopEig(testMat);
    //		for(int i = 0; i < orthogMat.colDim; i++){
    //			orthogMat.set(0, i, 1.0);
    //		}
    int topK = 10;
    for (int j = 0; j < topK; j++) {
      orthogMat.addRow(j, new Counter(topEig));
      //			double norm = testMat.multiply(topEig).norm();
      //			System.out.println("norm: "+norm);
      topEig = SparseMatrix.ConstrainedEig(testMat, orthogMat);
    }
    //		orthogMat.addRow(topK, new Counter(topEig));
    //		for(int i: orthogMat.rows){
    //			Counter eig = orthogMat.getRow(i);
    //			for(int j: orthogMat.rows){
    //				Counter eigOther = orthogMat.getRow(j);
    //				double sim = eig.dot(eigOther);
    ////				int sim = (int)(eig.dot(eigOther)+0.9999);
    //				System.out.print(sim+" ");
    //			}
    //			System.out.println();
    //		}

    // SparseMatrix tcMin = testMat.minimize().transitiveClosure();
    // SparseMatrix tcMat = testMat.transitiveClosure();
    // System.out.println(tcMin.cardinality()+" "+tcMat.cardinality());
    // testMat.add(0,0,1.0);
    // testMat.add(0,1,1.0);
    // testMat.add(1,1,1.0);
    // testMat.add(1,2,1.0);
    // testMat.add(2,2,1.0);
    // System.out.println(testMat.cardinality());
    // for(int t = 0; t < 1000; t++){
    // testMat = testMat.multiply(testMat);
    // System.out.println(testMat.cardinality());
    // }
    // System.out.println(testMat.toString());
  }