public void InverseTest()
        {
            double[,] value = new double[,]
            { 
                  { 1.0, 1.0 },
                  { 2.0, 2.0 }
            };

            var target = new SingularValueDecomposition(value);

            double[,] expected = new double[,]
            {
               { 0.1, 0.2 },
               { 0.1, 0.2 }
            };

            double[,] actual = target.Solve(Matrix.Identity(2));
            Assert.IsTrue(Matrix.IsEqual(expected, actual, 1e-3));
            Assert.IsTrue(Matrix.IsEqual(value, target.Reverse(), 1e-3));

            actual = target.Inverse();
            Assert.IsTrue(Matrix.IsEqual(expected, actual, 1e-3));
        }
        public void InverseTest2()
        {
            int n = 5;

            var I = Matrix.Identity(n);

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    double[,] value = Matrix.Magic(n);

                    var target = new SingularValueDecomposition(value);

                    double[,] solution = target.Solve(I);
                    double[,] inverse = target.Inverse();
                    double[,] reverse = target.Reverse();

                    Assert.IsTrue(Matrix.IsEqual(solution, inverse, 1e-4));
                    Assert.IsTrue(Matrix.IsEqual(value, reverse, 1e-4));
                }
            }
        }
        public void SingularValueDecompositionConstructorTest7()
        {
            int count = 100;
            double[,] value = new double[count, 3];
            double[] output = new double[count];

            for (int i = 0; i < count; i++)
            {
                double x = i + 1;
                double y = 2 * (i + 1) - 1;
                value[i, 0] = x;
                value[i, 1] = y;
                value[i, 2] = 1;
                output[i] = 4 * x - y + 3;
            }



            SingularValueDecomposition target = new SingularValueDecomposition(value,
                computeLeftSingularVectors: true,
                computeRightSingularVectors: true);

            {
                double[,] expected = value;
                double[,] actual = Matrix.Multiply(Matrix.Multiply(target.LeftSingularVectors, 
                    Matrix.Diagonal(target.Diagonal)), target.RightSingularVectors.Transpose());

                // Checking the decomposition
                Assert.IsTrue(Matrix.IsEqual(actual, expected, 1e-8));
                Assert.IsTrue(Matrix.IsEqual(target.Reverse(), expected, 1e-8));
            }

            {
                double[] solution = target.Solve(output);

                double[] expected= output;
                double[] actual = value.Multiply(solution);

                Assert.IsTrue(Matrix.IsEqual(actual, expected, 1e-8));
            }
        }
        public void SingularValueDecompositionConstructorTest6()
        {
            // Test using SVD assumption auto-correction feature in place

            double[,] value1 =
            {
                { 2.5,  2.4 },
                { 0.5,  0.7 },
                { 2.2,  2.9 },
                { 1.9,  2.2 },
                { 3.1,  3.0 },
                { 2.3,  2.7 },
                { 2.0,  1.6 },
                { 1.0,  1.1 },
                { 1.5,  1.6 },
                { 1.1,  0.9 }
            };

            double[,] value2 = value1.Transpose();

            var cvalue1 = value1.Copy();
            var cvalue2 = value2.Copy();

            var target1 = new SingularValueDecomposition(cvalue1, true, true, true, true);
            var target2 = new SingularValueDecomposition(cvalue2, true, true, true, true);

            Assert.IsFalse(cvalue1.IsEqual(value1, 1e-5));
            // Assert.IsFalse(cvalue2.IsEqual(value2, 1e-5));

            Assert.IsTrue(target1.LeftSingularVectors.IsEqual(target2.RightSingularVectors));
            Assert.IsTrue(target1.RightSingularVectors.IsEqual(target2.LeftSingularVectors));
            Assert.IsTrue(target1.DiagonalMatrix.IsEqual(target2.DiagonalMatrix));

            Assert.IsTrue(Matrix.IsEqual(target1.Reverse(), value1, 1e-5));
            Assert.IsTrue(Matrix.IsEqual(target2.Reverse(), value2, 1e-5));
        }
        public void SingularValueDecompositionConstructorTest2()
        {
            // test for m-x-n matrices where m > n (4 > 2)

            double[,] value = new double[,]
             { 
                 { 1, 2 },
                 { 3, 4 },
                 { 5, 6 },
                 { 7, 8 }
             }; // value is 4x2, thus having more rows than columns


            SingularValueDecomposition target = new SingularValueDecomposition(value, true, true, false);

            double[,] actual = Matrix.Multiply(Matrix.Multiply(target.LeftSingularVectors,
                Matrix.Diagonal(target.Diagonal)), target.RightSingularVectors.Transpose());

            // Checking the decomposition
            Assert.IsTrue(Matrix.IsEqual(actual, value, 0.01));
            Assert.IsTrue(Matrix.IsEqual(target.Reverse(), value, 1e-2));

            double[,] U = // economy svd
            {
                {  0.152483233310201,  0.822647472225661,  },
                {  0.349918371807964,  0.421375287684580,  },
                {  0.547353510305727,  0.0201031031435023, },
                {  0.744788648803490, -0.381169081397574,  },
            };

            // U should be equal except for some sign changes
            Assert.IsTrue(Matrix.IsEqual(target.LeftSingularVectors, U, 0.001));



            // Checking values
            double[,] V =
            {
                {  0.641423027995072, -0.767187395072177 },
                {  0.767187395072177,  0.641423027995072 },
            };

            // V should be equal except for some sign changes
            Assert.IsTrue(Matrix.IsEqual(target.RightSingularVectors, V, 0.0001));


            double[,] S = 
            {
                { 14.2690954992615, 0.000000000000000 },
                {  0.0000000000000,	0.626828232417543 },
            };

            // The diagonal values should be equal
            Assert.IsTrue(Matrix.IsEqual(target.Diagonal, Matrix.Diagonal(S), 0.001));
        }
        public void SingularValueDecompositionConstructorTest3()
        {
            // Test using SVD assumption auto-correction feature.

            // Test for m-x-n matrices where m < n. The available SVD
            // routine was not meant to be used in this case.

            double[,] value = new double[,]
             { 
                 { 1, 2 },
                 { 3, 4 },
                 { 5, 6 },
                 { 7, 8 }
             }.Transpose(); // value is 2x4, having less rows than columns.

            var target = new SingularValueDecomposition(value, true, true, true);

            double[,] actual = Matrix.Multiply(Matrix.Multiply(target.LeftSingularVectors, 
                Matrix.Diagonal(target.Diagonal)), target.RightSingularVectors.Transpose());

            // Checking the decomposition
            Assert.IsTrue(Matrix.IsEqual(actual, value, 0.01));
            Assert.IsTrue(Matrix.IsEqual(target.Reverse(), value, 1e-2));
            
            // Checking values
            double[,] U =
            {
                { 0.641423027995072, -0.767187395072177 },
                { 0.767187395072177,  0.641423027995072 },
            };

            // U should be equal despite some sign changes
            Assert.IsTrue(Matrix.IsEqual(target.LeftSingularVectors, U, 0.001));


            double[,] V = // economy svd
            {
                {  0.152483233310201,  0.822647472225661,  },
                {  0.349918371807964,  0.421375287684580,  },
                {  0.547353510305727,  0.0201031031435023, },
                {  0.744788648803490, -0.381169081397574,  },
            };

            // V can be different, but for the economy SVD it is often equal
            Assert.IsTrue(Matrix.IsEqual(target.RightSingularVectors, V, 0.0001));


            double[,] S = 
            {
                { 14.2690954992615, 0.000000000000000 },
                {  0.0000000000000,	0.626828232417543 },
            };

            // The diagonal values should be equal
            Assert.IsTrue(Matrix.IsEqual(target.Diagonal, Matrix.Diagonal(S), 0.001));
        }
        public void SingularValueDecompositionConstructorTest1()
        {
            // This test catches the bug in SingularValueDecomposition in the line
            //   for (int j = k + 1; j < nu; j++)
            // where it should be
            //   for (int j = k + 1; j < n; j++)


            // Test for m-x-n matrices where m < n. The available SVD
            // routine was not meant to be used in this case.

            double[,] value = new double[,]
             { 
                 { 1, 2 },
                 { 3, 4 },
                 { 5, 6 },
                 { 7, 8 }
             }.Transpose(); // value is 2x4, having less rows than columns.

            var target = new SingularValueDecomposition(value, true, true, false);

            double[,] actual = target.LeftSingularVectors.Multiply(
                target.DiagonalMatrix).Multiply(target.RightSingularVectors.Transpose());

            // Checking the decomposition
            Assert.IsTrue(Matrix.IsEqual(actual, value, 1e-2));
            Assert.IsTrue(Matrix.IsEqual(target.Reverse(), value, 1e-2));

            // Checking values
            double[,] U =
            {
                { -0.641423027995072, -0.767187395072177 },
                { -0.767187395072177,  0.641423027995072 },
            };

            // U should be equal
            Assert.IsTrue(Matrix.IsEqual(target.LeftSingularVectors, U, 0.001));


            double[,] V = // economy svd
            {
                { -0.152483233310201,  0.822647472225661,  },
                { -0.349918371807964,  0.421375287684580,  },
                { -0.547353510305727,  0.0201031031435023, },
                { -0.744788648803490, -0.381169081397574,  },
            };

            // V can be different, but for the economy SVD it is often equal
            Assert.IsTrue(Matrix.IsEqual(target.RightSingularVectors.Submatrix(0, 3, 0, 1), V, 0.0001));


            double[,] S = 
            {
                { 14.2690954992615, 0.000000000000000 },
                {  0.0000000000000,	0.626828232417543 },
            };

            // The diagonal values should be equal
            Assert.IsTrue(Matrix.IsEqual(target.Diagonal.First(2), 
                Matrix.Diagonal(S), 0.001));
        }