//constructor TheEngine::TheEngine(shared_ptr<BGMProducts>& the_product_, FwdVolStructure& term_structure, shared_ptr<RandomBase>& the_generator_, const std::vector<double>& fwd_rtes_, const std::vector<double>& times_, double sub_stepping_, unsigned int numeraire_, double initial_numeraire_) :the_product(the_product_), the_generator(the_generator_), times(times_), sub_stepping(sub_stepping_), numeraire(numeraire_), initial_numeraire(initial_numeraire_), M(fwd_rtes_.size()) { //matrix - m rates, n times. m x n mat fwd_rtes.resize(M, std::vector<double>(the_product->GetEvolutionTimes().size()+1)); for (size_t i(0); i <fwd_rtes.size(); ++i) fwd_rtes[i][0] = fwd_rtes_[i]; //compute covariance matrix cov.resize(M, M); //resize cov mat std::vector<double> K(cov.size1(), 1.0); //K = 1 term_structure.covariance(cov, K, times, 0, sub_stepping); //precompute pseudo_square root of cov-var using Cholesky decomposition A = zero_matrix<double>(cov.size1(), cov.size2()); size_t res = cholesky_decompose(cov, A); if (res != 0) throw("cholesky decomposition fails "); //precompute initial drift mu = drifts(times, fwd_rtes_, numeraire); }
/***********************************************************************//** * @brief Test Cholesky decomposition ***************************************************************************/ void TestGSparseMatrix::matrix_cholesky(void) { // Setup matrix for Cholesky decomposition GSparseMatrix chol_test(5,5); chol_test(0,0) = 1.0; chol_test(0,1) = 0.2; chol_test(0,2) = 0.2; chol_test(0,3) = 0.2; chol_test(0,4) = 0.2; chol_test(1,0) = 0.2; chol_test(2,0) = 0.2; chol_test(3,0) = 0.2; chol_test(4,0) = 0.2; chol_test(1,1) = 1.0; chol_test(2,2) = 1.0; chol_test(3,3) = 1.0; chol_test(4,4) = 1.0; // Try to solve now (should not work) test_try("Try Cholesky solver without factorisation"); try { GVector vector(5); vector = chol_test.cholesky_solver(vector); test_try_failure("Expected GException::matrix_not_factorised exception."); } catch (GException::matrix_not_factorised &e) { test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Perform Cholesky decomposition GSparseMatrix cd = cholesky_decompose(chol_test); // Perform inplace Cholesky decomposition cd = chol_test; cd.cholesky_decompose(); // Test Cholesky solver (first test) GVector e0(5); GVector a0(5); e0[0] = 1.0; a0[0] = 1.0; a0[1] = 0.2; a0[2] = 0.2; a0[3] = 0.2; a0[4] = 0.2; GVector s0 = cd.cholesky_solver(a0); double res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 1"); // Test Cholesky solver (second test) e0[0] = 0.0; e0[1] = 1.0; a0[0] = 0.2; a0[1] = 1.0; a0[2] = 0.0; a0[3] = 0.0; a0[4] = 0.0; s0 = cd.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 2"); // Test Cholesky solver (third test) e0[1] = 0.0; e0[2] = 1.0; a0[1] = 0.0; a0[2] = 1.0; s0 = cd.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 3"); // Test Cholesky solver (forth test) e0[2] = 0.0; e0[3] = 1.0; a0[2] = 0.0; a0[3] = 1.0; s0 = cd.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 4"); // Test Cholesky solver (fifth test) e0[3] = 0.0; e0[4] = 1.0; a0[3] = 0.0; a0[4] = 1.0; s0 = cd.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 5"); // Setup matrix for Cholesky decomposition with zero row/col GSparseMatrix chol_test_zero(6,6); chol_test_zero(0,0) = 1.0; chol_test_zero(0,1) = 0.2; chol_test_zero(0,2) = 0.2; chol_test_zero(0,4) = 0.2; chol_test_zero(0,5) = 0.2; chol_test_zero(1,0) = 0.2; chol_test_zero(2,0) = 0.2; chol_test_zero(4,0) = 0.2; chol_test_zero(5,0) = 0.2; chol_test_zero(1,1) = 1.0; chol_test_zero(2,2) = 1.0; chol_test_zero(4,4) = 1.0; chol_test_zero(5,5) = 1.0; // Test compressed Cholesky decomposition GSparseMatrix cd_zero = chol_test_zero; cd_zero.cholesky_decompose(); // Test compressed Cholesky solver (first test) e0 = GVector(6); a0 = GVector(6); e0[0] = 1.0; a0[0] = 1.0; a0[1] = 0.2; a0[2] = 0.2; a0[4] = 0.2; a0[5] = 0.2; s0 = cd_zero.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 1"); // Test compressed Cholesky solver (second test) e0[0] = 0.0; e0[1] = 1.0; a0[0] = 0.2; a0[1] = 1.0; a0[2] = 0.0; a0[4] = 0.0; a0[5] = 0.0; s0 = cd_zero.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 2"); // Test compressed Cholesky solver (third test) e0[1] = 0.0; e0[2] = 1.0; a0[1] = 0.0; a0[2] = 1.0; s0 = cd_zero.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 3"); // Test compressed Cholesky solver (forth test) e0[2] = 0.0; e0[4] = 1.0; a0[2] = 0.0; a0[4] = 1.0; s0 = cd_zero.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 4"); // Test compressed Cholesky solver (fifth test) e0[4] = 0.0; e0[5] = 1.0; a0[4] = 0.0; a0[5] = 1.0; s0 = cd_zero.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 5"); // Setup matrix for Cholesky decomposition with zero row/col (unsymmetric case) GSparseMatrix chol_test_zero2(6,5); chol_test_zero2(0,0) = 1.0; chol_test_zero2(0,1) = 0.2; chol_test_zero2(0,2) = 0.2; chol_test_zero2(0,3) = 0.2; chol_test_zero2(0,4) = 0.2; chol_test_zero2(1,0) = 0.2; chol_test_zero2(2,0) = 0.2; chol_test_zero2(4,0) = 0.2; chol_test_zero2(5,0) = 0.2; chol_test_zero2(1,1) = 1.0; chol_test_zero2(2,2) = 1.0; chol_test_zero2(4,3) = 1.0; chol_test_zero2(5,4) = 1.0; // Test compressed Cholesky decomposition (unsymmetric case) GSparseMatrix cd_zero2 = chol_test_zero2; cd_zero2.cholesky_decompose(); // Test compressed Cholesky solver (unsymmetric case) e0 = GVector(5); a0 = GVector(6); e0[0] = 1.0; a0[0] = 1.0; a0[1] = 0.2; a0[2] = 0.2; a0[4] = 0.2; a0[5] = 0.2; s0 = cd_zero2.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test unsymmetric compressed cholesky_solver() method - 1"); // Test compressed Cholesky solver (unsymmetric case) e0[0] = 0.0; e0[1] = 1.0; a0[0] = 0.2; a0[1] = 1.0; a0[2] = 0.0; a0[4] = 0.0; a0[5] = 0.0; s0 = cd_zero2.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test unsymmetric compressed cholesky_solver() method - 2"); // Test compressed Cholesky solver (unsymmetric case) e0[1] = 0.0; e0[2] = 1.0; a0[1] = 0.0; a0[2] = 1.0; s0 = cd_zero2.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test unsymmetric compressed cholesky_solver() method - 3"); // Test compressed Cholesky solver (unsymmetric case) e0[2] = 0.0; e0[3] = 1.0; a0[2] = 0.0; a0[4] = 1.0; s0 = cd_zero2.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test unsymmetric compressed cholesky_solver() method - 4"); // Test compressed Cholesky solver (unsymmetric case) e0[3] = 0.0; e0[4] = 1.0; a0[4] = 0.0; a0[5] = 1.0; s0 = cd_zero2.cholesky_solver(a0); res = max(abs(s0-e0)); test_value(res, 0.0, 1.0e-15, "Test unsymmetric compressed cholesky_solver() method - 5"); // Test Cholesky inverter (inplace) GSparseMatrix unit(5,5); unit(0,0) = 1.0; unit(1,1) = 1.0; unit(2,2) = 1.0; unit(3,3) = 1.0; unit(4,4) = 1.0; GSparseMatrix chol_test_inv = chol_test; chol_test_inv.cholesky_invert(); GSparseMatrix ci_product = chol_test * chol_test_inv; GSparseMatrix ci_residuals = ci_product - unit; res = (abs(ci_residuals)).max(); test_value(res, 0.0, 1.0e-15, "Test inplace Cholesky inverter"); // Test Cholesky inverter chol_test_inv = cholesky_invert(chol_test); ci_product = chol_test * chol_test_inv; ci_residuals = ci_product - unit; res = (abs(ci_residuals)).max(); test_value(res, 0.0, 1.0e-15, "Test Cholesky inverter"); // Test Cholesky inverter for compressed matrix unit = GSparseMatrix(6,6); unit(0,0) = 1.0; unit(1,1) = 1.0; unit(2,2) = 1.0; unit(4,4) = 1.0; unit(5,5) = 1.0; GSparseMatrix chol_test_zero_inv = chol_test_zero; chol_test_zero_inv.cholesky_invert(); GSparseMatrix ciz_product = chol_test_zero * chol_test_zero_inv; GSparseMatrix ciz_residuals = ciz_product - unit; res = (abs(ciz_residuals)).max(); test_value(res, 0.0, 1.0e-15, "Test compressed matrix Cholesky inverter"); // Return return; }
/***********************************************************************//** * @brief Test Cholesky decomposition ***************************************************************************/ void TestGSymMatrix::matrix_cholesky(void) { // Test Cholesky decomposition GSymMatrix cd = cholesky_decompose(m_test); GMatrix cd_lower = cd.extract_lower_triangle(); GMatrix cd_upper = transpose(cd_lower); GMatrix cd_product = cd_lower * cd_upper; GMatrix cd_residuals = GMatrix(m_test) - cd_product; double res = (abs(cd_residuals)).max(); test_value(res, 0.0, 1.0e-15, "Test cholesky_decompose() method"); // Test compressed Cholesky decomposition GSymMatrix test_zero = set_matrix_zero(); GSymMatrix cd_zero = cholesky_decompose(test_zero); GMatrix cd_zero_lower = cd_zero.extract_lower_triangle(); GMatrix cd_zero_upper = transpose(cd_zero_lower); GMatrix cd_zero_product = cd_zero_lower * cd_zero_upper; GMatrix cd_zero_residuals = GMatrix(test_zero) - cd_zero_product; res = (abs(cd_zero_residuals)).max(); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_decompose() method"); // Test Cholesky inplace decomposition GSymMatrix test = m_test; test.cholesky_decompose(); GMatrix cd_lower2 = test.extract_lower_triangle(); test_assert((cd_lower2 == cd_lower), "Test inplace cholesky_decompose() method"); // Test Cholesky solver (first test) GVector e0(g_rows); GVector a0(g_rows); e0[0] = 1.0; e0[1] = 0.0; e0[2] = 0.0; a0[0] = g_matrix[0]; a0[1] = g_matrix[3]; a0[2] = g_matrix[6]; GVector s0 = cd.cholesky_solver(a0) - e0; res = max(abs(s0)); test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method"); // Test Cholesky solver (second test) e0[0] = 0.0; e0[1] = 1.0; e0[2] = 0.0; a0[0] = g_matrix[1]; a0[1] = g_matrix[4]; a0[2] = g_matrix[7]; s0 = cd.cholesky_solver(a0) - e0; res = max(abs(s0)); test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method"); // Test Cholesky solver (third test) e0[0] = 0.0; e0[1] = 0.0; e0[2] = 1.0; a0[0] = g_matrix[2]; a0[1] = g_matrix[5]; a0[2] = g_matrix[8]; s0 = cd.cholesky_solver(a0) - e0; res = max(abs(s0)); test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method"); // Test compressed Cholesky solver (first test) e0 = GVector(g_rows+1); a0 = GVector(g_rows+1); e0[0] = 1.0; e0[1] = 0.0; e0[2] = 0.0; e0[3] = 0.0; a0[0] = g_matrix[0]; a0[1] = g_matrix[3]; a0[2] = 0.0; a0[3] = g_matrix[6]; s0 = cd_zero.cholesky_solver(a0) - e0; res = max(abs(s0)); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method"); // Test compressed Cholesky solver (second test) e0[0] = 0.0; e0[1] = 1.0; e0[2] = 0.0; e0[3] = 0.0; a0[0] = g_matrix[1]; a0[1] = g_matrix[4]; a0[2] = 0.0; a0[3] = g_matrix[7]; s0 = cd_zero.cholesky_solver(a0) - e0; res = max(abs(s0)); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method"); // Test compressed Cholesky solver (third test) e0[0] = 0.0; e0[1] = 0.0; e0[2] = 0.0; e0[3] = 1.0; a0[0] = g_matrix[2]; a0[1] = g_matrix[5]; a0[2] = 0.0; a0[3] = g_matrix[8]; s0 = cd_zero.cholesky_solver(a0) - e0; res = max(abs(s0)); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method"); // Test Cholesky inverter GSymMatrix unit(g_rows,g_cols); unit(0,0) = unit(1,1) = unit(2,2) = 1.0; GSymMatrix test_inv = m_test; test_inv.cholesky_invert(); GMatrix ci_product = m_test * test_inv; GMatrix ci_residuals = ci_product - unit; res = (abs(ci_residuals)).max(); test_value(res, 0.0, 1.0e-15, "Test cholesky_invert method"); // Test Cholesky inverter for compressed matrix unit = GSymMatrix(4,4); unit(0,0) = unit(1,1) = unit(3,3) = 1.0; GSymMatrix test_zero_inv = test_zero; test_zero_inv.cholesky_invert(); GMatrix ciz_product = test_zero * test_zero_inv; GMatrix ciz_residuals = ciz_product - unit; res = (abs(ciz_residuals)).max(); test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_invert method"); // Return return; }
void computeFSPAI(MatrixType const & A, MatrixType const & PatternA, MatrixType & L, MatrixType & L_trans, fspai_tag) { typedef typename MatrixType::value_type ScalarType; typedef boost::numeric::ublas::matrix<ScalarType> DenseMatrixType; typedef std::vector<std::map<unsigned int, ScalarType> > SparseMatrixType; // // preprocessing: Store A in a STL container: // //std::cout << "Transferring to STL container:" << std::endl; std::vector<std::vector<ScalarType> > y_k(A.size1()); SparseMatrixType STL_A(A.size1()); sym_sparse_matrix_to_stl(A, STL_A); // // Step 1: Generate pattern indices // //std::cout << "computeFSPAI(): Generating pattern..." << std::endl; std::vector<std::vector<vcl_size_t> > J(A.size1()); generateJ(PatternA, J); // // Step 2: Set up matrix blocks // //std::cout << "computeFSPAI(): Setting up matrix blocks..." << std::endl; std::vector<DenseMatrixType> subblocks_A(A.size1()); fill_blocks(STL_A, subblocks_A, J, y_k); STL_A.clear(); //not needed anymore // // Step 3: Cholesky-factor blocks // //std::cout << "computeFSPAI(): Cholesky-factorization..." << std::endl; for (vcl_size_t i=0; i<subblocks_A.size(); ++i) { //std::cout << "Block before: " << subblocks_A[i] << std::endl; cholesky_decompose(subblocks_A[i]); //std::cout << "Block after: " << subblocks_A[i] << std::endl; } /*vcl_size_t num_bytes = 0; for (vcl_size_t i=0; i<subblocks_A.size(); ++i) num_bytes += 8*subblocks_A[i].size1()*subblocks_A[i].size2();*/ //std::cout << "Memory for FSPAI matrix: " << num_bytes / (1024.0 * 1024.0) << " MB" << std::endl; // // Step 4: Solve for y_k // //std::cout << "computeFSPAI(): Cholesky-solve..." << std::endl; for (vcl_size_t i=0; i<y_k.size(); ++i) { if (subblocks_A[i].size1() > 0) //block might be empty... { //y_k[i].resize(subblocks_A[i].size1()); //std::cout << "y_k[" << i << "]: "; //for (vcl_size_t j=0; j<y_k[i].size(); ++j) // std::cout << y_k[i][j] << " "; //std::cout << std::endl; cholesky_solve(subblocks_A[i], y_k[i]); } } // // Step 5: Set up Cholesky factors L and L_trans // //std::cout << "computeFSPAI(): Computing L..." << std::endl; L.resize(A.size1(), A.size2(), false); L.reserve(A.nnz(), false); L_trans.resize(A.size1(), A.size2(), false); L_trans.reserve(A.nnz(), false); computeL(A, L, L_trans, y_k, J); //std::cout << "L: " << L << std::endl; }
void Bayes::sample_muOmega() { double tau = 10.0; int d0 = p + 2; // matrix_t S0(p, p); ublas::matrix<double> S0(p, p); S0 = d0 * ublas::identity_matrix<double>(p, p)/4.0; std::vector<int> idx; ublas::indirect_array<> irow(p); // projection - want every row for (size_t i=0; i<irow.size(); ++i) irow(i) = i; // size_t rank; ublas::matrix<double> S(p, p); // matrix_t SS(p, p); ublas::matrix<double> SS(p, p); ublas::matrix<double> Omega_inv(p, p); // identity matrix for inverting cholesky factorization ublas::matrix<double> I(p, p); I.assign(ublas::identity_matrix<double> (p, p)); ublas::symmetric_adaptor<ublas::matrix<double>, ublas::upper> SH(I); // triangular matrix for cholesky_decompose ublas::triangular_matrix<double, ublas::lower, ublas::row_major> L(p, p); int df; for (int j=0; j<k; ++j) { idx = find_all(z, j); int n_idx = idx.size(); ublas::matrix<double> xx(p, n_idx); ublas::matrix<double> e(p, n_idx); // ublas::matrix<double> m(p, 1); ublas::vector<double> m(p); ublas::indirect_array<> icol(n_idx); for (size_t i=0; i<idx.size(); ++i) icol(i) = idx[i]; if (n_idx > 0) { double a = tau/(1.0 + n_idx*tau); //! REFACTOR - should be able to do matrix_sum directly on projection rather than make a copy? xx.assign(project(x, irow, icol)); m.assign(ublas::matrix_sum(xx, 1)/n_idx); // e.assign(xx - outer_prod(column(m, 0), ublas::scalar_vector<double>(n_idx, 1))); e.assign(xx - outer_prod(m, ublas::scalar_vector<double>(n_idx, 1))); S.assign(prod(e, trans(e)) + outer_prod(m, m) * n_idx * a/tau); // SS = trans(S) + S0; SS = S + S0; df = d0 + n_idx; // Omega(j).assign(wishart_rnd(df, SS)); Omega(j).assign(wishart_InvA_rnd(df, SS)); SH.assign(Omega(j)); cholesky_decompose(SH, L); Omega_inv.assign(solve(SH, I, ublas::upper_tag())); mu(j).assign(a*n_idx*m + sqrt(a)*prod(Omega_inv, Rmath::rnorm(0, 1, p))); } else { // Omega(j).assign(wishart_rnd(d0, S0)); Omega(j).assign(wishart_InvA_rnd(d0, S0)); SH.assign(Omega(j)); cholesky_decompose(SH, L); Omega_inv.assign(solve(SH, I, ublas::upper_tag())); mu(j).assign(sqrt(tau) * prod(Omega_inv, Rmath::rnorm(0, 1, p))); } } }