Example #1
0
void nilss_solve(const std::vector<MatrixXd>& R,
                 const std::vector<MatrixXd>& D,
                 const std::vector<VectorXd>& b,
                 const std::vector<VectorXd>& c,
                 std::vector<VectorXd>& a)
{
    int n = R.size();
    assert(D.size() == n + 1);
    assert(b.size() == n);
    assert(c.size() == n + 1);

    std::unique_ptr<MatrixXd> kkt = assemble_kkt(R, D);
    std::unique_ptr<VectorXd> rhs = assemble_rhs(b, c);

    typedef SparseMatrix<double> SpMat;
    SpMat A(kkt->sparseView());

    SparseLU<SparseMatrix<double>> solver;
    solver.analyzePattern(A); 
    solver.factorize(A); 
    VectorXd sol = solver.solve(*rhs); 

    //VectorXd sol = kkt->partialPivLu().solve(*rhs);

    assert(sol.size() % (2 * n + 1) == 0);
    int m = sol.size() / (2 * n + 1);

    a.empty();
    a.reserve(n + 1);
    for (int i = 0; i <= n; ++ i) {
        a.push_back(sol.segment(i * m, m));
    }
}
Example #2
0
// Solve the stokes equation
// F -> U X P
void ProblemStructure::solveStokes() {
  Map<VectorXd> stokesSolnVector (geometry.getStokesData(), M * (N - 1) + (M - 1) * N + M * N);
  
  #ifndef USE_DENSE
  static SparseMatrix<double> stokesMatrix   (3 * M * N - M - N, 3 * M * N - M - N);
  static SparseMatrix<double> forcingMatrix  (3 * M * N - M - N, 2 * M * N - M - N);
  static SparseMatrix<double> boundaryMatrix (3 * M * N - M - N, 2 * M + 2 * N);
  static SparseLU<SparseMatrix<double>, COLAMDOrdering<int> > solver;
  #else
  /* Don't use this unless you hate your computer. */
  static MatrixXd stokesMatrix   (3 * M * N - M - N, 3 * M * N - M - N);
  static MatrixXd forcingMatrix  (3 * M * N - M - N, 2 * M * N - M - N);
  static MatrixXd boundaryMatrix (3 * M * N - M - N, 2 * M + 2 * N);
  static PartialPivLU<MatrixXd> solver;
  #endif

  static bool initialized;

  double * viscosityData = geometry.getViscosityData();

  if (!(initialized) || !(viscosityModel=="constant")) {

  #ifndef USE_DENSE
    SparseForms::makeStokesMatrix   (stokesMatrix,   M, N, h, viscosityData);
    stokesMatrix.makeCompressed();
    SparseForms::makeForcingMatrix  (forcingMatrix,  M, N);
    forcingMatrix.makeCompressed();
    SparseForms::makeBoundaryMatrix (boundaryMatrix, M, N, h, viscosityData);
    boundaryMatrix.makeCompressed();

    solver.analyzePattern (stokesMatrix);
    solver.factorize (stokesMatrix);
  #else
    DenseForms::makeStokesMatrix   (stokesMatrix, M, N, h, viscosityData);
    DenseForms::makeForcingMatrix  (forcingMatrix, M, N);
    DenseForms::makeBoundaryMatrix (boundaryMatrix, M, N, h, viscosityData);

    solver.compute (stokesMatrix);
  #endif
    initialized = true;
  }

  stokesSolnVector = solver.solve (forcingMatrix  * Map<VectorXd>(geometry.getForcingData(), 2 * M * N - M - N) + 
                                   boundaryMatrix * Map<VectorXd>(geometry.getVelocityBoundaryData(), 2 * M + 2 * N));

  Map<VectorXd> pressureVector (geometry.getPressureData(), M * N);
  double pressureMean = pressureVector.sum() / (M * N);
  pressureVector -= VectorXd::Constant (M * N, pressureMean);

#ifdef DEBUG
  cout << "<Calculated Stokes Equation Solutions>" << endl;
  cout << "<U Velocity Data>" << endl;
  cout << DataWindow<double> (geometry.getUVelocityData(), N - 1, M).displayMatrix() << endl;
  cout << "<V Velocity Data>" << endl;
  cout << DataWindow<double> (geometry.getVVelocityData(), N, M - 1).displayMatrix() << endl;
  cout << "<Pressure Data>" << endl;
  cout << DataWindow<double> (geometry.getPressureData(), N, M).displayMatrix() << endl << endl;
#endif
}
Example #3
0
int main(){
        
        //Dati
        double T=1;                 // Scadenza
        double K=90;                // Strike price
        double H=110;               // Barriera up
        double S0=95;               // Spot price
        double r=0.0367;            // Tasso risk free
        
        // Parametri della parte continua
        double sigma=0.120381;      // Volatilità
        
        // Parametri della parte salto
        double p=0.20761;           // Parametro 1 Kou
        double lambda=0.330966;     // Parametro 2 Kou
        double lambda_piu=9.65997;  // Parametro 3 Kou
        double lambda_meno=3.13868; // Parametro 4 Kou
        
        // Discretizzazione
        int N=10; // Spazio
        int M=10; // Tempo
        
        // Griglie
        double dt=T/M;
        double Smin=0.5*S0*exp((r-sigma*sigma/2)*T-6*sigma*sqrt(T));
        
        // Troncamento di x=log(S/S0)
        double xmin=log(Smin/S0);
        double xmax=log(H/S0);
        //x=linspace(xmin,xmax,N+1);
        double dx=(xmax-xmin)/N;
        
        VectorXd x(N+1);
        for (int i=0; i<N+1; ++i) {
                x(i)=xmin+i*dx;
        }
        
        double alpha, lambda2, Bmin, Bmax;
        
        integrale_Levy(alpha, lambda2, Bmin, Bmax, p, lambda, lambda_piu, lambda_meno, xmin, xmax, 2*N);
        
        cout<<"lambda "<<lambda<<" lambda2 "<<lambda2<<"\n";
        
        SpMatrix M1(N-1,N-1);
        SpMatrix M2(N-1,N-1);
        SpMatrix FF(N-1,N-1);
        
        buildMatrix(M1, M2, FF, sigma, r, lambda2, alpha, N, dx, dt);
        
        VectorXd u(x.size()-2);
        
        for (int i=0; i<u.size(); ++i) {
                u(i)=payoff(x(i+1), K, S0);
        }
        
        double BC1_0=M1.coeffRef(1,0); 
        double BC1_N=M1.coeffRef(0,1);
        double BC2_0=M2.coeffRef(1,0); 
        double BC2_N=M2.coeffRef(0,1);
        
        for (int j=M-1; j>=0; --j) {
                cout<<j<<"\n";
                
                // rhs
                VectorXd J(N-1);
                VectorXd z(u.size()+2);
                z(0)=(K-S0*exp(xmin))*exp(r*(T-(j+1)*dt));
                for (int i=1; i<u.size(); ++i) {
                        z(i)=u(i-1);
                }
                z(z.size()-1)=0;
                integrale2_Levy(J, Bmin, Bmax, x, z, N, K, S0, p, lambda, lambda_piu, lambda_meno);
                VectorXd rhs(N-1);
                rhs=FF*J;
                rhs(0)+=-BC1_0*(K-S0*exp(xmin))*exp(r*(T-(j-2)*dt))+BC2_0*(K-S0*exp(xmin))*exp(r*(T-(j-1)*dt));
                
                // Solver
                SparseLU<SpMatrix> solver;
                M1.makeCompressed();
                solver.analyzePattern(M1);
                solver.factorize(M1);
                u=solver.solve(M2*u+rhs);
        }
        
        VectorXd sol(u.size()+2);
        sol(0)=(K-S0*exp(xmin))*exp(r*T);
        for (int i=0; i<u.size(); ++i) {
                sol(i+1)=u(i);
        }
        sol(sol.size()-1)=0;

        VectorXd S(x.size());
        VectorXd Put(sol.size());
        for (int i=0; i<x.size(); ++i) {
                S(i)=S0*exp(x(i));
                Put(i)=sol(i)*exp(-r*T);
        }
        
        double x_array[S.size()];
        double u_array[Put.size()];
        
        for (int i=0; i<x.size(); ++i) {
                x_array[i]=S(i);
                u_array[i]=Put(i);
        }
        
        gsl_interp_accel *my_accel_ptr = gsl_interp_accel_alloc ();
        gsl_spline *my_spline_ptr = gsl_spline_alloc (gsl_interp_cspline, x.size());
        gsl_spline_init (my_spline_ptr, x_array, u_array, x.size());
        
        double Prezzo=gsl_spline_eval(my_spline_ptr, S0 , my_accel_ptr);
        
        gsl_spline_free(my_spline_ptr);
        gsl_interp_accel_free(my_accel_ptr);
        
        cout<<"Prezzo="<<setprecision(8)<<Prezzo<<"\n";
                
        return 0;
}