// // Created by Wei Chen on 3/31/22 // #include "EigenLibSolver.hpp" namespace ssim { template void EigenLibSolver::set_pattern(const std::vector>& vNeighbor) { Base::set_pattern(vNeighbor); //TODO: directly save into mtr coefMtr.resize(Base::numRows, Base::numRows); coefMtr.reserve(Base::ja.size()); Base::ia.array() -= 1.0; Base::ja.array() -= 1.0; memcpy(coefMtr.innerIndexPtr(), Base::ja.data(), Base::ja.size() * sizeof(Base::ja[0])); memcpy(coefMtr.outerIndexPtr(), Base::ia.data(), Base::ia.size() * sizeof(Base::ia[0])); } template void EigenLibSolver::set_pattern(const Eigen::SparseMatrix& mtr) //NOTE: mtr must be SPD { Base::numRows = static_cast(mtr.rows()); coefMtr = mtr; } template void EigenLibSolver::analyze_pattern(void) { simplicialLDLT.analyzePattern(coefMtr); assert(simplicialLDLT.info() == Eigen::Success); } template bool EigenLibSolver::factorize(void) { bool succeeded = false; simplicialLDLT.factorize(coefMtr); succeeded = (simplicialLDLT.info() == Eigen::Success); assert(succeeded); return succeeded; } template void EigenLibSolver::solve(Eigen::VectorXd& rhs, Eigen::VectorXd& result) { result = simplicialLDLT.solve(rhs); assert(simplicialLDLT.info() == Eigen::Success); } template double EigenLibSolver::coeffMtr(int rowI, int colI) const { return Base::coeffMtr(rowI, colI); } template void EigenLibSolver::setZero(void) { //TODO: directly manipulate valuePtr without a Base::setZero(); memcpy(coefMtr.valuePtr(), Base::a.data(), Base::a.size() * sizeof(Base::a[0])); } template void EigenLibSolver::setCoeff(int rowI, int colI, double val) { //TODO: directly manipulate valuePtr without a if (rowI <= colI) { assert(rowI < Base::IJ2aI.size()); const auto finder = Base::IJ2aI[rowI].find(colI); assert(finder != Base::IJ2aI[rowI].end()); Base::a[finder->second] = val; coefMtr.valuePtr()[finder->second] = val; } } template void EigenLibSolver::addCoeff(int rowI, int colI, double val) { //TODO: directly manipulate valuePtr without a if (rowI <= colI) { assert(rowI < Base::IJ2aI.size()); const auto finder = Base::IJ2aI[rowI].find(colI); assert(finder != Base::IJ2aI[rowI].end()); Base::a[finder->second] += val; coefMtr.valuePtr()[finder->second] += val; } } template void EigenLibSolver::setUnit_row(int rowI) { for (const auto& colIter : Base::IJ2aI[rowI]) { coefMtr.valuePtr()[colIter.second] = (colIter.first == rowI); } } template void EigenLibSolver::setUnit_col(int colI, const std::set& rowVIs) { for (const auto& rowVI : rowVIs) { for (int dimI = 0; dimI < DIM_; ++dimI) { int rowI = rowVI * DIM_ + dimI; if (rowI <= colI) { const auto finder = Base::IJ2aI[rowI].find(colI); if (finder != Base::IJ2aI[rowI].end()) { coefMtr.valuePtr()[finder->second] = (rowI == colI); } } } } } template void EigenLibSolver::setZeroCol(int colI) { assert(colIsecond] = 0.0; } } } template class EigenLibSolver; } // namespace SIM