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) + ")"); } }
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 ) + ")" ); } } } } }