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
void solve(int n,  int m,  int* rowptr, int* colidx,
           int nn, int mm, Float* Avals, Float* bvals, Float* xvals) {
#ifdef EIGEN
  auto A = csr2eigen<Float,ColMajor>(n, m, rowptr, colidx, nn, mm, Avals);
  auto x = new Map<Matrix<Float,Dynamic,1>>(xvals, m);
  auto b = new Map<Matrix<Float,Dynamic,1>>(bvals, n);

  SparseLU<SparseMatrix<Float, ColMajor>> solver;
  solver.compute(A);
  *x = solver.solve(*b);
#else
  SOLVER_ERROR;
#endif
}
Example #4
0
void NRICP::solveLinearSystem()
{
    //TO DO: This is the slow bit of the algorithm...understand matrices better to optimize!
    //Important stuff down here
        m_A->makeCompressed();
        m_B->makeCompressed();

        SparseLU <SparseMatrix<GLfloat, ColMajor>, COLAMDOrdering<int>  > solver;
        solver.compute((*m_A).transpose() * (*m_A));
        SparseMatrix<GLfloat, ColMajor> I(4 * m_templateVertCount, 4 * m_templateVertCount);
        I.setIdentity();      
        SparseMatrix<GLfloat, ColMajor> A_inv = solver.solve(I);
        SparseMatrix<GLfloat, ColMajor> result = A_inv * (*m_A).transpose() * (*m_B);
        result.uncompress();
        (*m_X) = result;
}
bool WHeadPositionCorrection::computeInverseOperation( MatrixT* const g, const MatrixT& lf ) const
{
    WLTimeProfiler profiler( CLASS, __func__, true );

    const float snr = 25;
    const MatrixT noiseCov = MatrixT::Identity( lf.rows(), lf.rows() );

    // Leafield transpose matrix
    const MatrixT LT = lf.transpose();

    // WinvLT = W^-1 * LT
    SpMatrixT w = SpMatrixT( lf.cols(), lf.cols() );
    w.setIdentity();
    w.makeCompressed();

    SparseLU< SpMatrixT > spSolver;
    spSolver.compute( w );
    if( spSolver.info() != Eigen::Success )
    {
        wlog::error( CLASS ) << "spSolver.compute( weighting ) not succeeded: " << spSolver.info();
        return false;
    }
    const MatrixT WinvLT = spSolver.solve( LT ); // needs dense matrix, returns dense matrix
    if( spSolver.info() != Eigen::Success )
    {
        wlog::error( CLASS ) << "spSolver.solve( LT ) not succeeded: " << spSolver.info();
        return false;
    }
    wlog::debug( CLASS ) << "WinvLT " << WinvLT.rows() << " x " << WinvLT.cols();

    // LWL = L * W^-1 * LT
    const MatrixT LWL = lf * WinvLT;
    wlog::debug( CLASS ) << "LWL " << LWL.rows() << " x " << LWL.cols();

    // alpha = sqrt(trace(LWL)/(snr * num_sensors));
    double alpha = sqrt( LWL.trace() / ( snr * lf.rows() ) );

    // G = W^-1 * LT * inv( (L W^-1 * LT) + alpha^2 * Cn )
    const MatrixT toInv = LWL + pow( alpha, 2 ) * noiseCov;
    const MatrixT inv = toInv.inverse();
    *g = WinvLT * inv;

    WAssertDebug( g->rows() == lf.cols() && g->cols() == lf.rows(), "Dimension of G and L does not match." );
    return true;
}
Example #6
0
void PSpline::computeControlPoints(const DataTable &samples)
{
    // Assuming regular grid
    unsigned int numSamples = samples.getNumSamples();

    /* Setup and solve equations Lc = R,
     * L = B'*W*B + l*D'*D
     * R = B'*W*y
     * c = control coefficients or knot averages.
     * B = basis functions at sample x-values,
     * W = weighting matrix for interpolating specific points
     * D = second-order finite difference matrix
     * l = penalizing parameter (increase for more smoothing)
     * y = sample y-values when calculating control coefficients,
     * y = sample x-values when calculating knot averages
     */

    SparseMatrix L, B, D, W;
    DenseMatrix Rx, Ry, Bx, By;

    // Weight matrix
    W.resize(numSamples, numSamples);
    W.setIdentity();

    // Basis function matrix
    computeBasisFunctionMatrix(samples, B);

    // Second order finite difference matrix
    getSecondOrderFiniteDifferenceMatrix(D);

    // Left-hand side matrix
    L = B.transpose()*W*B + lambda*D.transpose()*D;

    // Compute right-hand side matrices
    controlPointEquationRHS(samples, Bx, By);
    Rx = B.transpose()*W*Bx;
    Ry = B.transpose()*W*By;

    // Matrices to store the resulting coefficients
    DenseMatrix Cx, Cy;

    int numEquations = L.rows();
    int maxNumEquations = pow(2,10);

    bool solveAsDense = (numEquations < maxNumEquations);

    if (!solveAsDense)
    {
#ifndef NDEBUG
        std::cout << "Computing B-spline control points using sparse solver." << std::endl;
#endif // NDEBUG

        SparseLU s;
        bool successfulSolve = (s.solve(L,Rx,Cx) && s.solve(L,Ry,Cy));

        solveAsDense = !successfulSolve;
    }

    if (solveAsDense)
    {
#ifndef NDEBUG
        std::cout << "Computing B-spline control points using dense solver." << std::endl;
#endif // NDEBUG

        DenseMatrix Ld = L.toDense();
        DenseQR s;
        bool successfulSolve = s.solve(Ld, Rx, Cx) && s.solve(Ld, Ry, Cy);

        if (!successfulSolve)
        {
            throw Exception("PSpline::computeControlPoints: Failed to solve for B-spline coefficients.");
        }
    }

    coefficients = Cy.transpose();
    knotaverages = Cx.transpose();
}
Example #7
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;
}