10 #include "fei_CSRMat.hpp"
11 #include <fei_impl_utils.hpp>
12 #include "fei_ArrayUtils.hpp"
24 CSRMat::CSRMat(
const FillableMat& fmat)
36 CSRMat::operator=(
const fei::FillableMat& src)
38 FillableMat::const_iterator iter = src.begin(), iter_end = src.end();
40 unsigned nrows = src.getNumRows();
42 srg_.rowNumbers.resize(nrows);
43 srg_.rowOffsets.resize(nrows+1);
47 for(; iter != iter_end; ++iter, ++i) {
48 srg_.rowNumbers[i] = iter->first;
49 srg_.rowOffsets[i] = nnz;
50 nnz += iter->second->size();
53 srg_.rowOffsets[nrows] = nnz;
55 srg_.packedColumnIndices.resize(nnz);
56 packedcoefs_.resize(nnz);
58 int* colind_ptr = (srg_.packedColumnIndices.size()
59 ? &(srg_.packedColumnIndices[0]) : 0);
60 double* coef_ptr = (packedcoefs_.size()
61 ? &(packedcoefs_[0]) : 0);
66 for(; iter != iter_end; ++iter) {
67 const CSVec* v = iter->second;
68 const std::vector<int>& v_ind = v->indices();
69 const std::vector<double>& v_coef = v->coefs();
70 for(
size_t i=0; i<v_ind.size(); ++i) {
71 colind_ptr[offset] = v_ind[i];
72 coef_ptr[offset++] = v_coef[i];
80 CSRMat::operator+=(
const CSRMat& src)
83 add_CSRMat_to_FillableMat(*
this, tmp);
84 add_CSRMat_to_FillableMat(src, tmp);
90 CSRMat::operator==(
const CSRMat& rhs)
const
92 if (getGraph() != rhs.getGraph())
return false;
93 return getPackedCoefs() == rhs.getPackedCoefs();
97 CSRMat::operator!=(
const CSRMat& rhs)
const
99 return !(*
this == rhs);
106 const std::vector<int>& rows = A.getGraph().rowNumbers;
107 const int* rowoffs = &(A.getGraph().rowOffsets[0]);
108 const std::vector<int>& colinds = A.getGraph().packedColumnIndices;
109 const double* Acoef = A.getPackedCoefs().size() > 0 ? &(A.getPackedCoefs()[0]): NULL;
111 const std::vector<int>& xind = x.indices();
112 const std::vector<double>& xcoef = x.coefs();
114 const double* xcoef_ptr = xcoef.empty() ? NULL : &xcoef[0];
115 const int* xind_ptr = xind.empty() ? NULL : &xind[0];
116 int xlen = xcoef.size();
118 std::vector<int>& yind = y.indices();
119 std::vector<double>& ycoef = y.coefs();
121 unsigned nrows = A.getNumRows();
126 int* yind_ptr = yind.size() > 0 ? &yind[0] : NULL;
127 double* ycoef_ptr = ycoef.size() > 0 ? &ycoef[0] : NULL;
129 int jbeg = *rowoffs++;
130 for(
unsigned i=0; i<nrows; ++i) {
131 int jend = *rowoffs++;
138 sum += Acoef[jbeg]*xcoef_ptr[xoff];
143 yind_ptr[i] = rows[i];
150 const std::vector<int>& rows = A.getGraph().rowNumbers;
151 const int* rowoffs = &(A.getGraph().rowOffsets[0]);
152 const int* colinds = A.getGraph().packedColumnIndices.empty() ? NULL : &(A.getGraph().packedColumnIndices[0]);
153 const double* Acoef = A.getPackedCoefs().empty() ? NULL : &(A.getPackedCoefs()[0]);
155 const std::vector<int>& xind = x.indices();
156 const std::vector<double>& xcoef = x.coefs();
158 const double* xcoef_ptr = xcoef.empty() ? NULL : &xcoef[0];
160 unsigned nrows = A.getNumRows();
162 std::vector<int> offsets;
164 const int* offsetsptr = &offsets[0];
168 int jbeg = *rowoffs++;
169 for(
unsigned i=0; i<nrows; ++i) {
170 int jend = *rowoffs++;
172 int xoff = offsetsptr[i];
178 double xcoeff = xcoef_ptr[xoff];
181 add_entry(fy, colinds[jbeg],Acoef[jbeg]*xcoeff);
190 bool storeResultZeros)
196 const std::vector<int>& Arows = A.getGraph().rowNumbers;
197 const std::vector<int>& Brows = B.getGraph().rowNumbers;
198 if (Arows.size() < 1 || Brows.size() < 1) {
202 const int* Arowoffs = &(A.getGraph().rowOffsets[0]);
203 const int* Acols = &(A.getGraph().packedColumnIndices[0]);
204 const double* Acoefs = &(A.getPackedCoefs()[0]);
206 const int* Browoffs = &(B.getGraph().rowOffsets[0]);
207 const std::vector<int>& Bcols = B.getGraph().packedColumnIndices;
208 const double* Bcoefs = B.getPackedCoefs().empty() ? NULL : &(B.getPackedCoefs()[0]);
210 static double fei_min = std::numeric_limits<double>::min();
212 int jbeg = *Arowoffs++;
213 for(
size_t i=0; i<Arows.size(); ++i) {
215 int jend = *Arowoffs++;
218 if (storeResultZeros) {
219 fc_row = fc.create_or_getRow(row);
222 fc_row = fc.hasRow(row) ? fc.create_or_getRow(row) : NULL;
228 double Acoef = *Acoefs++;
232 if (Brow_offset < 0) {
236 if (!storeResultZeros) {
237 if (std::abs(Acoef) < fei_min) {
242 const int* Brow_cols = Bcols.empty() ? NULL : &(Bcols[Browoffs[Brow_offset]]);
243 const double* Brow_coefs = Bcoefs==NULL ? NULL : &(Bcoefs[Browoffs[Brow_offset]]);
244 int Brow_len = Browoffs[Brow_offset+1]-Browoffs[Brow_offset];
246 for(
int k=0; k<Brow_len; ++k) {
247 double resultCoef = Acoef*Brow_coefs[k];
248 int resultCol = Brow_cols[k];
250 if (!storeResultZeros) {
251 if (std::abs(resultCoef) < fei_min) {
256 if (fc_row == NULL) {
257 fc_row = fc.create_or_getRow(row);
260 add_entry(*fc_row, resultCol, resultCoef);
269 bool storeResultZeros)
275 const std::vector<int>& Arows = A.getGraph().rowNumbers;
276 const std::vector<int>& Brows = B.getGraph().rowNumbers;
277 if (Arows.size() < 1 || Brows.size() < 1) {
282 const size_t numArows = Arows.size();
283 const int* Arowoffs = &(A.getGraph().rowOffsets[0]);
284 const int* Acols = A.getGraph().packedColumnIndices.empty() ? NULL : &(A.getGraph().packedColumnIndices[0]);
285 const double* Acoefs = A.getPackedCoefs().empty() ? NULL : &(A.getPackedCoefs()[0]);
287 const int* Browoffs = &(B.getGraph().rowOffsets[0]);
288 const std::vector<int>& Bcols = B.getGraph().packedColumnIndices;
289 const double* Bcoefs = B.getPackedCoefs().empty() ? NULL : &(B.getPackedCoefs()[0]);
291 std::vector<double> row_coefs;
293 static double fei_min = std::numeric_limits<double>::min();
295 std::vector<int> offsets;
298 int jbeg = *Arowoffs++;
299 for(
size_t i=0; i<numArows; ++i) {
300 int jend = *Arowoffs++;
302 int Brow_offset = offsets[i];
303 if (Brow_offset < 0) {
308 const int* Brow_cols = Bcols.empty() ? NULL : &(Bcols[Browoffs[Brow_offset]]);
309 const double* Brow_coefs = Bcoefs==NULL ? NULL : &(Bcoefs[Browoffs[Brow_offset]]);
310 int Brow_len = Browoffs[Brow_offset+1]-Browoffs[Brow_offset];
312 if ((
int)row_coefs.size() < Brow_len) row_coefs.resize(Brow_len*2);
313 double* row_coefs_ptr = &row_coefs[0];
316 int Acol = Acols[jbeg];
317 double Acoef = Acoefs[jbeg++];
319 if (std::abs(Acoef) < fei_min && !storeResultZeros) {
323 for(
int k=0; k<Brow_len; ++k) {
324 row_coefs_ptr[k] = Acoef*Brow_coefs[k];
327 fc.sumInRow(Acol, Brow_cols, row_coefs_ptr, Brow_len);
334 void add_CSRMat_to_FillableMat(
const CSRMat& csrm, FillableMat& fm)
336 const std::vector<int>& rows = csrm.getGraph().rowNumbers;
337 const int* rowoffs = &(csrm.getGraph().rowOffsets[0]);
338 const std::vector<int>& cols = csrm.getGraph().packedColumnIndices;
339 const double* coefs = &(csrm.getPackedCoefs()[0]);
341 for(
size_t i=0; i<rows.size(); ++i) {
344 for(
int j=rowoffs[i]; j<rowoffs[i+1]; ++j) {
345 fm.sumInCoef(row, cols[j], coefs[j]);
void multiply_CSRMat_CSRMat(const CSRMat &A, const CSRMat &B, CSRMat &C, bool storeResultZeros)
void multiply_trans_CSRMat_CSVec(const CSRMat &A, const CSVec &x, CSVec &y)
void find_offsets(const std::vector< int > &sources, const std::vector< int > &targets, std::vector< int > &offsets)
int binarySearch(const T &item, const T *list, int len)
void multiply_trans_CSRMat_CSRMat(const CSRMat &A, const CSRMat &B, CSRMat &C, bool storeResultZeros)
void multiply_CSRMat_CSVec(const CSRMat &A, const CSVec &x, CSVec &y)