Пример #1
0
        public void testSVD()
        {
            //BOOST_MESSAGE("Testing singular value decomposition...");

            setup();

            double tol = 1.0e-12;
            Matrix[] testMatrices = { M1, M2, M3, M4 };

            for (int j = 0; j < testMatrices.Length; j++) {
                // m >= n required (rows >= columns)
                Matrix A = testMatrices[j];
                SVD svd = new SVD(A);
                // U is m x n
                Matrix U = svd.U();
                // s is n long
                Vector s = svd.singularValues();
                // S is n x n
                Matrix S = svd.S();
                // V is n x n
                Matrix V = svd.V();

                for (int i=0; i < S.rows(); i++) {
                    if (S[i,i] != s[i])
                        Assert.Fail("S not consistent with s");
                }

                // tests
                Matrix U_Utranspose = Matrix.transpose(U)*U;
                if (norm(U_Utranspose-I) > tol)
                    Assert.Fail("U not orthogonal (norm of U^T*U-I = " + norm(U_Utranspose-I) + ")");

                Matrix V_Vtranspose = Matrix.transpose(V) * V;
                if (norm(V_Vtranspose-I) > tol)
                    Assert.Fail("V not orthogonal (norm of V^T*V-I = " + norm(V_Vtranspose-I) + ")");

                Matrix A_reconstructed = U * S * Matrix.transpose(V);
                if (norm(A_reconstructed-A) > tol)
                    Assert.Fail("Product does not recover A: (norm of U*S*V^T-A = " + norm(A_reconstructed-A) + ")");
            }
        }
Пример #2
0
        public void testQRSolve()
        {
            // Testing QR solve...
               setup();

               double tol = 1.0e-12;
               MersenneTwisterUniformRng rng = new MersenneTwisterUniformRng( 1234 );
               Matrix bigM = new Matrix( 50, 100, 0.0 );
               for ( int i = 0; i < Math.Min( bigM.rows(), bigM.columns() ); ++i )
               {
              bigM[i, i] = i + 1.0;
               }
               Matrix[] testMatrices = { M1, M2, M3, Matrix.transpose(M3),
                                    M4, Matrix.transpose(M4), M5, I, M7, bigM, Matrix.transpose(bigM) };

               for ( int j = 0; j < testMatrices.Length; j++ )
               {
              Matrix A = testMatrices[j];
              Vector b = new Vector( A.rows() );

              for ( int k = 0; k < 10; ++k )
              {
                 for ( int i = 0; i < b.Count; ++i )
                 {
                    b[i] = rng.next().value;
                 }
                 Vector x = MatrixUtilities.qrSolve( A, b, true );

                 if ( A.columns() >= A.rows() )
                 {
                    if ( norm( A * x - b ) > tol )
                       Assert.Fail( "A*x does not match vector b (norm = "
                                  + norm( A * x - b ) + ")" );
                 }
                 else
                 {
                    // use the SVD to calculate the reference values
                    int n = A.columns();
                    Vector xr = new Vector( n, 0.0 );

                    SVD svd = new SVD( A );
                    Matrix V = svd.V();
                    Matrix U = svd.U();
                    Vector w = svd.singularValues();
                    double threshold = n * Const.QL_EPSILON;

                    for ( int i = 0; i < n; ++i )
                    {
                       if ( w[i] > threshold )
                       {
                          double u = 0;
                          int zero = 0;
                          for ( int kk = 0; kk < U.rows(); kk++ )
                             u += ( U[kk, i] * b[zero++] ) / w[i];

                          for ( int jj = 0; jj < n; ++jj )
                          {
                             xr[jj] += u * V[jj, i];
                          }
                       }
                    }

                    if ( norm( xr - x ) > tol )
                    {
                       Assert.Fail( "least square solution does not match (norm = "
                                  + norm( x - xr ) + ")" );

                    }
                 }
              }
               }
        }