45template <
class IT,
class NT>
49template <
class IT,
class NT>
54template <
class IT,
class NT>
56:m(nRow), n(nCol), nnz(
size), splits(0)
64template <
class IT,
class NT>
73 for(
int i=0; i<splits; ++i)
87template <
class IT,
class NT>
89: m(rhs.m), n(rhs.n), nnz(rhs.nnz), splits(rhs.splits)
93 for(
int i=0; i<splits; ++i)
108template <
class IT,
class NT>
110: m(rhs.m), n(rhs.n), nnz(rhs.nnz), splits(0)
115 if(transpose) std::swap(m,n);
124 for(
IT i=1; i< rhs.nnz; ++i)
135 for(
IT i=0; i<rhs.nnz; ++i)
142 for(
IT i=1; i<rhs.nnz; ++i)
147 dcsc->cp[jspos++] = i;
150 dcsc->cp[jspos] = rhs.nnz;
155 for(
IT i=1; i<rhs.nnz; ++i)
166 for(
IT i=0; i<rhs.nnz; ++i)
173 for(
IT i=1; i<rhs.nnz; ++i)
178 dcsc->cp[jspos++] = i;
181 dcsc->cp[jspos] = rhs.nnz;
197template <
class IT,
class NT>
199: m(nRow), n(nCol), nnz(nTuples), splits(0)
212 totThreads = omp_get_num_threads();
216 std::vector <IT> tstart(totThreads);
217 std::vector <IT> tend(totThreads);
218 std::vector <IT> tdisp(totThreads+1);
221 IT* temp_jc =
new IT[nTuples];
222 IT* temp_cp =
new IT[nTuples];
230 threadID = omp_get_thread_num();
232 IT start = threadID * (nTuples / totThreads);
233 IT end = (threadID + 1) * (nTuples / totThreads);
234 if(threadID == (totThreads-1)) end = nTuples;
238 temp_jc[start] = std::get<1>(tuples[start]);
239 temp_cp[start] = start;
240 for (
IT i = start+1; i < end; ++i)
242 if(std::get<1>(tuples[i]) != temp_jc[curpos] )
244 temp_jc[++curpos] = std::get<1>(tuples[i]);
250 tstart[threadID] = start;
251 if(end>start) tend[threadID] = curpos+1;
252 else tend[threadID] = end;
257 for(
int t=totThreads-1; t>0; --t)
259 if(tend[t] > tstart[t] && tend[t-1] > tstart[t-1])
261 if(temp_jc[tstart[t]] == temp_jc[tend[t-1]-1])
269 for(
int t=0; t<totThreads; ++t)
271 tdisp[t+1] = tdisp[t] + tend[t] - tstart[t];
274 IT localnzc = tdisp[totThreads];
283 threadID = omp_get_thread_num();
285 std::copy(temp_jc + tstart[threadID], temp_jc + tend[threadID],
dcsc->jc + tdisp[threadID]);
286 std::copy(temp_cp + tstart[threadID], temp_cp + tend[threadID],
dcsc->cp + tdisp[threadID]);
288 dcsc->cp[localnzc] = nTuples;
294#pragma omp parallel for schedule (static)
296 for(
IT i=0; i<nTuples; ++i)
298 dcsc->ir[i] = std::get<0>(tuples[i]);
299 dcsc->numx[i] = std::get<2>(tuples[i]);
364template <
class IT,
class NT>
371 if(dcsc != NULL && nnz > 0)
393template <
class IT,
class NT>
400 if(m == rhs.m && n == rhs.n)
413 (*dcsc) += (*(rhs.
dcsc));
419 std::cout<<
"Not addable: " << m <<
"!=" << rhs.m <<
" or " << n <<
"!=" << rhs.n <<std::endl;
424 std::cout<<
"Missing feature (A+A): Use multiply with 2 instead !"<<std::endl;
429template <
class IT,
class NT>
430template <
typename _UnaryOperation,
typename GlobalIT>
452 retcols->nnz = retcols->
dcsc->nz;
467 retcols->
dcsc = NULL;
476template <
class IT,
class NT>
477template <
typename _UnaryOperation>
499 retcols->nnz = retcols->
dcsc->nz;
514 retcols->
dcsc = NULL;
525template <
class IT,
class NT>
526template <
typename _BinaryOperation>
548 retcols->nnz = retcols->
dcsc->nz;
563 retcols->
dcsc = NULL;
572template <
class IT,
class NT>
577 dcsc->PruneColumnByIndex(ci);
582template <
class IT,
class NT>
583template <
typename _BinaryOperation>
605 retcols->nnz = retcols->
dcsc->nz;
620 retcols->
dcsc = NULL;
630template <
class IT,
class NT>
635 if(m == rhs.m && n == rhs.n)
641 else if (rhs.nnz != 0 && nnz != 0)
643 dcsc->SetDifference (*(rhs.
dcsc));
651 std::cout<<
"Matrices do not conform for A - B !"<<std::endl;
656 std::cout<<
"Missing feature (A .* A): Use Square_EWise() instead !"<<std::endl;
661template <
class IT,
class NT>
666 if(m == rhs.m && n == rhs.n)
679 else if (rhs.nnz != 0 && nnz != 0)
681 dcsc->EWiseMult (*(rhs.
dcsc), exclude);
689 std::cout<<
"Matrices do not conform for A .* op(B) !"<<std::endl;
694 std::cout<<
"Missing feature (A .* A): Use Square_EWise() instead !"<<std::endl;
701template <
class IT,
class NT>
704 if(m == m_scaler && n == n_scaler)
707 dcsc->EWiseScale (scaler);
711 std::cout<<
"Matrices do not conform for EWiseScale !"<<std::endl;
720template <
class IT,
class NT>
728 dcsc =
new Dcsc<IT,NT>(_cp, _jc, _ir, _numx, _nz, _nzc,
false);
733template <
class IT,
class NT>
736 assert(essentials.size() == esscount);
747template <
class IT,
class NT>
754 std::pair<IT,IT> rlim = tuples.
RowLimits();
755 std::pair<IT,IT> clim = tuples.
ColLimits();
758 std::stringstream ss;
761 MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
764 std::string ofilename =
"Read";
766 oput.open(ofilename.c_str(), std::ios_base::app );
767 oput <<
"Creating of dimensions " << nRow <<
"-by-" << nCol <<
" of size: " <<
size <<
768 " with row range (" << rlim.first <<
"," << rlim.second <<
") and column range (" << clim.first <<
"," << clim.second <<
")" << std::endl;
771 IT minfr = joker::get<0>(tuples.
front());
772 IT minto = joker::get<1>(tuples.
front());
773 IT maxfr = joker::get<0>(tuples.
back());
774 IT maxto = joker::get<1>(tuples.
back());
776 oput <<
"Min: " << minfr <<
", " << minto <<
"; Max: " << maxfr <<
", " << maxto << std::endl;
786template <
class IT,
class NT>
789 std::vector<IT> essentials(esscount);
793 essentials[3] = (nnz > 0) ? dcsc->nzc : 0;
797template <
class IT,
class NT>
798template <
typename NNT>
811template <
class IT,
class NT>
812template <
typename NIT,
typename NNT>
825template <
class IT,
class NT>
853template <
class IT,
class NT>
876template <
class IT,
class NT>
890template <
class IT,
class NT>
905template <
class IT,
class NT>
911 std::cout<<
"Matrix is too small to be splitted" << std::endl;
920 dcsc->
Split(Adcsc, Bdcsc, cut);
935template <
class IT,
class NT>
940 matrices.emplace_back(*
this);
944 std::vector<IT> cuts(parts-1);
945 for(
int i=0; i< (parts-1); ++i)
947 cuts[i] = (i+1) * (n/parts);
951 std::cout<<
"Matrix is too small to be splitted" << std::endl;
954 std::vector< Dcsc<IT,NT> * > dcscs(parts, NULL);
958 dcsc->ColSplit(dcscs, cuts);
961 for(
int i=0; i< (parts-1); ++i)
964 matrices.emplace_back(matrix);
967 matrices.emplace_back(matrix);
977template <
class IT,
class NT>
986 std::vector<IT> cuts(parts-1);
987 for(
int i=0; i< (parts-1); ++i)
989 cuts[i] = (i+1) * (n/parts);
993 std::cout<<
"Matrix is too small to be splitted" << std::endl;
996 std::vector< Dcsc<IT,NT> * > dcscs(parts, NULL);
1000 dcsc->ColSplit(dcscs, cuts);
1003 for(
int i=0; i< (parts-1); ++i)
1006 matrices.emplace_back(matrix);
1009 matrices.emplace_back(matrix);
1019template <
class IT,
class NT>
1023 int parts = cutSizes.size();
1024 for(
int i = 0; i < parts; i++) totn += cutSizes[i];
1026 matrices.emplace_back(*
this);
1029 std::cout <<
"Cut sizes are not appropriate" << std::endl;
1033 std::vector<IT> cuts(parts-1);
1034 cuts[0] = cutSizes[0];
1035 for(
int i = 1; i < parts-1; i++){
1036 cuts[i] = cuts[i-1] + cutSizes[i];
1038 std::vector< Dcsc<IT,NT> * > dcscs(parts, NULL);
1041 dcsc->ColSplit(dcscs, cuts);
1044 for(
int i=0; i< parts; ++i){
1046 matrices.emplace_back(matrix);
1058template <
class IT,
class NT>
1062 int parts = cutSizes.size();
1063 for(
int i = 0; i < parts; i++) totn += cutSizes[i];
1068 std::cout <<
"Cut sizes are not appropriate" << std::endl;
1072 std::vector<IT> cuts(parts-1);
1073 cuts[0] = cutSizes[0];
1074 for(
int i = 1; i < parts-1; i++){
1075 cuts[i] = cuts[i-1] + cutSizes[i];
1077 std::vector< Dcsc<IT,NT> * > dcscs(parts, NULL);
1080 dcsc->ColSplit(dcscs, cuts);
1083 for(
int i=0; i< parts; ++i){
1085 matrices.emplace_back(matrix);
1095template <
class IT,
class NT>
1098 std::vector< SpDCCols<IT,NT> * > nonempties;
1099 std::vector< Dcsc<IT,NT> * > dcscs;
1100 std::vector< IT > offsets;
1101 IT runningoffset = 0;
1103 for(
size_t i=0; i< matrices.size(); ++i)
1105 if(matrices[i].nnz != 0)
1107 nonempties.push_back(&(matrices[i]));
1108 dcscs.push_back(matrices[i].dcsc);
1109 offsets.push_back(runningoffset);
1111 runningoffset += matrices[i].n;
1114 if(nonempties.size() < 1)
1117 std::cout <<
"Nothing to ColConcatenate" << std::endl;
1134 for(
size_t i=0; i< matrices.size(); ++i)
1144template <
class IT,
class NT>
1147 std::vector< SpDCCols<IT,NT> * > nonempties;
1148 std::vector< Dcsc<IT,NT> * > dcscs;
1149 std::vector< IT > offsets;
1150 IT runningoffset = 0;
1152 for(
size_t i=0; i< matrices.size(); ++i)
1154 if(matrices[i]->nnz != 0)
1156 nonempties.push_back(matrices[i]);
1157 dcscs.push_back(matrices[i]->dcsc);
1158 offsets.push_back(runningoffset);
1160 runningoffset += matrices[i]->n;
1163 if(nonempties.size() < 1)
1166 std::cout <<
"Nothing to ColConcatenate" << std::endl;
1183 for(
size_t i=0; i< matrices.size(); ++i)
1194template <
class IT,
class NT>
1197 assert( partA.m == partB.m );
1201 if(partA.nnz == 0 && partB.nnz == 0)
1205 else if(partA.nnz == 0)
1208 std::transform(Cdcsc->
jc, Cdcsc->
jc + Cdcsc->
nzc, Cdcsc->
jc, std::bind2nd(std::plus<IT>(), partA.n));
1210 else if(partB.nnz == 0)
1230template <
class IT,
class NT>
1234 if(
A.isZero() ||
B.isZero())
1238 Isect<IT> *isect1, *isect2, *itr1, *itr2, *cols, *rows;
1241 IT kisect =
static_cast<IT>(itr1-isect1);
1249 IT cnz = SpHelper::SpCartesian< SR > (*(
A.dcsc), *(
B.dcsc), kisect, isect1, isect2, multstack);
1256 dcsc =
new Dcsc<IT,NT>(multstack, mdim, ndim, cnz);
1260 dcsc->AddAndAssign(multstack, mdim, ndim, cnz);
1264 delete [] multstack;
1274template <
class IT,
class NT>
1275template <
typename SR>
1278 if(
A.isZero() ||
B.isZero())
1283 int cnz = SpHelper::SpColByCol< SR > (*(
A.dcsc), *(
B.dcsc),
A.n, multstack);
1289 dcsc =
new Dcsc<IT,NT>(multstack, mdim, ndim, cnz);
1293 dcsc->AddAndAssign(multstack, mdim, ndim, cnz);
1297 delete [] multstack;
1302template <
class IT,
class NT>
1303template <
typename SR>
1306 std::cout <<
"PlusEq_AtXBn function has not been implemented yet !" << std::endl;
1310template <
class IT,
class NT>
1311template <
typename SR>
1314 std::cout <<
"PlusEq_AtXBt function has not been implemented yet !" << std::endl;
1319template <
class IT,
class NT>
1322 IT * itr = std::find(dcsc->jc, dcsc->jc + dcsc->nzc, ci);
1323 if(itr != dcsc->jc + dcsc->nzc)
1325 IT irbeg = dcsc->cp[itr - dcsc->jc];
1326 IT irend = dcsc->cp[itr - dcsc->jc + 1];
1328 IT * ele = std::find(dcsc->ir + irbeg, dcsc->ir + irend, ri);
1329 if(ele != dcsc->ir + irend)
1332 *(SingEleMat.
dcsc->numx) = dcsc->numx[ele - dcsc->ir];
1333 *(SingEleMat.
dcsc->ir) = *ele;
1334 *(SingEleMat.
dcsc->jc) = *itr;
1335 (SingEleMat.
dcsc->cp)[0] = 0;
1336 (SingEleMat.
dcsc->cp)[1] = 1;
1354template <
class IT,
class NT>
1359 IT rsize = ri.size();
1360 IT csize = ci.size();
1362 if(rsize == 0 && csize == 0)
1370 return ColIndex(ci);
1375 return LeftMatrix.OrdColByCol< PT >(*this);
1381 return LeftMatrix.OrdColByCol< PT >( OrdColByCol< PT >(RightMatrix) );
1385template <
class IT,
class NT>
1390 outfile <<
"Matrix doesn't have any nonzeros" <<std::endl;
1394 outfile << tuples << std::endl;
1399template <
class IT,
class NT>
1402 std::cout <<
"Getting... SpDCCols" << std::endl;
1404 infile >> m >> n >> nnz;
1415template<
class IT,
class NT>
1419 out <<
", n: " << n ;
1420 out <<
", nnz: "<< nnz ;
1424 out <<
", local splits: " << splits << std::endl;
1430 out <<
", nzc: "<< dcsc->nzc << std::endl;
1434 out <<
", nzc: "<< 0 << std::endl;
1439template<
class IT,
class NT>
1442 std::cout <<
"m: " << m ;
1443 std::cout <<
", n: " << n ;
1444 std::cout <<
", nnz: "<< nnz ;
1448 std::cout <<
", local splits: " << splits << std::endl;
1454 std::cout <<
", nzc: "<< dcsc->nzc << std::endl;
1458 std::cout <<
", nzc: "<< 0 << std::endl;
1463 std::string **
A = SpHelper::allocate2D<std::string>(m,n);
1464 for(
IT i=0; i< m; ++i)
1465 for(
IT j=0; j<n; ++j)
1469 for(
IT i=0; i< dcsc->nzc; ++i)
1471 for(
IT j = dcsc->cp[i]; j<dcsc->cp[i+1]; ++j)
1473 IT colid = dcsc->jc[i];
1474 IT rowid = dcsc->ir[j];
1475 A[rowid][colid] = std::to_string(dcsc->numx[j]);
1479 for(
IT i=0; i< m; ++i)
1481 for(
IT j=0; j<n; ++j)
1483 std::cout <<
A[i][j];
1486 std::cout << std::endl;
1499template <
class IT,
class NT>
1501:dcsc(mydcsc), m(nRow), n(nCol), splits(0)
1510template <
class IT,
class NT>
1512:m(nRow), n(nCol), nnz(
size), splits(0)
1515 dcsc =
new Dcsc<IT,NT>(
size,indices,isRow);
1525template <
class IT,
class NT>
1526inline void SpDCCols<IT,NT>::CopyDcsc(Dcsc<IT,NT> * source)
1530 dcsc =
new Dcsc<IT,NT>(*source);
1541template <
class IT,
class NT>
1542SpDCCols<IT,NT> SpDCCols<IT,NT>::ColIndex(
const std::vector<IT> & ci)
const
1544 IT csize = ci.size();
1547 return SpDCCols<IT,NT>(0, m, csize, 0);
1551 return SpDCCols<IT,NT>(0, m,0, 0);
1557 for(
IT i=0, j=0; i< dcsc->nzc && j < csize;)
1559 if((dcsc->jc)[i] < ci[j])
1563 else if ((dcsc->jc)[i] > ci[j])
1569 estsize += (dcsc->cp)[i+1] - (dcsc->cp)[i];
1576 SpDCCols<IT,NT> SubA(estsize, m, csize, estnzc);
1581 SubA.dcsc->cp[0] = 0;
1584 for(
IT i=0, j=0; i < dcsc->nzc && j < csize;)
1586 if((dcsc->jc)[i] < ci[j])
1590 else if ((dcsc->jc)[i] > ci[j])
1596 IT columncount = (dcsc->cp)[i+1] - (dcsc->cp)[i];
1597 SubA.dcsc->jc[cnzc++] = j;
1598 SubA.dcsc->cp[cnzc] = SubA.dcsc->cp[cnzc-1] + columncount;
1599 std::copy(dcsc->ir + dcsc->cp[i], dcsc->ir + dcsc->cp[i+1], SubA.dcsc->ir + cnz);
1600 std::copy(dcsc->numx + dcsc->cp[i], dcsc->numx + dcsc->cp[i+1], SubA.dcsc->numx + cnz);
1609template <
class IT,
class NT>
1610template <
typename SR,
typename NTR>
1611SpDCCols< IT, typename promote_trait<NT,NTR>::T_promote > SpDCCols<IT,NT>::OrdOutProdMult(
const SpDCCols<IT,NTR> & rhs)
const
1615 if(isZero() || rhs.isZero())
1617 return SpDCCols< IT, T_promote > (0, m, rhs.n, 0);
1619 SpDCCols<IT,NTR> Btrans = rhs.TransposeConst();
1621 Isect<IT> *isect1, *isect2, *itr1, *itr2, *cols, *rows;
1624 IT kisect =
static_cast<IT>(itr1-isect1);
1628 return SpDCCols< IT, T_promote > (0, m, rhs.n, 0);
1630 StackEntry< T_promote, std::pair<IT,IT> > * multstack;
1631 IT cnz = SpHelper::SpCartesian< SR > (*dcsc, *(Btrans.dcsc), kisect, isect1, isect2, multstack);
1634 Dcsc<IT, T_promote> * mydcsc = NULL;
1637 mydcsc =
new Dcsc< IT,T_promote > (multstack, m, rhs.n, cnz);
1638 delete [] multstack;
1640 return SpDCCols< IT,T_promote > (m, rhs.n, mydcsc);
1644template <
class IT,
class NT>
1645template <
typename SR,
typename NTR>
1646SpDCCols< IT, typename promote_trait<NT,NTR>::T_promote > SpDCCols<IT,NT>::OrdColByCol(
const SpDCCols<IT,NTR> & rhs)
const
1650 if(isZero() || rhs.isZero())
1652 return SpDCCols<IT, T_promote> (0, m, rhs.n, 0);
1654 StackEntry< T_promote, std::pair<IT,IT> > * multstack;
1655 IT cnz = SpHelper::SpColByCol< SR > (*dcsc, *(rhs.dcsc), n, multstack);
1657 Dcsc<IT,T_promote > * mydcsc = NULL;
1660 mydcsc =
new Dcsc< IT,T_promote > (multstack, m, rhs.n, cnz);
1661 delete [] multstack;
1663 return SpDCCols< IT,T_promote > (m, rhs.n, mydcsc);
void convert(string ifname, string ofname, string sort="revsize")
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)
Dcsc< IT, NT > * PruneColumn(NT *pvals, _BinaryOperation __binary_op, bool inPlace)
void Merge(const Dcsc< IT, NT > *Adcsc, const Dcsc< IT, NT > *B, IT cut)
Dcsc< IT, NT > * Prune(_UnaryOperation __unary_op, bool inPlace)
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 * jc
col indices, size nzc
SpDCCols< IT, NT > & operator=(const SpDCCols< IT, NT > &rhs)
void EWiseMult(const SpDCCols< IT, NT > &rhs, bool exclude)
SpDCCols< IT, NT > * PruneI(_UnaryOperation __unary_op, bool inPlace, GlobalIT rowOffset, GlobalIT colOffset)
std::ofstream & put(std::ofstream &outfile) const
std::ifstream & get(std::ifstream &infile)
void ColSplit(int parts, std::vector< SpDCCols< IT, NT > > &matrices)
int PlusEq_AnXBn(const SpDCCols< IT, NT > &A, const SpDCCols< IT, NT > &B)
void PruneColumnByIndex(const std::vector< IT > &ci)
void ColConcatenate(std::vector< SpDCCols< IT, NT > > &matrices)
SpDCCols< IT, NT > * Prune(_UnaryOperation __unary_op, bool inPlace)
std::vector< IT > GetEssentials() const
void Merge(SpDCCols< IT, NT > &partA, SpDCCols< IT, NT > &partB)
int PlusEq_AnXBt(const SpDCCols< IT, NT > &A, const SpDCCols< IT, NT > &B)
SpDCCols< IT, NT > operator()(IT ri, IT ci) const
SpDCCols< IT, NT > & operator+=(const SpDCCols< IT, NT > &rhs)
SpDCCols< IT, NT > TransposeConst() const
Const version, doesn't touch the existing object.
void SetDifference(const SpDCCols< IT, NT > &rhs)
void Transpose()
Mutator version, replaces the calling object.
int PlusEq_AtXBt(const SpDCCols< IT, NT > &A, const SpDCCols< IT, NT > &B)
void EWiseScale(NT **scaler, IT m_scaler, IT n_scaler)
Dcsc< IT, NT > ** dcscarr
void CreateImpl(const std::vector< IT > &essentials)
SpDCCols< IT, NT > * TransposeConstPtr() const
Arr< IT, NT > GetArrays() const
SpDCCols< IT, NT > * PruneColumn(NT *pvals, _BinaryOperation __binary_op, bool inPlace)
int PlusEq_AtXBn(const SpDCCols< IT, NT > &A, const SpDCCols< IT, NT > &B)
void Split(SpDCCols< IT, NT > &partA, SpDCCols< IT, NT > &partB)
static void SpIntersect(const Dcsc< IT, NT1 > &Adcsc, const Dcsc< IT, NT2 > &Bdcsc, Isect< IT > *&cols, Isect< IT > *&rows, Isect< IT > *&isect1, Isect< IT > *&isect2, Isect< IT > *&itr1, Isect< IT > *&itr2)
static void deallocate2D(T **array, I m)
std::tuple< IT, IT, NT > back()
std::pair< IT, IT > ColLimits()
std::tuple< IT, IT, NT > front()
std::pair< IT, IT > RowLimits()
std::vector< LocArr< NT, IT > > numarrs
std::vector< LocArr< IT, IT > > indarrs