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)); } }
// 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 }
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 }
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; }
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(); }
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; }