public void RandomRectangularSVD()
        {
            for (int c = 1; c < 64; c += 11)
            {
                Console.WriteLine(c);

                RectangularMatrix R = GenerateRandomMatrix(64, c);

                SingularValueDecomposition SVD = R.SingularValueDecomposition();

                Assert.IsTrue(SVD.RowCount == R.RowCount);
                Assert.IsTrue(SVD.ColumnCount == SVD.ColumnCount);
                Assert.IsTrue(SVD.Dimension == SVD.ColumnCount);

                SquareMatrix U = SVD.LeftTransformMatrix();
                Assert.IsTrue(U.Dimension == R.RowCount);
                Assert.IsTrue(TestUtilities.IsNearlyEqual(U.Transpose() * U, TestUtilities.CreateSquareUnitMatrix(U.Dimension)));

                SquareMatrix V = SVD.RightTransformMatrix();
                Assert.IsTrue(V.Dimension == R.ColumnCount);
                Assert.IsTrue(TestUtilities.IsNearlyEqual(V.Transpose() * V, TestUtilities.CreateSquareUnitMatrix(V.Dimension)));

                RectangularMatrix S = U.Transpose() * R * V;
                for (int i = 0; i < SVD.Dimension; i++)
                {
                    double w = SVD.SingularValue(i);
                    Console.WriteLine("  {0} {1}", w, S[i, i]);
                    Assert.IsTrue(w >= 0.0);
                    Assert.IsTrue(TestUtilities.IsNearlyEqual(S[i, i], w));
                    Assert.IsTrue(TestUtilities.IsNearlyEqual(R * SVD.RightSingularVector(i), w * SVD.LeftSingularVector(i)));
                }
            }
        }
Exemple #2
0
 public void Bug7686()
 {
     // This SVD failed with a IndexOutOfBoundsException because we didn't handle SVD for cols > rows and didn't check for this condition on entry.
     RectangularMatrix A = new RectangularMatrix(new double[, ] {
         { -418.746, 310.726, 313.969, 1 },
         { -418.746, 337.451, 229.786, 1 },
         { -305.253, 321.895, 304.895, 1 }
     });
     var SVD = A.SingularValueDecomposition();
 }
Exemple #3
0
 public void Bug56()
 {
     RectangularMatrix M = new RectangularMatrix(new double[, ] {
         { 44.6667, -392.0000, -66.0000 },
         { -392.0000, 3488.0000, 504.0001 },
         { -66.0000, 504.0001, 216.0001 }
     });
     //M = M.Transpose;
     SingularValueDecomposition S = M.SingularValueDecomposition();
 }
        public void BigSVD()
        {
            RectangularMatrix R = GenerateRandomMatrix(500, 100);

            Stopwatch s = Stopwatch.StartNew();
            SingularValueDecomposition SVD = R.SingularValueDecomposition();

            s.Stop();

            Console.WriteLine(s.Elapsed);
            Console.WriteLine(SVD.ConditionNumber);
        }
        public void SvdOfRankOneMatrix()
        {
            // Create a rank-1 matrix
            ColumnVector      v = new ColumnVector(1.0, 2.0, 3.0, 4.0);
            RectangularMatrix A = v * v.Transpose();

            // Only the first singular value should be non-zero
            SingularValueDecomposition SVD = A.SingularValueDecomposition();

            Console.WriteLine(SVD.SingularValue(0));
            for (int i = 1; i < SVD.Dimension; i++)
            {
                Console.WriteLine(SVD.SingularValue(i));
                Assert.IsTrue(SVD.SingularValue(i) < TestUtilities.TargetPrecision * SVD.SingularValue(0));
            }
        }
        public void RandomRectangularSVD()
        {
            for (int c = 1; c < 64; c += 11)
            {
                Console.WriteLine(c);

                RectangularMatrix R = GenerateRandomMatrix(64, c);

                SingularValueDecomposition SVD = R.SingularValueDecomposition();

                Assert.IsTrue(SVD.RowCount == R.RowCount);
                Assert.IsTrue(SVD.ColumnCount == SVD.ColumnCount);
                Assert.IsTrue(SVD.Dimension == SVD.ColumnCount);

                // U has right dimensions and is orthogonal
                SquareMatrix U = SVD.LeftTransformMatrix;
                Assert.IsTrue(U.Dimension == R.RowCount);
                Assert.IsTrue(TestUtilities.IsNearlyEqual(U.Transpose * U, UnitMatrix.OfDimension(U.Dimension)));

                // V has right dimensions and is orthogonal
                SquareMatrix V = SVD.RightTransformMatrix;
                Assert.IsTrue(V.Dimension == R.ColumnCount);
                Assert.IsTrue(TestUtilities.IsNearlyEqual(V.Transpose * V, UnitMatrix.OfDimension(V.Dimension)));

                // The transforms decompose the matrix with the claimed singular values
                RectangularMatrix S = U.Transpose * R * 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));
                    Assert.IsTrue(TestUtilities.IsNearlyEqual(R * t.RightSingularVector, t.SingularValue * t.LeftSingularVector));
                }

                // We can reconstruct the original matrix from the claimed singular values
                RectangularMatrix R2 = new RectangularMatrix(SVD.RowCount, SVD.ColumnCount);
                foreach (SingularValueContributor t in SVD.Contributors)
                {
                    R2 += t.SingularValue * t.LeftSingularVector * t.RightSingularVector.Transpose;
                }
                Assert.IsTrue(TestUtilities.IsNearlyEqual(R, R2));
            }
        }
        public void SvdOfRankOneMatrix()
        {
            // Create a rank-1 matrix
            ColumnVector      v = new ColumnVector(1.0, 2.0, 3.0, 4.0);
            RectangularMatrix A = v * v.Transpose;

            SingularValueDecomposition SVD = A.SingularValueDecomposition();

            // The rank should be 1
            Assert.IsTrue(SVD.Rank == 1);

            // Only the first singular value should be non-zero
            double w = SVD.Contributors[0].SingularValue;

            Assert.IsTrue(w > 0.0);
            for (int i = 1; i < SVD.Contributors.Count; i++)
            {
                Assert.IsTrue(SVD.Contributors[i].SingularValue < TestUtilities.TargetPrecision * w);
            }
        }
        public void PC()
        {
            Random rng = new Random(1);
            double s   = 1.0 / Math.Sqrt(2.0);

            MultivariateSample MS = new MultivariateSample(2);
            RectangularMatrix  R  = new RectangularMatrix(1000, 2);

            for (int i = 0; i < 1000; i++)
            {
                double r1 = 2.0 * rng.NextDouble() - 1.0;
                double r2 = 2.0 * rng.NextDouble() - 1.0;
                double x  = r1 * 4.0 * s - r2 * 9.0 * s;
                double y  = r1 * 4.0 * s + r2 * 9.0 * s;
                R[i, 0] = x; R[i, 1] = y;
                MS.Add(x, y);
            }

            Console.WriteLine("x {0} {1}", MS.Column(0).Mean, MS.Column(0).Variance);
            Console.WriteLine("y {0} {1}", MS.Column(1).Mean, MS.Column(1).Variance);

            Console.WriteLine("SVD");

            SingularValueDecomposition SVD = R.SingularValueDecomposition();

            for (int i = 0; i < SVD.Dimension; i++)
            {
                Console.WriteLine("{0} {1}", i, SVD.SingularValue(i));
                ColumnVector v = SVD.RightSingularVector(i);
                Console.WriteLine("  {0} {1}", v[0], v[1]);
            }

            Console.WriteLine("PCA");

            PrincipalComponentAnalysis PCA = MS.PrincipalComponentAnalysis();

            Console.WriteLine("Dimension = {0} Count = {1}", PCA.Dimension, PCA.Count);
            for (int i = 0; i < PCA.Dimension; i++)
            {
                PrincipalComponent PC = PCA.Component(i);
                Console.WriteLine("  {0} {1} {2} {3}", PC.Index, PC.Weight, PC.VarianceFraction, PC.CumulativeVarianceFraction);
                RowVector v = PC.NormalizedVector();
                Console.WriteLine("  {0} {1}", v[0], v[1]);
            }

            // reconstruct
            SquareMatrix U  = SVD.LeftTransformMatrix();
            SquareMatrix V  = SVD.RightTransformMatrix();
            double       x1 = U[0, 0] * SVD.SingularValue(0) * V[0, 0] + U[0, 1] * SVD.SingularValue(1) * V[0, 1];

            Console.WriteLine("x1 = {0} {1}", x1, R[0, 0]);
            double y1 = U[0, 0] * SVD.SingularValue(0) * V[1, 0] + U[0, 1] * SVD.SingularValue(1) * V[1, 1];

            Console.WriteLine("y1 = {0} {1}", y1, R[0, 1]);
            double x100 = U[100, 0] * SVD.SingularValue(0) * V[0, 0] + U[100, 1] * SVD.SingularValue(1) * V[0, 1];

            Console.WriteLine("x100 = {0} {1}", x100, R[100, 0]);
            double y100 = U[100, 0] * SVD.SingularValue(0) * V[1, 0] + U[100, 1] * SVD.SingularValue(1) * V[1, 1];

            Console.WriteLine("y100 = {0} {1}", y100, R[100, 1]);

            ColumnVector d1 = U[0, 0] * SVD.SingularValue(0) * SVD.RightSingularVector(0) +
                              U[0, 1] * SVD.SingularValue(1) * SVD.RightSingularVector(1);

            Console.WriteLine("d1 = ({0} {1})", d1[0], d1[1]);
            ColumnVector d100 = U[100, 0] * SVD.SingularValue(0) * SVD.RightSingularVector(0) +
                                U[100, 1] * SVD.SingularValue(1) * SVD.RightSingularVector(1);

            Console.WriteLine("d100 = ({0} {1})", d100[0], d100[1]);

            Console.WriteLine("compare");
            MultivariateSample     RS  = PCA.TransformedSample();
            IEnumerator <double[]> RSE = RS.GetEnumerator();

            RSE.MoveNext();
            double[] dv1 = RSE.Current;
            Console.WriteLine("{0} {1}", dv1[0], dv1[1]);
            Console.WriteLine("{0} {1}", U[0, 0], U[0, 1]);
            RSE.Dispose();
        }