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));
            }
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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));
            }
        }
Beispiel #5
0
        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)));
            }
        }
Beispiel #7
0
        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);
            }
        }
Beispiel #8
0
        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));
            }
        }
Beispiel #9
0
        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);
        }