void test_svd(const std::string & fn, ScalarType EPS) { std::size_t sz1, sz2; //read matrix // sz1 = 2048, sz2 = 2048; // std::vector<ScalarType> in(sz1 * sz2); // random_fill(in); // read file std::fstream f(fn.c_str(), std::fstream::in); //read size of input matrix read_matrix_size(f, sz1, sz2); std::size_t to = std::min(sz1, sz2); viennacl::matrix<ScalarType> Ai(sz1, sz2), Aref(sz1, sz2), QL(sz1, sz1), QR(sz2, sz2); read_matrix_body(f, Ai); std::vector<ScalarType> sigma_ref(to); read_vector_body(f, sigma_ref); f.close(); // viennacl::fast_copy(&in[0], &in[0] + in.size(), Ai); Aref = Ai; viennacl::tools::timer timer; timer.start(); viennacl::linalg::svd(Ai, QL, QR); viennacl::backend::finish(); double time_spend = timer.get(); viennacl::matrix<ScalarType> result1(sz1, sz2), result2(sz1, sz2); result1 = viennacl::linalg::prod(QL, Ai); result2 = viennacl::linalg::prod(result1, trans(QR)); ScalarType sigma_diff = sigmas_compare(Ai, sigma_ref); ScalarType prods_diff = matrix_compare(result2, Aref); bool sigma_ok = (fabs(sigma_diff) < EPS) && (fabs(prods_diff) < std::sqrt(EPS)); //note: computing the product is not accurate down to 10^{-16}, so we allow for a higher tolerance here printf("%6s [%dx%d] %40s sigma_diff = %.6f; prod_diff = %.6f; time = %.6f\n", sigma_ok?"[[OK]]":"[FAIL]", (int)Aref.size1(), (int)Aref.size2(), fn.c_str(), sigma_diff, prods_diff, time_spend); if (!sigma_ok) exit(EXIT_FAILURE); }
void test_eigen(const std::string& fn, bool is_symm) { std::cout << "Reading..." << "\n"; std::size_t sz; // read file std::fstream f(fn.c_str(), std::fstream::in); //read size of input matrix read_matrix_size(f, sz); bool is_row = viennacl::is_row_major<MatrixLayout>::value; if (is_row) std::cout << "Testing row-major matrix of size " << sz << "-by-" << sz << std::endl; else std::cout << "Testing column-major matrix of size " << sz << "-by-" << sz << std::endl; viennacl::matrix<ScalarType> A_input(sz, sz), A_ref(sz, sz), Q(sz, sz); // reference vector with reference values from file std::vector<ScalarType> eigen_ref_re(sz); // calculated real eigenvalues std::vector<ScalarType> eigen_re(sz); // calculated im. eigenvalues std::vector<ScalarType> eigen_im(sz); // read input matrix from file read_matrix_body(f, A_input); // read reference eigenvalues from file read_vector_body(f, eigen_ref_re); f.close(); A_ref = A_input; std::cout << "Calculation..." << "\n"; Timer timer; timer.start(); // Start the calculation if(is_symm) viennacl::linalg::qr_method_sym(A_input, Q, eigen_re); else viennacl::linalg::qr_method_nsm(A_input, Q, eigen_re, eigen_im); /* std::cout << "\n\n Matrix A: \n\n"; matrix_print(A_input); std::cout << "\n\n"; std::cout << "\n\n Matrix Q: \n\n"; matrix_print(Q); std::cout << "\n\n"; */ double time_spend = timer.get(); std::cout << "Verification..." << "\n"; bool is_hessenberg = check_hessenberg(A_input); bool is_tridiag = check_tridiag(A_input); ublas::matrix<ScalarType> A_ref_ublas(sz, sz), A_input_ublas(sz, sz), Q_ublas(sz, sz), result1(sz, sz), result2(sz, sz); viennacl::copy(A_ref, A_ref_ublas); viennacl::copy(A_input, A_input_ublas); viennacl::copy(Q, Q_ublas); // compute result1 = ublas::prod(Q_ublas, A_input_ublas); (terribly slow when using ublas directly) for (std::size_t i=0; i<result1.size1(); ++i) for (std::size_t j=0; j<result1.size2(); ++j) { ScalarType value = 0; for (std::size_t k=0; k<Q_ublas.size2(); ++k) value += Q_ublas(i, k) * A_input_ublas(k, j); result1(i,j) = value; } // compute result2 = ublas::prod(A_ref_ublas, Q_ublas); (terribly slow when using ublas directly) for (std::size_t i=0; i<result2.size1(); ++i) for (std::size_t j=0; j<result2.size2(); ++j) { ScalarType value = 0; for (std::size_t k=0; k<A_ref_ublas.size2(); ++k) value += A_ref_ublas(i, k) * Q_ublas(k, j); result2(i,j) = value; } ScalarType prods_diff = matrix_compare(result1, result2); ScalarType eigen_diff = vector_compare(eigen_re, eigen_ref_re); bool is_ok = is_hessenberg; if(is_symm) is_ok = is_ok && is_tridiag; is_ok = is_ok && (eigen_diff < EPS); is_ok = is_ok && (prods_diff < EPS); // std::cout << A_ref << "\n"; // std::cout << A_input << "\n"; // std::cout << Q << "\n"; // std::cout << eigen_re << "\n"; // std::cout << eigen_im << "\n"; // std::cout << eigen_ref_re << "\n"; // std::cout << eigen_ref_im << "\n"; // std::cout << result1 << "\n"; // std::cout << result2 << "\n"; // std::cout << eigen_ref << "\n"; // std::cout << eigen << "\n"; printf("%6s [%dx%d] %40s time = %.4f\n", is_ok?"[[OK]]":"[FAIL]", (int)A_ref.size1(), (int)A_ref.size2(), fn.c_str(), time_spend); printf("tridiagonal = %d, hessenberg = %d prod-diff = %f eigen-diff = %f\n", is_tridiag, is_hessenberg, prods_diff, eigen_diff); std::cout << std::endl << std::endl; if (!is_ok) exit(EXIT_FAILURE); }