85 templateClassImp(TMatrixTSparse);
92 template<
class Element>
93 TMatrixTSparse<Element>::TMatrixTSparse(Int_t no_rows,Int_t no_cols)
95 Allocate(no_rows,no_cols,0,0,1);
102 template<
class Element>
103 TMatrixTSparse<Element>::TMatrixTSparse(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb)
105 Allocate(row_upb-row_lwb+1,col_upb-col_lwb+1,row_lwb,col_lwb,1);
112 template<
class Element>
113 TMatrixTSparse<Element>::TMatrixTSparse(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,
114 Int_t nr,Int_t *row, Int_t *col,Element *data)
116 const Int_t irowmin = TMath::LocMin(nr,row);
117 const Int_t irowmax = TMath::LocMax(nr,row);
118 const Int_t icolmin = TMath::LocMin(nr,col);
119 const Int_t icolmax = TMath::LocMax(nr,col);
121 if (row[irowmin] < row_lwb || row[irowmax] > row_upb) {
122 Error(
"TMatrixTSparse",
"Inconsistency between row index and its range");
123 if (row[irowmin] < row_lwb) {
124 Info(
"TMatrixTSparse",
"row index lower bound adjusted to %d",row[irowmin]);
125 row_lwb = row[irowmin];
127 if (row[irowmax] > row_upb) {
128 Info(
"TMatrixTSparse",
"row index upper bound adjusted to %d",row[irowmax]);
129 col_lwb = col[irowmax];
132 if (col[icolmin] < col_lwb || col[icolmax] > col_upb) {
133 Error(
"TMatrixTSparse",
"Inconsistency between column index and its range");
134 if (col[icolmin] < col_lwb) {
135 Info(
"TMatrixTSparse",
"column index lower bound adjusted to %d",col[icolmin]);
136 col_lwb = col[icolmin];
138 if (col[icolmax] > col_upb) {
139 Info(
"TMatrixTSparse",
"column index upper bound adjusted to %d",col[icolmax]);
140 col_upb = col[icolmax];
144 Allocate(row_upb-row_lwb+1,col_upb-col_lwb+1,row_lwb,col_lwb,1,nr);
146 SetMatrixArray(nr,row,col,data);
151 template<
class Element>
152 TMatrixTSparse<Element>::TMatrixTSparse(
const TMatrixTSparse<Element> &another) : TMatrixTBase<Element>(another)
154 Allocate(another.GetNrows(),another.GetNcols(),another.GetRowLwb(),another.GetColLwb(),1,
155 another.GetNoElements());
156 memcpy(fRowIndex,another.GetRowIndexArray(),this->fNrowIndex*
sizeof(Int_t));
157 memcpy(fColIndex,another.GetColIndexArray(),this->fNelems*
sizeof(Int_t));
164 template<
class Element>
165 TMatrixTSparse<Element>::TMatrixTSparse(
const TMatrixT<Element> &another) : TMatrixTBase<Element>(another)
167 const Int_t nr_nonzeros = another.NonZeros();
168 Allocate(another.GetNrows(),another.GetNcols(),another.GetRowLwb(),another.GetColLwb(),1,nr_nonzeros);
169 SetSparseIndex(another);
177 template<
class Element>
178 TMatrixTSparse<Element>::TMatrixTSparse(EMatrixCreatorsOp1 op,
const TMatrixTSparse<Element> &prototype)
180 R__ASSERT(prototype.IsValid());
182 Int_t nr_nonzeros = 0;
187 Allocate(prototype.GetNrows(),prototype.GetNcols(),
188 prototype.GetRowLwb(),prototype.GetColLwb(),1,nr_nonzeros);
193 const Int_t nrows = prototype.GetNrows();
194 const Int_t ncols = prototype.GetNcols();
195 const Int_t rowLwb = prototype.GetRowLwb();
196 const Int_t colLwb = prototype.GetColLwb();
197 for (Int_t i = rowLwb; i <= rowLwb+nrows-1; i++)
198 for (Int_t j = colLwb; j <= colLwb+ncols-1; j++)
199 if (i==j) nr_nonzeros++;
200 Allocate(nrows,ncols,rowLwb,colLwb,1,nr_nonzeros);
206 Allocate(prototype.GetNcols(), prototype.GetNrows(),
207 prototype.GetColLwb(),prototype.GetRowLwb(),1,prototype.GetNoElements());
208 Transpose(prototype);
213 const TMatrixTSparse<Element> at(TMatrixTSparse<Element>::kTransposed,prototype);
219 Error(
"TMatrixTSparse(EMatrixCreatorOp1)",
"operation %d not yet implemented", op);
227 template<
class Element>
228 TMatrixTSparse<Element>::TMatrixTSparse(
const TMatrixTSparse<Element> &a,EMatrixCreatorsOp2 op,
const TMatrixTSparse<Element> &b)
230 R__ASSERT(a.IsValid());
231 R__ASSERT(b.IsValid());
251 Error(
"TMatrixTSparse(EMatrixCreatorOp2)",
"operation %d not yet implemented",op);
259 template<
class Element>
260 TMatrixTSparse<Element>::TMatrixTSparse(
const TMatrixTSparse<Element> &a,EMatrixCreatorsOp2 op,
const TMatrixT<Element> &b)
262 R__ASSERT(a.IsValid());
263 R__ASSERT(b.IsValid());
283 Error(
"TMatrixTSparse(EMatrixCreatorOp2)",
"operation %d not yet implemented",op);
291 template<
class Element>
292 TMatrixTSparse<Element>::TMatrixTSparse(
const TMatrixT<Element> &a,EMatrixCreatorsOp2 op,
const TMatrixTSparse<Element> &b)
294 R__ASSERT(a.IsValid());
295 R__ASSERT(b.IsValid());
315 Error(
"TMatrixTSparse(EMatrixCreatorOp2)",
"operation %d not yet implemented",op);
324 template<
class Element>
325 void TMatrixTSparse<Element>::Allocate(Int_t no_rows,Int_t no_cols,Int_t row_lwb,Int_t col_lwb,
326 Int_t init,Int_t nr_nonzeros)
328 if ( (nr_nonzeros > 0 && (no_rows == 0 || no_cols == 0)) ||
329 (no_rows < 0 || no_cols < 0 || nr_nonzeros < 0) )
331 Error(
"Allocate",
"no_rows=%d no_cols=%d non_zeros=%d",no_rows,no_cols,nr_nonzeros);
337 this->fNrows = no_rows;
338 this->fNcols = no_cols;
339 this->fRowLwb = row_lwb;
340 this->fColLwb = col_lwb;
341 this->fNrowIndex = this->fNrows+1;
342 this->fNelems = nr_nonzeros;
343 this->fIsOwner = kTRUE;
344 this->fTol = std::numeric_limits<Element>::epsilon();
346 fRowIndex =
new Int_t[this->fNrowIndex];
348 memset(fRowIndex,0,this->fNrowIndex*
sizeof(Int_t));
350 if (this->fNelems > 0) {
351 fElements =
new Element[this->fNelems];
352 fColIndex =
new Int_t [this->fNelems];
354 memset(fElements,0,this->fNelems*
sizeof(Element));
355 memset(fColIndex,0,this->fNelems*
sizeof(Int_t));
366 template<
class Element>
367 TMatrixTBase<Element> &TMatrixTSparse<Element>::InsertRow(Int_t rown,Int_t coln,
const Element *v,Int_t n)
369 const Int_t arown = rown-this->fRowLwb;
370 const Int_t acoln = coln-this->fColLwb;
371 const Int_t nr = (n > 0) ? n : this->fNcols;
374 if (arown >= this->fNrows || arown < 0) {
375 Error(
"InsertRow",
"row %d out of matrix range",rown);
379 if (acoln >= this->fNcols || acoln < 0) {
380 Error(
"InsertRow",
"column %d out of matrix range",coln);
384 if (acoln+nr > this->fNcols || nr < 0) {
385 Error(
"InsertRow",
"row length %d out of range",nr);
390 const Int_t sIndex = fRowIndex[arown];
391 const Int_t eIndex = fRowIndex[arown+1];
398 Int_t lIndex = sIndex-1;
399 Int_t rIndex = sIndex-1;
401 for (index = sIndex; index < eIndex; index++) {
402 const Int_t icol = fColIndex[index];
404 if (icol >= acoln+nr)
break;
405 if (icol >= acoln) nslots++;
409 const Int_t nelems_old = this->fNelems;
410 const Int_t *colIndex_old = fColIndex;
411 const Element *elements_old = fElements;
413 const Int_t ndiff = nr-nslots;
414 this->fNelems += ndiff;
415 fColIndex =
new Int_t[this->fNelems];
416 fElements =
new Element[this->fNelems];
418 for (Int_t irow = arown+1; irow < this->fNrows+1; irow++)
419 fRowIndex[irow] += ndiff;
422 memmove(fColIndex,colIndex_old,(lIndex+1)*
sizeof(Int_t));
423 memmove(fElements,elements_old,(lIndex+1)*
sizeof(Element));
426 if (nelems_old > 0 && nelems_old-rIndex > 0) {
427 memmove(fColIndex+rIndex+ndiff,colIndex_old+rIndex,(nelems_old-rIndex)*
sizeof(Int_t));
428 memmove(fElements+rIndex+ndiff,elements_old+rIndex,(nelems_old-rIndex)*
sizeof(Element));
432 for (Int_t i = 0; i < nr; i++) {
433 fColIndex[index] = acoln+i;
434 fElements[index] = v[i];
438 if (colIndex_old)
delete [] (Int_t*) colIndex_old;
439 if (elements_old)
delete [] (Element*) elements_old;
441 R__ASSERT(this->fNelems == fRowIndex[this->fNrowIndex-1]);
449 template<
class Element>
450 void TMatrixTSparse<Element>::ExtractRow(Int_t rown, Int_t coln, Element *v,Int_t n)
const
452 const Int_t arown = rown-this->fRowLwb;
453 const Int_t acoln = coln-this->fColLwb;
454 const Int_t nr = (n > 0) ? n : this->fNcols;
457 if (arown >= this->fNrows || arown < 0) {
458 Error(
"ExtractRow",
"row %d out of matrix range",rown);
462 if (acoln >= this->fNcols || acoln < 0) {
463 Error(
"ExtractRow",
"column %d out of matrix range",coln);
467 if (acoln+nr > this->fNcols || nr < 0) {
468 Error(
"ExtractRow",
"row length %d out of range",nr);
473 const Int_t sIndex = fRowIndex[arown];
474 const Int_t eIndex = fRowIndex[arown+1];
476 memset(v,0,nr*
sizeof(Element));
477 const Int_t *
const pColIndex = GetColIndexArray();
478 const Element *
const pData = GetMatrixArray();
479 for (Int_t index = sIndex; index < eIndex; index++) {
480 const Int_t icol = pColIndex[index];
481 if (icol < acoln || icol >= acoln+nr)
continue;
482 v[icol-acoln] = pData[index];
490 template<
class Element>
491 void TMatrixTSparse<Element>::AMultBt(
const TMatrixTSparse<Element> &a,
const TMatrixTSparse<Element> &b,Int_t constr)
494 R__ASSERT(a.IsValid());
495 R__ASSERT(b.IsValid());
497 if (a.GetNcols() != b.GetNcols() || a.GetColLwb() != b.GetColLwb()) {
498 Error(
"AMultBt",
"A and B columns incompatible");
502 if (!constr && this->GetMatrixArray() == a.GetMatrixArray()) {
503 Error(
"AMultB",
"this = &a");
507 if (!constr && this->GetMatrixArray() == b.GetMatrixArray()) {
508 Error(
"AMultB",
"this = &b");
513 const Int_t *
const pRowIndexa = a.GetRowIndexArray();
514 const Int_t *
const pColIndexa = a.GetColIndexArray();
515 const Int_t *
const pRowIndexb = b.GetRowIndexArray();
516 const Int_t *
const pColIndexb = b.GetColIndexArray();
524 Int_t nr_nonzero_rowa = 0;
526 for (Int_t irowa = 0; irowa < a.GetNrows(); irowa++)
527 if (pRowIndexa[irowa] < pRowIndexa[irowa+1])
530 Int_t nr_nonzero_rowb = 0;
532 for (Int_t irowb = 0; irowb < b.GetNrows(); irowb++)
533 if (pRowIndexb[irowb] < pRowIndexb[irowb+1])
537 const Int_t nc = nr_nonzero_rowa*nr_nonzero_rowb;
538 Allocate(a.GetNrows(),b.GetNrows(),a.GetRowLwb(),b.GetRowLwb(),1,nc);
540 pRowIndexc = this->GetRowIndexArray();
541 pColIndexc = this->GetColIndexArray();
545 for (Int_t irowa = 0; irowa < a.GetNrows(); irowa++) {
546 pRowIndexc[irowa+1] = pRowIndexc[irowa];
547 if (pRowIndexa[irowa] >= pRowIndexa[irowa+1])
continue;
548 for (Int_t irowb = 0; irowb < b.GetNrows(); irowb++) {
549 if (pRowIndexb[irowb] >= pRowIndexb[irowb+1])
continue;
550 pRowIndexc[irowa+1]++;
551 pColIndexc[ielem++] = irowb;
555 pRowIndexc = this->GetRowIndexArray();
556 pColIndexc = this->GetColIndexArray();
559 const Element *
const pDataa = a.GetMatrixArray();
560 const Element *
const pDatab = b.GetMatrixArray();
561 Element *
const pDatac = this->GetMatrixArray();
563 for (Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
564 const Int_t sIndexa = pRowIndexa[irowc];
565 const Int_t eIndexa = pRowIndexa[irowc+1];
566 for (Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
567 const Int_t sIndexb = pRowIndexb[icolc];
568 const Int_t eIndexb = pRowIndexb[icolc+1];
570 Int_t indexb = sIndexb;
571 for (Int_t indexa = sIndexa; indexa < eIndexa && indexb < eIndexb; indexa++) {
572 const Int_t icola = pColIndexa[indexa];
573 while (indexb < eIndexb && pColIndexb[indexb] <= icola) {
574 if (icola == pColIndexb[indexb]) {
575 sum += pDataa[indexa]*pDatab[indexb];
582 pColIndexc[indexc_r] = icolc;
583 pDatac[indexc_r] = sum;
587 pRowIndexc[irowc+1] = indexc_r;
591 SetSparseIndex(indexc_r);
598 template<
class Element>
599 void TMatrixTSparse<Element>::AMultBt(
const TMatrixTSparse<Element> &a,
const TMatrixT<Element> &b,Int_t constr)
602 R__ASSERT(a.IsValid());
603 R__ASSERT(b.IsValid());
605 if (a.GetNcols() != b.GetNcols() || a.GetColLwb() != b.GetColLwb()) {
606 Error(
"AMultBt",
"A and B columns incompatible");
610 if (!constr && this->GetMatrixArray() == a.GetMatrixArray()) {
611 Error(
"AMultB",
"this = &a");
615 if (!constr && this->GetMatrixArray() == b.GetMatrixArray()) {
616 Error(
"AMultB",
"this = &b");
621 const Int_t *
const pRowIndexa = a.GetRowIndexArray();
622 const Int_t *
const pColIndexa = a.GetColIndexArray();
630 Int_t nr_nonzero_rowa = 0;
632 for (Int_t irowa = 0; irowa < a.GetNrows(); irowa++)
633 if (pRowIndexa[irowa] < pRowIndexa[irowa+1])
636 Int_t nr_nonzero_rowb = b.GetNrows();
638 const Int_t nc = nr_nonzero_rowa*nr_nonzero_rowb;
639 Allocate(a.GetNrows(),b.GetNrows(),a.GetRowLwb(),b.GetRowLwb(),1,nc);
641 pRowIndexc = this->GetRowIndexArray();
642 pColIndexc = this->GetColIndexArray();
646 for (Int_t irowa = 0; irowa < a.GetNrows(); irowa++) {
647 pRowIndexc[irowa+1] = pRowIndexc[irowa];
648 for (Int_t irowb = 0; irowb < b.GetNrows(); irowb++) {
649 pRowIndexc[irowa+1]++;
650 pColIndexc[ielem++] = irowb;
654 pRowIndexc = this->GetRowIndexArray();
655 pColIndexc = this->GetColIndexArray();
658 const Element *
const pDataa = a.GetMatrixArray();
659 const Element *
const pDatab = b.GetMatrixArray();
660 Element *
const pDatac = this->GetMatrixArray();
662 for (Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
663 const Int_t sIndexa = pRowIndexa[irowc];
664 const Int_t eIndexa = pRowIndexa[irowc+1];
665 for (Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
666 const Int_t off = icolc*b.GetNcols();
668 for (Int_t indexa = sIndexa; indexa < eIndexa; indexa++) {
669 const Int_t icola = pColIndexa[indexa];
670 sum += pDataa[indexa]*pDatab[off+icola];
673 pColIndexc[indexc_r] = icolc;
674 pDatac[indexc_r] = sum;
678 pRowIndexc[irowc+1]= indexc_r;
682 SetSparseIndex(indexc_r);
689 template<
class Element>
690 void TMatrixTSparse<Element>::AMultBt(
const TMatrixT<Element> &a,
const TMatrixTSparse<Element> &b,Int_t constr)
693 R__ASSERT(a.IsValid());
694 R__ASSERT(b.IsValid());
696 if (a.GetNcols() != b.GetNcols() || a.GetColLwb() != b.GetColLwb()) {
697 Error(
"AMultBt",
"A and B columns incompatible");
701 if (!constr && this->GetMatrixArray() == a.GetMatrixArray()) {
702 Error(
"AMultB",
"this = &a");
706 if (!constr && this->GetMatrixArray() == b.GetMatrixArray()) {
707 Error(
"AMultB",
"this = &b");
712 const Int_t *
const pRowIndexb = b.GetRowIndexArray();
713 const Int_t *
const pColIndexb = b.GetColIndexArray();
721 Int_t nr_nonzero_rowa = a.GetNrows();
722 Int_t nr_nonzero_rowb = 0;
724 for (Int_t irowb = 0; irowb < b.GetNrows(); irowb++)
725 if (pRowIndexb[irowb] < pRowIndexb[irowb+1])
729 const Int_t nc = nr_nonzero_rowa*nr_nonzero_rowb;
730 Allocate(a.GetNrows(),b.GetNrows(),a.GetRowLwb(),b.GetRowLwb(),1,nc);
732 pRowIndexc = this->GetRowIndexArray();
733 pColIndexc = this->GetColIndexArray();
737 for (Int_t irowa = 0; irowa < a.GetNrows(); irowa++) {
738 pRowIndexc[irowa+1] = pRowIndexc[irowa];
739 for (Int_t irowb = 0; irowb < b.GetNrows(); irowb++) {
740 if (pRowIndexb[irowb] >= pRowIndexb[irowb+1])
continue;
741 pRowIndexc[irowa+1]++;
742 pColIndexc[ielem++] = irowb;
746 pRowIndexc = this->GetRowIndexArray();
747 pColIndexc = this->GetColIndexArray();
750 const Element *
const pDataa = a.GetMatrixArray();
751 const Element *
const pDatab = b.GetMatrixArray();
752 Element *
const pDatac = this->GetMatrixArray();
754 for (Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
755 const Int_t off = irowc*a.GetNcols();
756 for (Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
757 const Int_t sIndexb = pRowIndexb[icolc];
758 const Int_t eIndexb = pRowIndexb[icolc+1];
760 for (Int_t indexb = sIndexb; indexb < eIndexb; indexb++) {
761 const Int_t icolb = pColIndexb[indexb];
762 sum += pDataa[off+icolb]*pDatab[indexb];
765 pColIndexc[indexc_r] = icolc;
766 pDatac[indexc_r] = sum;
770 pRowIndexc[irowc+1] = indexc_r;
774 SetSparseIndex(indexc_r);
781 template<
class Element>
782 void TMatrixTSparse<Element>::APlusB(
const TMatrixTSparse<Element> &a,
const TMatrixTSparse<Element> &b,Int_t constr)
785 R__ASSERT(a.IsValid());
786 R__ASSERT(b.IsValid());
788 if (a.GetNrows() != b.GetNrows() || a.GetNcols() != b.GetNcols() ||
789 a.GetRowLwb() != b.GetRowLwb() || a.GetColLwb() != b.GetColLwb()) {
790 Error(
"APlusB(const TMatrixTSparse &,const TMatrixTSparse &",
"matrices not compatible");
794 if (!constr && this->GetMatrixArray() == a.GetMatrixArray()) {
795 Error(
"APlusB",
"this = &a");
799 if (!constr && this->GetMatrixArray() == b.GetMatrixArray()) {
800 Error(
"APlusB",
"this = &b");
805 const Int_t *
const pRowIndexa = a.GetRowIndexArray();
806 const Int_t *
const pRowIndexb = b.GetRowIndexArray();
807 const Int_t *
const pColIndexa = a.GetColIndexArray();
808 const Int_t *
const pColIndexb = b.GetColIndexArray();
811 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb());
812 SetSparseIndexAB(a,b);
815 Int_t *
const pRowIndexc = this->GetRowIndexArray();
816 Int_t *
const pColIndexc = this->GetColIndexArray();
818 const Element *
const pDataa = a.GetMatrixArray();
819 const Element *
const pDatab = b.GetMatrixArray();
820 Element *
const pDatac = this->GetMatrixArray();
822 for (Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
823 const Int_t sIndexa = pRowIndexa[irowc];
824 const Int_t eIndexa = pRowIndexa[irowc+1];
825 const Int_t sIndexb = pRowIndexb[irowc];
826 const Int_t eIndexb = pRowIndexb[irowc+1];
827 Int_t indexa = sIndexa;
828 Int_t indexb = sIndexb;
829 for (Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
831 while (indexa < eIndexa && pColIndexa[indexa] <= icolc) {
832 if (icolc == pColIndexa[indexa]) {
833 sum += pDataa[indexa];
838 while (indexb < eIndexb && pColIndexb[indexb] <= icolc) {
839 if (icolc == pColIndexb[indexb]) {
840 sum += pDatab[indexb];
847 pColIndexc[indexc_r] = icolc;
848 pDatac[indexc_r] = sum;
852 pRowIndexc[irowc+1] = indexc_r;
856 SetSparseIndex(indexc_r);
863 template<
class Element>
864 void TMatrixTSparse<Element>::APlusB(
const TMatrixTSparse<Element> &a,
const TMatrixT<Element> &b,Int_t constr)
867 R__ASSERT(a.IsValid());
868 R__ASSERT(b.IsValid());
870 if (a.GetNrows() != b.GetNrows() || a.GetNcols() != b.GetNcols() ||
871 a.GetRowLwb() != b.GetRowLwb() || a.GetColLwb() != b.GetColLwb()) {
872 Error(
"APlusB(const TMatrixTSparse &,const TMatrixT &",
"matrices not compatible");
876 if (!constr && this->GetMatrixArray() == a.GetMatrixArray()) {
877 Error(
"APlusB",
"this = &a");
881 if (!constr && this->GetMatrixArray() == b.GetMatrixArray()) {
882 Error(
"APlusB",
"this = &b");
888 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb());
889 SetSparseIndexAB(a,b);
892 Int_t *
const pRowIndexc = this->GetRowIndexArray();
893 Int_t *
const pColIndexc = this->GetColIndexArray();
895 const Int_t *
const pRowIndexa = a.GetRowIndexArray();
896 const Int_t *
const pColIndexa = a.GetColIndexArray();
898 const Element *
const pDataa = a.GetMatrixArray();
899 const Element *
const pDatab = b.GetMatrixArray();
900 Element *
const pDatac = this->GetMatrixArray();
902 for (Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
903 const Int_t sIndexa = pRowIndexa[irowc];
904 const Int_t eIndexa = pRowIndexa[irowc+1];
905 const Int_t off = irowc*this->GetNcols();
906 Int_t indexa = sIndexa;
907 for (Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
908 Element sum = pDatab[off+icolc];
909 while (indexa < eIndexa && pColIndexa[indexa] <= icolc) {
910 if (icolc == pColIndexa[indexa]) {
911 sum += pDataa[indexa];
918 pColIndexc[indexc_r] = icolc;
919 pDatac[indexc_r] = sum;
923 pRowIndexc[irowc+1] = indexc_r;
927 SetSparseIndex(indexc_r);
934 template<
class Element>
935 void TMatrixTSparse<Element>::AMinusB(
const TMatrixTSparse<Element> &a,
const TMatrixTSparse<Element> &b,Int_t constr)
938 R__ASSERT(a.IsValid());
939 R__ASSERT(b.IsValid());
941 if (a.GetNrows() != b.GetNrows() || a.GetNcols() != b.GetNcols() ||
942 a.GetRowLwb() != b.GetRowLwb() || a.GetColLwb() != b.GetColLwb()) {
943 Error(
"AMinusB(const TMatrixTSparse &,const TMatrixTSparse &",
"matrices not compatible");
947 if (!constr && this->GetMatrixArray() == a.GetMatrixArray()) {
948 Error(
"AMinusB",
"this = &a");
952 if (!constr && this->GetMatrixArray() == b.GetMatrixArray()) {
953 Error(
"AMinusB",
"this = &b");
958 const Int_t *
const pRowIndexa = a.GetRowIndexArray();
959 const Int_t *
const pRowIndexb = b.GetRowIndexArray();
960 const Int_t *
const pColIndexa = a.GetColIndexArray();
961 const Int_t *
const pColIndexb = b.GetColIndexArray();
964 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb());
965 SetSparseIndexAB(a,b);
968 Int_t *
const pRowIndexc = this->GetRowIndexArray();
969 Int_t *
const pColIndexc = this->GetColIndexArray();
971 const Element *
const pDataa = a.GetMatrixArray();
972 const Element *
const pDatab = b.GetMatrixArray();
973 Element *
const pDatac = this->GetMatrixArray();
975 for (Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
976 const Int_t sIndexa = pRowIndexa[irowc];
977 const Int_t eIndexa = pRowIndexa[irowc+1];
978 const Int_t sIndexb = pRowIndexb[irowc];
979 const Int_t eIndexb = pRowIndexb[irowc+1];
980 Int_t indexa = sIndexa;
981 Int_t indexb = sIndexb;
982 for (Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
984 while (indexa < eIndexa && pColIndexa[indexa] <= icolc) {
985 if (icolc == pColIndexa[indexa]) {
986 sum += pDataa[indexa];
991 while (indexb < eIndexb && pColIndexb[indexb] <= icolc) {
992 if (icolc == pColIndexb[indexb]) {
993 sum -= pDatab[indexb];
1000 pColIndexc[indexc_r] = icolc;
1001 pDatac[indexc_r] = sum;
1005 pRowIndexc[irowc+1] = indexc_r;
1009 SetSparseIndex(indexc_r);
1016 template<
class Element>
1017 void TMatrixTSparse<Element>::AMinusB(
const TMatrixTSparse<Element> &a,
const TMatrixT<Element> &b,Int_t constr)
1020 R__ASSERT(a.IsValid());
1021 R__ASSERT(b.IsValid());
1023 if (a.GetNrows() != b.GetNrows() || a.GetNcols() != b.GetNcols() ||
1024 a.GetRowLwb() != b.GetRowLwb() || a.GetColLwb() != b.GetColLwb()) {
1025 Error(
"AMinusB(const TMatrixTSparse &,const TMatrixT &",
"matrices not compatible");
1029 if (!constr && this->GetMatrixArray() == a.GetMatrixArray()) {
1030 Error(
"AMinusB",
"this = &a");
1034 if (!constr && this->GetMatrixArray() == b.GetMatrixArray()) {
1035 Error(
"AMinusB",
"this = &b");
1041 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb());
1042 SetSparseIndexAB(a,b);
1045 Int_t *
const pRowIndexc = this->GetRowIndexArray();
1046 Int_t *
const pColIndexc = this->GetColIndexArray();
1048 const Int_t *
const pRowIndexa = a.GetRowIndexArray();
1049 const Int_t *
const pColIndexa = a.GetColIndexArray();
1051 const Element *
const pDataa = a.GetMatrixArray();
1052 const Element *
const pDatab = b.GetMatrixArray();
1053 Element *
const pDatac = this->GetMatrixArray();
1055 for (Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
1056 const Int_t sIndexa = pRowIndexa[irowc];
1057 const Int_t eIndexa = pRowIndexa[irowc+1];
1058 const Int_t off = irowc*this->GetNcols();
1059 Int_t indexa = sIndexa;
1060 for (Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
1061 Element sum = -pDatab[off+icolc];
1062 while (indexa < eIndexa && pColIndexa[indexa] <= icolc) {
1063 if (icolc == pColIndexa[indexa]) {
1064 sum += pDataa[indexa];
1071 pColIndexc[indexc_r] = icolc;
1072 pDatac[indexc_r] = sum;
1076 pRowIndexc[irowc+1] = indexc_r;
1080 SetSparseIndex(indexc_r);
1087 template<
class Element>
1088 void TMatrixTSparse<Element>::AMinusB(
const TMatrixT<Element> &a,
const TMatrixTSparse<Element> &b,Int_t constr)
1091 R__ASSERT(a.IsValid());
1092 R__ASSERT(b.IsValid());
1094 if (a.GetNrows() != b.GetNrows() || a.GetNcols() != b.GetNcols() ||
1095 a.GetRowLwb() != b.GetRowLwb() || a.GetColLwb() != b.GetColLwb()) {
1096 Error(
"AMinusB(const TMatrixT &,const TMatrixTSparse &",
"matrices not compatible");
1100 if (!constr && this->GetMatrixArray() == a.GetMatrixArray()) {
1101 Error(
"AMinusB",
"this = &a");
1105 if (!constr && this->GetMatrixArray() == b.GetMatrixArray()) {
1106 Error(
"AMinusB",
"this = &b");
1112 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb());
1113 SetSparseIndexAB(a,b);
1116 Int_t *
const pRowIndexc = this->GetRowIndexArray();
1117 Int_t *
const pColIndexc = this->GetColIndexArray();
1119 const Int_t *
const pRowIndexb = b.GetRowIndexArray();
1120 const Int_t *
const pColIndexb = b.GetColIndexArray();
1122 const Element *
const pDataa = a.GetMatrixArray();
1123 const Element *
const pDatab = b.GetMatrixArray();
1124 Element *
const pDatac = this->GetMatrixArray();
1126 for (Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
1127 const Int_t sIndexb = pRowIndexb[irowc];
1128 const Int_t eIndexb = pRowIndexb[irowc+1];
1129 const Int_t off = irowc*this->GetNcols();
1130 Int_t indexb = sIndexb;
1131 for (Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
1132 Element sum = pDataa[off+icolc];
1133 while (indexb < eIndexb && pColIndexb[indexb] <= icolc) {
1134 if (icolc == pColIndexb[indexb]) {
1135 sum -= pDatab[indexb];
1142 pColIndexc[indexc_r] = icolc;
1143 pDatac[indexc_r] = sum;
1147 pRowIndexc[irowc+1] = indexc_r;
1151 SetSparseIndex(indexc_r);
1157 template<
class Element>
1158 void TMatrixTSparse<Element>::GetMatrix2Array(Element *data,Option_t * )
const
1160 R__ASSERT(this->IsValid());
1162 const Element *
const elem = GetMatrixArray();
1163 memcpy(data,elem,this->fNelems*
sizeof(Element));
1171 template<
class Element>
1172 TMatrixTBase<Element> &TMatrixTSparse<Element>::SetMatrixArray(Int_t nr,Int_t *row,Int_t *col,Element *data)
1174 R__ASSERT(this->IsValid());
1176 Error(
"SetMatrixArray(Int_t,Int_t*,Int_t*,Element*",
"nr <= 0");
1180 const Int_t irowmin = TMath::LocMin(nr,row);
1181 const Int_t irowmax = TMath::LocMax(nr,row);
1182 const Int_t icolmin = TMath::LocMin(nr,col);
1183 const Int_t icolmax = TMath::LocMax(nr,col);
1185 R__ASSERT(row[irowmin] >= this->fRowLwb && row[irowmax] <= this->fRowLwb+this->fNrows-1);
1186 R__ASSERT(col[icolmin] >= this->fColLwb && col[icolmax] <= this->fColLwb+this->fNcols-1);
1188 if (row[irowmin] < this->fRowLwb || row[irowmax] > this->fRowLwb+this->fNrows-1) {
1189 Error(
"SetMatrixArray",
"Inconsistency between row index and its range");
1190 if (row[irowmin] < this->fRowLwb) {
1191 Info(
"SetMatrixArray",
"row index lower bound adjusted to %d",row[irowmin]);
1192 this->fRowLwb = row[irowmin];
1194 if (row[irowmax] > this->fRowLwb+this->fNrows-1) {
1195 Info(
"SetMatrixArray",
"row index upper bound adjusted to %d",row[irowmax]);
1196 this->fNrows = row[irowmax]-this->fRowLwb+1;
1199 if (col[icolmin] < this->fColLwb || col[icolmax] > this->fColLwb+this->fNcols-1) {
1200 Error(
"SetMatrixArray",
"Inconsistency between column index and its range");
1201 if (col[icolmin] < this->fColLwb) {
1202 Info(
"SetMatrixArray",
"column index lower bound adjusted to %d",col[icolmin]);
1203 this->fColLwb = col[icolmin];
1205 if (col[icolmax] > this->fColLwb+this->fNcols-1) {
1206 Info(
"SetMatrixArray",
"column index upper bound adjusted to %d",col[icolmax]);
1207 this->fNcols = col[icolmax]-this->fColLwb+1;
1211 TMatrixTBase<Element>::DoubleLexSort(nr,row,col,data);
1213 Int_t nr_nonzeros = 0;
1214 const Element *ep = data;
1215 const Element *
const fp = data+nr;
1218 if (*ep++ != 0.0) nr_nonzeros++;
1220 if (nr_nonzeros != this->fNelems) {
1221 if (fColIndex) {
delete [] fColIndex; fColIndex = 0; }
1222 if (fElements) {
delete [] fElements; fElements = 0; }
1223 this->fNelems = nr_nonzeros;
1224 if (this->fNelems > 0) {
1225 fColIndex =
new Int_t[nr_nonzeros];
1226 fElements =
new Element[nr_nonzeros];
1233 if (this->fNelems <= 0)
1239 for (Int_t irow = 1; irow < this->fNrows+1; irow++) {
1240 if (ielem < nr && row[ielem] < irow) {
1241 while (ielem < nr) {
1242 if (data[ielem] != 0.0) {
1243 fColIndex[nr_nonzeros] = col[ielem]-this->fColLwb;
1244 fElements[nr_nonzeros] = data[ielem];
1248 if (ielem >= nr || row[ielem] != row[ielem-1])
1252 fRowIndex[irow] = nr_nonzeros;
1261 template<
class Element>
1262 TMatrixTSparse<Element> &TMatrixTSparse<Element>::SetSparseIndex(Int_t nelems_new)
1264 if (nelems_new != this->fNelems) {
1265 Int_t nr = TMath::Min(nelems_new,this->fNelems);
1266 Int_t *oIp = fColIndex;
1267 fColIndex =
new Int_t[nelems_new];
1269 memmove(fColIndex,oIp,nr*
sizeof(Int_t));
1272 Element *oDp = fElements;
1273 fElements =
new Element[nelems_new];
1275 memmove(fElements,oDp,nr*
sizeof(Element));
1278 this->fNelems = nelems_new;
1279 if (nelems_new > nr) {
1280 memset(fElements+nr,0,(nelems_new-nr)*
sizeof(Element));
1281 memset(fColIndex+nr,0,(nelems_new-nr)*
sizeof(Int_t));
1283 for (Int_t irow = 0; irow < this->fNrowIndex; irow++)
1284 if (fRowIndex[irow] > nelems_new)
1285 fRowIndex[irow] = nelems_new;
1295 template<
class Element>
1296 TMatrixTSparse<Element> &TMatrixTSparse<Element>::SetSparseIndex(
const TMatrixTBase<Element> &source)
1299 R__ASSERT(source.IsValid());
1300 if (this->GetNrows() != source.GetNrows() || this->GetNcols() != source.GetNcols() ||
1301 this->GetRowLwb() != source.GetRowLwb() || this->GetColLwb() != source.GetColLwb()) {
1302 Error(
"SetSparseIndex",
"matrices not compatible");
1307 const Int_t nr_nonzeros = source.NonZeros();
1309 if (nr_nonzeros != this->fNelems)
1310 SetSparseIndex(nr_nonzeros);
1312 if (source.GetRowIndexArray() && source.GetColIndexArray()) {
1313 memmove(fRowIndex,source.GetRowIndexArray(),this->fNrowIndex*
sizeof(Int_t));
1314 memmove(fColIndex,source.GetColIndexArray(),this->fNelems*
sizeof(Int_t));
1316 const Element *ep = source.GetMatrixArray();
1318 for (Int_t irow = 0; irow < this->fNrows; irow++) {
1319 fRowIndex[irow] = nr;
1320 for (Int_t icol = 0; icol < this->fNcols; icol++) {
1322 fColIndex[nr] = icol;
1328 fRowIndex[this->fNrows] = nr;
1338 template<
class Element>
1339 TMatrixTSparse<Element> &TMatrixTSparse<Element>::SetSparseIndexAB(
const TMatrixTSparse<Element> &a,
const TMatrixTSparse<Element> &b)
1342 R__ASSERT(a.IsValid());
1343 R__ASSERT(b.IsValid());
1345 if (a.GetNrows() != b.GetNrows() || a.GetNcols() != b.GetNcols() ||
1346 a.GetRowLwb() != b.GetRowLwb() || a.GetColLwb() != b.GetColLwb()) {
1347 Error(
"SetSparseIndexAB",
"source matrices not compatible");
1351 if (this->GetNrows() != a.GetNrows() || this->GetNcols() != a.GetNcols() ||
1352 this->GetRowLwb() != a.GetRowLwb() || this->GetColLwb() != a.GetColLwb()) {
1353 Error(
"SetSparseIndexAB",
"matrix not compatible with source matrices");
1358 const Int_t *
const pRowIndexa = a.GetRowIndexArray();
1359 const Int_t *
const pRowIndexb = b.GetRowIndexArray();
1360 const Int_t *
const pColIndexa = a.GetColIndexArray();
1361 const Int_t *
const pColIndexb = b.GetColIndexArray();
1365 for (Int_t irowc = 0; irowc < a.GetNrows(); irowc++) {
1366 const Int_t sIndexa = pRowIndexa[irowc];
1367 const Int_t eIndexa = pRowIndexa[irowc+1];
1368 const Int_t sIndexb = pRowIndexb[irowc];
1369 const Int_t eIndexb = pRowIndexb[irowc+1];
1370 nc += eIndexa-sIndexa;
1371 Int_t indexb = sIndexb;
1372 for (Int_t indexa = sIndexa; indexa < eIndexa; indexa++) {
1373 const Int_t icola = pColIndexa[indexa];
1374 for (; indexb < eIndexb; indexb++) {
1375 if (pColIndexb[indexb] >= icola) {
1376 if (pColIndexb[indexb] == icola)
1383 while (indexb < eIndexb) {
1384 const Int_t icola = (eIndexa > sIndexa && eIndexa > 0) ? pColIndexa[eIndexa-1] : -1;
1385 if (pColIndexb[indexb++] > icola)
1391 if (this->NonZeros() != nc)
1394 Int_t *
const pRowIndexc = this->GetRowIndexArray();
1395 Int_t *
const pColIndexc = this->GetColIndexArray();
1399 for (Int_t irowc = 0; irowc < a.GetNrows(); irowc++) {
1400 const Int_t sIndexa = pRowIndexa[irowc];
1401 const Int_t eIndexa = pRowIndexa[irowc+1];
1402 const Int_t sIndexb = pRowIndexb[irowc];
1403 const Int_t eIndexb = pRowIndexb[irowc+1];
1404 Int_t indexb = sIndexb;
1405 for (Int_t indexa = sIndexa; indexa < eIndexa; indexa++) {
1406 const Int_t icola = pColIndexa[indexa];
1407 for (; indexb < eIndexb; indexb++) {
1408 if (pColIndexb[indexb] >= icola) {
1409 if (pColIndexb[indexb] == icola)
1413 pColIndexc[nc++] = pColIndexb[indexb];
1415 pColIndexc[nc++] = pColIndexa[indexa];
1417 while (indexb < eIndexb) {
1418 const Int_t icola = (eIndexa > 0) ? pColIndexa[eIndexa-1] : -1;
1419 if (pColIndexb[indexb++] > icola)
1420 pColIndexc[nc++] = pColIndexb[indexb-1];
1422 pRowIndexc[irowc+1] = nc;
1432 template<
class Element>
1433 TMatrixTSparse<Element> &TMatrixTSparse<Element>::SetSparseIndexAB(
const TMatrixT<Element> &a,
const TMatrixTSparse<Element> &b)
1436 R__ASSERT(a.IsValid());
1437 R__ASSERT(b.IsValid());
1439 if (a.GetNrows() != b.GetNrows() || a.GetNcols() != b.GetNcols() ||
1440 a.GetRowLwb() != b.GetRowLwb() || a.GetColLwb() != b.GetColLwb()) {
1441 Error(
"SetSparseIndexAB",
"source matrices not compatible");
1445 if (this->GetNrows() != a.GetNrows() || this->GetNcols() != a.GetNcols() ||
1446 this->GetRowLwb() != a.GetRowLwb() || this->GetColLwb() != a.GetColLwb()) {
1447 Error(
"SetSparseIndexAB",
"matrix not compatible with source matrices");
1452 const Element *
const pDataa = a.GetMatrixArray();
1454 const Int_t *
const pRowIndexb = b.GetRowIndexArray();
1455 const Int_t *
const pColIndexb = b.GetColIndexArray();
1458 Int_t nc = a.NonZeros();
1459 for (Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
1460 const Int_t sIndexb = pRowIndexb[irowc];
1461 const Int_t eIndexb = pRowIndexb[irowc+1];
1462 const Int_t off = irowc*this->GetNcols();
1463 Int_t indexb = sIndexb;
1464 for (Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
1465 if (pDataa[off+icolc] != 0.0 || pColIndexb[indexb] > icolc)
continue;
1466 for (; indexb < eIndexb; indexb++) {
1467 if (pColIndexb[indexb] >= icolc) {
1468 if (pColIndexb[indexb] == icolc) {
1479 if (this->NonZeros() != nc)
1482 Int_t *
const pRowIndexc = this->GetRowIndexArray();
1483 Int_t *
const pColIndexc = this->GetColIndexArray();
1487 for (Int_t irowc = 0; irowc < this->GetNrows(); irowc++) {
1488 const Int_t sIndexb = pRowIndexb[irowc];
1489 const Int_t eIndexb = pRowIndexb[irowc+1];
1490 const Int_t off = irowc*this->GetNcols();
1491 Int_t indexb = sIndexb;
1492 for (Int_t icolc = 0; icolc < this->GetNcols(); icolc++) {
1493 if (pDataa[off+icolc] != 0.0)
1494 pColIndexc[nc++] = icolc;
1495 else if (pColIndexb[indexb] <= icolc) {
1496 for (; indexb < eIndexb; indexb++) {
1497 if (pColIndexb[indexb] >= icolc) {
1498 if (pColIndexb[indexb] == icolc)
1499 pColIndexc[nc++] = pColIndexb[indexb++];
1505 pRowIndexc[irowc+1] = nc;
1517 template<
class Element>
1518 TMatrixTBase<Element> &TMatrixTSparse<Element>::ResizeTo(Int_t nrows,Int_t ncols,Int_t nr_nonzeros)
1520 R__ASSERT(this->IsValid());
1521 if (!this->fIsOwner) {
1522 Error(
"ResizeTo(Int_t,Int_t,Int_t)",
"Not owner of data array,cannot resize");
1526 if (this->fNelems > 0) {
1527 if (this->fNrows == nrows && this->fNcols == ncols &&
1528 (this->fNelems == nr_nonzeros || nr_nonzeros < 0))
1530 else if (nrows == 0 || ncols == 0 || nr_nonzeros == 0) {
1531 this->fNrows = nrows; this->fNcols = ncols;
1536 const Element *elements_old = GetMatrixArray();
1537 const Int_t *rowIndex_old = GetRowIndexArray();
1538 const Int_t *colIndex_old = GetColIndexArray();
1540 Int_t nrows_old = this->fNrows;
1541 Int_t nrowIndex_old = this->fNrowIndex;
1544 if (nr_nonzeros > 0)
1545 nelems_new = nr_nonzeros;
1548 for (Int_t irow = 0; irow < nrows_old; irow++) {
1549 if (irow >= nrows)
continue;
1550 const Int_t sIndex = rowIndex_old[irow];
1551 const Int_t eIndex = rowIndex_old[irow+1];
1552 for (Int_t index = sIndex; index < eIndex; index++) {
1553 const Int_t icol = colIndex_old[index];
1560 Allocate(nrows,ncols,0,0,1,nelems_new);
1561 R__ASSERT(this->IsValid());
1563 Element *elements_new = GetMatrixArray();
1564 Int_t *rowIndex_new = GetRowIndexArray();
1565 Int_t *colIndex_new = GetColIndexArray();
1567 Int_t nelems_copy = 0;
1568 rowIndex_new[0] = 0;
1569 Bool_t cont = kTRUE;
1570 for (Int_t irow = 0; irow < nrows_old && cont; irow++) {
1571 if (irow >= nrows)
continue;
1572 const Int_t sIndex = rowIndex_old[irow];
1573 const Int_t eIndex = rowIndex_old[irow+1];
1574 for (Int_t index = sIndex; index < eIndex; index++) {
1575 const Int_t icol = colIndex_old[index];
1577 rowIndex_new[irow+1] = nelems_copy+1;
1578 colIndex_new[nelems_copy] = icol;
1579 elements_new[nelems_copy] = elements_old[index];
1582 if (nelems_copy >= nelems_new) {
1589 if (rowIndex_old)
delete [] (Int_t*) rowIndex_old;
1590 if (colIndex_old)
delete [] (Int_t*) colIndex_old;
1591 if (elements_old)
delete [] (Element*) elements_old;
1593 if (nrowIndex_old < this->fNrowIndex) {
1594 for (Int_t irow = nrowIndex_old; irow < this->fNrowIndex; irow++)
1595 rowIndex_new[irow] = rowIndex_new[nrowIndex_old-1];
1598 const Int_t nelems_new = (nr_nonzeros >= 0) ? nr_nonzeros : 0;
1599 Allocate(nrows,ncols,0,0,1,nelems_new);
1611 template<
class Element>
1612 TMatrixTBase<Element> &TMatrixTSparse<Element>::ResizeTo(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,
1615 R__ASSERT(this->IsValid());
1616 if (!this->fIsOwner) {
1617 Error(
"ResizeTo(Int_t,Int_t,Int_t,Int_t,Int_t)",
"Not owner of data array,cannot resize");
1621 const Int_t new_nrows = row_upb-row_lwb+1;
1622 const Int_t new_ncols = col_upb-col_lwb+1;
1624 if (this->fNelems > 0) {
1625 if (this->fNrows == new_nrows && this->fNcols == new_ncols &&
1626 this->fRowLwb == row_lwb && this->fColLwb == col_lwb &&
1627 (this->fNelems == nr_nonzeros || nr_nonzeros < 0))
1629 else if (new_nrows == 0 || new_ncols == 0 || nr_nonzeros == 0) {
1630 this->fNrows = new_nrows; this->fNcols = new_ncols;
1631 this->fRowLwb = row_lwb; this->fColLwb = col_lwb;
1636 const Int_t *rowIndex_old = GetRowIndexArray();
1637 const Int_t *colIndex_old = GetColIndexArray();
1638 const Element *elements_old = GetMatrixArray();
1640 const Int_t nrowIndex_old = this->fNrowIndex;
1642 const Int_t nrows_old = this->fNrows;
1643 const Int_t rowLwb_old = this->fRowLwb;
1644 const Int_t colLwb_old = this->fColLwb;
1647 if (nr_nonzeros > 0)
1648 nelems_new = nr_nonzeros;
1651 for (Int_t irow = 0; irow < nrows_old; irow++) {
1652 if (irow+rowLwb_old > row_upb || irow+rowLwb_old < row_lwb)
continue;
1653 const Int_t sIndex = rowIndex_old[irow];
1654 const Int_t eIndex = rowIndex_old[irow+1];
1655 for (Int_t index = sIndex; index < eIndex; index++) {
1656 const Int_t icol = colIndex_old[index];
1657 if (icol+colLwb_old <= col_upb && icol+colLwb_old >= col_lwb)
1663 Allocate(new_nrows,new_ncols,row_lwb,col_lwb,1,nelems_new);
1664 R__ASSERT(this->IsValid());
1666 Int_t *rowIndex_new = GetRowIndexArray();
1667 Int_t *colIndex_new = GetColIndexArray();
1668 Element *elements_new = GetMatrixArray();
1670 Int_t nelems_copy = 0;
1671 rowIndex_new[0] = 0;
1672 const Int_t row_off = rowLwb_old-row_lwb;
1673 const Int_t col_off = colLwb_old-col_lwb;
1674 for (Int_t irow = 0; irow < nrows_old; irow++) {
1675 if (irow+rowLwb_old > row_upb || irow+rowLwb_old < row_lwb)
continue;
1676 const Int_t sIndex = rowIndex_old[irow];
1677 const Int_t eIndex = rowIndex_old[irow+1];
1678 for (Int_t index = sIndex; index < eIndex; index++) {
1679 const Int_t icol = colIndex_old[index];
1680 if (icol+colLwb_old <= col_upb && icol+colLwb_old >= col_lwb) {
1681 rowIndex_new[irow+row_off+1] = nelems_copy+1;
1682 colIndex_new[nelems_copy] = icol+col_off;
1683 elements_new[nelems_copy] = elements_old[index];
1686 if (nelems_copy >= nelems_new) {
1692 if (rowIndex_old)
delete [] (Int_t*) rowIndex_old;
1693 if (colIndex_old)
delete [] (Int_t*) colIndex_old;
1694 if (elements_old)
delete [] (Element*) elements_old;
1696 if (nrowIndex_old < this->fNrowIndex) {
1697 for (Int_t irow = nrowIndex_old; irow < this->fNrowIndex; irow++)
1698 rowIndex_new[irow] = rowIndex_new[nrowIndex_old-1];
1701 const Int_t nelems_new = (nr_nonzeros >= 0) ? nr_nonzeros : 0;
1702 Allocate(new_nrows,new_ncols,row_lwb,col_lwb,1,nelems_new);
1710 template<
class Element>
1711 TMatrixTSparse<Element> &TMatrixTSparse<Element>::Use(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,
1712 Int_t nr_nonzeros,Int_t *pRowIndex,Int_t *pColIndex,Element *pData)
1715 if (row_upb < row_lwb) {
1716 Error(
"Use",
"row_upb=%d < row_lwb=%d",row_upb,row_lwb);
1719 if (col_upb < col_lwb) {
1720 Error(
"Use",
"col_upb=%d < col_lwb=%d",col_upb,col_lwb);
1727 this->fNrows = row_upb-row_lwb+1;
1728 this->fNcols = col_upb-col_lwb+1;
1729 this->fRowLwb = row_lwb;
1730 this->fColLwb = col_lwb;
1731 this->fNrowIndex = this->fNrows+1;
1732 this->fNelems = nr_nonzeros;
1733 this->fIsOwner = kFALSE;
1734 this->fTol = std::numeric_limits<Element>::epsilon();
1737 fRowIndex = pRowIndex;
1738 fColIndex = pColIndex;
1750 template<
class Element>
1751 TMatrixTBase<Element> &TMatrixTSparse<Element>::GetSub(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,
1752 TMatrixTBase<Element> &target,Option_t *option)
const
1755 R__ASSERT(this->IsValid());
1756 if (row_lwb < this->fRowLwb || row_lwb > this->fRowLwb+this->fNrows-1) {
1757 Error(
"GetSub",
"row_lwb out-of-bounds");
1760 if (col_lwb < this->fColLwb || col_lwb > this->fColLwb+this->fNcols-1) {
1761 Error(
"GetSub",
"col_lwb out-of-bounds");
1764 if (row_upb < this->fRowLwb || row_upb > this->fRowLwb+this->fNrows-1) {
1765 Error(
"GetSub",
"row_upb out-of-bounds");
1768 if (col_upb < this->fColLwb || col_upb > this->fColLwb+this->fNcols-1) {
1769 Error(
"GetSub",
"col_upb out-of-bounds");
1772 if (row_upb < row_lwb || col_upb < col_lwb) {
1773 Error(
"GetSub",
"row_upb < row_lwb || col_upb < col_lwb");
1778 TString opt(option);
1780 const Int_t shift = (opt.Contains(
"S")) ? 1 : 0;
1782 const Int_t row_lwb_sub = (shift) ? 0 : row_lwb;
1783 const Int_t row_upb_sub = (shift) ? row_upb-row_lwb : row_upb;
1784 const Int_t col_lwb_sub = (shift) ? 0 : col_lwb;
1785 const Int_t col_upb_sub = (shift) ? col_upb-col_lwb : col_upb;
1787 Int_t nr_nonzeros = 0;
1788 for (Int_t irow = 0; irow < this->fNrows; irow++) {
1789 if (irow+this->fRowLwb > row_upb || irow+this->fRowLwb < row_lwb)
continue;
1790 const Int_t sIndex = fRowIndex[irow];
1791 const Int_t eIndex = fRowIndex[irow+1];
1792 for (Int_t index = sIndex; index < eIndex; index++) {
1793 const Int_t icol = fColIndex[index];
1794 if (icol+this->fColLwb <= col_upb && icol+this->fColLwb >= col_lwb)
1799 target.ResizeTo(row_lwb_sub,row_upb_sub,col_lwb_sub,col_upb_sub,nr_nonzeros);
1801 const Element *ep = this->GetMatrixArray();
1803 Int_t *rowIndex_sub = target.GetRowIndexArray();
1804 Int_t *colIndex_sub = target.GetColIndexArray();
1805 Element *ep_sub = target.GetMatrixArray();
1807 if (target.GetRowIndexArray() && target.GetColIndexArray()) {
1808 Int_t nelems_copy = 0;
1809 rowIndex_sub[0] = 0;
1810 const Int_t row_off = this->fRowLwb-row_lwb;
1811 const Int_t col_off = this->fColLwb-col_lwb;
1812 for (Int_t irow = 0; irow < this->fNrows; irow++) {
1813 if (irow+this->fRowLwb > row_upb || irow+this->fRowLwb < row_lwb)
continue;
1814 const Int_t sIndex = fRowIndex[irow];
1815 const Int_t eIndex = fRowIndex[irow+1];
1816 for (Int_t index = sIndex; index < eIndex; index++) {
1817 const Int_t icol = fColIndex[index];
1818 if (icol+this->fColLwb <= col_upb && icol+this->fColLwb >= col_lwb) {
1819 rowIndex_sub[irow+row_off+1] = nelems_copy+1;
1820 colIndex_sub[nelems_copy] = icol+col_off;
1821 ep_sub[nelems_copy] = ep[index];
1827 const Int_t row_off = this->fRowLwb-row_lwb;
1828 const Int_t col_off = this->fColLwb-col_lwb;
1829 const Int_t ncols_sub = col_upb_sub-col_lwb_sub+1;
1830 for (Int_t irow = 0; irow < this->fNrows; irow++) {
1831 if (irow+this->fRowLwb > row_upb || irow+this->fRowLwb < row_lwb)
continue;
1832 const Int_t sIndex = fRowIndex[irow];
1833 const Int_t eIndex = fRowIndex[irow+1];
1834 const Int_t off = (irow+row_off)*ncols_sub;
1835 for (Int_t index = sIndex; index < eIndex; index++) {
1836 const Int_t icol = fColIndex[index];
1837 if (icol+this->fColLwb <= col_upb && icol+this->fColLwb >= col_lwb)
1838 ep_sub[off+icol+col_off] = ep[index];
1850 template<
class Element>
1851 TMatrixTBase<Element> &TMatrixTSparse<Element>::SetSub(Int_t row_lwb,Int_t col_lwb,
const TMatrixTBase<Element> &source)
1854 R__ASSERT(this->IsValid());
1855 R__ASSERT(source.IsValid());
1857 if (row_lwb < this->fRowLwb || row_lwb > this->fRowLwb+this->fNrows-1) {
1858 Error(
"SetSub",
"row_lwb out-of-bounds");
1861 if (col_lwb < this->fColLwb || col_lwb > this->fColLwb+this->fNcols-1) {
1862 Error(
"SetSub",
"col_lwb out-of-bounds");
1865 if (row_lwb+source.GetNrows() > this->fRowLwb+this->fNrows || col_lwb+source.GetNcols() > this->fColLwb+this->fNcols) {
1866 Error(
"SetSub",
"source matrix too large");
1871 const Int_t nRows_source = source.GetNrows();
1872 const Int_t nCols_source = source.GetNcols();
1876 Int_t nr_nonzeros = 0;
1877 for (Int_t irow = 0; irow < this->fNrows; irow++) {
1878 if (irow+this->fRowLwb >= row_lwb+nRows_source || irow+this->fRowLwb < row_lwb)
continue;
1879 const Int_t sIndex = fRowIndex[irow];
1880 const Int_t eIndex = fRowIndex[irow+1];
1881 for (Int_t index = sIndex; index < eIndex; index++) {
1882 const Int_t icol = fColIndex[index];
1883 if (icol+this->fColLwb < col_lwb+nCols_source && icol+this->fColLwb >= col_lwb)
1888 const Int_t *rowIndex_s = source.GetRowIndexArray();
1889 const Int_t *colIndex_s = source.GetColIndexArray();
1890 const Element *elements_s = source.GetMatrixArray();
1892 const Int_t nelems_old = this->fNelems;
1893 const Int_t *rowIndex_old = GetRowIndexArray();
1894 const Int_t *colIndex_old = GetColIndexArray();
1895 const Element *elements_old = GetMatrixArray();
1897 const Int_t nelems_new = nelems_old+source.NonZeros()-nr_nonzeros;
1898 fRowIndex =
new Int_t[this->fNrowIndex];
1899 fColIndex =
new Int_t[nelems_new];
1900 fElements =
new Element[nelems_new];
1901 this->fNelems = nelems_new;
1903 Int_t *rowIndex_new = GetRowIndexArray();
1904 Int_t *colIndex_new = GetColIndexArray();
1905 Element *elements_new = GetMatrixArray();
1907 const Int_t row_off = row_lwb-this->fRowLwb;
1908 const Int_t col_off = col_lwb-this->fColLwb;
1911 rowIndex_new[0] = 0;
1912 for (Int_t irow = 0; irow < this->fNrows; irow++) {
1913 rowIndex_new[irow+1] = rowIndex_new[irow];
1914 Bool_t flagRow = kFALSE;
1915 if (irow+this->fRowLwb < row_lwb+nRows_source && irow+this->fRowLwb >= row_lwb)
1918 const Int_t sIndex_o = rowIndex_old[irow];
1919 const Int_t eIndex_o = rowIndex_old[irow+1];
1922 const Int_t icol_left = col_off-1;
1923 const Int_t left = TMath::BinarySearch(eIndex_o-sIndex_o,colIndex_old+sIndex_o,icol_left)+sIndex_o;
1924 for (Int_t index = sIndex_o; index <= left; index++) {
1925 rowIndex_new[irow+1]++;
1926 colIndex_new[nr] = colIndex_old[index];
1927 elements_new[nr] = elements_old[index];
1931 if (rowIndex_s && colIndex_s) {
1932 const Int_t sIndex_s = rowIndex_s[irow-row_off];
1933 const Int_t eIndex_s = rowIndex_s[irow-row_off+1];
1934 for (Int_t index = sIndex_s; index < eIndex_s; index++) {
1935 rowIndex_new[irow+1]++;
1936 colIndex_new[nr] = colIndex_s[index]+col_off;
1937 elements_new[nr] = elements_s[index];
1941 const Int_t off = (irow-row_off)*nCols_source;
1942 for (Int_t icol = 0; icol < nCols_source; icol++) {
1943 rowIndex_new[irow+1]++;
1944 colIndex_new[nr] = icol+col_off;
1945 elements_new[nr] = elements_s[off+icol];
1950 const Int_t icol_right = col_off+nCols_source-1;
1952 Int_t right = TMath::BinarySearch(eIndex_o-sIndex_o,colIndex_old+sIndex_o,icol_right)+sIndex_o;
1953 while (right < eIndex_o-1 && colIndex_old[right+1] <= icol_right)
1957 for (Int_t index = right; index < eIndex_o; index++) {
1958 rowIndex_new[irow+1]++;
1959 colIndex_new[nr] = colIndex_old[index];
1960 elements_new[nr] = elements_old[index];
1965 for (Int_t index = sIndex_o; index < eIndex_o; index++) {
1966 rowIndex_new[irow+1]++;
1967 colIndex_new[nr] = colIndex_old[index];
1968 elements_new[nr] = elements_old[index];
1974 R__ASSERT(this->fNelems == fRowIndex[this->fNrowIndex-1]);
1976 if (rowIndex_old)
delete [] (Int_t*) rowIndex_old;
1977 if (colIndex_old)
delete [] (Int_t*) colIndex_old;
1978 if (elements_old)
delete [] (Element*) elements_old;
1986 template<
class Element>
1987 TMatrixTSparse<Element> &TMatrixTSparse<Element>::Transpose(
const TMatrixTSparse<Element> &source)
1990 R__ASSERT(this->IsValid());
1991 R__ASSERT(source.IsValid());
1993 if (this->fNrows != source.GetNcols() || this->fNcols != source.GetNrows() ||
1994 this->fRowLwb != source.GetColLwb() || this->fColLwb != source.GetRowLwb()) {
1995 Error(
"Transpose",
"matrix has wrong shape");
1999 if (source.NonZeros() <= 0)
2003 const Int_t nr_nonzeros = source.NonZeros();
2005 const Int_t *
const pRowIndex_s = source.GetRowIndexArray();
2006 const Int_t *
const pColIndex_s = source.GetColIndexArray();
2007 const Element *
const pData_s = source.GetMatrixArray();
2009 Int_t *rownr =
new Int_t [nr_nonzeros];
2010 Int_t *colnr =
new Int_t [nr_nonzeros];
2011 Element *pData_t =
new Element[nr_nonzeros];
2014 for (Int_t irow_s = 0; irow_s < source.GetNrows(); irow_s++) {
2015 const Int_t sIndex = pRowIndex_s[irow_s];
2016 const Int_t eIndex = pRowIndex_s[irow_s+1];
2017 for (Int_t index = sIndex; index < eIndex; index++) {
2018 rownr[ielem] = pColIndex_s[index]+this->fRowLwb;
2019 colnr[ielem] = irow_s+this->fColLwb;
2020 pData_t[ielem] = pData_s[index];
2025 R__ASSERT(nr_nonzeros >= ielem);
2027 TMatrixTBase<Element>::DoubleLexSort(nr_nonzeros,rownr,colnr,pData_t);
2028 SetMatrixArray(nr_nonzeros,rownr,colnr,pData_t);
2030 R__ASSERT(this->fNelems == fRowIndex[this->fNrowIndex-1]);
2032 if (pData_t)
delete [] pData_t;
2033 if (rownr)
delete [] rownr;
2034 if (colnr)
delete [] colnr;
2041 template<
class Element>
2042 TMatrixTBase<Element> &TMatrixTSparse<Element>::Zero()
2044 R__ASSERT(this->IsValid());
2046 if (fElements) {
delete [] fElements; fElements = 0; }
2047 if (fColIndex) {
delete [] fColIndex; fColIndex = 0; }
2049 memset(this->GetRowIndexArray(),0,this->fNrowIndex*
sizeof(Int_t));
2057 template<
class Element>
2058 TMatrixTBase<Element> &TMatrixTSparse<Element>::UnitMatrix()
2060 R__ASSERT(this->IsValid());
2064 Int_t nr_nonzeros = 0;
2065 for (i = this->fRowLwb; i <= this->fRowLwb+this->fNrows-1; i++)
2066 for (Int_t j = this->fColLwb; j <= this->fColLwb+this->fNcols-1; j++)
2067 if (i == j) nr_nonzeros++;
2069 if (nr_nonzeros != this->fNelems) {
2070 this->fNelems = nr_nonzeros;
2071 Int_t *oIp = fColIndex;
2072 fColIndex =
new Int_t[nr_nonzeros];
2073 if (oIp)
delete [] oIp;
2074 Element *oDp = fElements;
2075 fElements =
new Element[nr_nonzeros];
2076 if (oDp)
delete [] oDp;
2081 for (i = this->fRowLwb; i <= this->fRowLwb+this->fNrows-1; i++) {
2082 for (Int_t j = this->fColLwb; j <= this->fColLwb+this->fNcols-1; j++) {
2084 const Int_t irow = i-this->fRowLwb;
2085 fRowIndex[irow+1] = ielem+1;
2086 fElements[ielem] = 1.0;
2087 fColIndex[ielem++] = j-this->fColLwb;
2099 template<
class Element>
2100 Element TMatrixTSparse<Element>::RowNorm()
const
2102 R__ASSERT(this->IsValid());
2104 const Element * ep = GetMatrixArray();
2105 const Element *
const fp = ep+this->fNelems;
2106 const Int_t *
const pR = GetRowIndexArray();
2110 for (Int_t irow = 0; irow < this->fNrows; irow++) {
2111 const Int_t sIndex = pR[irow];
2112 const Int_t eIndex = pR[irow+1];
2114 for (Int_t index = sIndex; index < eIndex; index++)
2115 sum += TMath::Abs(*ep++);
2116 norm = TMath::Max(norm,sum);
2119 R__ASSERT(ep == fp);
2128 template<
class Element>
2129 Element TMatrixTSparse<Element>::ColNorm()
const
2131 R__ASSERT(this->IsValid());
2133 const TMatrixTSparse<Element> mt(kTransposed,*
this);
2135 const Element * ep = mt.GetMatrixArray();
2136 const Element *
const fp = ep+this->fNcols;
2143 for (Int_t i = 0; i < this->fNrows; i++,ep += this->fNcols)
2144 sum += TMath::Abs(*ep);
2145 ep -= this->fNelems-1;
2146 norm = TMath::Max(norm,sum);
2149 R__ASSERT(ep == fp);
2156 template<
class Element>
2157 Element &TMatrixTSparse<Element>::operator()(Int_t rown,Int_t coln)
2159 R__ASSERT(this->IsValid());
2161 const Int_t arown = rown-this->fRowLwb;
2162 const Int_t acoln = coln-this->fColLwb;
2163 if (arown >= this->fNrows || arown < 0) {
2164 Error(
"operator()",
"Request row(%d) outside matrix range of %d - %d",rown,this->fRowLwb,this->fRowLwb+this->fNrows);
2165 return fElements[0];
2167 if (acoln >= this->fNcols || acoln < 0) {
2168 Error(
"operator()",
"Request column(%d) outside matrix range of %d - %d",coln,this->fColLwb,this->fColLwb+this->fNcols);
2169 return fElements[0];
2175 if (this->fNrowIndex > 0 && fRowIndex[this->fNrowIndex-1] != 0) {
2176 sIndex = fRowIndex[arown];
2177 eIndex = fRowIndex[arown+1];
2178 index = TMath::BinarySearch(eIndex-sIndex,fColIndex+sIndex,acoln)+sIndex;
2181 if (index >= sIndex && fColIndex[index] == acoln)
2182 return fElements[index];
2185 InsertRow(rown,coln,&val,1);
2186 sIndex = fRowIndex[arown];
2187 eIndex = fRowIndex[arown+1];
2188 index = TMath::BinarySearch(eIndex-sIndex,fColIndex+sIndex,acoln)+sIndex;
2189 if (index >= sIndex && fColIndex[index] == acoln)
2190 return fElements[index];
2192 Error(
"operator()(Int_t,Int_t",
"Insert row failed");
2193 return fElements[0];
2200 template <
class Element>
2201 Element TMatrixTSparse<Element>::operator()(Int_t rown,Int_t coln)
const
2203 R__ASSERT(this->IsValid());
2204 if (this->fNrowIndex > 0 && this->fRowIndex[this->fNrowIndex-1] == 0) {
2205 Error(
"operator()(Int_t,Int_t) const",
"row/col indices are not set");
2206 Info(
"operator()",
"fNrowIndex = %d fRowIndex[fNrowIndex-1] = %d\n",this->fNrowIndex,this->fRowIndex[this->fNrowIndex-1]);
2209 const Int_t arown = rown-this->fRowLwb;
2210 const Int_t acoln = coln-this->fColLwb;
2212 if (arown >= this->fNrows || arown < 0) {
2213 Error(
"operator()",
"Request row(%d) outside matrix range of %d - %d",rown,this->fRowLwb,this->fRowLwb+this->fNrows);
2216 if (acoln >= this->fNcols || acoln < 0) {
2217 Error(
"operator()",
"Request column(%d) outside matrix range of %d - %d",coln,this->fColLwb,this->fColLwb+this->fNcols);
2221 const Int_t sIndex = fRowIndex[arown];
2222 const Int_t eIndex = fRowIndex[arown+1];
2223 const Int_t index = (Int_t)TMath::BinarySearch(eIndex-sIndex,fColIndex+sIndex,acoln)+sIndex;
2224 if (index < sIndex || fColIndex[index] != acoln)
return 0.0;
2225 else return fElements[index];
2232 template<
class Element>
2233 TMatrixTSparse<Element> &TMatrixTSparse<Element>::operator=(
const TMatrixTSparse<Element> &source)
2235 if (gMatrixCheck && !AreCompatible(*
this,source)) {
2236 Error(
"operator=(const TMatrixTSparse &)",
"matrices not compatible");
2240 if (this->GetMatrixArray() != source.GetMatrixArray()) {
2241 TObject::operator=(source);
2243 const Element *
const sp = source.GetMatrixArray();
2244 Element *
const tp = this->GetMatrixArray();
2245 memcpy(tp,sp,this->fNelems*
sizeof(Element));
2246 this->fTol = source.GetTol();
2255 template<
class Element>
2256 TMatrixTSparse<Element> &TMatrixTSparse<Element>::operator=(
const TMatrixT<Element> &source)
2258 if (gMatrixCheck && !AreCompatible(*
this,(TMatrixTBase<Element> &)source)) {
2259 Error(
"operator=(const TMatrixT &)",
"matrices not compatible");
2263 if (this->GetMatrixArray() != source.GetMatrixArray()) {
2264 TObject::operator=(source);
2266 const Element *
const sp = source.GetMatrixArray();
2267 Element *
const tp = this->GetMatrixArray();
2268 for (Int_t irow = 0; irow < this->fNrows; irow++) {
2269 const Int_t sIndex = fRowIndex[irow];
2270 const Int_t eIndex = fRowIndex[irow+1];
2271 const Int_t off = irow*this->fNcols;
2272 for (Int_t index = sIndex; index < eIndex; index++) {
2273 const Int_t icol = fColIndex[index];
2274 tp[index] = sp[off+icol];
2277 this->fTol = source.GetTol();
2286 template<
class Element>
2287 TMatrixTSparse<Element> &TMatrixTSparse<Element>::operator=(Element val)
2289 R__ASSERT(this->IsValid());
2291 if (fRowIndex[this->fNrowIndex-1] == 0) {
2292 Error(
"operator=(Element",
"row/col indices are not set");
2296 Element *ep = this->GetMatrixArray();
2297 const Element *
const ep_last = ep+this->fNelems;
2298 while (ep < ep_last)
2307 template<
class Element>
2308 TMatrixTSparse<Element> &TMatrixTSparse<Element>::operator+=(Element val)
2310 R__ASSERT(this->IsValid());
2312 Element *ep = this->GetMatrixArray();
2313 const Element *
const ep_last = ep+this->fNelems;
2314 while (ep < ep_last)
2323 template<
class Element>
2324 TMatrixTSparse<Element> &TMatrixTSparse<Element>::operator-=(Element val)
2326 R__ASSERT(this->IsValid());
2328 Element *ep = this->GetMatrixArray();
2329 const Element *
const ep_last = ep+this->fNelems;
2330 while (ep < ep_last)
2339 template<
class Element>
2340 TMatrixTSparse<Element> &TMatrixTSparse<Element>::operator*=(Element val)
2342 R__ASSERT(this->IsValid());
2344 Element *ep = this->GetMatrixArray();
2345 const Element *
const ep_last = ep+this->fNelems;
2346 while (ep < ep_last)
2355 template<
class Element>
2356 TMatrixTBase<Element> &TMatrixTSparse<Element>::Randomize(Element alpha,Element beta,Double_t &seed)
2358 R__ASSERT(this->IsValid());
2360 const Element scale = beta-alpha;
2361 const Element shift = alpha/scale;
2363 Int_t *
const pRowIndex = GetRowIndexArray();
2364 Int_t *
const pColIndex = GetColIndexArray();
2365 Element *
const ep = GetMatrixArray();
2367 const Int_t m = this->GetNrows();
2368 const Int_t n = this->GetNcols();
2371 const Int_t nn = this->GetNrows()*this->GetNcols();
2372 const Int_t length = (this->GetNoElements() <= nn) ? this->GetNoElements() : nn;
2376 for (Int_t k = 0; k < nn; k++) {
2377 const Element r = Drand(seed);
2379 if ((nn-k)*r < length-chosen) {
2380 pColIndex[chosen] = k%n;
2381 const Int_t irow = k/n;
2383 if (irow > icurrent) {
2384 for ( ; icurrent < irow; icurrent++)
2385 pRowIndex[icurrent+1] = chosen;
2387 ep[chosen] = scale*(Drand(seed)+shift);
2391 for ( ; icurrent < m; icurrent++)
2392 pRowIndex[icurrent+1] = length;
2394 R__ASSERT(chosen == length);
2402 template<
class Element>
2403 TMatrixTSparse<Element> &TMatrixTSparse<Element>::RandomizePD(Element alpha,Element beta,Double_t &seed)
2405 const Element scale = beta-alpha;
2406 const Element shift = alpha/scale;
2409 R__ASSERT(this->IsValid());
2411 if (this->fNrows != this->fNcols || this->fRowLwb != this->fColLwb) {
2412 Error(
"RandomizePD(Element &",
"matrix should be square");
2417 const Int_t n = this->fNcols;
2419 Int_t *
const pRowIndex = this->GetRowIndexArray();
2420 Int_t *
const pColIndex = this->GetColIndexArray();
2421 Element *
const ep = GetMatrixArray();
2428 ep[0] = 1e-8+scale*(Drand(seed)+shift);
2432 const Int_t nn = n*(n-1)/2;
2437 Int_t length = this->fNelems-n;
2438 length = (length <= nn) ? length : nn;
2448 for (Int_t k = 0; k < nn; k++ ) {
2449 const Element r = Drand(seed);
2451 if( (nn-k)*r < length-chosen) {
2456 Int_t row = (int) TMath::Floor((-1+TMath::Sqrt(1.0+8.0*k))/2);
2458 Int_t col = k-row*(row+1)/2;
2463 if (row > icurrent) {
2467 for ( ; icurrent < row; icurrent++) {
2470 for (Int_t ll = pRowIndex[icurrent]; ll < nnz; ll++)
2471 ep[nnz] += TMath::Abs(ep[ll]);
2472 ep[nnz] += 1e-8+scale*(Drand(seed)+shift);
2473 pColIndex[nnz] = icurrent;
2476 pRowIndex[icurrent+1] = nnz;
2479 ep[nnz] = scale*(Drand(seed)+shift);
2480 pColIndex[nnz] = col;
2483 ep[pRowIndex[col+1]-1] += TMath::Abs(ep[nnz]);
2490 R__ASSERT(chosen == length);
2493 for ( ; icurrent < n; icurrent++) {
2496 for(Int_t ll = pRowIndex[icurrent]; ll < nnz; ll++)
2497 ep[nnz] += TMath::Abs(ep[ll]);
2498 ep[nnz] += 1e-8+scale*(Drand(seed)+shift);
2499 pColIndex[nnz] = icurrent;
2502 pRowIndex[icurrent+1] = nnz;
2504 this->fNelems = nnz;
2506 TMatrixTSparse<Element> tmp(TMatrixTSparse<Element>::kTransposed,*
this);
2512 const Int_t *
const pR = this->GetRowIndexArray();
2513 const Int_t *
const pC = this->GetColIndexArray();
2514 Element *
const pD = GetMatrixArray();
2515 for (Int_t irow = 0; irow < this->fNrows+1; irow++) {
2516 const Int_t sIndex = pR[irow];
2517 const Int_t eIndex = pR[irow+1];
2518 for (Int_t index = sIndex; index < eIndex; index++) {
2519 const Int_t icol = pC[index];
2531 template<
class Element>
2532 TMatrixTSparse<Element> operator+(
const TMatrixTSparse<Element> &source1,
const TMatrixTSparse<Element> &source2)
2534 TMatrixTSparse<Element> target(source1,TMatrixTSparse<Element>::kPlus,source2);
2540 template<
class Element>
2541 TMatrixTSparse<Element> operator+(
const TMatrixTSparse<Element> &source1,
const TMatrixT<Element> &source2)
2543 TMatrixTSparse<Element> target(source1,TMatrixTSparse<Element>::kPlus,source2);
2549 template<
class Element>
2550 TMatrixTSparse<Element> operator+(
const TMatrixT<Element> &source1,
const TMatrixTSparse<Element> &source2)
2552 TMatrixTSparse<Element> target(source1,TMatrixTSparse<Element>::kPlus,source2);
2558 template<
class Element>
2559 TMatrixTSparse<Element> operator+(
const TMatrixTSparse<Element> &source,Element val)
2561 TMatrixTSparse<Element> target(source);
2568 template<
class Element>
2569 TMatrixTSparse<Element> operator+(Element val,
const TMatrixTSparse<Element> &source)
2571 TMatrixTSparse<Element> target(source);
2578 template<
class Element>
2579 TMatrixTSparse<Element> operator-(
const TMatrixTSparse<Element> &source1,
const TMatrixTSparse<Element> &source2)
2581 TMatrixTSparse<Element> target(source1,TMatrixTSparse<Element>::kMinus,source2);
2587 template<
class Element>
2588 TMatrixTSparse<Element> operator-(
const TMatrixTSparse<Element> &source1,
const TMatrixT<Element> &source2)
2590 TMatrixTSparse<Element> target(source1,TMatrixTSparse<Element>::kMinus,source2);
2596 template<
class Element>
2597 TMatrixTSparse<Element> operator-(
const TMatrixT<Element> &source1,
const TMatrixTSparse<Element> &source2)
2599 TMatrixTSparse<Element> target(source1,TMatrixTSparse<Element>::kMinus,source2);
2605 template<
class Element>
2606 TMatrixTSparse<Element> operator-(
const TMatrixTSparse<Element> &source,Element val)
2608 TMatrixTSparse<Element> target(source);
2615 template<
class Element>
2616 TMatrixTSparse<Element> operator-(Element val,
const TMatrixTSparse<Element> &source)
2618 TMatrixTSparse<Element> target(source);
2625 template<
class Element>
2626 TMatrixTSparse<Element> operator*(
const TMatrixTSparse<Element> &source1,
const TMatrixTSparse<Element> &source2)
2628 TMatrixTSparse<Element> target(source1,TMatrixTSparse<Element>::kMult,source2);
2634 template<
class Element>
2635 TMatrixTSparse<Element> operator*(
const TMatrixTSparse<Element> &source1,
const TMatrixT<Element> &source2)
2637 TMatrixTSparse<Element> target(source1,TMatrixTSparse<Element>::kMult,source2);
2643 template<
class Element>
2644 TMatrixTSparse<Element> operator*(
const TMatrixT<Element> &source1,
const TMatrixTSparse<Element> &source2)
2646 TMatrixTSparse<Element> target(source1,TMatrixTSparse<Element>::kMult,source2);
2652 template<
class Element>
2653 TMatrixTSparse<Element> operator*(Element val,
const TMatrixTSparse<Element> &source)
2655 TMatrixTSparse<Element> target(source);
2662 template<
class Element>
2663 TMatrixTSparse<Element> operator*(
const TMatrixTSparse<Element> &source,Element val)
2665 TMatrixTSparse<Element> target(source);
2673 template<
class Element>
2674 TMatrixTSparse<Element> &Add(TMatrixTSparse<Element> &target,Element scalar,
const TMatrixTSparse<Element> &source)
2676 target += scalar * source;
2683 template<
class Element>
2684 TMatrixTSparse<Element> &ElementMult(TMatrixTSparse<Element> &target,
const TMatrixTSparse<Element> &source)
2686 if (gMatrixCheck && !AreCompatible(target,source)) {
2687 ::Error(
"ElementMult(TMatrixTSparse &,const TMatrixTSparse &)",
"matrices not compatible");
2691 const Element *sp = source.GetMatrixArray();
2692 Element *tp = target.GetMatrixArray();
2693 const Element *ftp = tp+target.GetNoElements();
2703 template<
class Element>
2704 TMatrixTSparse<Element> &ElementDiv(TMatrixTSparse<Element> &target,
const TMatrixTSparse<Element> &source)
2706 if (gMatrixCheck && !AreCompatible(target,source)) {
2707 ::Error(
"ElementDiv(TMatrixT &,const TMatrixT &)",
"matrices not compatible");
2711 const Element *sp = source.GetMatrixArray();
2712 Element *tp = target.GetMatrixArray();
2713 const Element *ftp = tp+target.GetNoElements();
2714 while ( tp < ftp ) {
2718 Error(
"ElementDiv",
"source element is zero");
2728 template<
class Element>
2729 Bool_t AreCompatible(
const TMatrixTSparse<Element> &m1,
const TMatrixTSparse<Element> &m2,Int_t verbose)
2731 if (!m1.IsValid()) {
2733 ::Error(
"AreCompatible",
"matrix 1 not valid");
2736 if (!m2.IsValid()) {
2738 ::Error(
"AreCompatible",
"matrix 2 not valid");
2742 if (m1.GetNrows() != m2.GetNrows() || m1.GetNcols() != m2.GetNcols() ||
2743 m1.GetRowLwb() != m2.GetRowLwb() || m1.GetColLwb() != m2.GetColLwb()) {
2745 ::Error(
"AreCompatible",
"matrices 1 and 2 not compatible");
2749 const Int_t *pR1 = m1.GetRowIndexArray();
2750 const Int_t *pR2 = m2.GetRowIndexArray();
2751 const Int_t nRows = m1.GetNrows();
2752 if (memcmp(pR1,pR2,(nRows+1)*
sizeof(Int_t))) {
2754 ::Error(
"AreCompatible",
"matrices 1 and 2 have different rowIndex");
2755 for (Int_t i = 0; i < nRows+1; i++)
2756 printf(
"%d: %d %d\n",i,pR1[i],pR2[i]);
2759 const Int_t *pD1 = m1.GetColIndexArray();
2760 const Int_t *pD2 = m2.GetColIndexArray();
2761 const Int_t nData = m1.GetNoElements();
2762 if (memcmp(pD1,pD2,nData*
sizeof(Int_t))) {
2764 ::Error(
"AreCompatible",
"matrices 1 and 2 have different colIndex");
2765 for (Int_t i = 0; i < nData; i++)
2766 printf(
"%d: %d %d\n",i,pD1[i],pD2[i]);
2776 template<
class Element>
2777 void TMatrixTSparse<Element>::Streamer(TBuffer &R__b)
2779 if (R__b.IsReading()) {
2781 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
2783 R__b.ReadClassBuffer(TMatrixTSparse<Element>::Class(),
this,R__v,R__s,R__c);
2784 if (this->fNelems < 0)
2787 R__b.WriteClassBuffer(TMatrixTSparse<Element>::Class(),
this);
2791 template class TMatrixTSparse<Float_t>;
2796 template TMatrixFSparse
operator+ <Float_t>(
const TMatrixFSparse &source1,
const TMatrixFSparse &source2);
2797 template TMatrixFSparse
operator+ <Float_t>(
const TMatrixFSparse &source1,
const TMatrixF &source2);
2798 template TMatrixFSparse
operator+ <Float_t>(
const TMatrixF &source1,
const TMatrixFSparse &source2);
2799 template TMatrixFSparse
operator+ <Float_t>(
const TMatrixFSparse &source , Float_t val );
2800 template TMatrixFSparse
operator+ <Float_t>( Float_t val ,
const TMatrixFSparse &source );
2801 template TMatrixFSparse
operator- <Float_t>(
const TMatrixFSparse &source1,
const TMatrixFSparse &source2);
2802 template TMatrixFSparse
operator- <Float_t>(
const TMatrixFSparse &source1,
const TMatrixF &source2);
2803 template TMatrixFSparse
operator- <Float_t>(
const TMatrixF &source1,
const TMatrixFSparse &source2);
2804 template TMatrixFSparse
operator- <Float_t>(
const TMatrixFSparse &source , Float_t val );
2805 template TMatrixFSparse
operator- <Float_t>( Float_t val ,
const TMatrixFSparse &source );
2806 template TMatrixFSparse
operator* <Float_t>(
const TMatrixFSparse &source1,
const TMatrixFSparse &source2);
2807 template TMatrixFSparse
operator* <Float_t>(
const TMatrixFSparse &source1,
const TMatrixF &source2);
2808 template TMatrixFSparse
operator* <Float_t>(
const TMatrixF &source1,
const TMatrixFSparse &source2);
2809 template TMatrixFSparse
operator* <Float_t>( Float_t val ,
const TMatrixFSparse &source );
2810 template TMatrixFSparse
operator* <Float_t>(
const TMatrixFSparse &source, Float_t val );
2812 template TMatrixFSparse &Add <Float_t>(TMatrixFSparse &target, Float_t scalar,
const TMatrixFSparse &source);
2813 template TMatrixFSparse &ElementMult <Float_t>(TMatrixFSparse &target,
const TMatrixFSparse &source);
2814 template TMatrixFSparse &ElementDiv <Float_t>(TMatrixFSparse &target,
const TMatrixFSparse &source);
2816 template Bool_t AreCompatible<Float_t>(
const TMatrixFSparse &m1,
const TMatrixFSparse &m2,Int_t verbose);
2821 template class TMatrixTSparse<Double_t>;
2823 template TMatrixDSparse
operator+ <Double_t>(
const TMatrixDSparse &source1,
const TMatrixDSparse &source2);
2824 template TMatrixDSparse
operator+ <Double_t>(
const TMatrixDSparse &source1,
const TMatrixD &source2);
2825 template TMatrixDSparse
operator+ <Double_t>(
const TMatrixD &source1,
const TMatrixDSparse &source2);
2826 template TMatrixDSparse
operator+ <Double_t>(
const TMatrixDSparse &source , Double_t val );
2827 template TMatrixDSparse
operator+ <Double_t>( Double_t val ,
const TMatrixDSparse &source );
2828 template TMatrixDSparse
operator- <Double_t>(
const TMatrixDSparse &source1,
const TMatrixDSparse &source2);
2829 template TMatrixDSparse
operator- <Double_t>(
const TMatrixDSparse &source1,
const TMatrixD &source2);
2830 template TMatrixDSparse
operator- <Double_t>(
const TMatrixD &source1,
const TMatrixDSparse &source2);
2831 template TMatrixDSparse
operator- <Double_t>(
const TMatrixDSparse &source , Double_t val );
2832 template TMatrixDSparse
operator- <Double_t>( Double_t val ,
const TMatrixDSparse &source );
2833 template TMatrixDSparse
operator* <Double_t>(
const TMatrixDSparse &source1,
const TMatrixDSparse &source2);
2834 template TMatrixDSparse
operator* <Double_t>(
const TMatrixDSparse &source1,
const TMatrixD &source2);
2835 template TMatrixDSparse
operator* <Double_t>(
const TMatrixD &source1,
const TMatrixDSparse &source2);
2836 template TMatrixDSparse
operator* <Double_t>( Double_t val ,
const TMatrixDSparse &source );
2837 template TMatrixDSparse
operator* <Double_t>(
const TMatrixDSparse &source, Double_t val );
2839 template TMatrixDSparse &Add <Double_t>(TMatrixDSparse &target, Double_t scalar,
const TMatrixDSparse &source);
2840 template TMatrixDSparse &ElementMult <Double_t>(TMatrixDSparse &target,
const TMatrixDSparse &source);
2841 template TMatrixDSparse &ElementDiv <Double_t>(TMatrixDSparse &target,
const TMatrixDSparse &source);
2843 template Bool_t AreCompatible<Double_t>(
const TMatrixDSparse &m1,
const TMatrixDSparse &m2,Int_t verbose);