40template <
class IT,
class NT>
43template <
class IT,
class NT>
55template <
class IT,
class NT>
56inline void Dcsc<IT,NT>::getindices (
StackEntry<
NT, std::pair<IT,IT> > * multstack,
IT & rindex,
IT & cindex,
IT & j,
IT nnz)
60 cindex = multstack[j].key.first;
61 rindex = multstack[j].key.second;
65 rindex = std::numeric_limits<IT>::max();
66 cindex = std::numeric_limits<IT>::max();
71template <
class IT,
class NT>
74 if(nnz == 0)
return *
this;
76 IT estnzc =
nzc + nnz;
85 getindices(multstack, rindex, cindex,j,nnz);
88 while(i<
nzc && cindex < std::numeric_limits<IT>::max())
93 temp.
jc[curnzc++] = cindex;
96 temp.
ir[curnz] = rindex;
97 temp.
numx[curnz++] = multstack[j-1].value;
99 getindices(multstack, rindex, cindex,j,nnz);
102 while(temp.
jc[curnzc-1] == cindex);
104 temp.
cp[curnzc] = temp.
cp[curnzc-1] + columncount;
106 else if(
jc[i] < cindex)
108 temp.
jc[curnzc++] =
jc[i++];
109 for(
IT k =
cp[i-1]; k<
cp[i]; ++k)
111 temp.
ir[curnz] =
ir[k];
114 temp.
cp[curnzc] = temp.
cp[curnzc-1] + (
cp[i] -
cp[i-1]);
118 temp.
jc[curnzc++] =
jc[i];
121 while (ii <
cp[i+1] && cindex ==
jc[i])
125 temp.
ir[curnz] =
ir[ii];
128 else if (
ir[ii] > rindex)
130 temp.
ir[curnz] = rindex;
131 temp.
numx[curnz++] = multstack[j-1].value;
133 getindices(multstack, rindex, cindex,j,nnz);
137 temp.
ir[curnz] =
ir[ii];
138 temp.
numx[curnz++] =
numx[ii++] + multstack[j-1].value;
140 getindices(multstack, rindex, cindex,j,nnz);
145 temp.
ir[curnz] =
ir[ii];
148 while (cindex ==
jc[i])
150 temp.
ir[curnz] = rindex;
151 temp.
numx[curnz++] = multstack[j-1].value;
153 getindices(multstack, rindex, cindex,j,nnz);
155 temp.
cp[curnzc] = temp.
cp[curnzc-1] + curnz-prevnz;
161 temp.
jc[curnzc++] =
jc[i++];
162 for(
IT k =
cp[i-1]; k<
cp[i]; ++k)
164 temp.
ir[curnz] =
ir[k];
167 temp.
cp[curnzc] = temp.
cp[curnzc-1] + (
cp[i] -
cp[i-1]);
169 while(cindex < std::numeric_limits<IT>::max())
172 temp.
jc[curnzc++] = cindex;
175 temp.
ir[curnz] = rindex;
176 temp.
numx[curnz++] = multstack[j-1].value;
178 getindices(multstack, rindex, cindex,j,nnz);
181 while(temp.
jc[curnzc-1] == cindex);
183 temp.
cp[curnzc] = temp.
cp[curnzc-1] + columncount;
185 temp.
Resize(curnzc, curnz);
195template <
class IT,
class NT>
198 nzc = std::min(ndim, nnz);
207 IT cindex = multstack[0].key.first;
208 IT rindex = multstack[0].key.second;
211 numx[0] = multstack[0].value;
216 for(
IT i=1; i<
nz; ++i)
218 cindex = multstack[i].key.first;
219 rindex = multstack[i].key.second;
222 numx[i] = multstack[i].value;
223 if(cindex !=
jc[curnzc-1])
238template <
class IT,
class NT>
241 assert((nnz != 0) && (indices.size() == nnz));
248 std::fill_n(
numx, nnz,
static_cast<NT>(1));
253 std::copy (indices.begin(), indices.end(),
jc);
258 std::copy (indices.begin(), indices.end(),
ir);
263template <
class IT,
class NT>
264template <
typename NNT>
269 for(
IT i=0; i<
nz; ++i)
279template <
class IT,
class NT>
280template <
typename NIT,
typename NNT>
285 for(
IT i=0; i<
nz; ++i)
287 for(
IT i=0; i<
nz; ++i)
289 for(
IT i=0; i<
nzc; ++i)
291 for(
IT i=0; i<=
nzc; ++i)
296template <
class IT,
class NT>
328template <
class IT,
class NT>
374template <
class IT,
class NT>
386 while(i<
nzc && j<rhs.
nzc)
388 if(
jc[i] > rhs.
jc[j])
390 temp.
jc[curnzc++] = rhs.
jc[j++];
391 for(
IT k = rhs.
cp[j-1]; k< rhs.
cp[j]; ++k)
393 temp.
ir[curnz] = rhs.
ir[k];
396 temp.
cp[curnzc] = temp.
cp[curnzc-1] + (rhs.
cp[j] - rhs.
cp[j-1]);
398 else if(
jc[i] < rhs.
jc[j])
400 temp.
jc[curnzc++] =
jc[i++];
401 for(
IT k =
cp[i-1]; k<
cp[i]; k++)
403 temp.
ir[curnz] =
ir[k];
406 temp.
cp[curnzc] = temp.
cp[curnzc-1] + (
cp[i] -
cp[i-1]);
410 temp.
jc[curnzc++] =
jc[i];
414 while (ii <
cp[i+1] && jj < rhs.
cp[j+1])
416 if (
ir[ii] < rhs.
ir[jj])
418 temp.
ir[curnz] =
ir[ii];
421 else if (
ir[ii] > rhs.
ir[jj])
423 temp.
ir[curnz] = rhs.
ir[jj];
424 temp.
numx[curnz++] = rhs.
numx[jj++];
428 temp.
ir[curnz] =
ir[ii];
434 temp.
ir[curnz] =
ir[ii];
437 while (jj < rhs.
cp[j+1])
439 temp.
ir[curnz] = rhs.
ir[jj];
440 temp.
numx[curnz++] = rhs.
numx[jj++];
442 temp.
cp[curnzc] = temp.
cp[curnzc-1] + curnz-prevnz;
449 temp.
jc[curnzc++] =
jc[i++];
450 for(
IT k =
cp[i-1]; k<
cp[i]; ++k)
452 temp.
ir[curnz] =
ir[k];
455 temp.
cp[curnzc] = temp.
cp[curnzc-1] + (
cp[i] -
cp[i-1]);
459 temp.
jc[curnzc++] = rhs.
jc[j++];
460 for(
IT k = rhs.
cp[j-1]; k< rhs.
cp[j]; ++k)
462 temp.
ir[curnz] = rhs.
ir[k];
465 temp.
cp[curnzc] = temp.
cp[curnzc-1] + (rhs.
cp[j] - rhs.
cp[j-1]);
467 temp.
Resize(curnzc, curnz);
472template <
class IT,
class NT>
475 if(
nzc != rhs.
nzc)
return false;
476 bool same = std::equal(
cp,
cp+
nzc+1, rhs.
cp);
477 same = same && std::equal(
jc,
jc+
nzc, rhs.
jc);
478 same = same && std::equal(
ir,
ir+
nz, rhs.
ir);
481 std::vector<NT> error(
nz);
483 std::vector< std::pair<NT, NT> > error_original_pair(
nz);
484 for(
IT i=0; i <
nz; ++i)
485 error_original_pair[i] = std::make_pair(error[i],
numx[i]);
486 if(error_original_pair.size() > 10)
488 partial_sort(error_original_pair.begin(), error_original_pair.begin()+10, error_original_pair.end(), std::greater< std::pair<NT,NT> >());
489 std::cout <<
"Highest 10 different entries are: " << std::endl;
490 for(
IT i=0; i < 10; ++i)
491 std::cout <<
"Diff: " << error_original_pair[i].first <<
" on " << error_original_pair[i].second << std::endl;
495 sort(error_original_pair.begin(), error_original_pair.end(), std::greater< std::pair<NT,NT> >());
496 std::cout <<
"Highest different entries are: " << std::endl;
497 for(
typename std::vector< std::pair<NT, NT> >::iterator it=error_original_pair.begin(); it != error_original_pair.end(); ++it)
498 std::cout <<
"Diff: " << it->first <<
" on " << it->second << std::endl;
500 std::cout <<
"Same before num: " << same << std::endl;
504 same = same && std::equal(
numx,
numx+
nz, rhs.
numx, epsilonequal );
513template <
class IT,
class NT>
525template <
class IT,
class NT>
534template <
class IT,
class NT>
535template <
typename _UnaryOperation,
typename GlobalIT>
541 for(
IT i=0; i<
nzc; ++i)
543 bool colexists =
false;
544 for(
IT j=
cp[i]; j <
cp[i+1]; ++j)
546 if(!(__unary_op(std::make_tuple(rowOffset+
ir[j], colOffset+
jc[i],
numx[j]))))
552 if(colexists) ++prunednzc;
559 cp =
new IT[prunednzc+1];
560 jc =
new IT[prunednzc];
561 ir =
new IT[prunednnz];
567 for(
IT i=0; i<
nzc; ++i)
569 for(
IT j = oldcp[i]; j < oldcp[i+1]; ++j)
571 if(!(__unary_op(std::make_tuple(rowOffset+oldir[j], colOffset+oldjc[i], oldnumx[j]))))
574 numx[cnnz++] = oldnumx[j];
584 assert(cnzc == prunednzc);
585 assert(cnnz == prunednnz);
615template <
class IT,
class NT>
616template <
typename _UnaryOperation>
622 for(
IT i=0; i<
nzc; ++i)
624 bool colexists =
false;
625 for(
IT j=
cp[i]; j <
cp[i+1]; ++j)
627 if(!(__unary_op(
numx[j])))
633 if(colexists) ++prunednzc;
640 cp =
new IT[prunednzc+1];
641 jc =
new IT[prunednzc];
642 ir =
new IT[prunednnz];
648 for(
IT i=0; i<
nzc; ++i)
650 for(
IT j = oldcp[i]; j < oldcp[i+1]; ++j)
652 if(!(__unary_op(oldnumx[j])))
655 numx[cnnz++] = oldnumx[j];
665 assert(cnzc == prunednzc);
666 assert(cnnz == prunednnz);
697template <
class IT,
class NT>
698template <
typename _BinaryOperation>
704 for(
IT i=0; i<
nzc; ++i)
706 bool colexists =
false;
707 for(
IT j=
cp[i]; j <
cp[i+1]; ++j)
710 if(!(__binary_op(
numx[j], pvals[colid])))
716 if(colexists) ++prunednzc;
723 cp =
new IT[prunednzc+1];
724 jc =
new IT[prunednzc];
725 ir =
new IT[prunednnz];
731 for(
IT i=0; i<
nzc; ++i)
733 for(
IT j = oldcp[i]; j < oldcp[i+1]; ++j)
736 if(!(__binary_op(oldnumx[j], pvals[colid])))
739 numx[cnnz++] = oldnumx[j];
749 assert(cnzc == prunednzc);
779template <
class IT,
class NT>
790 std::vector<IT> vjc, vir, nzpercol;
791 std::vector<NT> vnumx;
795 if (c >= ci.size() || ci[c] >
jc[j])
797 vjc.push_back(
jc[j]);
798 nzpercol.push_back(
cp[j+1] -
cp[j]);
800 for (
IT p =
cp[j]; p <
cp[j+1]; ++p)
802 vir.push_back(
ir[p]);
803 vnumx.push_back(
numx[p]);
808 else if (ci[c] <
jc[j]) ++c;
830 std::partial_sum(nzpercol.begin(), nzpercol.end(),
cp + 1);
831 std::copy(vjc.begin(), vjc.end(),
jc);
832 std::copy(vir.begin(), vir.end(),
ir);
833 std::copy(vnumx.begin(), vnumx.end(),
numx);
838template <
class IT,
class NT>
839template <
typename _BinaryOperation>
847 for(
IT i=0; i<
nzc; ++i)
849 bool colexists =
false;
853 for(
IT j=
cp[i]; j <
cp[i+1]; ++j)
855 if(!(__binary_op(
numx[j], pvals[k])))
866 prunednnz += (
cp[i+1] -
cp[i]);
868 if(colexists) ++prunednzc;
875 cp =
new IT[prunednzc+1];
876 jc =
new IT[prunednzc];
877 ir =
new IT[prunednnz];
884 for(
IT i=0; i<
nzc; ++i)
889 for(
IT j = oldcp[i]; j < oldcp[i+1]; ++j)
891 if(!(__binary_op(oldnumx[j], pvals[k])))
894 numx[cnnz++] = oldnumx[j];
901 for(
IT j = oldcp[i]; j < oldcp[i+1]; ++j)
904 numx[cnnz++] = oldnumx[j];
914 assert(cnzc == prunednzc);
944template <
class IT,
class NT>
947 for(
IT i=0; i<
nzc; ++i)
950 for(
IT j=
cp[i]; j <
cp[i+1]; ++j)
953 numx[j] *= scaler[rowid][colid];
962template <
class IT,
class NT>
963template <
typename _BinaryOperation>
966 for(
IT i=0; i<
nzc; ++i)
969 for(
IT j=
cp[i]; j <
cp[i+1]; ++j)
972 array[rowid][colid] = __binary_op(array[rowid][colid],
numx[j]);
982template <
class IT,
class NT>
985 float cf =
static_cast<float>(ndim+1) /
static_cast<float>(
nzc);
986 IT colchunks =
static_cast<IT> ( ceil(
static_cast<float>(ndim+1) / ceil(cf)) );
988 aux =
new IT[colchunks+1];
990 IT chunksize =
static_cast<IT>(ceil(cf));
994 for(
IT i = 0; i<
nzc; ++i)
996 if(
jc[i] >= curchunk * chunksize)
998 while(
jc[i] >= curchunk * chunksize)
1000 aux[curchunk++] = reg;
1005 while(curchunk <= colchunks)
1007 aux[curchunk++] = reg;
1016template <
class IT,
class NT>
1031 if ( nzcnew == 0 && nznew == 0)
1039 cp =
new IT[nzcnew+1];
1040 jc =
new IT[nzcnew];
1043 std::copy(tmpcp, tmpcp+
nzc+1,
cp);
1044 std::copy(tmpjc, tmpjc+
nzc,
jc);
1048 std::copy(tmpcp, tmpcp+nzcnew+1,
cp);
1049 std::copy(tmpjc, tmpjc+nzcnew,
jc);
1063 std::copy(tmpnumx, tmpnumx+
nz,
numx);
1064 std::copy(tmpir, tmpir+
nz,
ir);
1068 std::copy(tmpnumx, tmpnumx+nznew,
numx);
1069 std::copy(tmpir, tmpir+nznew,
ir);
1083template<
class IT,
class NT>
1086 IT base =
static_cast<IT>(floor((
float) (colind/csize)));
1087 IT start = aux[base];
1088 IT end = aux[base+1];
1090 IT * itr = std::find(
jc + start,
jc + end, colind);
1092 found = (itr !=
jc + end);
1100template<
class IT,
class NT>
1103 IT * itr = std::lower_bound(
jc,
jc+
nzc, cut);
1113 std::copy(
jc,
jc+pos,
A->jc);
1114 std::copy(
cp,
cp+pos+1,
A->cp);
1115 std::copy(
ir,
ir+
cp[pos],
A->ir);
1126 transform(
B->jc,
B->jc + (
nzc-pos),
B->jc, bind2nd(std::minus<IT>(), cut));
1127 std::copy(
cp+pos,
cp+
nzc+1,
B->cp);
1128 transform(
B->cp,
B->cp + (
nzc-pos+1),
B->cp, bind2nd(std::minus<IT>(),
cp[pos]));
1140template<
class IT,
class NT>
1144 std::vector<IT> pos;
1145 for(
auto cutpoint = cuts.begin(); cutpoint != cuts.end(); ++cutpoint)
1147 IT * itr = std::lower_bound(jcbegin,
jc+
nzc, *cutpoint);
1148 pos.push_back(itr -
jc);
1159 std::copy(
jc,
jc+pos[0], parts[0]->
jc);
1160 std::copy(
cp,
cp+pos[0]+1, parts[0]->
cp);
1161 std::copy(
ir,
ir+
cp[pos[0]], parts[0]->
ir);
1164 int ncuts = cuts.size();
1165 for(
int i=1; i< ncuts; ++i)
1167 if(
cp[pos[i]] -
cp[pos[i-1]] == 0)
1173 parts[i] =
new Dcsc<IT,NT>(
cp[pos[i]] -
cp[pos[i-1]], pos[i] - pos[i-1]);
1174 std::copy(
jc+pos[i-1],
jc+pos[i], parts[i]->
jc);
1175 transform(parts[i]->
jc, parts[i]->
jc + (pos[i]-pos[i-1]), parts[i]->
jc, bind2nd(std::minus<IT>(), cuts[i-1]));
1177 std::copy(
cp+pos[i-1],
cp+pos[i]+1, parts[i]->
cp);
1178 transform(parts[i]->
cp, parts[i]->
cp + (pos[i]-pos[i-1]+1), parts[i]->
cp, bind2nd(std::minus<IT>(),
cp[pos[i-1]]));
1180 std::copy(
ir+
cp[pos[i-1]],
ir+
cp[pos[i]], parts[i]->
ir);
1184 if(
nz -
cp[pos[ncuts-1]] == 0)
1186 parts[ncuts] = NULL;
1191 std::copy(
jc+pos[ncuts-1],
jc+
nzc, parts[ncuts]->
jc);
1192 transform(parts[ncuts]->
jc, parts[ncuts]->
jc + (
nzc-pos[ncuts-1]), parts[ncuts]->
jc, bind2nd(std::minus<IT>(), cuts[ncuts-1]));
1194 std::copy(
cp+pos[ncuts-1],
cp+
nzc+1, parts[ncuts]->
cp);
1195 transform(parts[ncuts]->
cp, parts[ncuts]->
cp + (
nzc-pos[ncuts-1]+1), parts[ncuts]->
cp, bind2nd(std::minus<IT>(),
cp[pos[ncuts-1]]));
1196 std::copy(
ir+
cp[pos[ncuts-1]],
ir+
nz, parts[ncuts]->
ir);
1204template<
class IT,
class NT>
1207 assert((
A != NULL) && (
B != NULL));
1208 IT cnz =
A->nz +
B->nz;
1209 IT cnzc =
A->nzc +
B->nzc;
1214 std::copy(
A->jc,
A->jc +
A->nzc,
jc);
1215 std::copy(
B->jc,
B->jc +
B->nzc,
jc +
A->nzc);
1216 transform(
jc +
A->nzc,
jc + cnzc,
jc +
A->nzc, bind2nd(std::plus<IT>(), cut));
1218 std::copy(
A->cp,
A->cp +
A->nzc,
cp);
1219 std::copy(
B->cp,
B->cp +
B->nzc +1,
cp +
A->nzc);
1220 transform(
cp +
A->nzc,
cp+cnzc+1,
cp +
A->nzc, bind2nd(std::plus<IT>(),
A->cp[
A->nzc]));
1222 std::copy(
A->ir,
A->ir +
A->nz,
ir);
1223 std::copy(
B->ir,
B->ir +
B->nz,
ir +
A->nz);
1226 std::copy(
A->numx,
A->numx +
A->nz,
numx);
1227 std::copy(
B->numx,
B->numx +
B->nz,
numx +
A->nz);
1238template<
class IT,
class NT>
1243 size_t nmembers = parts.size();
1244 for(
size_t i=0; i< nmembers; ++i)
1246 cnz += parts[i]->nz;
1247 cnzc += parts[i]->nzc;
1255 for(
size_t i=0; i< nmembers; ++i)
1257 std::copy(parts[i]->
jc, parts[i]->
jc + parts[i]->
nzc,
jc + run_nzc);
1258 transform(
jc + run_nzc,
jc + run_nzc + parts[i]->
nzc,
jc + run_nzc, bind2nd(std::plus<IT>(), offsets[i]));
1261 std::copy(parts[i]->
cp, parts[i]->
cp + parts[i]->
nzc,
cp + run_nzc);
1262 transform(
cp + run_nzc,
cp + run_nzc + parts[i]->
nzc,
cp + run_nzc, bind2nd(std::plus<IT>(),run_nz));
1264 std::copy(parts[i]->
ir, parts[i]->
ir + parts[i]->
nz,
ir + run_nz);
1265 std::copy(parts[i]->
numx, parts[i]->
numx + parts[i]->
nz,
numx + run_nz);
1267 run_nzc += parts[i]->nzc;
1268 run_nz += parts[i]->nz;
1271 cp[run_nzc] = run_nz;
1280template<
class IT,
class NT>
1286 IT mink = std::min(
nzc, nind);
1287 std::pair<IT,IT> * isect =
new std::pair<IT,IT>[mink];
1288 std::pair<IT,IT> * range1 =
new std::pair<IT,IT>[
nzc];
1289 std::pair<IT,IT> * range2 =
new std::pair<IT,IT>[nind];
1291 for(
IT i=0; i <
nzc; ++i)
1293 range1[i] = std::make_pair(
jc[i], i);
1295 for(
IT i=0; i < nind; ++i)
1297 range2[i] = std::make_pair(
static_cast<IT>(colnums[i]), 0);
1305 IT kisect =
static_cast<IT>(itr-isect);
1306 for(
IT j=0, i =0; j< nind; ++j)
1309 if( i == kisect || isect[i].first !=
static_cast<IT>(colnums[j]))
1312 colinds[j].first = 0;
1313 colinds[j].second = 0;
1317 IT p = isect[i++].second;
1318 colinds[j].first =
cp[p];
1319 colinds[j].second =
cp[p+1];
1327 for(
IT j =0; j< nind; ++j)
1329 IT pos =
AuxIndex(
static_cast<IT>(colnums[j]), found, aux, csize);
1332 colinds[j].first =
cp[pos];
1333 colinds[j].second =
cp[pos+1];
1337 colinds[j].first = 0;
1338 colinds[j].second = 0;
1345template <
class IT,
class NT>
void convert(string ifname, string ofname, string sort="revsize")
void EWiseScale(NT **scaler)
void SetDifference(const Dcsc< IT, NT > &rhs)
Dcsc< IT, NT > * PruneI(_UnaryOperation __unary_op, bool inPlace, GlobalIT rowOffset, GlobalIT colOffset)
void ColConcatenate(std::vector< Dcsc< IT, NT > * > &parts, std::vector< IT > &offsets)
void ColSplit(std::vector< Dcsc< IT, NT > * > &parts, std::vector< IT > &cuts)
Dcsc< IT, NT > * PruneColumn(NT *pvals, _BinaryOperation __binary_op, bool inPlace)
Dcsc< IT, NT > & operator=(const Dcsc< IT, NT > &rhs)
void EWiseMult(const Dcsc< IT, NT > &rhs, bool exclude)
IT AuxIndex(const IT colind, bool &found, IT *aux, IT csize) const
IT * ir
row indices, size nz
bool operator==(const Dcsc< IT, NT > &rhs)
void PruneColumnByIndex(const std::vector< IT > &ci)
void Merge(const Dcsc< IT, NT > *Adcsc, const Dcsc< IT, NT > *B, IT cut)
Dcsc< IT, NT > * Prune(_UnaryOperation __unary_op, bool inPlace)
Dcsc< IT, NT > & AddAndAssign(StackEntry< NT, std::pair< IT, IT > > *multstack, IT mdim, IT ndim, IT nnz)
IT * cp
The master array, size nzc+1 (keeps column pointers).
void Resize(IT nzcnew, IT nznew)
IT nzc
number of columns with at least one non-zero in them
void Split(Dcsc< IT, NT > *&A, Dcsc< IT, NT > *&B, IT cut)
IT ConstructAux(IT ndim, IT *&aux) const
NT * numx
generic values, size nz
Dcsc< IT, NT > & operator+=(const Dcsc< IT, NT > &rhs)
void FillColInds(const VT *colnums, IT nind, std::vector< std::pair< IT, IT > > &colinds, IT *aux, IT csize) const
void UpdateDense(NT **array, _BinaryOperation __binary_op) const
IT * jc
col indices, size nzc
static bool first_compare(std::pair< IT, IT > pair1, std::pair< IT, IT > pair2)
static void iota(_ForwardIter __first, _ForwardIter __last, T __val)
Dcsc< IU, typename promote_trait< NU1, NU2 >::T_promote > SetDifference(const Dcsc< IU, NU1 > &A, const Dcsc< IU, NU2 > *B)
Dcsc< IU, typename promote_trait< NU1, NU2 >::T_promote > EWiseMult(const Dcsc< IU, NU1 > &A, const Dcsc< IU, NU2 > *B, bool exclude)