void multiply_CSRMat_CSVec(const CSRMat& A, const CSVec& x, CSVec& y) { //This function is unit-tested in fei/utest_cases/fei_unit_CSRMat_CSVec.cpp const std::vector<int>& rows = A.getGraph().rowNumbers; const int* rowoffs = &(A.getGraph().rowOffsets[0]); const std::vector<int>& colinds = A.getGraph().packedColumnIndices; const double* Acoef = &(A.getPackedCoefs()[0]); const std::vector<int>& xind = x.indices(); const std::vector<double>& xcoef = x.coefs(); const double* xcoef_ptr = &xcoef[0]; const int* xind_ptr = &xind[0]; int xlen = xcoef.size(); std::vector<int>& yind = y.indices(); std::vector<double>& ycoef = y.coefs(); unsigned nrows = A.getNumRows(); yind.resize(nrows); ycoef.resize(nrows); int* yind_ptr = &yind[0]; double* ycoef_ptr = &ycoef[0]; int jbeg = *rowoffs++; for(unsigned i=0; i<nrows; ++i) { int jend = *rowoffs++; double sum = 0.0; while(jbeg<jend) { int xoff = fei::binarySearch(colinds[jbeg], xind_ptr, xlen); if (xoff > -1) { sum += Acoef[jbeg]*xcoef_ptr[xoff]; } ++jbeg; } yind_ptr[i] = rows[i]; ycoef_ptr[i] = sum; } }
void add_CSVec_CSVec(const CSVec& u, CSVec& v) { const std::vector<int>& indices = u.indices(); const std::vector<double>& coefs = u.coefs(); for(size_t i=0; i<indices.size(); ++i) { add_entry(v, indices[i], coefs[i]); } }
void remove_entry(CSVec& vec, int eqn) { std::vector<int>& v_ind = vec.indices(); std::vector<double>& v_coef = vec.coefs(); std::vector<int>::iterator iter = std::lower_bound(v_ind.begin(), v_ind.end(), eqn); if (iter != v_ind.end() && *iter == eqn) { v_ind.erase(iter); size_t offset = iter - v_ind.begin(); std::vector<double>::iterator coef_iter = v_coef.begin()+offset; v_coef.erase(coef_iter); } }
void put_entry(CSVec& vec, int eqn, double coef) { std::vector<int>& v_ind = vec.indices(); std::vector<double>& v_coef = vec.coefs(); std::vector<int>::iterator iter = std::lower_bound(v_ind.begin(), v_ind.end(), eqn); size_t offset = iter - v_ind.begin(); if (iter == v_ind.end() || *iter != eqn) { v_ind.insert(iter, eqn); v_coef.insert(v_coef.begin()+offset, coef); } else { v_coef[offset] = coef; } }
double get_entry(const CSVec& vec, int eqn) { const std::vector<int>& v_ind = vec.indices(); const std::vector<double>& v_coef = vec.coefs(); if (vec.size() == 0) { throw std::runtime_error("get_entry error, CSVec is empty"); } std::vector<int>::const_iterator iter = std::lower_bound(v_ind.begin(), v_ind.end(), eqn); if (iter == v_ind.end()) { throw std::runtime_error("get_entry error, entry not found."); } return v_coef[iter - v_ind.begin()]; }
void multiply_trans_CSRMat_CSVec(const CSRMat& A, const CSVec& x, CSVec& y) { const std::vector<int>& rows = A.getGraph().rowNumbers; const int* rowoffs = &(A.getGraph().rowOffsets[0]); const int* colinds = &(A.getGraph().packedColumnIndices[0]); const double* Acoef = &(A.getPackedCoefs()[0]); const std::vector<int>& xind = x.indices(); const std::vector<double>& xcoef = x.coefs(); const double* xcoef_ptr = &xcoef[0]; unsigned nrows = A.getNumRows(); std::vector<int> offsets; fei::impl_utils::find_offsets(rows, xind, offsets); const int* offsetsptr = &offsets[0]; fei::CSVec fy; int jbeg = *rowoffs++; for(unsigned i=0; i<nrows; ++i) { int jend = *rowoffs++; int xoff = offsetsptr[i]; if (xoff < 0) { jbeg = jend; continue; } double xcoeff = xcoef_ptr[xoff]; while(jbeg<jend) { add_entry(fy, colinds[jbeg],Acoef[jbeg]*xcoeff); ++jbeg; } } y = fy; }
void set_values(CSVec& vec, double scalar) { std::fill(vec.coefs().begin(), vec.coefs().end(), scalar); }