45template <
class IT,
class NT>
49template <
class IT,
class NT>
54template <
class IT,
class NT>
55SpDCCols<IT,NT>::SpDCCols(IT
size, IT nRow, IT nCol, IT nzc)
56:m(nRow), n(nCol), nnz(
size), splits(0)
59 dcsc =
new Dcsc<IT,NT>(nnz, nzc);
64template <
class IT,
class NT>
65SpDCCols<IT,NT>::~SpDCCols()
73 for(
int i=0; i<splits; ++i)
87template <
class IT,
class NT>
88SpDCCols<IT,NT>::SpDCCols(
const SpDCCols<IT,NT> & rhs)
89: m(rhs.m), n(rhs.n), nnz(rhs.nnz), splits(rhs.splits)
93 for(
int i=0; i<splits; ++i)
94 CopyDcsc(rhs.dcscarr[i]);
108template <
class IT,
class NT>
109SpDCCols<IT,NT>::SpDCCols(
const SpTuples<IT, NT> & rhs,
bool transpose)
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)
126 if(rhs.rowindex(i) != rhs.rowindex(i-1))
131 dcsc =
new Dcsc<IT,NT>(rhs.nnz,localnzc);
132 dcsc->jc[0] = rhs.rowindex(0);
135 for(IT i=0; i<rhs.nnz; ++i)
137 dcsc->ir[i] = rhs.colindex(i);
138 dcsc->numx[i] = rhs.numvalue(i);
142 for(IT i=1; i<rhs.nnz; ++i)
144 if(rhs.rowindex(i) != dcsc->jc[jspos-1])
146 dcsc->jc[jspos] = rhs.rowindex(i);
147 dcsc->cp[jspos++] = i;
150 dcsc->cp[jspos] = rhs.nnz;
155 for(IT i=1; i<rhs.nnz; ++i)
157 if(rhs.colindex(i) != rhs.colindex(i-1))
162 dcsc =
new Dcsc<IT,NT>(rhs.nnz,localnzc);
163 dcsc->jc[0] = rhs.colindex(0);
166 for(IT i=0; i<rhs.nnz; ++i)
168 dcsc->ir[i] = rhs.rowindex(i);
169 dcsc->numx[i] = rhs.numvalue(i);
173 for(IT i=1; i<rhs.nnz; ++i)
175 if(rhs.colindex(i) != dcsc->jc[jspos-1])
177 dcsc->jc[jspos] = rhs.colindex(i);
178 dcsc->cp[jspos++] = i;
181 dcsc->cp[jspos] = rhs.nnz;
197template <
class IT,
class NT>
198SpDCCols<IT,NT>::SpDCCols(IT nRow, IT nCol, IT nTuples,
const std::tuple<IT, IT, NT>* tuples,
bool transpose)
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];
275 dcsc =
new Dcsc<IT,NT>(nTuples,localnzc);
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]);
303 if(transpose) Transpose();
364template <
class IT,
class NT>
365SpDCCols<IT,NT> & SpDCCols<IT,NT>::operator=(
const SpDCCols<IT,NT> & rhs)
371 if(dcsc != NULL && nnz > 0)
377 dcsc =
new Dcsc<IT,NT>(*(rhs.dcsc));
393template <
class IT,
class NT>
394SpDCCols<IT,NT> & SpDCCols<IT,NT>::operator+= (
const SpDCCols<IT,NT> & rhs)
400 if(m == rhs.m && n == rhs.n)
408 dcsc =
new Dcsc<IT,NT>(*(rhs.dcsc));
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>
431SpDCCols<IT,NT>* SpDCCols<IT,NT>::PruneI(_UnaryOperation __unary_op,
bool inPlace, GlobalIT rowOffset, GlobalIT colOffset)
435 Dcsc<IT,NT>* ret = dcsc->PruneI (__unary_op, inPlace, rowOffset, colOffset);
450 SpDCCols<IT,NT>* retcols =
new SpDCCols<IT, NT>();
452 retcols->nnz = retcols->dcsc->nz;
466 SpDCCols<IT,NT>* retcols =
new SpDCCols<IT, NT>();
467 retcols->dcsc = NULL;
476template <
class IT,
class NT>
477template <
typename _UnaryOperation>
478SpDCCols<IT,NT>* SpDCCols<IT,NT>::Prune(_UnaryOperation __unary_op,
bool inPlace)
482 Dcsc<IT,NT>* ret = dcsc->Prune (__unary_op, inPlace);
497 SpDCCols<IT,NT>* retcols =
new SpDCCols<IT, NT>();
499 retcols->nnz = retcols->dcsc->nz;
513 SpDCCols<IT,NT>* retcols =
new SpDCCols<IT, NT>();
514 retcols->dcsc = NULL;
525template <
class IT,
class NT>
526template <
typename _BinaryOperation>
527SpDCCols<IT,NT>* SpDCCols<IT,NT>::PruneColumn(NT* pvals, _BinaryOperation __binary_op,
bool inPlace)
531 Dcsc<IT,NT>* ret = dcsc->PruneColumn (pvals, __binary_op, inPlace);
546 SpDCCols<IT,NT>* retcols =
new SpDCCols<IT, NT>();
548 retcols->nnz = retcols->dcsc->nz;
562 SpDCCols<IT,NT>* retcols =
new SpDCCols<IT, NT>();
563 retcols->dcsc = NULL;
573template <
class IT,
class NT>
574template <
typename _BinaryOperation>
575SpDCCols<IT,NT>* SpDCCols<IT,NT>::PruneColumn(IT* pinds, NT* pvals, _BinaryOperation __binary_op,
bool inPlace)
579 Dcsc<IT,NT>* ret = dcsc->PruneColumn (pinds, pvals, __binary_op, inPlace);
594 SpDCCols<IT,NT>* retcols =
new SpDCCols<IT, NT>();
596 retcols->nnz = retcols->dcsc->nz;
610 SpDCCols<IT,NT>* retcols =
new SpDCCols<IT, NT>();
611 retcols->dcsc = NULL;
622template <
class IT,
class NT>
623void SpDCCols<IT,NT>::EWiseMult (
const SpDCCols<IT,NT> & rhs,
bool exclude)
627 if(m == rhs.m && n == rhs.n)
637 *
this = SpDCCols<IT,NT>(0,m,n,0);
640 else if (rhs.nnz != 0 && nnz != 0)
642 dcsc->EWiseMult (*(rhs.dcsc), exclude);
650 std::cout<<
"Matrices do not conform for A .* op(B) !"<<std::endl;
655 std::cout<<
"Missing feature (A .* A): Use Square_EWise() instead !"<<std::endl;
662template <
class IT,
class NT>
663void SpDCCols<IT,NT>::EWiseScale(NT ** scaler, IT m_scaler, IT n_scaler)
665 if(m == m_scaler && n == n_scaler)
668 dcsc->EWiseScale (scaler);
672 std::cout<<
"Matrices do not conform for EWiseScale !"<<std::endl;
681template <
class IT,
class NT>
682void SpDCCols<IT,NT>::CreateImpl(IT * _cp, IT * _jc, IT * _ir, NT * _numx, IT _nz, IT _nzc, IT _m, IT _n)
689 dcsc =
new Dcsc<IT,NT>(_cp, _jc, _ir, _numx, _nz, _nzc,
false);
694template <
class IT,
class NT>
695void SpDCCols<IT,NT>::CreateImpl(
const std::vector<IT> & essentials)
697 assert(essentials.size() == esscount);
703 dcsc =
new Dcsc<IT,NT>(nnz,essentials[3]);
708template <
class IT,
class NT>
709void SpDCCols<IT,NT>::CreateImpl(IT
size, IT nRow, IT nCol, std::tuple<IT, IT, NT> * mytuples)
711 SpTuples<IT,NT> tuples(
size, nRow, nCol, mytuples);
712 tuples.SortColBased();
715 std::pair<IT,IT> rlim = tuples.RowLimits();
716 std::pair<IT,IT> clim = tuples.ColLimits();
719 std::stringstream ss;
722 MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
725 std::string ofilename =
"Read";
727 oput.open(ofilename.c_str(), std::ios_base::app );
728 oput <<
"Creating of dimensions " << nRow <<
"-by-" << nCol <<
" of size: " <<
size <<
729 " with row range (" << rlim.first <<
"," << rlim.second <<
") and column range (" << clim.first <<
"," << clim.second <<
")" << std::endl;
730 if(tuples.getnnz() > 0)
732 IT minfr = joker::get<0>(tuples.front());
733 IT minto = joker::get<1>(tuples.front());
734 IT maxfr = joker::get<0>(tuples.back());
735 IT maxto = joker::get<1>(tuples.back());
737 oput <<
"Min: " << minfr <<
", " << minto <<
"; Max: " << maxfr <<
", " << maxto << std::endl;
742 SpDCCols<IT,NT> object(tuples,
false);
747template <
class IT,
class NT>
748std::vector<IT> SpDCCols<IT,NT>::GetEssentials()
const
750 std::vector<IT> essentials(esscount);
754 essentials[3] = (nnz > 0) ? dcsc->nzc : 0;
758template <
class IT,
class NT>
759template <
typename NNT>
760SpDCCols<IT,NT>::operator SpDCCols<IT,NNT> ()
const
762 Dcsc<IT,NNT> * convert;
764 convert =
new Dcsc<IT,NNT>(*dcsc);
768 return SpDCCols<IT,NNT>(m, n, convert);
772template <
class IT,
class NT>
773template <
typename NIT,
typename NNT>
774SpDCCols<IT,NT>::operator SpDCCols<NIT,NNT> ()
const
776 Dcsc<NIT,NNT> * convert;
778 convert =
new Dcsc<NIT,NNT>(*dcsc);
782 return SpDCCols<NIT,NNT>(m, n, convert);
786template <
class IT,
class NT>
787Arr<IT,NT> SpDCCols<IT,NT>::GetArrays()
const
793 arr.indarrs[0] = LocArr<IT,IT>(dcsc->cp, dcsc->nzc+1);
794 arr.indarrs[1] = LocArr<IT,IT>(dcsc->jc, dcsc->nzc);
795 arr.indarrs[2] = LocArr<IT,IT>(dcsc->ir, dcsc->nz);
796 arr.numarrs[0] = LocArr<NT,IT>(dcsc->numx, dcsc->nz);
800 arr.indarrs[0] = LocArr<IT,IT>(NULL, 0);
801 arr.indarrs[1] = LocArr<IT,IT>(NULL, 0);
802 arr.indarrs[2] = LocArr<IT,IT>(NULL, 0);
803 arr.numarrs[0] = LocArr<NT,IT>(NULL, 0);
814template <
class IT,
class NT>
815void SpDCCols<IT,NT>::Transpose()
819 SpTuples<IT,NT> Atuples(*
this);
820 Atuples.SortRowBased();
823 *
this = SpDCCols<IT,NT>(Atuples,
true);
827 *
this = SpDCCols<IT,NT>(0, n, m, 0);
837template <
class IT,
class NT>
838SpDCCols<IT,NT> SpDCCols<IT,NT>::TransposeConst()
const
840 SpTuples<IT,NT> Atuples(*
this);
841 Atuples.SortRowBased();
843 return SpDCCols<IT,NT>(Atuples,
true);
851template <
class IT,
class NT>
852SpDCCols<IT,NT> * SpDCCols<IT,NT>::TransposeConstPtr()
const
854 SpTuples<IT,NT> Atuples(*
this);
855 Atuples.SortRowBased();
857 return new SpDCCols<IT,NT>(Atuples,
true);
866template <
class IT,
class NT>
867void SpDCCols<IT,NT>::Split(SpDCCols<IT,NT> & partA, SpDCCols<IT,NT> & partB)
872 std::cout<<
"Matrix is too small to be splitted" << std::endl;
876 Dcsc<IT,NT> *Adcsc = NULL;
877 Dcsc<IT,NT> *Bdcsc = NULL;
881 dcsc->Split(Adcsc, Bdcsc, cut);
884 partA = SpDCCols<IT,NT> (m, cut, Adcsc);
885 partB = SpDCCols<IT,NT> (m, n-cut, Bdcsc);
888 *
this = SpDCCols<IT, NT>();
896template <
class IT,
class NT>
897void SpDCCols<IT,NT>::ColSplit(
int parts, std::vector< SpDCCols<IT,NT> > & matrices)
901 matrices.emplace_back(*
this);
905 std::vector<IT> cuts(parts-1);
906 for(
int i=0; i< (parts-1); ++i)
908 cuts[i] = (i+1) * (n/parts);
912 std::cout<<
"Matrix is too small to be splitted" << std::endl;
915 std::vector< Dcsc<IT,NT> * > dcscs(parts, NULL);
919 dcsc->ColSplit(dcscs, cuts);
922 for(
int i=0; i< (parts-1); ++i)
924 SpDCCols<IT,NT> matrix = SpDCCols<IT,NT>(m, (n/parts), dcscs[i]);
925 matrices.emplace_back(matrix);
927 SpDCCols<IT,NT> matrix = SpDCCols<IT,NT>(m, n-cuts[parts-2], dcscs[parts-1]);
928 matrices.emplace_back(matrix);
930 *
this = SpDCCols<IT, NT>();
938template <
class IT,
class NT>
939void SpDCCols<IT,NT>::ColConcatenate(std::vector< SpDCCols<IT,NT> > & matrices)
941 std::vector< SpDCCols<IT,NT> * > nonempties;
942 std::vector< Dcsc<IT,NT> * > dcscs;
943 std::vector< IT > offsets;
944 IT runningoffset = 0;
946 for(
size_t i=0; i< matrices.size(); ++i)
948 if(matrices[i].nnz != 0)
950 nonempties.push_back(&(matrices[i]));
951 dcscs.push_back(matrices[i].dcsc);
952 offsets.push_back(runningoffset);
954 runningoffset += matrices[i].n;
957 if(nonempties.size() < 1)
960 std::cout <<
"Nothing to ColConcatenate" << std::endl;
964 else if(nonempties.size() < 2)
966 *
this = *(nonempties[0]);
971 Dcsc<IT,NT> * Cdcsc =
new Dcsc<IT,NT>();
972 Cdcsc->ColConcatenate(dcscs, offsets);
973 *
this = SpDCCols<IT,NT> (nonempties[0]->m, runningoffset, Cdcsc);
977 for(
size_t i=0; i< matrices.size(); ++i)
979 matrices[i] = SpDCCols<IT,NT>();
989template <
class IT,
class NT>
990void SpDCCols<IT,NT>::Merge(SpDCCols<IT,NT> & partA, SpDCCols<IT,NT> & partB)
992 assert( partA.m == partB.m );
994 Dcsc<IT,NT> * Cdcsc =
new Dcsc<IT,NT>();
996 if(partA.nnz == 0 && partB.nnz == 0)
1000 else if(partA.nnz == 0)
1002 Cdcsc =
new Dcsc<IT,NT>(*(partB.dcsc));
1003 std::transform(Cdcsc->jc, Cdcsc->jc + Cdcsc->nzc, Cdcsc->jc, std::bind2nd(std::plus<IT>(), partA.n));
1005 else if(partB.nnz == 0)
1007 Cdcsc =
new Dcsc<IT,NT>(*(partA.dcsc));
1011 Cdcsc->Merge(partA.dcsc, partB.dcsc, partA.n);
1013 *
this = SpDCCols<IT,NT> (partA.m, partA.n + partB.n, Cdcsc);
1015 partA = SpDCCols<IT, NT>();
1016 partB = SpDCCols<IT, NT>();
1025template <
class IT,
class NT>
1027int SpDCCols<IT,NT>::PlusEq_AnXBt(
const SpDCCols<IT,NT> &
A,
const SpDCCols<IT,NT> &
B)
1029 if(
A.isZero() ||
B.isZero())
1033 Isect<IT> *isect1, *isect2, *itr1, *itr2, *cols, *rows;
1034 SpHelper::SpIntersect(*(
A.dcsc), *(
B.dcsc), cols, rows, isect1, isect2, itr1, itr2);
1036 IT kisect =
static_cast<IT
>(itr1-isect1);
1043 StackEntry< NT, std::pair<IT,IT> > * multstack;
1044 IT cnz = SpHelper::SpCartesian< SR > (*(
A.dcsc), *(
B.dcsc), kisect, isect1, isect2, multstack);
1051 dcsc =
new Dcsc<IT,NT>(multstack, mdim, ndim, cnz);
1055 dcsc->AddAndAssign(multstack, mdim, ndim, cnz);
1059 delete [] multstack;
1069template <
class IT,
class NT>
1070template <
typename SR>
1071int SpDCCols<IT,NT>::PlusEq_AnXBn(
const SpDCCols<IT,NT> &
A,
const SpDCCols<IT,NT> &
B)
1073 if(
A.isZero() ||
B.isZero())
1077 StackEntry< NT, std::pair<IT,IT> > * multstack;
1078 int cnz = SpHelper::SpColByCol< SR > (*(
A.dcsc), *(
B.dcsc),
A.n, multstack);
1084 dcsc =
new Dcsc<IT,NT>(multstack, mdim, ndim, cnz);
1088 dcsc->AddAndAssign(multstack, mdim, ndim, cnz);
1092 delete [] multstack;
1097template <
class IT,
class NT>
1098template <
typename SR>
1099int SpDCCols<IT,NT>::PlusEq_AtXBn(
const SpDCCols<IT,NT> &
A,
const SpDCCols<IT,NT> &
B)
1101 std::cout <<
"PlusEq_AtXBn function has not been implemented yet !" << std::endl;
1105template <
class IT,
class NT>
1106template <
typename SR>
1107int SpDCCols<IT,NT>::PlusEq_AtXBt(
const SpDCCols<IT,NT> &
A,
const SpDCCols<IT,NT> &
B)
1109 std::cout <<
"PlusEq_AtXBt function has not been implemented yet !" << std::endl;
1114template <
class IT,
class NT>
1115SpDCCols<IT,NT> SpDCCols<IT,NT>::operator() (IT ri, IT ci)
const
1117 IT * itr = std::find(dcsc->jc, dcsc->jc + dcsc->nzc, ci);
1118 if(itr != dcsc->jc + dcsc->nzc)
1120 IT irbeg = dcsc->cp[itr - dcsc->jc];
1121 IT irend = dcsc->cp[itr - dcsc->jc + 1];
1123 IT * ele = std::find(dcsc->ir + irbeg, dcsc->ir + irend, ri);
1124 if(ele != dcsc->ir + irend)
1126 SpDCCols<IT,NT> SingEleMat(1, 1, 1, 1);
1127 *(SingEleMat.dcsc->numx) = dcsc->numx[ele - dcsc->ir];
1128 *(SingEleMat.dcsc->ir) = *ele;
1129 *(SingEleMat.dcsc->jc) = *itr;
1130 (SingEleMat.dcsc->cp)[0] = 0;
1131 (SingEleMat.dcsc->cp)[1] = 1;
1136 return SpDCCols<IT,NT>();
1141 return SpDCCols<IT,NT>();
1149template <
class IT,
class NT>
1150SpDCCols<IT,NT> SpDCCols<IT,NT>::operator() (
const std::vector<IT> & ri,
const std::vector<IT> & ci)
const
1152 typedef PlusTimesSRing<NT,NT> PT;
1154 IT rsize = ri.size();
1155 IT csize = ci.size();
1157 if(rsize == 0 && csize == 0)
1161 return SpDCCols<IT,NT> (0, m, n, 0);
1165 return ColIndex(ci);
1169 SpDCCols<IT,NT> LeftMatrix(rsize, rsize, this->m, ri,
true);
1170 return LeftMatrix.OrdColByCol< PT >(*this);
1174 SpDCCols<IT,NT> LeftMatrix(rsize, rsize, this->m, ri,
true);
1175 SpDCCols<IT,NT> RightMatrix(csize, this->n, csize, ci,
false);
1176 return LeftMatrix.OrdColByCol< PT >( OrdColByCol< PT >(RightMatrix) );
1180template <
class IT,
class NT>
1181std::ofstream & SpDCCols<IT,NT>::put(std::ofstream & outfile)
const
1185 outfile <<
"Matrix doesn't have any nonzeros" <<std::endl;
1188 SpTuples<IT,NT> tuples(*
this);
1189 outfile << tuples << std::endl;
1194template <
class IT,
class NT>
1195std::ifstream & SpDCCols<IT,NT>::get(std::ifstream & infile)
1197 std::cout <<
"Getting... SpDCCols" << std::endl;
1199 infile >> m >> n >> nnz;
1200 SpTuples<IT,NT> tuples(nnz, m, n);
1202 tuples.SortColBased();
1204 SpDCCols<IT,NT> object(tuples,
false);
1210template<
class IT,
class NT>
1211void SpDCCols<IT,NT>::PrintInfo(std::ofstream & out)
const
1214 out <<
", n: " << n ;
1215 out <<
", nnz: "<< nnz ;
1219 out <<
", local splits: " << splits << std::endl;
1225 out <<
", nzc: "<< dcsc->nzc << std::endl;
1229 out <<
", nzc: "<< 0 << std::endl;
1234template<
class IT,
class NT>
1235void SpDCCols<IT,NT>::PrintInfo()
const
1237 std::cout <<
"m: " << m ;
1238 std::cout <<
", n: " << n ;
1239 std::cout <<
", nnz: "<< nnz ;
1243 std::cout <<
", local splits: " << splits << std::endl;
1249 std::cout <<
", nzc: "<< dcsc->nzc << std::endl;
1253 std::cout <<
", nzc: "<< 0 << std::endl;
1258 NT **
A = SpHelper::allocate2D<NT>(m,n);
1259 for(IT i=0; i< m; ++i)
1260 for(IT j=0; j<n; ++j)
1264 for(IT i=0; i< dcsc->nzc; ++i)
1266 for(IT j = dcsc->cp[i]; j<dcsc->cp[i+1]; ++j)
1268 IT colid = dcsc->jc[i];
1269 IT rowid = dcsc->ir[j];
1270 A[rowid][colid] = dcsc->numx[j];
1274 for(IT i=0; i< m; ++i)
1276 for(IT j=0; j<n; ++j)
1278 std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(2) <<
A[i][j];
1281 std::cout << std::endl;
1283 SpHelper::deallocate2D(
A,m);
1294template <
class IT,
class NT>
1295SpDCCols<IT,NT>::SpDCCols(IT nRow, IT nCol, Dcsc<IT,NT> * mydcsc)
1296:dcsc(mydcsc), m(nRow), n(nCol), splits(0)
1305template <
class IT,
class NT>
1306SpDCCols<IT,NT>::SpDCCols (IT
size, IT nRow, IT nCol,
const std::vector<IT> & indices,
bool isRow)
1307:m(nRow), n(nCol), nnz(
size), splits(0)
1310 dcsc =
new Dcsc<IT,NT>(
size,indices,isRow);
1320template <
class IT,
class NT>
1321inline void SpDCCols<IT,NT>::CopyDcsc(Dcsc<IT,NT> * source)
1325 dcsc =
new Dcsc<IT,NT>(*source);
1336template <
class IT,
class NT>
1337SpDCCols<IT,NT> SpDCCols<IT,NT>::ColIndex(
const std::vector<IT> & ci)
const
1339 IT csize = ci.size();
1342 return SpDCCols<IT,NT>(0, m, csize, 0);
1346 return SpDCCols<IT,NT>(0, m,0, 0);
1352 for(IT i=0, j=0; i< dcsc->nzc && j < csize;)
1354 if((dcsc->jc)[i] < ci[j])
1358 else if ((dcsc->jc)[i] > ci[j])
1364 estsize += (dcsc->cp)[i+1] - (dcsc->cp)[i];
1371 SpDCCols<IT,NT> SubA(estsize, m, csize, estnzc);
1376 SubA.dcsc->cp[0] = 0;
1379 for(IT i=0, j=0; i < dcsc->nzc && j < csize;)
1381 if((dcsc->jc)[i] < ci[j])
1385 else if ((dcsc->jc)[i] > ci[j])
1391 IT columncount = (dcsc->cp)[i+1] - (dcsc->cp)[i];
1392 SubA.dcsc->jc[cnzc++] = j;
1393 SubA.dcsc->cp[cnzc] = SubA.dcsc->cp[cnzc-1] + columncount;
1394 std::copy(dcsc->ir + dcsc->cp[i], dcsc->ir + dcsc->cp[i+1], SubA.dcsc->ir + cnz);
1395 std::copy(dcsc->numx + dcsc->cp[i], dcsc->numx + dcsc->cp[i+1], SubA.dcsc->numx + cnz);
1404template <
class IT,
class NT>
1405template <
typename SR,
typename NTR>
1406SpDCCols< IT, typename promote_trait<NT,NTR>::T_promote > SpDCCols<IT,NT>::OrdOutProdMult(
const SpDCCols<IT,NTR> & rhs)
const
1408 typedef typename promote_trait<NT,NTR>::T_promote T_promote;
1410 if(isZero() || rhs.isZero())
1412 return SpDCCols< IT, T_promote > (0, m, rhs.n, 0);
1414 SpDCCols<IT,NTR> Btrans = rhs.TransposeConst();
1416 Isect<IT> *isect1, *isect2, *itr1, *itr2, *cols, *rows;
1417 SpHelper::SpIntersect(*dcsc, *(Btrans.dcsc), cols, rows, isect1, isect2, itr1, itr2);
1419 IT kisect =
static_cast<IT
>(itr1-isect1);
1423 return SpDCCols< IT, T_promote > (0, m, rhs.n, 0);
1425 StackEntry< T_promote, std::pair<IT,IT> > * multstack;
1426 IT cnz = SpHelper::SpCartesian< SR > (*dcsc, *(Btrans.dcsc), kisect, isect1, isect2, multstack);
1429 Dcsc<IT, T_promote> * mydcsc = NULL;
1432 mydcsc =
new Dcsc< IT,T_promote > (multstack, m, rhs.n, cnz);
1433 delete [] multstack;
1435 return SpDCCols< IT,T_promote > (m, rhs.n, mydcsc);
1439template <
class IT,
class NT>
1440template <
typename SR,
typename NTR>
1441SpDCCols< IT, typename promote_trait<NT,NTR>::T_promote > SpDCCols<IT,NT>::OrdColByCol(
const SpDCCols<IT,NTR> & rhs)
const
1443 typedef typename promote_trait<NT,NTR>::T_promote T_promote;
1445 if(isZero() || rhs.isZero())
1447 return SpDCCols<IT, T_promote> (0, m, rhs.n, 0);
1449 StackEntry< T_promote, std::pair<IT,IT> > * multstack;
1450 IT cnz = SpHelper::SpColByCol< SR > (*dcsc, *(rhs.dcsc), n, multstack);
1452 Dcsc<IT,T_promote > * mydcsc = NULL;
1455 mydcsc =
new Dcsc< IT,T_promote > (multstack, m, rhs.n, cnz);
1456 delete [] multstack;
1458 return SpDCCols< IT,T_promote > (m, rhs.n, mydcsc);