95 template<
class Element>
98 Allocate(row_upb-row_lwb+1,col_upb-col_lwb+1,row_lwb,col_lwb,1);
105 template<
class Element>
114 if (row[irowmin] < row_lwb || row[irowmax] > row_upb) {
115 Error(
"TMatrixTSparse",
"Inconsistency between row index and its range");
116 if (row[irowmin] < row_lwb) {
117 Info(
"TMatrixTSparse",
"row index lower bound adjusted to %d",row[irowmin]);
118 row_lwb = row[irowmin];
120 if (row[irowmax] > row_upb) {
121 Info(
"TMatrixTSparse",
"row index upper bound adjusted to %d",row[irowmax]);
122 col_lwb = col[irowmax];
125 if (col[icolmin] < col_lwb || col[icolmax] > col_upb) {
126 Error(
"TMatrixTSparse",
"Inconsistency between column index and its range");
127 if (col[icolmin] < col_lwb) {
128 Info(
"TMatrixTSparse",
"column index lower bound adjusted to %d",col[icolmin]);
129 col_lwb = col[icolmin];
131 if (col[icolmax] > col_upb) {
132 Info(
"TMatrixTSparse",
"column index upper bound adjusted to %d",col[icolmax]);
133 col_upb = col[icolmax];
137 Allocate(row_upb-row_lwb+1,col_upb-col_lwb+1,row_lwb,col_lwb,1,nr);
139 SetMatrixArray(nr,row,col,data);
144 template<
class Element>
157 template<
class Element>
170 template<
class Element>
175 Int_t nr_nonzeros = 0;
190 for (
Int_t i = rowLwb; i <= rowLwb+nrows-1; i++)
191 for (
Int_t j = colLwb; j <= colLwb+ncols-1; j++)
192 if (i==j) nr_nonzeros++;
193 Allocate(nrows,ncols,rowLwb,colLwb,1,nr_nonzeros);
212 Error(
"TMatrixTSparse(EMatrixCreatorOp1)",
"operation %d not yet implemented", op);
220 template<
class Element>
244 Error(
"TMatrixTSparse(EMatrixCreatorOp2)",
"operation %d not yet implemented",op);
252 template<
class Element>
276 Error(
"TMatrixTSparse(EMatrixCreatorOp2)",
"operation %d not yet implemented",op);
284 template<
class Element>
308 Error(
"TMatrixTSparse(EMatrixCreatorOp2)",
"operation %d not yet implemented",op);
317 template<
class Element>
321 if ( (nr_nonzeros > 0 && (no_rows == 0 || no_cols == 0)) ||
322 (no_rows < 0 || no_cols < 0 || nr_nonzeros < 0) )
324 Error(
"Allocate",
"no_rows=%d no_cols=%d non_zeros=%d",no_rows,no_cols,nr_nonzeros);
330 this->fNrows = no_rows;
331 this->fNcols = no_cols;
332 this->fRowLwb = row_lwb;
333 this->fColLwb = col_lwb;
334 this->fNrowIndex = this->fNrows+1;
335 this->fNelems = nr_nonzeros;
336 this->fIsOwner =
kTRUE;
339 fRowIndex =
new Int_t[this->fNrowIndex];
341 memset(fRowIndex,0,this->fNrowIndex*
sizeof(
Int_t));
343 if (this->fNelems > 0) {
344 fElements =
new Element[this->fNelems];
345 fColIndex =
new Int_t [this->fNelems];
347 memset(fElements,0,this->fNelems*
sizeof(Element));
348 memset(fColIndex,0,this->fNelems*
sizeof(
Int_t));
359 template<
class Element>
362 const Int_t arown = rown-this->fRowLwb;
363 const Int_t acoln = coln-this->fColLwb;
364 const Int_t nr = (n > 0) ? n : this->fNcols;
367 if (arown >= this->fNrows || arown < 0) {
368 Error(
"InsertRow",
"row %d out of matrix range",rown);
372 if (acoln >= this->fNcols || acoln < 0) {
373 Error(
"InsertRow",
"column %d out of matrix range",coln);
377 if (acoln+nr > this->fNcols || nr < 0) {
378 Error(
"InsertRow",
"row length %d out of range",nr);
383 const Int_t sIndex = fRowIndex[arown];
384 const Int_t eIndex = fRowIndex[arown+1];
391 Int_t lIndex = sIndex-1;
392 Int_t rIndex = sIndex-1;
394 for (index = sIndex; index < eIndex; index++) {
395 const Int_t icol = fColIndex[index];
397 if (icol >= acoln+nr)
break;
398 if (icol >= acoln) nslots++;
402 const Int_t nelems_old = this->fNelems;
403 const Int_t *colIndex_old = fColIndex;
404 const Element *elements_old = fElements;
406 const Int_t ndiff = nr-nslots;
407 this->fNelems += ndiff;
408 fColIndex =
new Int_t[this->fNelems];
409 fElements =
new Element[this->fNelems];
411 for (
Int_t irow = arown+1; irow < this->fNrows+1; irow++)
412 fRowIndex[irow] += ndiff;
415 memmove(fColIndex,colIndex_old,(lIndex+1)*
sizeof(
Int_t));
416 memmove(fElements,elements_old,(lIndex+1)*
sizeof(Element));
419 if (nelems_old > 0 && nelems_old-rIndex > 0) {
420 memmove(fColIndex+rIndex+ndiff,colIndex_old+rIndex,(nelems_old-rIndex)*
sizeof(
Int_t));
421 memmove(fElements+rIndex+ndiff,elements_old+rIndex,(nelems_old-rIndex)*
sizeof(Element));
425 for (
Int_t i = 0; i < nr; i++) {
426 fColIndex[index] = acoln+i;
427 fElements[index] = v[i];
431 if (colIndex_old)
delete [] (
Int_t*) colIndex_old;
432 if (elements_old)
delete [] (Element*) elements_old;
434 R__ASSERT(this->fNelems == fRowIndex[this->fNrowIndex-1]);
442 template<
class Element>
445 const Int_t arown = rown-this->fRowLwb;
446 const Int_t acoln = coln-this->fColLwb;
447 const Int_t nr = (n > 0) ? n : this->fNcols;
450 if (arown >= this->fNrows || arown < 0) {
451 Error(
"ExtractRow",
"row %d out of matrix range",rown);
455 if (acoln >= this->fNcols || acoln < 0) {
456 Error(
"ExtractRow",
"column %d out of matrix range",coln);
460 if (acoln+nr > this->fNcols || nr < 0) {
461 Error(
"ExtractRow",
"row length %d out of range",nr);
466 const Int_t sIndex = fRowIndex[arown];
467 const Int_t eIndex = fRowIndex[arown+1];
469 memset(v,0,nr*
sizeof(Element));
470 const Int_t *
const pColIndex = GetColIndexArray();
471 const Element *
const pData = GetMatrixArray();
472 for (
Int_t index = sIndex; index < eIndex; index++) {
473 const Int_t icol = pColIndex[index];
474 if (icol < acoln || icol >= acoln+nr)
continue;
475 v[icol-acoln] = pData[index];
483 template<
class Element>
491 Error(
"AMultBt",
"A and B columns incompatible");
496 Error(
"AMultB",
"this = &a");
501 Error(
"AMultB",
"this = &b");
517 Int_t nr_nonzero_rowa = 0;
520 if (pRowIndexa[irowa] < pRowIndexa[irowa+1])
523 Int_t nr_nonzero_rowb = 0;
526 if (pRowIndexb[irowb] < pRowIndexb[irowb+1])
530 const Int_t nc = nr_nonzero_rowa*nr_nonzero_rowb;
533 pRowIndexc = this->GetRowIndexArray();
534 pColIndexc = this->GetColIndexArray();
539 pRowIndexc[irowa+1] = pRowIndexc[irowa];
540 if (pRowIndexa[irowa] >= pRowIndexa[irowa+1])
continue;
542 if (pRowIndexb[irowb] >= pRowIndexb[irowb+1])
continue;
543 pRowIndexc[irowa+1]++;
544 pColIndexc[ielem++] = irowb;
548 pRowIndexc = this->GetRowIndexArray();
549 pColIndexc = this->GetColIndexArray();
554 Element *
const pDatac = this->GetMatrixArray();
556 for (
Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
557 const Int_t sIndexa = pRowIndexa[irowc];
558 const Int_t eIndexa = pRowIndexa[irowc+1];
559 for (
Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
560 const Int_t sIndexb = pRowIndexb[icolc];
561 const Int_t eIndexb = pRowIndexb[icolc+1];
563 Int_t indexb = sIndexb;
564 for (
Int_t indexa = sIndexa; indexa < eIndexa && indexb < eIndexb; indexa++) {
565 const Int_t icola = pColIndexa[indexa];
566 while (indexb < eIndexb && pColIndexb[indexb] <= icola) {
567 if (icola == pColIndexb[indexb]) {
568 sum += pDataa[indexa]*pDatab[indexb];
575 pColIndexc[indexc_r] = icolc;
576 pDatac[indexc_r] = sum;
580 pRowIndexc[irowc+1] = indexc_r;
584 SetSparseIndex(indexc_r);
591 template<
class Element>
599 Error(
"AMultBt",
"A and B columns incompatible");
604 Error(
"AMultB",
"this = &a");
609 Error(
"AMultB",
"this = &b");
623 Int_t nr_nonzero_rowa = 0;
626 if (pRowIndexa[irowa] < pRowIndexa[irowa+1])
631 const Int_t nc = nr_nonzero_rowa*nr_nonzero_rowb;
634 pRowIndexc = this->GetRowIndexArray();
635 pColIndexc = this->GetColIndexArray();
640 pRowIndexc[irowa+1] = pRowIndexc[irowa];
642 pRowIndexc[irowa+1]++;
643 pColIndexc[ielem++] = irowb;
647 pRowIndexc = this->GetRowIndexArray();
648 pColIndexc = this->GetColIndexArray();
653 Element *
const pDatac = this->GetMatrixArray();
655 for (
Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
656 const Int_t sIndexa = pRowIndexa[irowc];
657 const Int_t eIndexa = pRowIndexa[irowc+1];
658 for (
Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
661 for (
Int_t indexa = sIndexa; indexa < eIndexa; indexa++) {
662 const Int_t icola = pColIndexa[indexa];
663 sum += pDataa[indexa]*pDatab[off+icola];
666 pColIndexc[indexc_r] = icolc;
667 pDatac[indexc_r] = sum;
671 pRowIndexc[irowc+1]= indexc_r;
675 SetSparseIndex(indexc_r);
682 template<
class Element>
690 Error(
"AMultBt",
"A and B columns incompatible");
695 Error(
"AMultB",
"this = &a");
700 Error(
"AMultB",
"this = &b");
715 Int_t nr_nonzero_rowb = 0;
718 if (pRowIndexb[irowb] < pRowIndexb[irowb+1])
722 const Int_t nc = nr_nonzero_rowa*nr_nonzero_rowb;
725 pRowIndexc = this->GetRowIndexArray();
726 pColIndexc = this->GetColIndexArray();
731 pRowIndexc[irowa+1] = pRowIndexc[irowa];
733 if (pRowIndexb[irowb] >= pRowIndexb[irowb+1])
continue;
734 pRowIndexc[irowa+1]++;
735 pColIndexc[ielem++] = irowb;
739 pRowIndexc = this->GetRowIndexArray();
740 pColIndexc = this->GetColIndexArray();
745 Element *
const pDatac = this->GetMatrixArray();
747 for (
Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
749 for (
Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
750 const Int_t sIndexb = pRowIndexb[icolc];
751 const Int_t eIndexb = pRowIndexb[icolc+1];
753 for (
Int_t indexb = sIndexb; indexb < eIndexb; indexb++) {
754 const Int_t icolb = pColIndexb[indexb];
755 sum += pDataa[off+icolb]*pDatab[indexb];
758 pColIndexc[indexc_r] = icolc;
759 pDatac[indexc_r] = sum;
763 pRowIndexc[irowc+1] = indexc_r;
767 SetSparseIndex(indexc_r);
774 template<
class Element>
783 Error(
"APlusB(const TMatrixTSparse &,const TMatrixTSparse &",
"matrices not compatible");
788 Error(
"APlusB",
"this = &a");
793 Error(
"APlusB",
"this = &b");
805 SetSparseIndexAB(a,b);
808 Int_t *
const pRowIndexc = this->GetRowIndexArray();
809 Int_t *
const pColIndexc = this->GetColIndexArray();
813 Element *
const pDatac = this->GetMatrixArray();
815 for (
Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
816 const Int_t sIndexa = pRowIndexa[irowc];
817 const Int_t eIndexa = pRowIndexa[irowc+1];
818 const Int_t sIndexb = pRowIndexb[irowc];
819 const Int_t eIndexb = pRowIndexb[irowc+1];
820 Int_t indexa = sIndexa;
821 Int_t indexb = sIndexb;
822 for (
Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
824 while (indexa < eIndexa && pColIndexa[indexa] <= icolc) {
825 if (icolc == pColIndexa[indexa]) {
826 sum += pDataa[indexa];
831 while (indexb < eIndexb && pColIndexb[indexb] <= icolc) {
832 if (icolc == pColIndexb[indexb]) {
833 sum += pDatab[indexb];
840 pColIndexc[indexc_r] = icolc;
841 pDatac[indexc_r] = sum;
845 pRowIndexc[irowc+1] = indexc_r;
849 SetSparseIndex(indexc_r);
856 template<
class Element>
865 Error(
"APlusB(const TMatrixTSparse &,const TMatrixT &",
"matrices not compatible");
870 Error(
"APlusB",
"this = &a");
875 Error(
"APlusB",
"this = &b");
882 SetSparseIndexAB(a,b);
885 Int_t *
const pRowIndexc = this->GetRowIndexArray();
886 Int_t *
const pColIndexc = this->GetColIndexArray();
893 Element *
const pDatac = this->GetMatrixArray();
895 for (
Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
896 const Int_t sIndexa = pRowIndexa[irowc];
897 const Int_t eIndexa = pRowIndexa[irowc+1];
898 const Int_t off = irowc*this->GetNcols();
899 Int_t indexa = sIndexa;
900 for (
Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
901 Element sum = pDatab[off+icolc];
902 while (indexa < eIndexa && pColIndexa[indexa] <= icolc) {
903 if (icolc == pColIndexa[indexa]) {
904 sum += pDataa[indexa];
911 pColIndexc[indexc_r] = icolc;
912 pDatac[indexc_r] = sum;
916 pRowIndexc[irowc+1] = indexc_r;
920 SetSparseIndex(indexc_r);
927 template<
class Element>
936 Error(
"AMinusB(const TMatrixTSparse &,const TMatrixTSparse &",
"matrices not compatible");
941 Error(
"AMinusB",
"this = &a");
946 Error(
"AMinusB",
"this = &b");
958 SetSparseIndexAB(a,b);
961 Int_t *
const pRowIndexc = this->GetRowIndexArray();
962 Int_t *
const pColIndexc = this->GetColIndexArray();
966 Element *
const pDatac = this->GetMatrixArray();
968 for (
Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
969 const Int_t sIndexa = pRowIndexa[irowc];
970 const Int_t eIndexa = pRowIndexa[irowc+1];
971 const Int_t sIndexb = pRowIndexb[irowc];
972 const Int_t eIndexb = pRowIndexb[irowc+1];
973 Int_t indexa = sIndexa;
974 Int_t indexb = sIndexb;
975 for (
Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
977 while (indexa < eIndexa && pColIndexa[indexa] <= icolc) {
978 if (icolc == pColIndexa[indexa]) {
979 sum += pDataa[indexa];
984 while (indexb < eIndexb && pColIndexb[indexb] <= icolc) {
985 if (icolc == pColIndexb[indexb]) {
986 sum -= pDatab[indexb];
993 pColIndexc[indexc_r] = icolc;
994 pDatac[indexc_r] = sum;
998 pRowIndexc[irowc+1] = indexc_r;
1002 SetSparseIndex(indexc_r);
1009 template<
class Element>
1018 Error(
"AMinusB(const TMatrixTSparse &,const TMatrixT &",
"matrices not compatible");
1023 Error(
"AMinusB",
"this = &a");
1028 Error(
"AMinusB",
"this = &b");
1035 SetSparseIndexAB(a,b);
1038 Int_t *
const pRowIndexc = this->GetRowIndexArray();
1039 Int_t *
const pColIndexc = this->GetColIndexArray();
1046 Element *
const pDatac = this->GetMatrixArray();
1048 for (
Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
1049 const Int_t sIndexa = pRowIndexa[irowc];
1050 const Int_t eIndexa = pRowIndexa[irowc+1];
1051 const Int_t off = irowc*this->GetNcols();
1052 Int_t indexa = sIndexa;
1053 for (
Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
1054 Element sum = -pDatab[off+icolc];
1055 while (indexa < eIndexa && pColIndexa[indexa] <= icolc) {
1056 if (icolc == pColIndexa[indexa]) {
1057 sum += pDataa[indexa];
1064 pColIndexc[indexc_r] = icolc;
1065 pDatac[indexc_r] = sum;
1069 pRowIndexc[irowc+1] = indexc_r;
1073 SetSparseIndex(indexc_r);
1080 template<
class Element>
1089 Error(
"AMinusB(const TMatrixT &,const TMatrixTSparse &",
"matrices not compatible");
1094 Error(
"AMinusB",
"this = &a");
1099 Error(
"AMinusB",
"this = &b");
1106 SetSparseIndexAB(a,b);
1109 Int_t *
const pRowIndexc = this->GetRowIndexArray();
1110 Int_t *
const pColIndexc = this->GetColIndexArray();
1117 Element *
const pDatac = this->GetMatrixArray();
1119 for (
Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
1120 const Int_t sIndexb = pRowIndexb[irowc];
1121 const Int_t eIndexb = pRowIndexb[irowc+1];
1122 const Int_t off = irowc*this->GetNcols();
1123 Int_t indexb = sIndexb;
1124 for (
Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
1125 Element sum = pDataa[off+icolc];
1126 while (indexb < eIndexb && pColIndexb[indexb] <= icolc) {
1127 if (icolc == pColIndexb[indexb]) {
1128 sum -= pDatab[indexb];
1135 pColIndexc[indexc_r] = icolc;
1136 pDatac[indexc_r] = sum;
1140 pRowIndexc[irowc+1] = indexc_r;
1144 SetSparseIndex(indexc_r);
1150 template<
class Element>
1155 const Element *
const elem = GetMatrixArray();
1156 memcpy(data,elem,this->fNelems*
sizeof(Element));
1164 template<
class Element>
1169 Error(
"SetMatrixArray(Int_t,Int_t*,Int_t*,Element*",
"nr <= 0");
1178 R__ASSERT(row[irowmin] >= this->fRowLwb && row[irowmax] <= this->fRowLwb+this->fNrows-1);
1179 R__ASSERT(col[icolmin] >= this->fColLwb && col[icolmax] <= this->fColLwb+this->fNcols-1);
1181 if (row[irowmin] < this->fRowLwb || row[irowmax] > this->fRowLwb+this->fNrows-1) {
1182 Error(
"SetMatrixArray",
"Inconsistency between row index and its range");
1183 if (row[irowmin] < this->fRowLwb) {
1184 Info(
"SetMatrixArray",
"row index lower bound adjusted to %d",row[irowmin]);
1185 this->fRowLwb = row[irowmin];
1187 if (row[irowmax] > this->fRowLwb+this->fNrows-1) {
1188 Info(
"SetMatrixArray",
"row index upper bound adjusted to %d",row[irowmax]);
1189 this->fNrows = row[irowmax]-this->fRowLwb+1;
1192 if (col[icolmin] < this->fColLwb || col[icolmax] > this->fColLwb+this->fNcols-1) {
1193 Error(
"SetMatrixArray",
"Inconsistency between column index and its range");
1194 if (col[icolmin] < this->fColLwb) {
1195 Info(
"SetMatrixArray",
"column index lower bound adjusted to %d",col[icolmin]);
1196 this->fColLwb = col[icolmin];
1198 if (col[icolmax] > this->fColLwb+this->fNcols-1) {
1199 Info(
"SetMatrixArray",
"column index upper bound adjusted to %d",col[icolmax]);
1200 this->fNcols = col[icolmax]-this->fColLwb+1;
1206 Int_t nr_nonzeros = 0;
1207 const Element *ep = data;
1208 const Element *
const fp = data+nr;
1211 if (*ep++ != 0.0) nr_nonzeros++;
1213 if (nr_nonzeros != this->fNelems) {
1214 if (fColIndex) {
delete [] fColIndex; fColIndex = 0; }
1215 if (fElements) {
delete [] fElements; fElements = 0; }
1216 this->fNelems = nr_nonzeros;
1217 if (this->fNelems > 0) {
1218 fColIndex =
new Int_t[nr_nonzeros];
1219 fElements =
new Element[nr_nonzeros];
1226 if (this->fNelems <= 0)
1232 for (
Int_t irow = 1; irow < this->fNrows+1; irow++) {
1233 if (ielem < nr && row[ielem] < irow) {
1234 while (ielem < nr) {
1235 if (data[ielem] != 0.0) {
1236 fColIndex[nr_nonzeros] = col[ielem]-this->fColLwb;
1237 fElements[nr_nonzeros] = data[ielem];
1241 if (ielem >= nr || row[ielem] != row[ielem-1])
1245 fRowIndex[irow] = nr_nonzeros;
1254 template<
class Element>
1257 if (nelems_new != this->fNelems) {
1259 Int_t *oIp = fColIndex;
1260 fColIndex =
new Int_t[nelems_new];
1262 memmove(fColIndex,oIp,nr*
sizeof(
Int_t));
1265 Element *oDp = fElements;
1266 fElements =
new Element[nelems_new];
1268 memmove(fElements,oDp,nr*
sizeof(Element));
1271 this->fNelems = nelems_new;
1272 if (nelems_new > nr) {
1273 memset(fElements+nr,0,(nelems_new-nr)*
sizeof(Element));
1274 memset(fColIndex+nr,0,(nelems_new-nr)*
sizeof(
Int_t));
1276 for (
Int_t irow = 0; irow < this->fNrowIndex; irow++)
1277 if (fRowIndex[irow] > nelems_new)
1278 fRowIndex[irow] = nelems_new;
1288 template<
class Element>
1293 if (this->GetNrows() != source.
GetNrows() || this->GetNcols() != source.
GetNcols() ||
1294 this->GetRowLwb() != source.
GetRowLwb() || this->GetColLwb() != source.
GetColLwb()) {
1295 Error(
"SetSparseIndex",
"matrices not compatible");
1302 if (nr_nonzeros != this->fNelems)
1303 SetSparseIndex(nr_nonzeros);
1311 for (
Int_t irow = 0; irow < this->fNrows; irow++) {
1312 fRowIndex[irow] = nr;
1313 for (
Int_t icol = 0; icol < this->fNcols; icol++) {
1315 fColIndex[nr] = icol;
1321 fRowIndex[this->fNrows] = nr;
1331 template<
class Element>
1340 Error(
"SetSparseIndexAB",
"source matrices not compatible");
1344 if (this->GetNrows() != a.
GetNrows() || this->GetNcols() != a.
GetNcols() ||
1346 Error(
"SetSparseIndexAB",
"matrix not compatible with source matrices");
1359 const Int_t sIndexa = pRowIndexa[irowc];
1360 const Int_t eIndexa = pRowIndexa[irowc+1];
1361 const Int_t sIndexb = pRowIndexb[irowc];
1362 const Int_t eIndexb = pRowIndexb[irowc+1];
1363 nc += eIndexa-sIndexa;
1364 Int_t indexb = sIndexb;
1365 for (
Int_t indexa = sIndexa; indexa < eIndexa; indexa++) {
1366 const Int_t icola = pColIndexa[indexa];
1367 for (; indexb < eIndexb; indexb++) {
1368 if (pColIndexb[indexb] >= icola) {
1369 if (pColIndexb[indexb] == icola)
1376 while (indexb < eIndexb) {
1377 const Int_t icola = (eIndexa > sIndexa && eIndexa > 0) ? pColIndexa[eIndexa-1] : -1;
1378 if (pColIndexb[indexb++] > icola)
1384 if (this->NonZeros() != nc)
1387 Int_t *
const pRowIndexc = this->GetRowIndexArray();
1388 Int_t *
const pColIndexc = this->GetColIndexArray();
1393 const Int_t sIndexa = pRowIndexa[irowc];
1394 const Int_t eIndexa = pRowIndexa[irowc+1];
1395 const Int_t sIndexb = pRowIndexb[irowc];
1396 const Int_t eIndexb = pRowIndexb[irowc+1];
1397 Int_t indexb = sIndexb;
1398 for (
Int_t indexa = sIndexa; indexa < eIndexa; indexa++) {
1399 const Int_t icola = pColIndexa[indexa];
1400 for (; indexb < eIndexb; indexb++) {
1401 if (pColIndexb[indexb] >= icola) {
1402 if (pColIndexb[indexb] == icola)
1406 pColIndexc[nc++] = pColIndexb[indexb];
1408 pColIndexc[nc++] = pColIndexa[indexa];
1410 while (indexb < eIndexb) {
1411 const Int_t icola = (eIndexa > 0) ? pColIndexa[eIndexa-1] : -1;
1412 if (pColIndexb[indexb++] > icola)
1413 pColIndexc[nc++] = pColIndexb[indexb-1];
1415 pRowIndexc[irowc+1] = nc;
1425 template<
class Element>
1434 Error(
"SetSparseIndexAB",
"source matrices not compatible");
1438 if (this->GetNrows() != a.
GetNrows() || this->GetNcols() != a.
GetNcols() ||
1440 Error(
"SetSparseIndexAB",
"matrix not compatible with source matrices");
1452 for (
Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
1453 const Int_t sIndexb = pRowIndexb[irowc];
1454 const Int_t eIndexb = pRowIndexb[irowc+1];
1455 const Int_t off = irowc*this->GetNcols();
1456 Int_t indexb = sIndexb;
1457 for (
Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
1458 if (pDataa[off+icolc] != 0.0 || pColIndexb[indexb] > icolc)
continue;
1459 for (; indexb < eIndexb; indexb++) {
1460 if (pColIndexb[indexb] >= icolc) {
1461 if (pColIndexb[indexb] == icolc) {
1472 if (this->NonZeros() != nc)
1475 Int_t *
const pRowIndexc = this->GetRowIndexArray();
1476 Int_t *
const pColIndexc = this->GetColIndexArray();
1480 for (
Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
1481 const Int_t sIndexb = pRowIndexb[irowc];
1482 const Int_t eIndexb = pRowIndexb[irowc+1];
1483 const Int_t off = irowc*this->GetNcols();
1484 Int_t indexb = sIndexb;
1485 for (
Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
1486 if (pDataa[off+icolc] != 0.0)
1487 pColIndexc[nc++] = icolc;
1488 else if (pColIndexb[indexb] <= icolc) {
1489 for (; indexb < eIndexb; indexb++) {
1490 if (pColIndexb[indexb] >= icolc) {
1491 if (pColIndexb[indexb] == icolc)
1492 pColIndexc[nc++] = pColIndexb[indexb++];
1498 pRowIndexc[irowc+1] = nc;
1510 template<
class Element>
1514 if (!this->fIsOwner) {
1515 Error(
"ResizeTo(Int_t,Int_t,Int_t)",
"Not owner of data array,cannot resize");
1519 if (this->fNelems > 0) {
1520 if (this->fNrows == nrows && this->fNcols == ncols &&
1521 (this->fNelems == nr_nonzeros || nr_nonzeros < 0))
1523 else if (nrows == 0 || ncols == 0 || nr_nonzeros == 0) {
1524 this->fNrows = nrows; this->fNcols = ncols;
1529 const Element *elements_old = GetMatrixArray();
1530 const Int_t *rowIndex_old = GetRowIndexArray();
1531 const Int_t *colIndex_old = GetColIndexArray();
1533 Int_t nrows_old = this->fNrows;
1534 Int_t nrowIndex_old = this->fNrowIndex;
1537 if (nr_nonzeros > 0)
1538 nelems_new = nr_nonzeros;
1541 for (
Int_t irow = 0; irow < nrows_old; irow++) {
1542 if (irow >= nrows)
continue;
1543 const Int_t sIndex = rowIndex_old[irow];
1544 const Int_t eIndex = rowIndex_old[irow+1];
1545 for (
Int_t index = sIndex; index < eIndex; index++) {
1546 const Int_t icol = colIndex_old[index];
1553 Allocate(nrows,ncols,0,0,1,nelems_new);
1556 Element *elements_new = GetMatrixArray();
1557 Int_t *rowIndex_new = GetRowIndexArray();
1558 Int_t *colIndex_new = GetColIndexArray();
1560 Int_t nelems_copy = 0;
1561 rowIndex_new[0] = 0;
1563 for (
Int_t irow = 0; irow < nrows_old && cont; irow++) {
1564 if (irow >= nrows)
continue;
1565 const Int_t sIndex = rowIndex_old[irow];
1566 const Int_t eIndex = rowIndex_old[irow+1];
1567 for (
Int_t index = sIndex; index < eIndex; index++) {
1568 const Int_t icol = colIndex_old[index];
1570 rowIndex_new[irow+1] = nelems_copy+1;
1571 colIndex_new[nelems_copy] = icol;
1572 elements_new[nelems_copy] = elements_old[index];
1575 if (nelems_copy >= nelems_new) {
1582 if (rowIndex_old)
delete [] (
Int_t*) rowIndex_old;
1583 if (colIndex_old)
delete [] (
Int_t*) colIndex_old;
1584 if (elements_old)
delete [] (Element*) elements_old;
1586 if (nrowIndex_old < this->fNrowIndex) {
1587 for (
Int_t irow = nrowIndex_old; irow < this->fNrowIndex; irow++)
1588 rowIndex_new[irow] = rowIndex_new[nrowIndex_old-1];
1591 const Int_t nelems_new = (nr_nonzeros >= 0) ? nr_nonzeros : 0;
1592 Allocate(nrows,ncols,0,0,1,nelems_new);
1604 template<
class Element>
1609 if (!this->fIsOwner) {
1610 Error(
"ResizeTo(Int_t,Int_t,Int_t,Int_t,Int_t)",
"Not owner of data array,cannot resize");
1614 const Int_t new_nrows = row_upb-row_lwb+1;
1615 const Int_t new_ncols = col_upb-col_lwb+1;
1617 if (this->fNelems > 0) {
1618 if (this->fNrows == new_nrows && this->fNcols == new_ncols &&
1619 this->fRowLwb == row_lwb && this->fColLwb == col_lwb &&
1620 (this->fNelems == nr_nonzeros || nr_nonzeros < 0))
1622 else if (new_nrows == 0 || new_ncols == 0 || nr_nonzeros == 0) {
1623 this->fNrows = new_nrows; this->fNcols = new_ncols;
1624 this->fRowLwb = row_lwb; this->fColLwb = col_lwb;
1629 const Int_t *rowIndex_old = GetRowIndexArray();
1630 const Int_t *colIndex_old = GetColIndexArray();
1631 const Element *elements_old = GetMatrixArray();
1633 const Int_t nrowIndex_old = this->fNrowIndex;
1635 const Int_t nrows_old = this->fNrows;
1636 const Int_t rowLwb_old = this->fRowLwb;
1637 const Int_t colLwb_old = this->fColLwb;
1640 if (nr_nonzeros > 0)
1641 nelems_new = nr_nonzeros;
1644 for (
Int_t irow = 0; irow < nrows_old; irow++) {
1645 if (irow+rowLwb_old > row_upb || irow+rowLwb_old < row_lwb)
continue;
1646 const Int_t sIndex = rowIndex_old[irow];
1647 const Int_t eIndex = rowIndex_old[irow+1];
1648 for (
Int_t index = sIndex; index < eIndex; index++) {
1649 const Int_t icol = colIndex_old[index];
1650 if (icol+colLwb_old <= col_upb && icol+colLwb_old >= col_lwb)
1656 Allocate(new_nrows,new_ncols,row_lwb,col_lwb,1,nelems_new);
1659 Int_t *rowIndex_new = GetRowIndexArray();
1660 Int_t *colIndex_new = GetColIndexArray();
1661 Element *elements_new = GetMatrixArray();
1663 Int_t nelems_copy = 0;
1664 rowIndex_new[0] = 0;
1665 const Int_t row_off = rowLwb_old-row_lwb;
1666 const Int_t col_off = colLwb_old-col_lwb;
1667 for (
Int_t irow = 0; irow < nrows_old; irow++) {
1668 if (irow+rowLwb_old > row_upb || irow+rowLwb_old < row_lwb)
continue;
1669 const Int_t sIndex = rowIndex_old[irow];
1670 const Int_t eIndex = rowIndex_old[irow+1];
1671 for (
Int_t index = sIndex; index < eIndex; index++) {
1672 const Int_t icol = colIndex_old[index];
1673 if (icol+colLwb_old <= col_upb && icol+colLwb_old >= col_lwb) {
1674 rowIndex_new[irow+row_off+1] = nelems_copy+1;
1675 colIndex_new[nelems_copy] = icol+col_off;
1676 elements_new[nelems_copy] = elements_old[index];
1679 if (nelems_copy >= nelems_new) {
1685 if (rowIndex_old)
delete [] (
Int_t*) rowIndex_old;
1686 if (colIndex_old)
delete [] (
Int_t*) colIndex_old;
1687 if (elements_old)
delete [] (Element*) elements_old;
1689 if (nrowIndex_old < this->fNrowIndex) {
1690 for (
Int_t irow = nrowIndex_old; irow < this->fNrowIndex; irow++)
1691 rowIndex_new[irow] = rowIndex_new[nrowIndex_old-1];
1694 const Int_t nelems_new = (nr_nonzeros >= 0) ? nr_nonzeros : 0;
1695 Allocate(new_nrows,new_ncols,row_lwb,col_lwb,1,nelems_new);
1703 template<
class Element>
1708 if (row_upb < row_lwb) {
1709 Error(
"Use",
"row_upb=%d < row_lwb=%d",row_upb,row_lwb);
1712 if (col_upb < col_lwb) {
1713 Error(
"Use",
"col_upb=%d < col_lwb=%d",col_upb,col_lwb);
1720 this->fNrows = row_upb-row_lwb+1;
1721 this->fNcols = col_upb-col_lwb+1;
1722 this->fRowLwb = row_lwb;
1723 this->fColLwb = col_lwb;
1724 this->fNrowIndex = this->fNrows+1;
1725 this->fNelems = nr_nonzeros;
1730 fRowIndex = pRowIndex;
1731 fColIndex = pColIndex;
1743 template<
class Element>
1749 if (row_lwb < this->fRowLwb || row_lwb > this->fRowLwb+this->fNrows-1) {
1750 Error(
"GetSub",
"row_lwb out-of-bounds");
1753 if (col_lwb < this->fColLwb || col_lwb > this->fColLwb+this->fNcols-1) {
1754 Error(
"GetSub",
"col_lwb out-of-bounds");
1757 if (row_upb < this->fRowLwb || row_upb > this->fRowLwb+this->fNrows-1) {
1758 Error(
"GetSub",
"row_upb out-of-bounds");
1761 if (col_upb < this->fColLwb || col_upb > this->fColLwb+this->fNcols-1) {
1762 Error(
"GetSub",
"col_upb out-of-bounds");
1765 if (row_upb < row_lwb || col_upb < col_lwb) {
1766 Error(
"GetSub",
"row_upb < row_lwb || col_upb < col_lwb");
1775 const Int_t row_lwb_sub = (shift) ? 0 : row_lwb;
1776 const Int_t row_upb_sub = (shift) ? row_upb-row_lwb : row_upb;
1777 const Int_t col_lwb_sub = (shift) ? 0 : col_lwb;
1778 const Int_t col_upb_sub = (shift) ? col_upb-col_lwb : col_upb;
1780 Int_t nr_nonzeros = 0;
1781 for (
Int_t irow = 0; irow < this->fNrows; irow++) {
1782 if (irow+this->fRowLwb > row_upb || irow+this->fRowLwb < row_lwb)
continue;
1783 const Int_t sIndex = fRowIndex[irow];
1784 const Int_t eIndex = fRowIndex[irow+1];
1785 for (
Int_t index = sIndex; index < eIndex; index++) {
1786 const Int_t icol = fColIndex[index];
1787 if (icol+this->fColLwb <= col_upb && icol+this->fColLwb >= col_lwb)
1792 target.
ResizeTo(row_lwb_sub,row_upb_sub,col_lwb_sub,col_upb_sub,nr_nonzeros);
1794 const Element *ep = this->GetMatrixArray();
1801 Int_t nelems_copy = 0;
1802 rowIndex_sub[0] = 0;
1803 const Int_t row_off = this->fRowLwb-row_lwb;
1804 const Int_t col_off = this->fColLwb-col_lwb;
1805 for (
Int_t irow = 0; irow < this->fNrows; irow++) {
1806 if (irow+this->fRowLwb > row_upb || irow+this->fRowLwb < row_lwb)
continue;
1807 const Int_t sIndex = fRowIndex[irow];
1808 const Int_t eIndex = fRowIndex[irow+1];
1809 for (
Int_t index = sIndex; index < eIndex; index++) {
1810 const Int_t icol = fColIndex[index];
1811 if (icol+this->fColLwb <= col_upb && icol+this->fColLwb >= col_lwb) {
1812 rowIndex_sub[irow+row_off+1] = nelems_copy+1;
1813 colIndex_sub[nelems_copy] = icol+col_off;
1814 ep_sub[nelems_copy] = ep[index];
1820 const Int_t row_off = this->fRowLwb-row_lwb;
1821 const Int_t col_off = this->fColLwb-col_lwb;
1822 const Int_t ncols_sub = col_upb_sub-col_lwb_sub+1;
1823 for (
Int_t irow = 0; irow < this->fNrows; irow++) {
1824 if (irow+this->fRowLwb > row_upb || irow+this->fRowLwb < row_lwb)
continue;
1825 const Int_t sIndex = fRowIndex[irow];
1826 const Int_t eIndex = fRowIndex[irow+1];
1827 const Int_t off = (irow+row_off)*ncols_sub;
1828 for (
Int_t index = sIndex; index < eIndex; index++) {
1829 const Int_t icol = fColIndex[index];
1830 if (icol+this->fColLwb <= col_upb && icol+this->fColLwb >= col_lwb)
1831 ep_sub[off+icol+col_off] = ep[index];
1843 template<
class Element>
1850 if (row_lwb < this->fRowLwb || row_lwb > this->fRowLwb+this->fNrows-1) {
1851 Error(
"SetSub",
"row_lwb out-of-bounds");
1854 if (col_lwb < this->fColLwb || col_lwb > this->fColLwb+this->fNcols-1) {
1855 Error(
"SetSub",
"col_lwb out-of-bounds");
1858 if (row_lwb+source.
GetNrows() > this->fRowLwb+this->fNrows || col_lwb+source.
GetNcols() > this->fColLwb+this->fNcols) {
1859 Error(
"SetSub",
"source matrix too large");
1869 Int_t nr_nonzeros = 0;
1870 for (
Int_t irow = 0; irow < this->fNrows; irow++) {
1871 if (irow+this->fRowLwb >= row_lwb+nRows_source || irow+this->fRowLwb < row_lwb)
continue;
1872 const Int_t sIndex = fRowIndex[irow];
1873 const Int_t eIndex = fRowIndex[irow+1];
1874 for (
Int_t index = sIndex; index < eIndex; index++) {
1875 const Int_t icol = fColIndex[index];
1876 if (icol+this->fColLwb < col_lwb+nCols_source && icol+this->fColLwb >= col_lwb)
1885 const Int_t nelems_old = this->fNelems;
1886 const Int_t *rowIndex_old = GetRowIndexArray();
1887 const Int_t *colIndex_old = GetColIndexArray();
1888 const Element *elements_old = GetMatrixArray();
1890 const Int_t nelems_new = nelems_old+source.
NonZeros()-nr_nonzeros;
1891 fRowIndex =
new Int_t[this->fNrowIndex];
1892 fColIndex =
new Int_t[nelems_new];
1893 fElements =
new Element[nelems_new];
1894 this->fNelems = nelems_new;
1896 Int_t *rowIndex_new = GetRowIndexArray();
1897 Int_t *colIndex_new = GetColIndexArray();
1898 Element *elements_new = GetMatrixArray();
1900 const Int_t row_off = row_lwb-this->fRowLwb;
1901 const Int_t col_off = col_lwb-this->fColLwb;
1904 rowIndex_new[0] = 0;
1905 for (
Int_t irow = 0; irow < this->fNrows; irow++) {
1906 rowIndex_new[irow+1] = rowIndex_new[irow];
1908 if (irow+this->fRowLwb < row_lwb+nRows_source && irow+this->fRowLwb >= row_lwb)
1911 const Int_t sIndex_o = rowIndex_old[irow];
1912 const Int_t eIndex_o = rowIndex_old[irow+1];
1915 const Int_t icol_left = col_off-1;
1917 for (
Int_t index = sIndex_o; index <= left; index++) {
1918 rowIndex_new[irow+1]++;
1919 colIndex_new[nr] = colIndex_old[index];
1920 elements_new[nr] = elements_old[index];
1924 if (rowIndex_s && colIndex_s) {
1925 const Int_t sIndex_s = rowIndex_s[irow-row_off];
1926 const Int_t eIndex_s = rowIndex_s[irow-row_off+1];
1927 for (
Int_t index = sIndex_s; index < eIndex_s; index++) {
1928 rowIndex_new[irow+1]++;
1929 colIndex_new[nr] = colIndex_s[index]+col_off;
1930 elements_new[nr] = elements_s[index];
1934 const Int_t off = (irow-row_off)*nCols_source;
1935 for (
Int_t icol = 0; icol < nCols_source; icol++) {
1936 rowIndex_new[irow+1]++;
1937 colIndex_new[nr] = icol+col_off;
1938 elements_new[nr] = elements_s[off+icol];
1943 const Int_t icol_right = col_off+nCols_source-1;
1946 while (right < eIndex_o-1 && colIndex_old[right+1] <= icol_right)
1950 for (
Int_t index = right; index < eIndex_o; index++) {
1951 rowIndex_new[irow+1]++;
1952 colIndex_new[nr] = colIndex_old[index];
1953 elements_new[nr] = elements_old[index];
1958 for (
Int_t index = sIndex_o; index < eIndex_o; index++) {
1959 rowIndex_new[irow+1]++;
1960 colIndex_new[nr] = colIndex_old[index];
1961 elements_new[nr] = elements_old[index];
1967 R__ASSERT(this->fNelems == fRowIndex[this->fNrowIndex-1]);
1969 if (rowIndex_old)
delete [] (
Int_t*) rowIndex_old;
1970 if (colIndex_old)
delete [] (
Int_t*) colIndex_old;
1971 if (elements_old)
delete [] (Element*) elements_old;
1979 template<
class Element>
1986 if (this->fNrows != source.
GetNcols() || this->fNcols != source.
GetNrows() ||
1988 Error(
"Transpose",
"matrix has wrong shape");
2004 Element *pData_t =
new Element[nr_nonzeros];
2007 for (
Int_t irow_s = 0; irow_s < source.
GetNrows(); irow_s++) {
2008 const Int_t sIndex = pRowIndex_s[irow_s];
2009 const Int_t eIndex = pRowIndex_s[irow_s+1];
2010 for (
Int_t index = sIndex; index < eIndex; index++) {
2011 rownr[ielem] = pColIndex_s[index]+this->fRowLwb;
2012 colnr[ielem] = irow_s+this->fColLwb;
2013 pData_t[ielem] = pData_s[index];
2021 SetMatrixArray(nr_nonzeros,rownr,colnr,pData_t);
2023 R__ASSERT(this->fNelems == fRowIndex[this->fNrowIndex-1]);
2025 if (pData_t)
delete [] pData_t;
2026 if (rownr)
delete [] rownr;
2027 if (colnr)
delete [] colnr;
2034 template<
class Element>
2039 if (fElements) {
delete [] fElements; fElements = 0; }
2040 if (fColIndex) {
delete [] fColIndex; fColIndex = 0; }
2042 memset(this->GetRowIndexArray(),0,this->fNrowIndex*
sizeof(
Int_t));
2050 template<
class Element>
2057 Int_t nr_nonzeros = 0;
2058 for (i = this->fRowLwb; i <= this->fRowLwb+this->fNrows-1; i++)
2059 for (
Int_t j = this->fColLwb; j <= this->fColLwb+this->fNcols-1; j++)
2060 if (i == j) nr_nonzeros++;
2062 if (nr_nonzeros != this->fNelems) {
2063 this->fNelems = nr_nonzeros;
2064 Int_t *oIp = fColIndex;
2065 fColIndex =
new Int_t[nr_nonzeros];
2066 if (oIp)
delete [] oIp;
2067 Element *oDp = fElements;
2068 fElements =
new Element[nr_nonzeros];
2069 if (oDp)
delete [] oDp;
2074 for (i = this->fRowLwb; i <= this->fRowLwb+this->fNrows-1; i++) {
2075 for (
Int_t j = this->fColLwb; j <= this->fColLwb+this->fNcols-1; j++) {
2077 const Int_t irow = i-this->fRowLwb;
2078 fRowIndex[irow+1] = ielem+1;
2079 fElements[ielem] = 1.0;
2080 fColIndex[ielem++] = j-this->fColLwb;
2092 template<
class Element>
2097 const Element * ep = GetMatrixArray();
2098 const Element *
const fp = ep+this->fNelems;
2099 const Int_t *
const pR = GetRowIndexArray();
2103 for (
Int_t irow = 0; irow < this->fNrows; irow++) {
2104 const Int_t sIndex = pR[irow];
2105 const Int_t eIndex = pR[irow+1];
2107 for (
Int_t index = sIndex; index < eIndex; index++)
2121 template<
class Element>
2129 const Element *
const fp = ep+this->fNcols;
2136 for (
Int_t i = 0; i < this->fNrows; i++,ep += this->fNcols)
2138 ep -= this->fNelems-1;
2149 template<
class Element>
2154 const Int_t arown = rown-this->fRowLwb;
2155 const Int_t acoln = coln-this->fColLwb;
2156 if (arown >= this->fNrows || arown < 0) {
2157 Error(
"operator()",
"Request row(%d) outside matrix range of %d - %d",rown,this->fRowLwb,this->fRowLwb+this->fNrows);
2158 return fElements[0];
2160 if (acoln >= this->fNcols || acoln < 0) {
2161 Error(
"operator()",
"Request column(%d) outside matrix range of %d - %d",coln,this->fColLwb,this->fColLwb+this->fNcols);
2162 return fElements[0];
2168 if (this->fNrowIndex > 0 && fRowIndex[this->fNrowIndex-1] != 0) {
2169 sIndex = fRowIndex[arown];
2170 eIndex = fRowIndex[arown+1];
2174 if (index >= sIndex && fColIndex[index] == acoln)
2175 return fElements[index];
2178 InsertRow(rown,coln,&val,1);
2179 sIndex = fRowIndex[arown];
2180 eIndex = fRowIndex[arown+1];
2182 if (index >= sIndex && fColIndex[index] == acoln)
2183 return fElements[index];
2185 Error(
"operator()(Int_t,Int_t",
"Insert row failed");
2186 return fElements[0];
2193 template <
class Element>
2197 if (this->fNrowIndex > 0 && this->fRowIndex[this->fNrowIndex-1] == 0) {
2198 Error(
"operator()(Int_t,Int_t) const",
"row/col indices are not set");
2199 Info(
"operator()",
"fNrowIndex = %d fRowIndex[fNrowIndex-1] = %d\n",this->fNrowIndex,this->fRowIndex[this->fNrowIndex-1]);
2202 const Int_t arown = rown-this->fRowLwb;
2203 const Int_t acoln = coln-this->fColLwb;
2205 if (arown >= this->fNrows || arown < 0) {
2206 Error(
"operator()",
"Request row(%d) outside matrix range of %d - %d",rown,this->fRowLwb,this->fRowLwb+this->fNrows);
2209 if (acoln >= this->fNcols || acoln < 0) {
2210 Error(
"operator()",
"Request column(%d) outside matrix range of %d - %d",coln,this->fColLwb,this->fColLwb+this->fNcols);
2214 const Int_t sIndex = fRowIndex[arown];
2215 const Int_t eIndex = fRowIndex[arown+1];
2217 if (index < sIndex || fColIndex[index] != acoln)
return 0.0;
2218 else return fElements[index];
2225 template<
class Element>
2229 Error(
"operator=(const TMatrixTSparse &)",
"matrices not compatible");
2237 Element *
const tp = this->GetMatrixArray();
2238 memcpy(tp,sp,this->fNelems*
sizeof(Element));
2239 this->fTol = source.
GetTol();
2248 template<
class Element>
2252 Error(
"operator=(const TMatrixT &)",
"matrices not compatible");
2260 Element *
const tp = this->GetMatrixArray();
2261 for (
Int_t irow = 0; irow < this->fNrows; irow++) {
2262 const Int_t sIndex = fRowIndex[irow];
2263 const Int_t eIndex = fRowIndex[irow+1];
2264 const Int_t off = irow*this->fNcols;
2265 for (
Int_t index = sIndex; index < eIndex; index++) {
2266 const Int_t icol = fColIndex[index];
2267 tp[index] = sp[off+icol];
2270 this->fTol = source.
GetTol();
2279 template<
class Element>
2284 if (fRowIndex[this->fNrowIndex-1] == 0) {
2285 Error(
"operator=(Element",
"row/col indices are not set");
2289 Element *ep = this->GetMatrixArray();
2290 const Element *
const ep_last = ep+this->fNelems;
2291 while (ep < ep_last)
2300 template<
class Element>
2305 Element *ep = this->GetMatrixArray();
2306 const Element *
const ep_last = ep+this->fNelems;
2307 while (ep < ep_last)
2316 template<
class Element>
2321 Element *ep = this->GetMatrixArray();
2322 const Element *
const ep_last = ep+this->fNelems;
2323 while (ep < ep_last)
2332 template<
class Element>
2337 Element *ep = this->GetMatrixArray();
2338 const Element *
const ep_last = ep+this->fNelems;
2339 while (ep < ep_last)
2348 template<
class Element>
2353 const Element scale = beta-alpha;
2354 const Element shift = alpha/scale;
2356 Int_t *
const pRowIndex = GetRowIndexArray();
2357 Int_t *
const pColIndex = GetColIndexArray();
2358 Element *
const ep = GetMatrixArray();
2360 const Int_t m = this->GetNrows();
2361 const Int_t n = this->GetNcols();
2364 const Int_t nn = this->GetNrows()*this->GetNcols();
2365 const Int_t length = (this->GetNoElements() <= nn) ? this->GetNoElements() : nn;
2369 for (
Int_t k = 0; k < nn; k++) {
2370 const Element
r =
Drand(seed);
2372 if ((nn-k)*r < length-chosen) {
2373 pColIndex[chosen] = k%
n;
2376 if (irow > icurrent) {
2377 for ( ; icurrent < irow; icurrent++)
2378 pRowIndex[icurrent+1] = chosen;
2380 ep[chosen] = scale*(
Drand(seed)+shift);
2384 for ( ; icurrent <
m; icurrent++)
2385 pRowIndex[icurrent+1] = length;
2395 template<
class Element>
2398 const Element scale = beta-alpha;
2399 const Element shift = alpha/scale;
2404 if (this->fNrows != this->fNcols || this->fRowLwb != this->fColLwb) {
2405 Error(
"RandomizePD(Element &",
"matrix should be square");
2410 const Int_t n = this->fNcols;
2412 Int_t *
const pRowIndex = this->GetRowIndexArray();
2413 Int_t *
const pColIndex = this->GetColIndexArray();
2414 Element *
const ep = GetMatrixArray();
2421 ep[0] = 1e-8+scale*(
Drand(seed)+shift);
2425 const Int_t nn = n*(n-1)/2;
2431 length = (length <= nn) ? length : nn;
2441 for (
Int_t k = 0; k < nn; k++ ) {
2442 const Element
r =
Drand(seed);
2444 if( (nn-k)*r < length-chosen) {
2451 Int_t col = k-row*(row+1)/2;
2456 if (row > icurrent) {
2460 for ( ; icurrent <
row; icurrent++) {
2463 for (
Int_t ll = pRowIndex[icurrent]; ll < nnz; ll++)
2465 ep[nnz] += 1e-8+scale*(
Drand(seed)+shift);
2466 pColIndex[nnz] = icurrent;
2469 pRowIndex[icurrent+1] = nnz;
2472 ep[nnz] = scale*(
Drand(seed)+shift);
2473 pColIndex[nnz] = col;
2476 ep[pRowIndex[col+1]-1] +=
TMath::Abs(ep[nnz]);
2486 for ( ; icurrent <
n; icurrent++) {
2489 for(
Int_t ll = pRowIndex[icurrent]; ll < nnz; ll++)
2491 ep[nnz] += 1e-8+scale*(
Drand(seed)+shift);
2492 pColIndex[nnz] = icurrent;
2495 pRowIndex[icurrent+1] = nnz;
2497 this->fNelems = nnz;
2505 const Int_t *
const pR = this->GetRowIndexArray();
2506 const Int_t *
const pC = this->GetColIndexArray();
2507 Element *
const pD = GetMatrixArray();
2508 for (
Int_t irow = 0; irow < this->fNrows+1; irow++) {
2509 const Int_t sIndex = pR[irow];
2510 const Int_t eIndex = pR[irow+1];
2511 for (
Int_t index = sIndex; index < eIndex; index++) {
2512 const Int_t icol = pC[index];
2524 template<
class Element>
2533 template<
class Element>
2542 template<
class Element>
2551 template<
class Element>
2561 template<
class Element>
2571 template<
class Element>
2580 template<
class Element>
2589 template<
class Element>
2598 template<
class Element>
2608 template<
class Element>
2618 template<
class Element>
2627 template<
class Element>
2636 template<
class Element>
2645 template<
class Element>
2655 template<
class Element>
2666 template<
class Element>
2669 target += scalar * source;
2676 template<
class Element>
2680 ::Error(
"ElementMult(TMatrixTSparse &,const TMatrixTSparse &)",
"matrices not compatible");
2696 template<
class Element>
2700 ::Error(
"ElementDiv(TMatrixT &,const TMatrixT &)",
"matrices not compatible");
2707 while ( tp < ftp ) {
2711 Error(
"ElementDiv",
"source element is zero");
2721 template<
class Element>
2726 ::Error(
"AreCompatible",
"matrix 1 not valid");
2731 ::Error(
"AreCompatible",
"matrix 2 not valid");
2738 ::Error(
"AreCompatible",
"matrices 1 and 2 not compatible");
2745 if (memcmp(pR1,pR2,(nRows+1)*
sizeof(
Int_t))) {
2747 ::Error(
"AreCompatible",
"matrices 1 and 2 have different rowIndex");
2748 for (
Int_t i = 0; i < nRows+1; i++)
2749 printf(
"%d: %d %d\n",i,pR1[i],pR2[i]);
2755 if (memcmp(pD1,pD2,nData*
sizeof(
Int_t))) {
2757 ::Error(
"AreCompatible",
"matrices 1 and 2 have different colIndex");
2758 for (
Int_t i = 0; i < nData; i++)
2759 printf(
"%d: %d %d\n",i,pD1[i],pD2[i]);
2769 template<
class Element>
2777 if (this->fNelems < 0)
2786 #ifndef ROOT_TMatrixFSparsefwd
2789 #ifndef ROOT_TMatrixFfwd
2815 #ifndef ROOT_TMatrixDSparsefwd
2818 #ifndef ROOT_TMatrixDfwd
2822 template class TMatrixTSparse<Double_t>;
void AMinusB(const TMatrixTSparse< Element > &a, const TMatrixTSparse< Element > &b, Int_t constr=0)
General matrix subtraction.
virtual const Element * GetMatrixArray() const =0
virtual TMatrixTBase< Element > & InsertRow(Int_t row, Int_t col, const Element *v, Int_t n=-1)
Insert in row rown, n elements of array v at column coln.
virtual void GetMatrix2Array(Element *data, Option_t *="") const
Copy matrix data to array . It is assumed that array is of size >= fNelems.
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
Double_t Floor(Double_t x)
Small helper to encapsulate whether to return the value pointed to by the iterator or its address...
Long64_t LocMax(Long64_t n, const T *a)
TMatrixTSparse< Element > & Transpose(const TMatrixTSparse< Element > &source)
Transpose a matrix.
virtual Int_t NonZeros() const
Compute the number of elements != 0.0.
virtual const Element * GetMatrixArray() const
virtual TMatrixTBase< Element > & UnitMatrix()
Make a unit matrix (matrix need not be a square one).
template TMatrixDSparse & Add< Double_t >(TMatrixDSparse &target, Double_t scalar, const TMatrixDSparse &source)
void ToUpper()
Change string to upper case.
Buffer base class used for serializing objects.
template TMatrixDSparse & ElementMult< Double_t >(TMatrixDSparse &target, const TMatrixDSparse &source)
Int_t GetNoElements() const
Expr< TransposeOp< SMatrix< T, D1, D2, R >, T, D1, D2 >, T, D2, D1, typename TranspPolicy< T, D1, D2, R >::RepType > Transpose(const SMatrix< T, D1, D2, R > &rhs)
Matrix Transpose B(i,j) = A(j,i) returning a matrix expression.
template TMatrixFSparse & ElementDiv< Float_t >(TMatrixFSparse &target, const TMatrixFSparse &source)
virtual TMatrixTBase< Element > & SetMatrixArray(const Element *data, Option_t *="")
Copy array data to matrix .
Short_t Min(Short_t a, Short_t b)
virtual Int_t NonZeros() const
Compute the number of elements != 0.0.
virtual TMatrixTBase< Element > & ResizeTo(Int_t nrows, Int_t ncols, Int_t nr_nonzeros=-1)=0
template TMatrixFSparse & Add< Float_t >(TMatrixFSparse &target, Float_t scalar, const TMatrixFSparse &source)
virtual Element RowNorm() const
Row matrix norm, MAX{ SUM{ |M(i,j)|, over j}, over i}.
double beta(double x, double y)
Calculates the beta function.
template TMatrixFSparse & ElementMult< Float_t >(TMatrixFSparse &target, const TMatrixFSparse &source)
template Bool_t AreCompatible< Float_t >(const TMatrixFSparse &m1, const TMatrixFSparse &m2, Int_t verbose)
void AMultB(int n, int m, int k, const double *A, const double *B, double *C)
void Info(const char *location, const char *msgfmt,...)
Bool_t AreCompatible(const TMatrixTSparse< Element > &m1, const TMatrixTSparse< Element > &m2, Int_t verbose)
virtual TMatrixTBase< Element > & Randomize(Element alpha, Element beta, Double_t &seed)
randomize matrix element values
void AMultBt(const TMatrixTSparse< Element > &a, const TMatrixTSparse< Element > &b, Int_t constr=0)
General matrix multiplication.
TMatrixTSparse< Element > & ElementMult(TMatrixTSparse< Element > &target, const TMatrixTSparse< Element > &source)
Multiply target by the source, element-by-element.
TObject & operator=(const TObject &rhs)
TObject assignment operator.
virtual TMatrixTSparse< Element > & RandomizePD(Element alpha, Element beta, Double_t &seed)
randomize matrix element values but keep matrix symmetric positive definite
TMatrixTSparse< Element > & Add(TMatrixTSparse< Element > &target, Element scalar, const TMatrixTSparse< Element > &source)
Modify addition: target += scalar * source.
void Error(const char *location, const char *msgfmt,...)
TMatrixTSparse< Element > & operator-=(Element val)
Subtract val from every element of the matrix.
virtual TMatrixTBase< Element > & Zero()
Set matrix elements to zero.
virtual const Int_t * GetRowIndexArray() const
Double_t length(const TVector2 &v)
static void DoubleLexSort(Int_t n, Int_t *first, Int_t *second, Element *data)
default kTRUE, when Use array kFALSE
virtual Element ColNorm() const
Column matrix norm, MAX{ SUM{ |M(i,j)|, over i}, over j}.
template TMatrixDSparse & ElementDiv< Double_t >(TMatrixDSparse &target, const TMatrixDSparse &source)
TMatrixTSparse< Element > & operator*=(Element val)
Multiply every element of the matrix with val.
TMatrixTSparse< Element > & SetSparseIndex(Int_t nelem_new)
Increase/decrease the number of non-zero elements to nelems_new.
TMatrixTSparse< Element > operator+(const TMatrixTSparse< Element > &source1, const TMatrixTSparse< Element > &source2)
virtual const Element * GetMatrixArray() const
R__EXTERN Int_t gMatrixCheck
void Allocate(Int_t nrows, Int_t ncols, Int_t row_lwb=0, Int_t col_lwb=0, Int_t init=0, Int_t nr_nonzeros=0)
Allocate new matrix.
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
TMatrixTSparse< Element > & ElementDiv(TMatrixTSparse< Element > &target, const TMatrixTSparse< Element > &source)
Divide target by the source, element-by-element.
templateClassImp(TMatrixTSparse) template< class Element > TMatrixTSparse< Element >
Space is allocated for row/column indices and data, but the sparse structure information has still to...
TMatrixTSparse< Element > & Use(Int_t row_lwb, Int_t row_upb, Int_t col_lwb, Int_t col_upb, Int_t nr_nonzeros, Int_t *pRowIndex, Int_t *pColIndex, Element *pData)
Element operator()(Int_t rown, Int_t coln) const
TMatrixTSparse< Element > & SetSparseIndexAB(const TMatrixTSparse< Element > &a, const TMatrixTSparse< Element > &b)
Set the row/column indices to the "sum" of matrices a and b It is checked that enough space has been ...
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
template Bool_t AreCompatible< Double_t >(const TMatrixDSparse &m1, const TMatrixDSparse &m2, Int_t verbose)
TCppObject_t Allocate(TCppType_t type)
virtual const Int_t * GetColIndexArray() const
virtual TMatrixTBase< Element > & ResizeTo(Int_t nrows, Int_t ncols, Int_t nr_nonzeros=-1)
Set size of the matrix to nrows x ncols with nr_nonzeros non-zero entries if nr_nonzeros > 0 ...
TMatrixTSparse< Element > & operator+=(Element val)
Add val to every element of the matrix.
Short_t Max(Short_t a, Short_t b)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
void AMultBt(const Element *const ap, Int_t na, Int_t ncolsa, const Element *const bp, Int_t nb, Int_t ncolsb, Element *cp)
Elementary routine to calculate matrix multiplication A*B^T.
virtual void ExtractRow(Int_t row, Int_t col, Element *v, Int_t n=-1) const
Store in array v, n matrix elements of row rown starting at column coln.
virtual TMatrixTBase< Element > & GetSub(Int_t row_lwb, Int_t row_upb, Int_t col_lwb, Int_t col_upb, TMatrixTBase< Element > &target, Option_t *option="S") const
Get submatrix [row_lwb..row_upb][col_lwb..col_upb]; The indexing range of the returned matrix depends...
TMatrixTSparse< Element > & operator=(const TMatrixT< Element > &source)
Notice that the sparsity of the matrix is NOT changed : its fRowIndex/fColIndex are used ! ...
Double_t Sqrt(Double_t x)
Long64_t LocMin(Long64_t n, const T *a)
TMatrixTSparse< Element > operator-(const TMatrixTSparse< Element > &source1, const TMatrixTSparse< Element > &source2)
void APlusB(const TMatrixTSparse< Element > &a, const TMatrixTSparse< Element > &b, Int_t constr=0)
General matrix addition.
double norm(double *x, double *p)
Double_t Drand(Double_t &ix)
Random number generator [0....1] with seed ix.
TMatrixTSparse< Element > operator*(const TMatrixTSparse< Element > &source1, const TMatrixTSparse< Element > &source2)
Long64_t BinarySearch(Long64_t n, const T *array, T value)
virtual TMatrixTBase< Element > & SetSub(Int_t row_lwb, Int_t col_lwb, const TMatrixTBase< Element > &source)
Insert matrix source starting at [row_lwb][col_lwb], thereby overwriting the part [row_lwb...
virtual const Int_t * GetColIndexArray() const =0
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual const Int_t * GetRowIndexArray() const =0