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) { QAssert.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) { QAssert.Fail("least square solution does not match (norm = " + norm(x - xr) + ")"); } } } } }