/** Checks to see if all the real eigenvectors are linearly independent of each other. */
  public void testVectorsLinearlyIndependent(SymmetricQRAlgorithmDecomposition alg) {
    int N = alg.getNumberOfEigenvalues();

    // create a matrix out of the eigenvectors
    Matrix A = Matrix.create(N, N);

    int off = 0;
    for (int i = 0; i < N; i++) {
      AVector v = alg.getEigenVector(i);

      // it can only handle real eigenvectors
      if (v == null) off++;
      else {
        for (int j = 0; j < N; j++) {
          A.set(i - off, j, v.get(j));
        }
      }
    }

    // see if there are any real eigenvectors
    if (N == off) return;

    //        A.reshape(N-off,N, false);
    A = A.reshape(N - off, N);

    AltLU lu = new AltLU();
    lu._decompose(A);
    assertFalse(lu.isSingular());
    //        assertTrue(MatrixFeatures.isRowsLinearIndependent(A));
  }
  /** Sees if the pair of eigenvalue and eigenvector was found in the decomposition. */
  public void testForEigenpair(
      SymmetricQRAlgorithmDecomposition alg, double valueReal, double valueImg, double... vector) {
    int N = alg.getNumberOfEigenvalues();

    int numMatched = 0;
    for (int i = 0; i < N; i++) {
      Vector2 c = alg.getEigenvalue(i);

      if (Math.abs(c.x - valueReal) < 1e-4 && Math.abs(c.y - valueImg) < 1e-4) {

        //                if( c.isReal() ) {
        if (Math.abs(c.y - 0) < 1e-8)
          if (vector.length > 0) {
            AVector v = alg.getEigenVector(i);
            AMatrix e = Matrix.createFromRows(vector);
            e = e.getTranspose();

            Matrix t = Matrix.create(v.length(), 1);
            t.setColumn(0, v);
            double error = diffNormF(e, t);
            //                        CommonOps.changeSign(e);
            e.multiply(-1);
            double error2 = diffNormF(e, t);

            if (error < 1e-3 || error2 < 1e-3) numMatched++;
          } else {
            numMatched++;
          }
        else if (Math.abs(c.y - 0) > 1e-8) {
          numMatched++;
        }
      }
    }

    assertEquals(1, numMatched);
  }
  /**
   * Checks to see if an eigenvalue is complex then the eigenvector is null. If it is real it then
   * checks to see if the equation A*v = lambda*v holds true.
   */
  public void testPairsConsistent(SymmetricQRAlgorithmDecomposition alg, Matrix A) {
    //
    // System.out.println("-------------------------------------------------------------------------");
    int N = alg.getNumberOfEigenvalues();

    for (int i = 0; i < N; i++) {
      Vector2 c = alg.getEigenvalue(i);
      AVector v = alg.getEigenVector(i);

      if (Double.isInfinite(c.x)
          || Double.isNaN(c.x)
          || Double.isInfinite(c.y)
          || Double.isNaN(c.y)) fail("Uncountable eigenvalue");

      if (Math.abs(c.y) > 1e-20) {
        assertTrue(v == null);
      } else {
        assertTrue(v != null);
        //                if( MatrixFeatures.hasUncountable(v)) {
        //                    throw new RuntimeException("Egads");
        //                }
        assertFalse(v.hasUncountable());

        //                CommonOps.mult(A,v,tempA);
        Matrix ta = Matrix.create(A.rowCount(), 1);
        ta.setColumn(0, (v));
        AMatrix tempA = Multiplications.multiply(A, ta);
        //                CommonOps.scale(c.real,v,tempB);
        Matrix tb = Matrix.create(v.length(), 1);
        tb.setColumn(0, v);
        AMatrix tempB = tb.multiplyCopy(c.x);
        //                double max = NormOps.normPInf(A);
        double max = normPInf(A);
        if (max == 0) max = 1;

        double error = diffNormF(tempA, tempB) / max;

        if (error > 1e-12) {
          //                    System.out.println("Original matrix:");
          //                    System.out.println(A);
          //                    A.print();
          //                    System.out.println("Eigenvalue = "+c.x);
          //                    Eigenpair p = EigenOps.computeEigenVector(A,c.real);
          //                    p.vector.print();
          //                    v.print();
          //
          //
          //                    CommonOps.mult(A,p.vector,tempA);
          //                    CommonOps.scale(c.real,p.vector,tempB);
          //
          //                    max = NormOps.normPInf(A);
          //
          //                    System.out.println("error before = "+error);
          //                    error = SpecializedOps.diffNormF(tempA,tempB)/max;
          //                    System.out.println("error after = "+error);
          //                    A.print("%f");
          //                    System.out.println();
          fail("Error was too large");
        }

        assertTrue(error <= 1e-12);
      }
    }
  }