コード例 #1
0
void BackwardEulerUpdater::update( const std::vector<double> & uOld,
                                   std::vector<double>* uNew,
                                   const std::vector<double> & prem ) const
{
    int N = uOld.size()-1;
    double c = getAlpha();

    // Construct b-vector
    Eigen::VectorXd b = Eigen::VectorXd::Zero(N-1);
    for (int i=0; i<N-1; i++) { b(i) = uOld[i+1]; }

    b(0) += c*(*uNew)[0];
    b(N-2) += c*(*uNew)[N];
    
    // Construct early exercise premium vector
    Eigen::VectorXd p = Eigen::VectorXd::Zero(0);
    if ( prem.size()>0 ) {
        p = Eigen::VectorXd::Zero(N-1);
        for (int i=0; i<N-1; i++) { p(i) = prem[i+1]; }
    }
   
    // update 
    Eigen::VectorXd y = forward_subst(d_L, b);
    Eigen::VectorXd x = backward_subst(d_U, y, p);
    
    for (int i=0; i<N-1; i++) { (*uNew)[i+1] = x(i); }
}
コード例 #2
0
void CrankNicolsonUpdater::update( const std::vector<double> & uOld,
                                   std::vector<double>* uNew,
                                   const std::vector<double> & prem ) const
{
    int N = uOld.size()-1;
    double c = getAlpha();

    // uOld restricted in the interior region
    Eigen::VectorXd u = Eigen::VectorXd::Zero(N-1);
    for (int i=0; i<N-1; i++) { u(i) = uOld[i+1]; }

    // Construct b-vector
    Eigen::VectorXd b = d_B*u;

    b(0) += 0.5*c*((*uNew)[0]+uOld[0]);
    b(N-2) += 0.5*c*((*uNew)[N]+uOld[N]);
    
    // Construct early exercise premium vector
    Eigen::VectorXd p = Eigen::VectorXd::Zero(0);
    if ( prem.size()>0 ) {
        p = Eigen::VectorXd::Zero(N-1);
        for (int i=0; i<N-1; i++) { p(i) = prem[i+1]; }
    }
    
    // update 
    Eigen::VectorXd y = forward_subst(d_L, b);
    Eigen::VectorXd x = backward_subst(d_U, y, p);
    
    for (int i=0; i<N-1; i++) { (*uNew)[i+1] = x(i); }
}
コード例 #3
0
ファイル: main.c プロジェクト: wojcikk2903/sor
void solve_parallel(matrix *a, double *x, double *b, int nproc, int steps)
{
    double w = 1.0;
    double *it_vec = get_iterative_vector(a, w, b);
    matrix upper = get_iterative_upper_matrix(a, w);
    matrix lower = get_iterative_lower_matrix(a, w);
    double *z = malloc(a->n*sizeof(*z));


    for (int i = 1; i < nproc; i++) 
        send_matrix(upper, i);

    for (int s = 0; s < steps; s++)
    {
        for (int i = 1; i < nproc; i++) 
            send_values(x, a->n, i);
        range r = compute_range(a->n, nproc, 0);
        mul_matrix_row(&upper, x, z, r.begin, r.end);

        for (int i = 1; i < nproc; i++)
            wait_for_results(z, a->n, nproc, i);

        add_vector(z, it_vec, a->n);
        forward_subst(&lower, x, z);
    }
    terminate_children(nproc);
}
コード例 #4
0
TEST_F(TriangularSolveTest, ForwardSubstMatchEigenComputedResults)
{
    Eigen::MatrixXd L = Eigen::MatrixXd::Random(2,2);
    Eigen::VectorXd b = Eigen::VectorXd::Random(2);
    L.triangularView<Eigen::StrictlyUpper>().setZero();
    Eigen::VectorXd x = forward_subst(L, b);
    Eigen::VectorXd y = L.triangularView<Eigen::Lower>().solve(b);
    double tol = 1e-16;
    EXPECT_NEAR((x-y).norm(), 0, tol);
}
コード例 #5
0
Eigen::VectorXd spd_solve(const Eigen::MatrixXd & A,
                          const Eigen::VectorXd & b)
{
    int n = b.size();
    assert(A.rows() == n);
    assert(A.cols() == n);

    Eigen::MatrixXd U = cholesky(A);
    Eigen::VectorXd y = forward_subst(U.transpose(), b);
    Eigen::VectorXd x = backward_subst(U, y);

    return x;
}
コード例 #6
0
ファイル: main.c プロジェクト: wojcikk2903/sor
void solve(matrix *a, double *x, double *b)
{
    double w = 1.0;
    int steps = 1000;
    double *it_vec = get_iterative_vector(a, w, b);
    matrix upper = get_iterative_upper_matrix(a, w);
    matrix lower = get_iterative_lower_matrix(a, w);
    double *z = malloc(a->n*sizeof(*z));

    for (int i = 0; i < steps; i++)
    {
        mul_matrix_row(&upper, x, z, 0, a->n);
        add_vector(z, it_vec, a->n);
        forward_subst(&lower, x, z);
    }
}
コード例 #7
0
ファイル: main.cpp プロジェクト: ShengQuanZhou/baruch-mfe-lab
int main(int argc, char* argv[])
{
    // Output precision
    int p=9;
    // Matrix dimension
    int N=9;
    // Matrix specification
    Eigen::MatrixXd A = Eigen::MatrixXd::Zero(N,N); 
    Eigen::MatrixXd A1 = Eigen::MatrixXd::Zero(N,N); 
    for (int i=0; i<N; i++) {
        A1(i,i) = 4.0;
        if (i>=1) A1(i,i-1) = -1.0;
        if (i>=2) A1(i,i-2) = 3.0;
        if (i<=6) A1(i,i+2) = -2.0;
    }
    // Could be AT+A or AT*A
    A = A1.transpose()+A1;
    // Vector specification
    Eigen::VectorXd b = Eigen::VectorXd::Zero(N);
    for (int i=0; i<N; i++) {
        b(i) = (i*i-9.0)/(i+5.0); 
    }

    // Cholesky decomposition
    Eigen::MatrixXd U = cholesky(A);
    Eigen::MatrixXd L = U.transpose();

    // Perform forward substitution and backward substitution
    // Using Eigen's library method: Eigen::VectorXd x = A.llt().solve(b);
    Eigen::VectorXd y = forward_subst(L, b);
    Eigen::VectorXd x = backward_subst(U, y);

    // Compute residual error
    double R = (A*x-b).norm();
    std::cout << "Residual error =, "
              << std::setprecision(p)
              << R
              << std::endl;

    // Compute L-inverse, U-inverse, and A-inverse
    Eigen::MatrixXd L_inv = Eigen::MatrixXd::Zero(N,N);
    Eigen::MatrixXd U_inv = Eigen::MatrixXd::Zero(N,N);
    Eigen::MatrixXd A_inv = Eigen::MatrixXd::Zero(N,N);
    // L-inverse
    for (int i=0; i<N; i++) {
        Eigen::VectorXd ei = Eigen::VectorXd::Zero(N);
        ei(i) = 1;
        Eigen::VectorXd x = forward_subst(L, ei);
        L_inv.col(i) = x;
    }
    // U-inverse
    for (int i=0; i<N; i++) {
        Eigen::VectorXd ei = Eigen::VectorXd::Zero(N);
        ei(i) = 1;
        Eigen::VectorXd x = backward_subst(U, ei);
        U_inv.col(i) = x;
    }
    // A-inverse
    for (int i=0; i<N; i++) {
        Eigen::VectorXd ei = Eigen::VectorXd::Zero(N);
        ei(i) = 1;
        Eigen::VectorXd y = forward_subst(L, ei);
        Eigen::VectorXd x = backward_subst(U, y);
        A_inv.col(i) = x;
    }
    
    // Compute residual error by matrix inverse
    Eigen::VectorXd v = A_inv*b;
    R = (b-A*v).norm();
    std::cout << "Residual error by inverse =, "
              << std::setprecision(p)
              << R
              << std::endl;

    std::cout << "Cholesky decomposition" << std::endl;
    for (int i=0; i<N; i++) {
        std::cout << " |, ";
        for (int j=0; j<N; j++) {
            std::cout << std::right 
                      << std::setw(p+3) 
                      << std::fixed 
                      << std::setprecision(p) 
                      << A(i,j) 
                      << ", ";
        }
        std::cout << " |, =, |, ";
        for (int j=0; j<N; j++) {
            std::cout << std::right 
                      << std::setw(p+3) 
                      << std::fixed 
                      << std::setprecision(p) 
                      << L(i,j) 
                      << ", ";
        }
        std::cout << " |, ";
        for (int j=0; j<N; j++) {
            std::cout << std::right 
                      << std::setw(p+3) 
                      << std::fixed 
                      << std::setprecision(p) 
                      << U(i,j) 
                      << ", ";
        }
        std::cout << " |, " << std::endl;
    }

    std::cout << "Linear solve - x:" << std::endl;
    for (int i=0; i<N; i++) {
        std::cout << std::right 
                  << std::setw(p+3) 
                  << std::fixed 
                  << std::setprecision(p) 
                  << x(i)
                  << std::endl; 
    }
    
    std::cout << "Inverse relations:" << std::endl;
    for (int i=0; i<N; i++) {
        std::cout << " |, ";
        for (int j=0; j<N; j++) {
            std::cout << std::right 
                      << std::setw(p+3) 
                      << std::fixed 
                      << std::setprecision(p) 
                      << A_inv(i,j) 
                      << ", ";
        }
        std::cout << " |, =, |, ";
        for (int j=0; j<N; j++) {
            std::cout << std::right 
                      << std::setw(p+3) 
                      << std::fixed 
                      << std::setprecision(p) 
                      << U_inv(i,j) 
                      << ", ";
        }
        std::cout << " |, ";
        for (int j=0; j<N; j++) {
            std::cout << std::right 
                      << std::setw(p+3) 
                      << std::fixed 
                      << std::setprecision(p) 
                      << L_inv(i,j) 
                      << ", ";
        }
        std::cout << " |, " << std::endl;
    }
    
    std::cout << "Linear solve by inversion- x:" << std::endl;
    for (int i=0; i<N; i++) {
        std::cout << std::right 
                  << std::setw(p+3) 
                  << std::fixed 
                  << std::setprecision(p) 
                  << v(i)
                  << std::endl; 
    }
    
    // Verify accuracy of matrix inverse
    std::cout << "L * L-inverse residual error =, "
              << std::scientific
              << std::setprecision(p)
              << (L*L_inv-Eigen::MatrixXd::Identity(N,N)).norm() 
              << std::endl;
    std::cout << "U * U-inverse residual error =, "
              << std::scientific
              << std::setprecision(p)
              << (U*U_inv-Eigen::MatrixXd::Identity(N,N)).norm() 
              << std::endl;
    std::cout << "A * A-inverse residual error =, "
              << std::scientific
              << std::setprecision(p)
              << (A*A_inv-Eigen::MatrixXd::Identity(N,N)).norm() 
              << std::endl;

    return 0;
}