public void SmallSVD() { SquareMatrix A0 = new SquareMatrix(1); A0[0, 0] = 0.0; SingularValueDecomposition SVD0 = A0.SingularValueDecomposition(); Assert.IsTrue(SVD0.Contributors.Count == 1); Assert.IsTrue(SVD0.Contributors[0].SingularValue == 0.0); SquareMatrix A1 = new SquareMatrix(1); A1[0, 0] = 1.0; SingularValueDecomposition SVD1 = A1.SingularValueDecomposition(); Assert.IsTrue(SVD1.Contributors.Count == 1); Assert.IsTrue(SVD1.Contributors[0].SingularValue == 1.0); SquareMatrix A2 = new SquareMatrix(2); A2[0, 0] = 0.0; A2[0, 1] = 1.0; A2[1, 0] = 0.0; A2[1, 1] = 1.0; // Singular values should be Sqrt(2), 0 double[] s = new double[] { Math.Sqrt(2.0), 0.0 }; SingularValueDecomposition SVD2 = A2.SingularValueDecomposition(); SquareMatrix S2 = SVD2.LeftTransformMatrix.Transpose * A2 * SVD2.RightTransformMatrix; Assert.IsTrue(SVD2.Contributors.Count == 2); for (int i = 0; i < SVD2.Contributors.Count; i++) { double w = SVD2.Contributors[i].SingularValue; Assert.IsTrue(TestUtilities.IsNearlyEqual(w, s[i])); Assert.IsTrue(TestUtilities.IsNearlyEqual(S2[i, i], w)); } }
public void HilbertMatrixSVD() { int n = 4; SquareMatrix H = TestUtilities.CreateSymmetricHilbertMatrix(n).ToSquareMatrix(); SingularValueDecomposition SVD = H.SingularValueDecomposition(); Assert.IsTrue(SVD.RowCount == n); Assert.IsTrue(SVD.ColumnCount == n); Assert.IsTrue(SVD.ConditionNumber > 1.0); // Reconstruct matrix SquareMatrix H2 = new SquareMatrix(n); foreach (SingularValueContributor contributor in SVD.Contributors) { H2 += contributor.SingularValue * ((SquareMatrix)(contributor.LeftSingularVector * contributor.RightSingularVector.Transpose)); } // Use SVD to solve ColumnVector b = new ColumnVector(n); for (int i = 0; i < b.Dimension; i++) { b[i] = i; } ColumnVector x = SVD.Solve(b); Assert.IsTrue(TestUtilities.IsNearlyEqual(H * x, b)); }
public void SquareMatrixNotInvertable() { SquareMatrix A = new SquareMatrix(2); A[1, 1] = 1.0; // Inverting should throw try { A.Inverse(); Assert.IsTrue(false); } catch (DivideByZeroException) { } // LU Decomposing should throw try { A.LUDecomposition(); Assert.IsTrue(false); } catch (DivideByZeroException) { } // SVD should succeed, and give infinite condition number SingularValueDecomposition SVD = A.SingularValueDecomposition(); Assert.IsTrue(Double.IsInfinity(SVD.ConditionNumber)); }
public void SquareMatrixSVD() { for (int d = 4; d < 50; d += 7) { SquareMatrix A = CreateSquareRandomMatrix(d, d); SingularValueDecomposition SVD = A.SingularValueDecomposition(); Assert.IsTrue(SVD.Dimension == A.Dimension); ColumnVector x = new ColumnVector(d); for (int i = 0; i < d; i++) { x[i] = i; } ColumnVector b = A * x; ColumnVector b1 = SVD.LeftTransformMatrix().Transpose() * b; for (int i = 0; i < SVD.Rank; i++) { b1[i] = b1[i] / SVD.SingularValue(i); } ColumnVector b2 = SVD.RightTransformMatrix() * b1; ColumnVector y = SVD.Solve(b); Assert.IsTrue(TestUtilities.IsNearlyEqual(x, y)); } }
public void HilbertMatrixSVD() { int n = 4; SquareMatrix H = new SquareMatrix(n); for (int r = 0; r < n; r++) { for (int c = 0; c < n; c++) { H[r, c] = 1.0 / (r + c + 1); } } SingularValueDecomposition SVD = H.SingularValueDecomposition(); for (int i = 0; i < n; i++) { Console.WriteLine(SVD.SingularValue(i)); } SquareMatrix S = SVD.LeftTransformMatrix().Transpose() * H * SVD.RightTransformMatrix(); for (int i = 0; i < SVD.Dimension; i++) { Console.WriteLine(S[i, i]); Assert.IsTrue(TestUtilities.IsNearlyEqual(S[i, i], SVD.SingularValue(i))); } }
public void SmallSVD() { SquareMatrix A0 = new SquareMatrix(1); A0[0, 0] = 0.0; SingularValueDecomposition SVD0 = A0.SingularValueDecomposition(); Console.WriteLine(SVD0.SingularValue(0)); Assert.IsTrue(SVD0.SingularValue(0) == 0.0); SquareMatrix A1 = new SquareMatrix(1); A1[0, 0] = 1.0; SingularValueDecomposition SVD1 = A1.SingularValueDecomposition(); Console.WriteLine(SVD1.SingularValue(0)); //Assert.IsTrue(SVD1.SingularValue(0) == 1.0); SquareMatrix A2 = new SquareMatrix(2); A2[0, 0] = 0.0; A2[0, 1] = 1.0; A2[1, 0] = 0.0; A2[1, 1] = 1.0; // Singular values Sqrt(2), 0 SingularValueDecomposition SVD2 = A2.SingularValueDecomposition(); SquareMatrix S2 = SVD2.LeftTransformMatrix().Transpose() * A2 * SVD2.RightTransformMatrix(); for (int i = 0; i < SVD2.Dimension; i++) { Console.WriteLine("{0} {1}", S2[i, i], SVD2.SingularValue(i)); Assert.IsTrue(TestUtilities.IsNearlyEqual(S2[i, i], SVD2.SingularValue(i))); } }
public void Bug7685() { // This SVD failed with a NonconvergenceException. // Probably this was due to a zero appearing in the super-diagonal band in an intermediate position, since the code change to handle that eliminated the problem. SquareMatrix A = new SquareMatrix(new double[, ] { { 1.900019E+01, 0.000000E+00, 0.000000E+00, -1.385471E+02, 1.027977E+05, 1.520100E+04 }, { 0.000000E+00, 1.900019E+01, 0.000000E+00, -1.026921E+05, -1.499209E+02, 1.410499E+05 }, { 0.000000E+00, 0.000000E+00, 1.900019E+01, -1.499527E+04, -1.410719E+05, 0.000000E+00 }, { -1.385471E+02, -1.026921E+05, -1.499527E+04, 5.669219E+08, 1.101144E+08, -7.618976E+08 }, { 1.027977E+05, -1.499209E+02, -1.410719E+05, 1.101144E+08, 1.670648E+09, 8.113594E+07 }, { 1.520100E+04, 1.410499E+05, 0.000000E+00, -7.618976E+08, 8.113594E+07, 1.126334E+09 } }); SingularValueDecomposition SVD = A.SingularValueDecomposition(); foreach (SingularValueContributor contributor in SVD.Contributors) { Console.WriteLine(contributor.SingularValue); } }
public void SquareMatrixSVD() { for (int d = 4; d < 64; d += 7) { SquareMatrix A = CreateSquareRandomMatrix(d, d); SingularValueDecomposition SVD = A.SingularValueDecomposition(); Assert.IsTrue(SVD.Dimension == A.Dimension); // U has right dimensions and is orthogonal SquareMatrix U = SVD.LeftTransformMatrix; Assert.IsTrue(U.Dimension == A.Dimension); Assert.IsTrue(TestUtilities.IsNearlyEqual(U.MultiplyTransposeBySelf(), UnitMatrix.OfDimension(U.Dimension))); // V has right dimensions and is orthogonal SquareMatrix V = SVD.RightTransformMatrix; Assert.IsTrue(V.Dimension == A.Dimension); Assert.IsTrue(TestUtilities.IsNearlyEqual(V.MultiplyTransposeBySelf(), UnitMatrix.OfDimension(V.Dimension))); Assert.IsTrue(SVD.Dimension == A.Dimension); // The transforms decompose the matrix with the claimed singular values SquareMatrix S = U.Transpose * A * V; for (int i = 0; i < SVD.Contributors.Count; i++) { SingularValueContributor t = SVD.Contributors[i]; Assert.IsTrue(t.SingularValue >= 0.0); Assert.IsTrue(TestUtilities.IsNearlyEqual(S[i, i], t.SingularValue)); } // We can solve a rhs using the SVD ColumnVector x = new ColumnVector(d); for (int i = 0; i < d; i++) { x[i] = i; } ColumnVector b = A * x; ColumnVector y = SVD.Solve(b); Assert.IsTrue(TestUtilities.IsNearlyEqual(x, y)); } }
public void SquareMatrixLowRankSVD() { // Form a rank-2 dimension-3 square matrix ColumnVector c1 = new ColumnVector(1.0, 1.0, 0.0); ColumnVector c2 = new ColumnVector(1.0, -1.0, 0.0); SquareMatrix A = (SquareMatrix)(1.0E6 * c1 * c1.Transpose + 1.03 * c2 * c2.Transpose); SingularValueDecomposition SVD = A.SingularValueDecomposition(); // We should see the rank Assert.IsTrue(SVD.Rank == 2); // Solve a solve-able problem even though matrix is singular ColumnVector b = new ColumnVector(2.0, 1.0, 0.0); ColumnVector x = SVD.Solve(b); Assert.IsTrue(TestUtilities.IsNearlyEqual(A * x, b, 1.0E-6)); // Increasing the tolerance should decrease the rank SVD.Tolerance = 1.0E-4; Assert.IsTrue(SVD.Tolerance == 1.0E-4); Assert.IsTrue(SVD.Rank == 1); }