You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

134 lines
4.3 KiB

//
// Created by Wei Chen on 3/31/22
//
#include "EigenLibSolver.hpp"
namespace ssim {
template <typename vectorTypeI, typename vectorTypeS>
void EigenLibSolver<vectorTypeI, vectorTypeS>::set_pattern(const std::vector<std::set<int>>& 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 <typename vectorTypeI, typename vectorTypeS>
void EigenLibSolver<vectorTypeI, vectorTypeS>::set_pattern(const Eigen::SparseMatrix<double>& mtr) //NOTE: mtr must be SPD
{
Base::numRows = static_cast<int>(mtr.rows());
coefMtr = mtr;
}
template <typename vectorTypeI, typename vectorTypeS>
void EigenLibSolver<vectorTypeI, vectorTypeS>::analyze_pattern(void)
{
simplicialLDLT.analyzePattern(coefMtr);
assert(simplicialLDLT.info() == Eigen::Success);
}
template <typename vectorTypeI, typename vectorTypeS>
bool EigenLibSolver<vectorTypeI, vectorTypeS>::factorize(void)
{
bool succeeded = false;
simplicialLDLT.factorize(coefMtr);
succeeded = (simplicialLDLT.info() == Eigen::Success);
assert(succeeded);
return succeeded;
}
template <typename vectorTypeI, typename vectorTypeS>
void EigenLibSolver<vectorTypeI, vectorTypeS>::solve(Eigen::VectorXd& rhs,
Eigen::VectorXd& result)
{
result = simplicialLDLT.solve(rhs);
assert(simplicialLDLT.info() == Eigen::Success);
}
template <typename vectorTypeI, typename vectorTypeS>
double EigenLibSolver<vectorTypeI, vectorTypeS>::coeffMtr(int rowI, int colI) const
{
return Base::coeffMtr(rowI, colI);
}
template <typename vectorTypeI, typename vectorTypeS>
void EigenLibSolver<vectorTypeI, vectorTypeS>::setZero(void)
{
//TODO: directly manipulate valuePtr without a
Base::setZero();
memcpy(coefMtr.valuePtr(), Base::a.data(), Base::a.size() * sizeof(Base::a[0]));
}
template <typename vectorTypeI, typename vectorTypeS>
void EigenLibSolver<vectorTypeI, vectorTypeS>::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 <typename vectorTypeI, typename vectorTypeS>
void EigenLibSolver<vectorTypeI, vectorTypeS>::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 <typename vectorTypeI, typename vectorTypeS>
void EigenLibSolver<vectorTypeI, vectorTypeS>::setUnit_row(int rowI)
{
for (const auto& colIter : Base::IJ2aI[rowI]) {
coefMtr.valuePtr()[colIter.second] = (colIter.first == rowI);
}
}
template <typename vectorTypeI, typename vectorTypeS>
void EigenLibSolver<vectorTypeI, vectorTypeS>::setUnit_col(int colI, const std::set<int>& 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 <typename vectorTypeI, typename vectorTypeS>
void EigenLibSolver<vectorTypeI, vectorTypeS>::setZeroCol(int colI)
{
assert(colI<Base::numRows);
for(int rowI=0; rowI<Base::numRows; ++rowI){
const auto finder = Base::IJ2aI[rowI].find(colI);
if(finder != Base::IJ2aI[rowI].end()){
coefMtr.valuePtr()[finder->second] = 0.0;
}
}
}
template class EigenLibSolver<Eigen::VectorXi, Eigen::VectorXd>;
} // namespace SIM