int main(int argc, char **argv) { print_version(argv[0]); if(argc==1) { cerr << "Not enough arguments \nPlease try \"" << argv[0] << " -h\" or \"" << argv[0] << " --help \" \n" << endl; return 0; } if ((!strcmp(argv[1],"-h")) | (!strcmp(argv[1],"--help"))) getHelp(argv); disp_argv(argc,argv); // Start Chrono cpuChrono C; C.start(); SymMatrix HeadMat; HeadMat.load(argv[1]); HeadMat.invert(); // invert inplace HeadMat.save(argv[2]); // Stop Chrono C.stop(); C.dispEllapsed(); return 0; }
int main(int argc, char **argv) { print_version(argv[0]); if(argc==1) { cerr << "Not enough arguments \nPlease try \"" << argv[0] << " -h\" or \"" << argv[0] << " --help \" \n" << endl; return 0; } if ((!strcmp(argv[1],"-h")) | (!strcmp(argv[1],"--help"))) getHelp(argv); disp_argv(argc,argv); // Start Chrono auto start_time = std::chrono::system_clock::now(); SymMatrix HeadMat; HeadMat.load(argv[1]); HeadMat.invert(); // invert inplace HeadMat.save(argv[2]); // Stop Chrono auto end_time = std::chrono::system_clock::now(); dispEllapsed(end_time-start_time); return 0; }
typename make_triangular_matrix<SymMatrix, boost::numeric::ublas::lower>::type cholesky_decomposition(SymMatrix const & A) { assert(A.size1() == A.size2()); auto L = matrix_lower_trianle(A); for(size_t i = 0; i != A.size1(); ++ i) { for(size_t j = 0; j != i; ++ j) { for(size_t k = 0; k != j; ++ k) { L(i, j) -= L(i, k) * L(j, k); } L(i, j) /= L(j, j); using ural::square; L(i, i) -= square(L(i, j)); } assert(L(i, i) >= 0); using std::sqrt; L(i, i) = sqrt(L(i, i)); } return L; }
bool isPSD (const SymMatrix &M) /* Check a Matrix is both Symetric and Positive Semi Definite * Creates a temporary copy * * Numerics of Algorithm: * Use UdUfactor and checks reciprocal condition number >=0 * Algorithms using UdUfactor will will therefore succeed if isPSD(M) is true * Do NOT assume because isPSD is true that M will appear to be PSD to other numerical algorithms * Return: * true iff M isSymetric and is PSD by the above algorithm */ { RowMatrix UD(M.size1(),M.size1()); RowMatrix::value_type rcond = UdUfactor(UD, M); return rcond >= 0.; }
void assemble_HM(const Geometry& geo, SymMatrix& mat, const unsigned gauss_order) { mat = SymMatrix((geo.size()-geo.outermost_interface().nb_triangles())); mat.set(0.0); double K = 1.0 / (4.0 * M_PI); // We iterate over the meshes (or pair of domains) to fill the lower half of the HeadMat (since its symmetry) for ( Geometry::const_iterator mit1 = geo.begin(); mit1 != geo.end(); ++mit1) { for ( Geometry::const_iterator mit2 = geo.begin(); (mit2 != (mit1+1)); ++mit2) { // if mit1 and mit2 communicate, i.e they are used for the definition of a common domain const int orientation = geo.oriented(*mit1, *mit2); // equals 0, if they don't have any domains in common // equals 1, if they are both oriented toward the same domain // equals -1, if they are not if ( orientation != 0 ) { double Scoeff = orientation * geo.sigma_inv(*mit1, *mit2) * K; double Dcoeff = - orientation * geo.indicator(*mit1, *mit2) * K; double Ncoeff; if ( !(mit1->outermost() || mit2->outermost()) ) { // Computing S block first because it's needed for the corresponding N block operatorS(*mit1, *mit2, mat, Scoeff, gauss_order); Ncoeff = geo.sigma(*mit1, *mit2)/geo.sigma_inv(*mit1, *mit2); } else { Ncoeff = orientation * geo.sigma(*mit1, *mit2) * K; } if ( !mit1->outermost() ) { // Computing D block operatorD(*mit1, *mit2, mat, Dcoeff, gauss_order); } if ( ( *mit1 != *mit2 ) && ( !mit2->outermost() ) ) { // Computing D* block operatorD(*mit1, *mit2, mat, Dcoeff, gauss_order, true); } // Computing N block operatorN(*mit1, *mit2, mat, Ncoeff, gauss_order); } } } // Deflate the diagonal block (N33) of 'mat' : (in order to have a zero-mean potential for the outermost interface) const Interface i = geo.outermost_interface(); unsigned i_first = (*i.begin()->mesh().vertex_begin())->index(); deflat(mat, i, mat(i_first, i_first) / (geo.outermost_interface().nb_vertices())); }
Vector<T> CholeskyDecomp<T>::operator()(const SymMatrix<T>& m, const Vector<T>& sol) const { ulong rows = m.numRows(); Vector<T> retval(rows); T ki; LowerTriangular<T> lower(rows); for(unsigned long k = 0; k < rows; k++) { for(unsigned long i = 0; i <= k; i++) { ki = m(k,i); for(unsigned long j = 0; j < i; j++) ki -= lower(i, j) * lower(k, j); if(i == k) ki = sqrt(ki); else ki /= lower(i,i); lower.at(k,i) = ki; } } Matrix<T> upper(lower); Vector<T> temp(rows); upper.transpose(); for(unsigned long i = 0; i < rows; i++) { ki = sol[i]; for(unsigned long j = 0; j < i; j++) { ki -= lower(i,j) * temp[j]; } temp.at(i) = ki/lower(i,i); } for(unsigned long i = rows; i > 0; i--) { ki = temp[i-1]; for(unsigned long j = rows; j > i; j--) { ki -= upper(i-1, j-1) * retval[j-1]; } retval.at(i-1) = ki/upper(i-1, i-1); } return retval; }
void PDFullSpaceSolver::ComputeResiduals( const SymMatrix& W, const Matrix& J_c, const Matrix& J_d, const Matrix& Px_L, const Matrix& Px_U, const Matrix& Pd_L, const Matrix& Pd_U, const Vector& z_L, const Vector& z_U, const Vector& v_L, const Vector& v_U, const Vector& slack_x_L, const Vector& slack_x_U, const Vector& slack_s_L, const Vector& slack_s_U, const Vector& sigma_x, const Vector& sigma_s, Number alpha, Number beta, const IteratesVector& rhs, const IteratesVector& res, IteratesVector& resid) { DBG_START_METH("PDFullSpaceSolver::ComputeResiduals", dbg_verbosity); DBG_PRINT_VECTOR(2, "res", res); IpData().TimingStats().ComputeResiduals().Start(); // Get the current sizes of the perturbation factors Number delta_x; Number delta_s; Number delta_c; Number delta_d; perturbHandler_->CurrentPerturbation(delta_x, delta_s, delta_c, delta_d); SmartPtr<Vector> tmp; // x W.MultVector(1., *res.x(), 0., *resid.x_NonConst()); J_c.TransMultVector(1., *res.y_c(), 1., *resid.x_NonConst()); J_d.TransMultVector(1., *res.y_d(), 1., *resid.x_NonConst()); Px_L.MultVector(-1., *res.z_L(), 1., *resid.x_NonConst()); Px_U.MultVector(1., *res.z_U(), 1., *resid.x_NonConst()); resid.x_NonConst()->AddTwoVectors(delta_x, *res.x(), -1., *rhs.x(), 1.); // s Pd_U.MultVector(1., *res.v_U(), 0., *resid.s_NonConst()); Pd_L.MultVector(-1., *res.v_L(), 1., *resid.s_NonConst()); resid.s_NonConst()->AddTwoVectors(-1., *res.y_d(), -1., *rhs.s(), 1.); if (delta_s!=0.) { resid.s_NonConst()->Axpy(delta_s, *res.s()); } // c J_c.MultVector(1., *res.x(), 0., *resid.y_c_NonConst()); resid.y_c_NonConst()->AddTwoVectors(-delta_c, *res.y_c(), -1., *rhs.y_c(), 1.); // d J_d.MultVector(1., *res.x(), 0., *resid.y_d_NonConst()); resid.y_d_NonConst()->AddTwoVectors(-1., *res.s(), -1., *rhs.y_d(), 1.); if (delta_d!=0.) { resid.y_d_NonConst()->Axpy(-delta_d, *res.y_d()); } // zL resid.z_L_NonConst()->Copy(*res.z_L()); resid.z_L_NonConst()->ElementWiseMultiply(slack_x_L); tmp = z_L.MakeNew(); Px_L.TransMultVector(1., *res.x(), 0., *tmp); tmp->ElementWiseMultiply(z_L); resid.z_L_NonConst()->AddTwoVectors(1., *tmp, -1., *rhs.z_L(), 1.); // zU resid.z_U_NonConst()->Copy(*res.z_U()); resid.z_U_NonConst()->ElementWiseMultiply(slack_x_U); tmp = z_U.MakeNew(); Px_U.TransMultVector(1., *res.x(), 0., *tmp); tmp->ElementWiseMultiply(z_U); resid.z_U_NonConst()->AddTwoVectors(-1., *tmp, -1., *rhs.z_U(), 1.); // vL resid.v_L_NonConst()->Copy(*res.v_L()); resid.v_L_NonConst()->ElementWiseMultiply(slack_s_L); tmp = v_L.MakeNew(); Pd_L.TransMultVector(1., *res.s(), 0., *tmp); tmp->ElementWiseMultiply(v_L); resid.v_L_NonConst()->AddTwoVectors(1., *tmp, -1., *rhs.v_L(), 1.); // vU resid.v_U_NonConst()->Copy(*res.v_U()); resid.v_U_NonConst()->ElementWiseMultiply(slack_s_U); tmp = v_U.MakeNew(); Pd_U.TransMultVector(1., *res.s(), 0., *tmp); tmp->ElementWiseMultiply(v_U); resid.v_U_NonConst()->AddTwoVectors(-1., *tmp, -1., *rhs.v_U(), 1.); DBG_PRINT_VECTOR(2, "resid", resid); if (Jnlst().ProduceOutput(J_MOREVECTOR, J_LINEAR_ALGEBRA)) { resid.Print(Jnlst(), J_MOREVECTOR, J_LINEAR_ALGEBRA, "resid"); } if (Jnlst().ProduceOutput(J_MOREDETAILED, J_LINEAR_ALGEBRA)) { Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_x %e\n", resid.x()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_s %e\n", resid.s()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_c %e\n", resid.y_c()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_d %e\n", resid.y_d()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_zL %e\n", resid.z_L()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_zU %e\n", resid.z_U()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_vL %e\n", resid.v_L()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_vU %e\n", resid.v_U()->Amax()); } IpData().TimingStats().ComputeResiduals().End(); }
bool PDFullSpaceSolver::SolveOnce(bool resolve_with_better_quality, bool pretend_singular, const SymMatrix& W, const Matrix& J_c, const Matrix& J_d, const Matrix& Px_L, const Matrix& Px_U, const Matrix& Pd_L, const Matrix& Pd_U, const Vector& z_L, const Vector& z_U, const Vector& v_L, const Vector& v_U, const Vector& slack_x_L, const Vector& slack_x_U, const Vector& slack_s_L, const Vector& slack_s_U, const Vector& sigma_x, const Vector& sigma_s, Number alpha, Number beta, const IteratesVector& rhs, IteratesVector& res) { // TO DO LIST: // // 1. decide for reasonable return codes (e.g. fatal error, too // ill-conditioned...) // 2. Make constants parameters that can be set from the outside // 3. Get Information out of Ipopt structures // 4. add heuristic for structurally singular problems // 5. see if it makes sense to distinguish delta_x and delta_s, // or delta_c and delta_d // 6. increase pivot tolerance if number of get evals so too small DBG_START_METH("PDFullSpaceSolver::SolveOnce",dbg_verbosity); IpData().TimingStats().PDSystemSolverSolveOnce().Start(); // Compute the right hand side for the augmented system formulation SmartPtr<Vector> augRhs_x = rhs.x()->MakeNewCopy(); Px_L.AddMSinvZ(1.0, slack_x_L, *rhs.z_L(), *augRhs_x); Px_U.AddMSinvZ(-1.0, slack_x_U, *rhs.z_U(), *augRhs_x); SmartPtr<Vector> augRhs_s = rhs.s()->MakeNewCopy(); Pd_L.AddMSinvZ(1.0, slack_s_L, *rhs.v_L(), *augRhs_s); Pd_U.AddMSinvZ(-1.0, slack_s_U, *rhs.v_U(), *augRhs_s); // Get space into which we can put the solution of the augmented system SmartPtr<IteratesVector> sol = res.MakeNewIteratesVector(true); // Now check whether any data has changed std::vector<const TaggedObject*> deps(13); deps[0] = &W; deps[1] = &J_c; deps[2] = &J_d; deps[3] = &z_L; deps[4] = &z_U; deps[5] = &v_L; deps[6] = &v_U; deps[7] = &slack_x_L; deps[8] = &slack_x_U; deps[9] = &slack_s_L; deps[10] = &slack_s_U; deps[11] = &sigma_x; deps[12] = &sigma_s; void* dummy; bool uptodate = dummy_cache_.GetCachedResult(dummy, deps); if (!uptodate) { dummy_cache_.AddCachedResult(dummy, deps); augsys_improved_ = false; } // improve_current_solution can only be true, if that system has // been solved before DBG_ASSERT((!resolve_with_better_quality && !pretend_singular) || uptodate); ESymSolverStatus retval; if (uptodate && !pretend_singular) { // Get the perturbation values Number delta_x; Number delta_s; Number delta_c; Number delta_d; perturbHandler_->CurrentPerturbation(delta_x, delta_s, delta_c, delta_d); // No need to go through the pain of finding the appropriate // values for the deltas, because the matrix hasn't changed since // the last call. So, just call the Solve Method // // Note: resolve_with_better_quality is true, then the Solve // method has already asked the augSysSolver to increase the // quality at the end solve, and we are now getting the solution // with that better quality retval = augSysSolver_->Solve(&W, 1.0, &sigma_x, delta_x, &sigma_s, delta_s, &J_c, NULL, delta_c, &J_d, NULL, delta_d, *augRhs_x, *augRhs_s, *rhs.y_c(), *rhs.y_d(), *sol->x_NonConst(), *sol->s_NonConst(), *sol->y_c_NonConst(), *sol->y_d_NonConst(), false, 0); if (retval!=SYMSOLVER_SUCCESS) { IpData().TimingStats().PDSystemSolverSolveOnce().End(); return false; } } else { const Index numberOfEVals=rhs.y_c()->Dim()+rhs.y_d()->Dim(); // counter for the number of trial evaluations // (ToDo is not at the correct place) Index count = 0; // Get the very first perturbation values from the perturbation // Handler Number delta_x; Number delta_s; Number delta_c; Number delta_d; perturbHandler_->ConsiderNewSystem(delta_x, delta_s, delta_c, delta_d); retval = SYMSOLVER_SINGULAR; bool fail = false; while (retval!= SYMSOLVER_SUCCESS && !fail) { if (pretend_singular) { retval = SYMSOLVER_SINGULAR; pretend_singular = false; } else { count++; Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "Solving system with delta_x=%e delta_s=%e\n delta_c=%e delta_d=%e\n", delta_x, delta_s, delta_c, delta_d); bool check_inertia = true; if (neg_curv_test_tol_ > 0.) { check_inertia = false; } retval = augSysSolver_->Solve(&W, 1.0, &sigma_x, delta_x, &sigma_s, delta_s, &J_c, NULL, delta_c, &J_d, NULL, delta_d, *augRhs_x, *augRhs_s, *rhs.y_c(), *rhs.y_d(), *sol->x_NonConst(), *sol->s_NonConst(), *sol->y_c_NonConst(), *sol->y_d_NonConst(), check_inertia, numberOfEVals); } if (retval==SYMSOLVER_FATAL_ERROR) return false; if (retval==SYMSOLVER_SINGULAR && (rhs.y_c()->Dim()+rhs.y_d()->Dim() > 0) ) { // Get new perturbation factors from the perturbation // handlers for the singular case bool pert_return = perturbHandler_->PerturbForSingularity(delta_x, delta_s, delta_c, delta_d); if (!pert_return) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "PerturbForSingularity can't be done\n"); IpData().TimingStats().PDSystemSolverSolveOnce().End(); return false; } } else if (retval==SYMSOLVER_WRONG_INERTIA && augSysSolver_->NumberOfNegEVals() < numberOfEVals) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Number of negative eigenvalues too small!\n"); // If the number of negative eigenvalues is too small, then // we first try to remedy this by asking for better quality // solution (e.g. increasing pivot tolerance), and if that // doesn't help, we assume that the system is singular bool assume_singular = true; if (!augsys_improved_) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Asking augmented system solver to improve quality of its solutions.\n"); augsys_improved_ = augSysSolver_->IncreaseQuality(); if (augsys_improved_) { IpData().Append_info_string("q"); assume_singular = false; } else { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Quality could not be improved\n"); } } if (assume_singular) { bool pert_return = perturbHandler_->PerturbForSingularity(delta_x, delta_s, delta_c, delta_d); if (!pert_return) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "PerturbForSingularity can't be done for assume singular.\n"); IpData().TimingStats().PDSystemSolverSolveOnce().End(); return false; } IpData().Append_info_string("a"); } } else if (retval==SYMSOLVER_WRONG_INERTIA || retval==SYMSOLVER_SINGULAR) { // Get new perturbation factors from the perturbation // handlers for the case of wrong inertia bool pert_return = perturbHandler_->PerturbForWrongInertia(delta_x, delta_s, delta_c, delta_d); if (!pert_return) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "PerturbForWrongInertia can't be done for wrong interia or singular.\n"); IpData().TimingStats().PDSystemSolverSolveOnce().End(); return false; } } else if (neg_curv_test_tol_ > 0.) { DBG_ASSERT(augSysSolver_->ProvidesInertia()); // we now check if the inertia is possible wrong Index neg_values = augSysSolver_->NumberOfNegEVals(); if (neg_values != numberOfEVals) { // check if we have a direction of sufficient positive curvature SmartPtr<Vector> x_tmp = sol->x()->MakeNew(); W.MultVector(1., *sol->x(), 0., *x_tmp); Number xWx = x_tmp->Dot(*sol->x()); x_tmp->Copy(*sol->x()); x_tmp->ElementWiseMultiply(sigma_x); xWx += x_tmp->Dot(*sol->x()); SmartPtr<Vector> s_tmp = sol->s()->MakeNewCopy(); s_tmp->ElementWiseMultiply(sigma_s); xWx += s_tmp->Dot(*sol->s()); if (neg_curv_test_reg_) { x_tmp->Copy(*sol->x()); x_tmp->Scal(delta_x); xWx += x_tmp->Dot(*sol->x()); s_tmp->Copy(*sol->s()); s_tmp->Scal(delta_s); xWx += s_tmp->Dot(*sol->s()); } Number xs_nrmsq = pow(sol->x()->Nrm2(),2) + pow(sol->s()->Nrm2(),2); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "In inertia heuristic: xWx = %e xx = %e\n", xWx, xs_nrmsq); if (xWx < neg_curv_test_tol_*xs_nrmsq) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, " -> Redo with modified matrix.\n"); bool pert_return = perturbHandler_->PerturbForWrongInertia(delta_x, delta_s, delta_c, delta_d); if (!pert_return) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "PerturbForWrongInertia can't be done for inertia heuristic.\n"); IpData().TimingStats().PDSystemSolverSolveOnce().End(); return false; } retval = SYMSOLVER_WRONG_INERTIA; } } } } // while (retval!=SYMSOLVER_SUCCESS && !fail) { // Some output Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Number of trial factorizations performed: %d\n", count); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Perturbation parameters: delta_x=%e delta_s=%e\n delta_c=%e delta_d=%e\n", delta_x, delta_s, delta_c, delta_d); // Set the perturbation values in the Data object IpData().setPDPert(delta_x, delta_s, delta_c, delta_d); } // Compute the remaining sol Vectors Px_L.SinvBlrmZMTdBr(-1., slack_x_L, *rhs.z_L(), z_L, *sol->x(), *sol->z_L_NonConst()); Px_U.SinvBlrmZMTdBr(1., slack_x_U, *rhs.z_U(), z_U, *sol->x(), *sol->z_U_NonConst()); Pd_L.SinvBlrmZMTdBr(-1., slack_s_L, *rhs.v_L(), v_L, *sol->s(), *sol->v_L_NonConst()); Pd_U.SinvBlrmZMTdBr(1., slack_s_U, *rhs.v_U(), v_U, *sol->s(), *sol->v_U_NonConst()); // Finally let's assemble the res result vectors res.AddOneVector(alpha, *sol, beta); IpData().TimingStats().PDSystemSolverSolveOnce().End(); return true; }
int main( int argc, char **argv) { print_version(argv[0]); //TODO doesn't say txt, if you don't specify it command_usage("Provides informations on a Matrix generated with OpenMEEG"); const char *filename = command_option("-i",(const char *) NULL,"Matrix file"); const char *txt = command_option("-txt",(const char *) 0,"Force reading data stored in ascii format"); const char *sym = command_option("-sym",(const char *) 0,"Data are symmetric matrices"); const char *sparse = command_option("-sparse",(const char *) 0,"Data are sparse matrices"); const char *mat = command_option("-mat",(const char *) 0,"Data are matlab format"); const char *bin = command_option("-bin",(const char *) 0,"Data are binary format"); if (command_option("-h",(const char *)0,0)) return 0; if (!filename) { cerr << "Please set Matrix File" << endl; exit(1); } cout << "Loading : " << filename << endl; if (sym) { if (txt) { SymMatrix M; M.load(filename); cout << "Format : ASCII" << endl; print_infos(M); } else if (mat) { cerr << "Unsupported Format : MAT for symmetric matrices" << endl; exit(1); } else if (bin) { SymMatrix M; M.load(filename); cout << "Format : BINARY" << endl; print_infos(M); } else { SymMatrix M; M.load(filename); print_infos(M); } } else if (sparse) { if (txt) { SparseMatrix M; M.load(filename); cout << "Format : ASCII" << endl; print_infos(M); } else if (mat) { SparseMatrix M; M.load(filename); cout << "Format : MAT" << endl; print_infos(M); } else if (bin) { SparseMatrix M; M.load(filename); cout << "Format : BINARY" << endl; print_infos(M); } else { SparseMatrix M; M.load(filename); print_infos(M); } } else { if (txt) { Matrix M; M.load(filename); cout << "Format : ASCII" << endl; print_infos(M); } else if (mat) { Matrix M; M.load(filename); cout << "Format : MAT" << endl; print_infos(M); } else if (bin) { Matrix M; M.load(filename); cout << "Format : BINARY" << endl; print_infos(M); } else { Matrix M; M.load(filename); print_infos(M); } } return 0; }
void QpGenData::putCIntoAt( SymMatrix& M, int row, int col ) { M.symAtPutSubmatrix( row, col, *C, 0, 0, mz, nx ); }
void QpGenData::putQIntoAt( SymMatrix& M, int row, int col ) { M.symAtPutSubmatrix( row, col, *Q, 0, 0, nx, nx ); }
Vector::Vector(SymMatrix& A) { nlin()=A.nlin()*(A.nlin()+1)/2; value = A.value; }
// Initialize the local copy of the positions of the nonzero // elements ESymSolverStatus TSymLinearSolver::InitializeStructure(const SymMatrix& sym_A) { DBG_START_METH("TSymLinearSolver::InitializeStructure", dbg_verbosity); DBG_ASSERT(!initialized_); ESymSolverStatus retval; // have_structure_ is already true if this is a warm start for a // problem with identical structure if (!have_structure_) { dim_ = sym_A.Dim(); nonzeros_triplet_ = TripletHelper::GetNumberEntries(sym_A); delete [] airn_; delete [] ajcn_; airn_ = new Index[nonzeros_triplet_]; ajcn_ = new Index[nonzeros_triplet_]; TripletHelper::FillRowCol(nonzeros_triplet_, sym_A, airn_, ajcn_); // If the solver wants the compressed format, the converter has to // be initialized const Index *ia; const Index *ja; Index nonzeros; if (matrix_format_ == SparseSymLinearSolverInterface::Triplet_Format) { ia = airn_; ja = ajcn_; nonzeros = nonzeros_triplet_; } else { if (HaveIpData()) { IpData().TimingStats().LinearSystemStructureConverter().Start(); IpData().TimingStats().LinearSystemStructureConverterInit().Start(); } nonzeros_compressed_ = triplet_to_csr_converter_->InitializeConverter(dim_, nonzeros_triplet_, airn_, ajcn_); if (HaveIpData()) { IpData().TimingStats().LinearSystemStructureConverterInit().End(); } ia = triplet_to_csr_converter_->IA(); ja = triplet_to_csr_converter_->JA(); if (HaveIpData()) { IpData().TimingStats().LinearSystemStructureConverter().End(); } nonzeros = nonzeros_compressed_; } retval = solver_interface_->InitializeStructure(dim_, nonzeros, ia, ja); if (retval != SYMSOLVER_SUCCESS) { return retval; } // Get space for the scaling factors delete [] scaling_factors_; if (IsValid(scaling_method_)) { if (HaveIpData()) { IpData().TimingStats().LinearSystemScaling().Start(); } scaling_factors_ = new double[dim_]; if (HaveIpData()) { IpData().TimingStats().LinearSystemScaling().End(); } } have_structure_ = true; } else { ASSERT_EXCEPTION(dim_==sym_A.Dim(), INVALID_WARMSTART, "TSymLinearSolver called with warm_start_same_structure, but the problem is solved for the first time."); // This is a warm start for identical structure, so we don't need to // recompute the nonzeros location arrays const Index *ia; const Index *ja; Index nonzeros; if (matrix_format_ == SparseSymLinearSolverInterface::Triplet_Format) { ia = airn_; ja = ajcn_; nonzeros = nonzeros_triplet_; } else { IpData().TimingStats().LinearSystemStructureConverter().Start(); ia = triplet_to_csr_converter_->IA(); ja = triplet_to_csr_converter_->JA(); IpData().TimingStats().LinearSystemStructureConverter().End(); nonzeros = nonzeros_compressed_; } retval = solver_interface_->InitializeStructure(dim_, nonzeros, ia, ja); } initialized_=true; return retval; }
ESymSolverStatus TSymLinearSolver::MultiSolve(const SymMatrix& sym_A, std::vector<SmartPtr<const Vector> >& rhsV, std::vector<SmartPtr<Vector> >& solV, bool check_NegEVals, Index numberOfNegEVals) { DBG_START_METH("TSymLinearSolver::MultiSolve",dbg_verbosity); DBG_ASSERT(!check_NegEVals || ProvidesInertia()); // Check if this object has ever seen a matrix If not, // allocate memory of the matrix structure and copy the nonzeros // structure (it is assumed that this will never change). if (!initialized_) { ESymSolverStatus retval = InitializeStructure(sym_A); if (retval != SYMSOLVER_SUCCESS) { return retval; } } DBG_ASSERT(nonzeros_triplet_== TripletHelper::GetNumberEntries(sym_A)); // Check if the matrix has been changed DBG_PRINT((1,"atag_=%d sym_A->GetTag()=%d\n",atag_,sym_A.GetTag())); bool new_matrix = sym_A.HasChanged(atag_); atag_ = sym_A.GetTag(); // If a new matrix is encountered, get the array for storing the // entries from the linear solver interface, fill in the new // values, compute the new scaling factors (if required), and // scale the matrix if (new_matrix || just_switched_on_scaling_) { GiveMatrixToSolver(true, sym_A); new_matrix = true; } // Retrieve the right hand sides and scale if required Index nrhs = (Index)rhsV.size(); double* rhs_vals = new double[dim_*nrhs]; for (Index irhs=0; irhs<nrhs; irhs++) { TripletHelper::FillValuesFromVector(dim_, *rhsV[irhs], &rhs_vals[irhs*(dim_)]); if (Jnlst().ProduceOutput(J_MOREMATRIX, J_LINEAR_ALGEBRA)) { Jnlst().Printf(J_MOREMATRIX, J_LINEAR_ALGEBRA, "Right hand side %d in TSymLinearSolver:\n", irhs); for (Index i=0; i<dim_; i++) { Jnlst().Printf(J_MOREMATRIX, J_LINEAR_ALGEBRA, "Trhs[%5d,%5d] = %23.16e\n", irhs, i, rhs_vals[irhs*(dim_)+i]); } } if (use_scaling_) { if (HaveIpData()) { IpData().TimingStats().LinearSystemScaling().Start(); } for (Index i=0; i<dim_; i++) { rhs_vals[irhs*(dim_)+i] *= scaling_factors_[i]; } if (HaveIpData()) { IpData().TimingStats().LinearSystemScaling().End(); } } } bool done = false; // Call the linear solver through the interface to solve the // system. This is repeated, if the return values is S_CALL_AGAIN // after the values have been restored (this might be necessary // for MA27 if the size of the work space arrays was not large // enough). ESymSolverStatus retval; while (!done) { const Index* ia; const Index* ja; if (matrix_format_==SparseSymLinearSolverInterface::Triplet_Format) { ia = airn_; ja = ajcn_; } else { if (HaveIpData()) { IpData().TimingStats().LinearSystemStructureConverter().Start(); } ia = triplet_to_csr_converter_->IA(); ja = triplet_to_csr_converter_->JA(); if (HaveIpData()) { IpData().TimingStats().LinearSystemStructureConverter().End(); } } retval = solver_interface_->MultiSolve(new_matrix, ia, ja, nrhs, rhs_vals, check_NegEVals, numberOfNegEVals); if (retval==SYMSOLVER_CALL_AGAIN) { DBG_PRINT((1, "Solver interface asks to be called again.\n")); GiveMatrixToSolver(false, sym_A); } else { done = true; } } // If the solve was successful, unscale the solution (if required) // and transfer the result into the Vectors if (retval==SYMSOLVER_SUCCESS) { for (Index irhs=0; irhs<nrhs; irhs++) { if (use_scaling_) { if (HaveIpData()) { IpData().TimingStats().LinearSystemScaling().Start(); } for (Index i=0; i<dim_; i++) { rhs_vals[irhs*(dim_)+i] *= scaling_factors_[i]; } if (HaveIpData()) { IpData().TimingStats().LinearSystemScaling().End(); } } if (Jnlst().ProduceOutput(J_MOREMATRIX, J_LINEAR_ALGEBRA)) { Jnlst().Printf(J_MOREMATRIX, J_LINEAR_ALGEBRA, "Solution %d in TSymLinearSolver:\n", irhs); for (Index i=0; i<dim_; i++) { Jnlst().Printf(J_MOREMATRIX, J_LINEAR_ALGEBRA, "Tsol[%5d,%5d] = %23.16e\n", irhs, i, rhs_vals[irhs*(dim_)+i]); } } TripletHelper::PutValuesInVector(dim_, &rhs_vals[irhs*(dim_)], *solV[irhs]); } } delete[] rhs_vals; return retval; }