45 template<
class Element>
48 const Int_t no_rows = row_upb-row_lwb+1;
49 Allocate(no_rows,no_rows,row_lwb,row_lwb,1);
60 template<
class Element>
64 SetMatrixArray(elements,option);
65 if (!this->IsSymmetric()) {
66 Error(
"TMatrixTSym(Int_t,Element*,Option_t*)",
"matrix not symmetric");
73 template<
class Element>
76 const Int_t no_rows = row_upb-row_lwb+1;
77 Allocate(no_rows,no_rows,row_lwb,row_lwb);
78 SetMatrixArray(elements,option);
79 if (!this->IsSymmetric()) {
80 Error(
"TMatrixTSym(Int_t,Int_t,Element*,Option_t*)",
"matrix not symmetric");
86 template<
class Element>
99 template<
class Element>
131 this->SetTol(oldTol);
141 Error(
"TMatrixTSym(EMatrixCreatorOp1,const TMatrixTSym)",
142 "operation %d not yet implemented", op);
148 template<
class Element>
160 Error(
"TMatrixTSym(EMatrixCreatorOp1,const TMatrixT)",
161 "operation %d not yet implemented", op);
167 template<
class Element>
189 Error(
"TMatrixTSym(EMatrixCreatorOp2)",
"operation %d not yet implemented", op);
195 template<
class Element>
201 lazy_constructor.
FillIn(*
this);
202 if (!this->IsSymmetric()) {
203 Error(
"TMatrixTSym(TMatrixTSymLazy)",
"matrix not symmetric");
210 template<
class Element>
214 if (size > this->kSizeMax)
224 template<
class Element>
227 if (size == 0)
return 0;
229 if ( size <= this->kSizeMax )
232 Element *heap =
new Element[size];
242 template<
class Element>
246 if (copySize == 0 || oldp == newp)
249 if ( newSize <= this->kSizeMax && oldSize <= this->kSizeMax ) {
252 for (
Int_t i = copySize-1; i >= 0; i--)
255 for (
Int_t i = 0; i < copySize; i++)
260 memcpy(newp,oldp,copySize*
sizeof(Element));
269 template<
class Element>
273 this->fIsOwner =
kTRUE;
282 if (no_rows < 0 || no_cols < 0)
284 Error(
"Allocate",
"no_rows=%d no_cols=%d",no_rows,no_cols);
290 this->fNrows = no_rows;
291 this->fNcols = no_cols;
292 this->fRowLwb = row_lwb;
293 this->fColLwb = col_lwb;
294 this->fNelems = this->fNrows*this->fNcols;
296 if (this->fNelems > 0) {
297 fElements = New_m(this->fNelems);
299 memset(fElements,0,this->fNelems*
sizeof(Element));
307 template<
class Element>
312 Error(
"Plus",
"matrices not compatible");
317 Error(
"Plus",
"this->GetMatrixArray() == a.GetMatrixArray()");
322 Error(
"Plus",
"this->GetMatrixArray() == b.GetMatrixArray()");
329 Element * cp = this->GetMatrixArray();
330 const Element *
const cp_last = cp+this->fNelems;
332 while (cp < cp_last) {
341 template<
class Element>
346 Error(
"Minus",
"matrices not compatible");
351 Error(
"Minus",
"this->GetMatrixArray() == a.GetMatrixArray()");
356 Error(
"Minus",
"this->GetMatrixArray() == b.GetMatrixArray()");
363 Element * cp = this->GetMatrixArray();
364 const Element *
const cp_last = cp+this->fNelems;
366 while (cp < cp_last) {
376 template<
class Element>
383 Element *cp = this->GetMatrixArray();
384 if (
typeid(Element) ==
typeid(
Double_t))
385 cblas_dgemm (CblasRowMajor,CblasTrans,CblasNoTrans,this->fNrows,this->fNcols,a.
GetNrows(),
387 else if (
typeid(Element) !=
typeid(
Float_t))
388 cblas_sgemm (CblasRowMajor,CblasTrans,CblasNoTrans,fNrows,fNcols,a.
GetNrows(),
391 Error(
"TMult",
"type %s not implemented in BLAS library",
typeid(Element));
395 const Int_t ncolsb = ncolsa;
397 const Element *
const bp = ap;
398 Element * cp = this->GetMatrixArray();
400 const Element *acp0 = ap;
402 for (
const Element *bcp = bp; bcp < bp+ncolsb; ) {
403 const Element *acp = acp0;
405 while (bcp < bp+nb) {
416 R__ASSERT(cp == this->GetMatrixArray()+this->fNelems && acp0 == ap+ncolsa);
424 template<
class Element>
431 Element *cp = this->GetMatrixArray();
432 if (
typeid(Element) ==
typeid(
Double_t))
433 cblas_dsymm (CblasRowMajor,CblasLeft,CblasUpper,this->fNrows,this->fNcols,1.0,
435 else if (
typeid(Element) !=
typeid(
Float_t))
436 cblas_ssymm (CblasRowMajor,CblasLeft,CblasUpper,fNrows,fNcols,1.0,
439 Error(
"TMult",
"type %s not implemented in BLAS library",
typeid(Element));
443 const Int_t ncolsb = ncolsa;
445 const Element *
const bp = ap;
446 Element * cp = this->GetMatrixArray();
448 const Element *acp0 = ap;
450 for (
const Element *bcp = bp; bcp < bp+ncolsb; ) {
451 const Element *acp = acp0;
453 while (bcp < bp+nb) {
464 R__ASSERT(cp == this->GetMatrixArray()+this->fNelems && acp0 == ap+ncolsa);
470 template<
class Element>
475 Error(
"Use",
"row_upb=%d < row_lwb=%d",row_upb,row_lwb);
480 this->fNrows = row_upb-row_lwb+1;
481 this->fNcols = this->fNrows;
482 this->fRowLwb = row_lwb;
483 this->fColLwb = row_lwb;
484 this->fNelems = this->fNrows*this->fNcols;
498 template<
class Element>
504 if (row_lwb < this->fRowLwb || row_lwb > this->fRowLwb+this->fNrows-1) {
505 Error(
"GetSub",
"row_lwb out of bounds");
508 if (row_upb < this->fRowLwb || row_upb > this->fRowLwb+this->fNrows-1) {
509 Error(
"GetSub",
"row_upb out of bounds");
512 if (row_upb < row_lwb) {
513 Error(
"GetSub",
"row_upb < row_lwb");
526 row_upb_sub = row_upb-row_lwb;
528 row_lwb_sub = row_lwb;
529 row_upb_sub = row_upb;
532 target.
ResizeTo(row_lwb_sub,row_upb_sub,row_lwb_sub,row_upb_sub);
533 const Int_t nrows_sub = row_upb_sub-row_lwb_sub+1;
536 for (
Int_t irow = 0; irow < nrows_sub; irow++) {
537 for (
Int_t icol = 0; icol < nrows_sub; icol++) {
538 target(irow+row_lwb_sub,icol+row_lwb_sub) = (*this)(row_lwb+irow,row_lwb+icol);
542 const Element *ap = this->GetMatrixArray()+(row_lwb-this->fRowLwb)*this->fNrows+(row_lwb-this->fRowLwb);
545 for (
Int_t irow = 0; irow < nrows_sub; irow++) {
546 const Element *ap_sub = ap;
547 for (
Int_t icol = 0; icol < nrows_sub; icol++) {
564 template<
class Element>
570 if (row_lwb < this->fRowLwb || row_lwb > this->fRowLwb+this->fNrows-1) {
571 Error(
"GetSub",
"row_lwb out of bounds");
574 if (col_lwb < this->fColLwb || col_lwb > this->fColLwb+this->fNcols-1) {
575 Error(
"GetSub",
"col_lwb out of bounds");
578 if (row_upb < this->fRowLwb || row_upb > this->fRowLwb+this->fNrows-1) {
579 Error(
"GetSub",
"row_upb out of bounds");
582 if (col_upb < this->fColLwb || col_upb > this->fColLwb+this->fNcols-1) {
583 Error(
"GetSub",
"col_upb out of bounds");
586 if (row_upb < row_lwb || col_upb < col_lwb) {
587 Error(
"GetSub",
"row_upb < row_lwb || col_upb < col_lwb");
596 const Int_t row_lwb_sub = (shift) ? 0 : row_lwb;
597 const Int_t row_upb_sub = (shift) ? row_upb-row_lwb : row_upb;
598 const Int_t col_lwb_sub = (shift) ? 0 : col_lwb;
599 const Int_t col_upb_sub = (shift) ? col_upb-col_lwb : col_upb;
601 target.
ResizeTo(row_lwb_sub,row_upb_sub,col_lwb_sub,col_upb_sub);
602 const Int_t nrows_sub = row_upb_sub-row_lwb_sub+1;
603 const Int_t ncols_sub = col_upb_sub-col_lwb_sub+1;
606 for (
Int_t irow = 0; irow < nrows_sub; irow++) {
607 for (
Int_t icol = 0; icol < ncols_sub; icol++) {
608 target(irow+row_lwb_sub,icol+col_lwb_sub) = (*this)(row_lwb+irow,col_lwb+icol);
612 const Element *ap = this->GetMatrixArray()+(row_lwb-this->fRowLwb)*this->fNcols+(col_lwb-this->fColLwb);
615 for (
Int_t irow = 0; irow < nrows_sub; irow++) {
616 const Element *ap_sub = ap;
617 for (
Int_t icol = 0; icol < ncols_sub; icol++) {
631 template<
class Element>
639 Error(
"SetSub",
"source matrix is not symmetric");
642 if (row_lwb < this->fRowLwb || row_lwb > this->fRowLwb+this->fNrows-1) {
643 Error(
"SetSub",
"row_lwb outof bounds");
646 if (row_lwb+source.
GetNrows() > this->fRowLwb+this->fNrows) {
647 Error(
"SetSub",
"source matrix too large");
656 for (
Int_t irow = 0; irow < nRows_source; irow++) {
657 for (
Int_t icol = 0; icol < nRows_source; icol++) {
658 (*this)(row_lwb+irow,row_lwb+icol) = source(rowlwb_s+irow,rowlwb_s+icol);
663 Element *ap = this->GetMatrixArray()+(row_lwb-this->fRowLwb)*this->fNrows+(row_lwb-this->fRowLwb);
665 for (
Int_t irow = 0; irow < nRows_source; irow++) {
666 Element *ap_sub = ap;
667 for (
Int_t icol = 0; icol < nRows_source; icol++) {
681 template<
class Element>
688 if (row_lwb < this->fRowLwb || row_lwb > this->fRowLwb+this->fNrows-1) {
689 Error(
"SetSub",
"row_lwb out of bounds");
692 if (col_lwb < this->fColLwb || col_lwb > this->fColLwb+this->fNcols-1) {
693 Error(
"SetSub",
"col_lwb out of bounds");
697 if (row_lwb+source.
GetNrows() > this->fRowLwb+this->fNrows || col_lwb+source.
GetNcols() > this->fRowLwb+this->fNrows) {
698 Error(
"SetSub",
"source matrix too large");
701 if (col_lwb+source.
GetNcols() > this->fRowLwb+this->fNrows || row_lwb+source.
GetNrows() > this->fRowLwb+this->fNrows) {
702 Error(
"SetSub",
"source matrix too large");
712 if (row_lwb >= col_lwb) {
715 for (irow = 0; irow < nRows_source; irow++) {
716 for (
Int_t icol = 0; col_lwb+icol <= row_lwb+irow &&
717 icol < nCols_source; icol++) {
718 (*this)(row_lwb+irow,col_lwb+icol) = source(irow+rowlwb_s,icol+collwb_s);
723 for (irow = 0; irow < nCols_source; irow++) {
724 for (
Int_t icol = nRows_source-1; row_lwb+icol > irow+col_lwb &&
726 (*this)(col_lwb+irow,row_lwb+icol) = source(icol+rowlwb_s,irow+collwb_s);
738 template<
class Element>
742 if (!this->IsSymmetric()) {
743 Error(
"SetMatrixArray",
"Matrix is not symmetric after Set");
751 template<
class Element>
754 if (row_shift != col_shift) {
755 Error(
"Shift",
"row_shift != col_shift");
766 template<
class Element>
770 if (!this->fIsOwner) {
771 Error(
"ResizeTo(Int_t,Int_t)",
"Not owner of data array,cannot resize");
775 if (nrows != ncols) {
776 Error(
"ResizeTo(Int_t,Int_t)",
"nrows != ncols");
780 if (this->fNelems > 0) {
781 if (this->fNrows == nrows && this->fNcols == ncols)
783 else if (nrows == 0 || ncols == 0) {
784 this->fNrows = nrows; this->fNcols = ncols;
789 Element *elements_old = GetMatrixArray();
790 const Int_t nelems_old = this->fNelems;
791 const Int_t nrows_old = this->fNrows;
792 const Int_t ncols_old = this->fNcols;
797 Element *elements_new = GetMatrixArray();
800 if (this->fNelems > this->kSizeMax || nelems_old > this->kSizeMax)
801 memset(elements_new,0,this->fNelems*
sizeof(Element));
802 else if (this->fNelems > nelems_old)
803 memset(elements_new+nelems_old,0,(this->fNelems-nelems_old)*
sizeof(Element));
809 const Int_t nelems_new = this->fNelems;
810 if (ncols_old < this->fNcols) {
811 for (
Int_t i = nrows_copy-1; i >= 0; i--) {
812 Memcpy_m(elements_new+i*this->fNcols,elements_old+i*ncols_old,ncols_copy,
813 nelems_new,nelems_old);
814 if (this->fNelems <= this->kSizeMax && nelems_old <= this->kSizeMax)
815 memset(elements_new+i*this->fNcols+ncols_copy,0,(this->fNcols-ncols_copy)*
sizeof(Element));
818 for (
Int_t i = 0; i < nrows_copy; i++)
819 Memcpy_m(elements_new+i*this->fNcols,elements_old+i*ncols_old,ncols_copy,
820 nelems_new,nelems_old);
823 Delete_m(nelems_old,elements_old);
836 template<
class Element>
841 if (!this->fIsOwner) {
842 Error(
"ResizeTo(Int_t,Int_t,Int_t,Int_t)",
"Not owner of data array,cannot resize");
846 if (row_lwb != col_lwb) {
847 Error(
"ResizeTo(Int_t,Int_t,Int_t,Int_t)",
"row_lwb != col_lwb");
850 if (row_upb != col_upb) {
851 Error(
"ResizeTo(Int_t,Int_t,Int_t,Int_t)",
"row_upb != col_upb");
855 const Int_t new_nrows = row_upb-row_lwb+1;
856 const Int_t new_ncols = col_upb-col_lwb+1;
858 if (this->fNelems > 0) {
860 if (this->fNrows == new_nrows && this->fNcols == new_ncols &&
861 this->fRowLwb == row_lwb && this->fColLwb == col_lwb)
863 else if (new_nrows == 0 || new_ncols == 0) {
864 this->fNrows = new_nrows; this->fNcols = new_ncols;
865 this->fRowLwb = row_lwb; this->fColLwb = col_lwb;
870 Element *elements_old = GetMatrixArray();
871 const Int_t nelems_old = this->fNelems;
872 const Int_t nrows_old = this->fNrows;
873 const Int_t ncols_old = this->fNcols;
874 const Int_t rowLwb_old = this->fRowLwb;
875 const Int_t colLwb_old = this->fColLwb;
877 Allocate(new_nrows,new_ncols,row_lwb,col_lwb);
880 Element *elements_new = GetMatrixArray();
883 if (this->fNelems > this->kSizeMax || nelems_old > this->kSizeMax)
884 memset(elements_new,0,this->fNelems*
sizeof(Element));
885 else if (this->fNelems > nelems_old)
886 memset(elements_new+nelems_old,0,(this->fNelems-nelems_old)*
sizeof(Element));
891 const Int_t rowUpb_copy =
TMath::Min(this->fRowLwb+this->fNrows-1,rowLwb_old+nrows_old-1);
892 const Int_t colUpb_copy =
TMath::Min(this->fColLwb+this->fNcols-1,colLwb_old+ncols_old-1);
894 const Int_t nrows_copy = rowUpb_copy-rowLwb_copy+1;
895 const Int_t ncols_copy = colUpb_copy-colLwb_copy+1;
897 if (nrows_copy > 0 && ncols_copy > 0) {
898 const Int_t colOldOff = colLwb_copy-colLwb_old;
899 const Int_t colNewOff = colLwb_copy-this->fColLwb;
900 if (ncols_old < this->fNcols) {
901 for (
Int_t i = nrows_copy-1; i >= 0; i--) {
902 const Int_t iRowOld = rowLwb_copy+i-rowLwb_old;
903 const Int_t iRowNew = rowLwb_copy+i-this->fRowLwb;
904 Memcpy_m(elements_new+iRowNew*this->fNcols+colNewOff,
905 elements_old+iRowOld*ncols_old+colOldOff,ncols_copy,this->fNelems,nelems_old);
906 if (this->fNelems <= this->kSizeMax && nelems_old <= this->kSizeMax)
907 memset(elements_new+iRowNew*this->fNcols+colNewOff+ncols_copy,0,
908 (this->fNcols-ncols_copy)*
sizeof(Element));
911 for (
Int_t i = 0; i < nrows_copy; i++) {
912 const Int_t iRowOld = rowLwb_copy+i-rowLwb_old;
913 const Int_t iRowNew = rowLwb_copy+i-this->fRowLwb;
914 Memcpy_m(elements_new+iRowNew*this->fNcols+colNewOff,
915 elements_old+iRowOld*ncols_old+colOldOff,ncols_copy,this->fNelems,nelems_old);
920 Delete_m(nelems_old,elements_old);
922 Allocate(new_nrows,new_ncols,row_lwb,col_lwb,1);
930 template<
class Element>
942 template<
class Element>
956 template<
class Element>
963 Element *
p2 = this->GetMatrixArray();
964 for (
Int_t i = 0; i < this->GetNoElements(); i++)
974 template<
class Element>
983 Element *pM = this->GetMatrixArray();
985 Error(
"InvertFast",
"matrix is singular");
995 TMatrixTSymCramerInv::Inv2x2<Element>(*
this,det);
1000 TMatrixTSymCramerInv::Inv3x3<Element>(*
this,det);
1005 TMatrixTSymCramerInv::Inv4x4<Element>(*
this,det);
1010 TMatrixTSymCramerInv::Inv5x5<Element>(*
this,det);
1015 TMatrixTSymCramerInv::Inv6x6<Element>(*
this,det);
1024 Element *
p2 = this->GetMatrixArray();
1025 for (
Int_t i = 0; i < this->GetNoElements(); i++)
1036 template<
class Element>
1045 Error(
"Transpose",
"matrix has wrong shape");
1058 template<
class Element>
1065 Error(
"Rank1Update",
"vector too short");
1071 Element *trp = this->GetMatrixArray();
1073 for (
Int_t i = 0; i < this->fNrows; i++) {
1075 tcp += i*this->fNcols;
1076 const Element tmp = alpha*pv[i];
1077 for (
Int_t j = i; j < this->fNcols; j++) {
1078 if (j > i) *tcp += tmp*pv[j];
1079 *trp++ += tmp*pv[j];
1080 tcp += this->fNcols;
1082 tcp -= this->fNelems-1;
1094 template<
class Element>
1101 Error(
"Similarity(const TMatrixT &)",
"matrices incompatible");
1106 const Int_t ncolsa = this->fNcols;
1113 Element work[kWorkMax];
1115 Element *bap = work;
1116 if (nrowsb*ncolsa > kWorkMax) {
1117 isAllocated =
kTRUE;
1118 bap =
new Element[nrowsb*ncolsa];
1121 AMultB(bp,nb,ncolsb,this->fElements,this->fNelems,this->fNcols,bap);
1123 if (nrowsb != this->fNrows)
1124 this->ResizeTo(nrowsb,nrowsb);
1127 Element *cp = this->GetMatrixArray();
1128 if (
typeid(Element) ==
typeid(
Double_t))
1129 cblas_dgemm (CblasRowMajor,CblasNoTrans,CblasTrans,this->fNrows,this->fNcols,ba.GetNcols(),
1130 1.0,bap,ba.GetNcols(),bp,b.
GetNcols(),1.0,cp,this->fNcols);
1131 else if (
typeid(Element) !=
typeid(
Float_t))
1132 cblas_sgemm (CblasRowMajor,CblasNoTrans,CblasTrans,this->fNrows,this->fNcols,ba.GetNcols(),
1133 1.0,bap,ba.GetNcols(),bp,b.
GetNcols(),1.0,cp,this->fNcols);
1135 Error(
"Similarity",
"type %s not implemented in BLAS library",
typeid(Element));
1137 const Int_t nba = nrowsb*ncolsa;
1138 const Int_t ncolsba = ncolsa;
1139 const Element * bi1p = bp;
1140 Element * cp = this->GetMatrixArray();
1141 Element *
const cp0 = cp;
1144 const Element *barp0 = bap;
1145 while (barp0 < bap+nba) {
1146 const Element *brp0 = bi1p;
1147 while (brp0 < bp+nb) {
1148 const Element *barp = barp0;
1149 const Element *brp = brp0;
1151 while (brp < brp0+ncolsb)
1152 cij += *barp++ * *brp++;
1161 R__ASSERT(cp == cp0+this->fNelems+ishift && barp0 == bap+nba);
1164 for (
Int_t irow = 0; irow < this->fNrows; irow++) {
1165 const Int_t rowOff1 = irow*this->fNrows;
1166 for (
Int_t icol = 0; icol < irow; icol++) {
1167 const Int_t rowOff2 = icol*this->fNrows;
1168 cp[rowOff1+icol] = cp[rowOff2+irow];
1185 template<
class Element>
1192 Error(
"Similarity(const TMatrixTSym &)",
"matrices incompatible");
1199 const Int_t ncolsa = this->GetNcols();
1201 Element work[kWorkMax];
1203 Element *abtp = work;
1204 if (this->fNcols > kWorkMax) {
1205 isAllocated =
kTRUE;
1206 abtp =
new Element[this->fNcols];
1212 Element *cp = this->GetMatrixArray();
1213 if (
typeid(Element) ==
typeid(
Double_t))
1214 cblas_dsymm (CblasRowMajor,CblasLeft,CblasUpper,this->fNrows,this->fNcols,1.0,
1216 else if (
typeid(Element) !=
typeid(
Float_t))
1217 cblas_ssymm (CblasRowMajor,CblasLeft,CblasUpper,this->fNrows,this->fNcols,1.0,
1220 Error(
"Similarity",
"type %s not implemented in BLAS library",
typeid(Element));
1225 const Int_t ncolsa = this->GetNcols();
1232 Element work[kWorkMax];
1234 Element *bap = work;
1235 if (nrowsb*ncolsa > kWorkMax) {
1236 isAllocated =
kTRUE;
1237 bap =
new Element[nrowsb*ncolsa];
1240 AMultB(bp,nb,ncolsb,this->fElements,this->fNelems,this->fNcols,bap);
1242 const Int_t nba = nrowsb*ncolsa;
1243 const Int_t ncolsba = ncolsa;
1244 const Element * bi1p = bp;
1245 Element * cp = this->GetMatrixArray();
1246 Element *
const cp0 = cp;
1249 const Element *barp0 = bap;
1250 while (barp0 < bap+nba) {
1251 const Element *brp0 = bi1p;
1252 while (brp0 < bp+nb) {
1253 const Element *barp = barp0;
1254 const Element *brp = brp0;
1256 while (brp < brp0+ncolsb)
1257 cij += *barp++ * *brp++;
1266 R__ASSERT(cp == cp0+this->fNelems+ishift && barp0 == bap+nba);
1269 for (
Int_t irow = 0; irow < this->fNrows; irow++) {
1270 const Int_t rowOff1 = irow*this->fNrows;
1271 for (
Int_t icol = 0; icol < irow; icol++) {
1272 const Int_t rowOff2 = icol*this->fNrows;
1273 cp[rowOff1+icol] = cp[rowOff2+irow];
1287 template<
class Element>
1293 if (this->fNcols != v.
GetNrows() || this->fColLwb != v.
GetLwb()) {
1294 Error(
"Similarity(const TVectorT &)",
"vector and matrix incompatible");
1299 const Element *mp = this->GetMatrixArray();
1303 const Element *
const vp_first = vp;
1304 const Element *
const vp_last = vp+v.
GetNrows();
1305 while (vp < vp_last) {
1307 for (
const Element *sp = vp_first; sp < vp_last; )
1308 sum2 += *mp++ * *sp++;
1309 sum1 += sum2 * *vp++;
1312 R__ASSERT(mp == this->GetMatrixArray()+this->GetNoElements());
1322 template<
class Element>
1329 Error(
"SimilarityT(const TMatrixT &)",
"matrices incompatible");
1335 const Int_t ncolsa = this->GetNcols();
1337 Element work[kWorkMax];
1339 Element *btap = work;
1340 if (ncolsb*ncolsa > kWorkMax) {
1341 isAllocated =
kTRUE;
1342 btap =
new Element[ncolsb*ncolsa];
1348 if (ncolsb != this->fNcols)
1349 this->ResizeTo(ncolsb,ncolsb);
1353 Element *cp = this->GetMatrixArray();
1354 if (
typeid(Element) ==
typeid(
Double_t))
1355 cblas_dgemm (CblasRowMajor,CblasNoTrans,CblasNoTrans,this->fNrows,this->fNcols,bta.
GetNcols(),
1357 else if (
typeid(Element) !=
typeid(
Float_t))
1358 cblas_sgemm (CblasRowMajor,CblasNoTrans,CblasNoTrans,this->fNrows,this->fNcols,bta.
GetNcols(),
1361 Error(
"similarityT",
"type %s not implemented in BLAS library",
typeid(Element));
1367 Element * cp = this->GetMatrixArray();
1368 Element *
const cp0 = cp;
1371 const Element *btarp0 = btap;
1372 const Element *bcp0 = bp;
1373 while (btarp0 < btap+nbta) {
1374 for (
const Element *bcp = bcp0; bcp < bp+ncolsb; ) {
1375 const Element *btarp = btarp0;
1377 while (bcp < bp+nb) {
1378 cij += *btarp++ * *bcp;
1389 R__ASSERT(cp == cp0+this->fNelems+ishift && btarp0 == btap+nbta);
1392 for (
Int_t irow = 0; irow < this->fNrows; irow++) {
1393 const Int_t rowOff1 = irow*this->fNrows;
1394 for (
Int_t icol = 0; icol < irow; icol++) {
1395 const Int_t rowOff2 = icol*this->fNrows;
1396 cp[rowOff1+icol] = cp[rowOff2+irow];
1409 template<
class Element>
1413 Error(
"operator=",
"matrices not compatible");
1419 memcpy(this->GetMatrixArray(),source.
fElements,this->fNelems*
sizeof(Element));
1426 template<
class Element>
1431 if (lazy_constructor.
fRowUpb != this->GetRowUpb() ||
1432 lazy_constructor.
fRowLwb != this->GetRowLwb()) {
1433 Error(
"operator=(const TMatrixTSymLazy&)",
"matrix is incompatible with "
1434 "the assigned Lazy matrix");
1438 lazy_constructor.
FillIn(*
this);
1445 template<
class Element>
1450 Element *ep = fElements;
1451 const Element *
const ep_last = ep+this->fNelems;
1452 while (ep < ep_last)
1461 template<
class Element>
1466 Element *ep = fElements;
1467 const Element *
const ep_last = ep+this->fNelems;
1468 while (ep < ep_last)
1477 template<
class Element>
1482 Element *ep = fElements;
1483 const Element *
const ep_last = ep+this->fNelems;
1484 while (ep < ep_last)
1493 template<
class Element>
1498 Element *ep = fElements;
1499 const Element *
const ep_last = ep+this->fNelems;
1500 while (ep < ep_last)
1509 template<
class Element>
1513 Error(
"operator+=",
"matrices not compatible");
1518 Element *tp = this->GetMatrixArray();
1519 const Element *
const tp_last = tp+this->fNelems;
1520 while (tp < tp_last)
1529 template<
class Element>
1533 Error(
"operator-=",
"matrices not compatible");
1538 Element *tp = this->GetMatrixArray();
1539 const Element *
const tp_last = tp+this->fNelems;
1540 while (tp < tp_last)
1548 template<
class Element>
1554 Element *trp = this->GetMatrixArray();
1556 for (
Int_t i = 0; i < this->fNrows; i++) {
1558 tcp += i*this->fNcols;
1559 for (
Int_t j = i; j < this->fNcols; j++) {
1561 if (j > i) *tcp = val;
1563 tcp += this->fNcols;
1565 tcp -= this->fNelems-1;
1575 template<
class Element>
1581 Element *trp = this->GetMatrixArray();
1583 for (
Int_t i = 0; i < this->fNrows; i++) {
1584 action.
fI = i+this->fRowLwb;
1586 tcp += i*this->fNcols;
1587 for (
Int_t j = i; j < this->fNcols; j++) {
1588 action.
fJ = j+this->fColLwb;
1590 if (j > i) *tcp = val;
1592 tcp += this->fNcols;
1594 tcp -= this->fNelems-1;
1603 template<
class Element>
1608 if (this->fNrows != this->fNcols || this->fRowLwb != this->fColLwb) {
1609 Error(
"Randomize(Element,Element,Element &",
"matrix should be square");
1614 const Element scale = beta-alpha;
1615 const Element shift = alpha/scale;
1617 Element *ep = GetMatrixArray();
1618 for (
Int_t i = 0; i < this->fNrows; i++) {
1619 const Int_t off = i*this->fNcols;
1620 for (
Int_t j = 0; j <= i; j++) {
1621 ep[off+j] = scale*(
Drand(seed)+shift);
1623 ep[j*this->fNcols+i] = ep[off+j];
1634 template<
class Element>
1639 if (this->fNrows != this->fNcols || this->fRowLwb != this->fColLwb) {
1640 Error(
"RandomizeSym(Element,Element,Element &",
"matrix should be square");
1645 const Element scale = beta-alpha;
1646 const Element shift = alpha/scale;
1648 Element *ep = GetMatrixArray();
1650 for (i = 0; i < this->fNrows; i++) {
1651 const Int_t off = i*this->fNcols;
1652 for (
Int_t j = 0; j <= i; j++)
1653 ep[off+j] = scale*(
Drand(seed)+shift);
1656 for (i = this->fNrows-1; i >= 0; i--) {
1657 const Int_t off1 = i*this->fNcols;
1658 for (
Int_t j = i; j >= 0; j--) {
1659 const Int_t off2 = j*this->fNcols;
1660 ep[off1+j] *= ep[off2+j];
1661 for (
Int_t k = j-1; k >= 0; k--) {
1662 ep[off1+j] += ep[off1+k]*ep[off2+k];
1665 ep[off2+i] = ep[off1+j];
1676 template<
class Element>
1679 TMatrixDSym tmp = *
this;
1681 eigenValues.
ResizeTo(this->fNrows);
1689 template<
class Element>
1699 template<
class Element>
1709 template<
class Element>
1719 template<
class Element>
1727 template<
class Element>
1737 template<
class Element>
1747 template<
class Element>
1750 return Element(-1.0)*
operator-(source1,val);
1755 template<
class Element>
1765 template<
class Element>
1774 template<
class Element>
1780 Error(
"operator&&(const TMatrixTSym&,const TMatrixTSym&)",
"matrices not compatible");
1790 while (tp < tp_last)
1791 *tp++ = (*sp1++ != 0.0 && *sp2++ != 0.0);
1799 template<
class Element>
1805 Error(
"operator||(const TMatrixTSym&,const TMatrixTSym&)",
"matrices not compatible");
1815 while (tp < tp_last)
1816 *tp++ = (*sp1++ != 0.0 || *sp2++ != 0.0);
1824 template<
class Element>
1830 Error(
"operator>(const TMatrixTSym&,const TMatrixTSym&)",
"matrices not compatible");
1840 while (tp < tp_last) {
1841 *tp++ = (*sp1) > (*sp2); sp1++; sp2++;
1850 template<
class Element>
1856 Error(
"operator>=(const TMatrixTSym&,const TMatrixTSym&)",
"matrices not compatible");
1866 while (tp < tp_last) {
1867 *tp++ = (*sp1) >= (*sp2); sp1++; sp2++;
1876 template<
class Element>
1882 Error(
"operator<=(const TMatrixTSym&,const TMatrixTSym&)",
"matrices not compatible");
1889 const Element *sp2 = source2.GetMatrixArray();
1892 while (tp < tp_last) {
1893 *tp++ = (*sp1) <= (*sp2); sp1++; sp2++;
1902 template<
class Element>
1908 Error(
"operator<(const TMatrixTSym&,const TMatrixTSym&)",
"matrices not compatible");
1915 const Element *sp2 = source2.GetMatrixArray();
1918 while (tp < tp_last) {
1919 *tp++ = (*sp1) < (*sp2); sp1++; sp2++;
1928 template<
class Element>
1932 ::Error(
"Add",
"matrices not compatible");
1942 for (
Int_t i = 0; i < nrows; i++) {
1946 for (
Int_t j = i; j < ncols; j++) {
1947 const Element tmp = scalar * *sp++;
1948 if (j > i) *tcp += tmp;
1961 template<
class Element>
1965 ::Error(
"ElementMult",
"matrices not compatible");
1975 for (
Int_t i = 0; i < nrows; i++) {
1979 for (
Int_t j = i; j < ncols; j++) {
1980 if (j > i) *tcp *= *sp;
1993 template<
class Element>
1997 ::Error(
"ElementDiv",
"matrices not compatible");
2007 for (
Int_t i = 0; i < nrows; i++) {
2011 for (
Int_t j = i; j < ncols; j++) {
2013 if (j > i) *tcp /= *sp;
2018 Error(
"ElementDiv",
"source (%d,%d) is zero",irow,icol);
2032 template<
class Element>
2040 fElements =
new Element[this->fNelems];
2042 for (i = 0; i < this->fNrows; i++) {
2043 R__b.
ReadFastArray(fElements+i*this->fNcols+i,this->fNcols-i);
2046 for (i = 0; i < this->fNrows; i++) {
2047 for (
Int_t j = 0; j < i; j++) {
2048 fElements[i*this->fNcols+j] = fElements[j*this->fNrows+i];
2051 if (this->fNelems <= this->kSizeMax) {
2052 memcpy(fDataStack,fElements,this->fNelems*
sizeof(Element));
2053 delete [] fElements;
2054 fElements = fDataStack;
2059 for (
Int_t i = 0; i < this->fNrows; i++) {
2065 #ifndef ROOT_TMatrixFSymfwd
2071 template Bool_t operator== <
Float_t>(
const TMatrixFSym &source1,
const TMatrixFSym &source2);
2072 template TMatrixFSym
operator+ <
Float_t>(
const TMatrixFSym &source1,
const TMatrixFSym &source2);
2073 template TMatrixFSym
operator+ <
Float_t>(
const TMatrixFSym &source1,
Float_t val);
2074 template TMatrixFSym
operator+ <
Float_t>(
Float_t val ,
const TMatrixFSym &source2);
2075 template TMatrixFSym
operator- <
Float_t>(
const TMatrixFSym &source1,
const TMatrixFSym &source2);
2076 template TMatrixFSym
operator- <
Float_t>(
const TMatrixFSym &source1,
Float_t val);
2077 template TMatrixFSym
operator- <
Float_t>(
Float_t val ,
const TMatrixFSym &source2);
2078 template TMatrixFSym
operator* <
Float_t>(
const TMatrixFSym &source,
Float_t val );
2079 template TMatrixFSym
operator* <
Float_t>(
Float_t val,
const TMatrixFSym &source );
2080 template TMatrixFSym
operator&& <
Float_t>(
const TMatrixFSym &source1,
const TMatrixFSym &source2);
2081 template TMatrixFSym
operator|| <
Float_t>(
const TMatrixFSym &source1,
const TMatrixFSym &source2);
2082 template TMatrixFSym
operator> <
Float_t>(
const TMatrixFSym &source1,
const TMatrixFSym &source2);
2083 template TMatrixFSym
operator>= <
Float_t>(
const TMatrixFSym &source1,
const TMatrixFSym &source2);
2084 template TMatrixFSym
operator<= <Float_t>(
const TMatrixFSym &source1,
const TMatrixFSym &source2);
2085 template TMatrixFSym
operator< <Float_t>(
const TMatrixFSym &source1,
const TMatrixFSym &source2);
2087 template TMatrixFSym &
Add <Float_t>(TMatrixFSym &target,
Float_t scalar,
const TMatrixFSym &source);
2091 #ifndef ROOT_TMatrixDSymfwd
2095 template class TMatrixTSym<Double_t>;
2097 template Bool_t operator== <
Double_t>(
const TMatrixDSym &source1,
const TMatrixDSym &source2);
2098 template TMatrixDSym
operator+ <
Double_t>(
const TMatrixDSym &source1,
const TMatrixDSym &source2);
2099 template TMatrixDSym
operator+ <
Double_t>(
const TMatrixDSym &source1,
Double_t val);
2100 template TMatrixDSym
operator+ <
Double_t>(
Double_t val ,
const TMatrixDSym &source2);
2101 template TMatrixDSym
operator- <
Double_t>(
const TMatrixDSym &source1,
const TMatrixDSym &source2);
2102 template TMatrixDSym
operator- <
Double_t>(
const TMatrixDSym &source1,
Double_t val);
2103 template TMatrixDSym
operator- <
Double_t>(
Double_t val ,
const TMatrixDSym &source2);
2104 template TMatrixDSym
operator* <
Double_t>(
const TMatrixDSym &source,
Double_t val );
2105 template TMatrixDSym
operator* <
Double_t>(
Double_t val,
const TMatrixDSym &source );
2106 template TMatrixDSym
operator&& <
Double_t>(
const TMatrixDSym &source1,
const TMatrixDSym &source2);
2107 template TMatrixDSym
operator|| <
Double_t>(
const TMatrixDSym &source1,
const TMatrixDSym &source2);
2108 template TMatrixDSym
operator> <
Double_t>(
const TMatrixDSym &source1,
const TMatrixDSym &source2);
2109 template TMatrixDSym
operator>= <
Double_t>(
const TMatrixDSym &source1,
const TMatrixDSym &source2);
2111 template TMatrixDSym
operator< <Double_t>(
const TMatrixDSym &source1,
const TMatrixDSym &source2);
TMatrixTSym< Element > & SimilarityT(const TMatrixT< Element > &n)
Calculate B^T * (*this) * B , final matrix will be (ncolsb x ncolsb) It is more efficient than applyi...
const TVectorD & GetEigenValues() const
virtual const Element * GetMatrixArray() const =0
virtual TMatrixTBase< Element > & Shift(Int_t row_shift, Int_t col_shift)
Shift the row index by adding row_shift and the column index by adding col_shift, respectively...
virtual TMatrixTBase< Element > & Shift(Int_t row_shift, Int_t col_shift)
Shift the row index by adding row_shift and the column index by adding col_shift, respectively...
template TMatrixFSym operator<=< Float_t >(const TMatrixFSym &source1, const TMatrixFSym &source2)
int Invert(LASymMatrix &)
TVectorT< Element > & ResizeTo(Int_t lwb, Int_t upb)
Resize the vector to [lwb:upb] .
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y)
template TMatrixDSym operator<< Double_t >(const TMatrixDSym &source1, const TMatrixDSym &source2)
TMatrixTSym< Element > & ElementMult(TMatrixTSym< Element > &target, const TMatrixTSym< Element > &source)
Multiply target by the source, element-by-element.
virtual TMatrixTBase< Element > & ResizeTo(Int_t nrows, Int_t ncols, Int_t=-1)
Set size of the matrix to nrows x ncols New dynamic elements are created, the overlapping part of the...
TMatrixTSym< Element > & Use(Int_t row_lwb, Int_t row_upb, Element *data)
Small helper to encapsulate whether to return the value pointed to by the iterator or its address...
virtual TMatrixTBase< Element > & SetMatrixArray(const Element *data, Option_t *option="")
Copy array data to matrix .
TMatrixTSym< Element > & Add(TMatrixTSym< Element > &target, Element scalar, const TMatrixTSym< Element > &source)
Modify addition: target += scalar * source.
void Allocate(Int_t nrows, Int_t ncols, Int_t row_lwb=0, Int_t col_lwb=0, Int_t init=0, Int_t=-1)
Allocate new matrix.
TMatrixTSym< Element > & operator=(const TMatrixTSym< Element > &source)
templateClassImp(TMatrixTSym) template< class Element > TMatrixTSym< Element >
const TMatrixT< Element > EigenVectors(TVectorT< Element > &eigenValues) const
Return a matrix containing the eigen-vectors ordered by descending eigen-values.
TMatrixTSym< Element > & ElementDiv(TMatrixTSym< Element > &target, const TMatrixTSym< Element > &source)
Multiply target by the source, element-by-element.
TMatrixTSym< Element > operator>=(const TMatrixTSym< Element > &source1, const TMatrixTSym< Element > &source2)
source1 >= source2
void ToUpper()
Change string to upper case.
Buffer base class used for serializing objects.
void TMult(const TMatrixT< Element > &a)
Create a matrix C such that C = A' * A.
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.
static Bool_t InvertLU(TMatrixD &a, Double_t tol, Double_t *det=0)
Calculate matrix inversion through in place forward/backward substitution.
Short_t Min(Short_t a, Short_t b)
virtual void Det(Double_t &d1, Double_t &d2)
Calculate determinant det = d1*TMath::Power(2.,d2)
TMatrixTSym< Element > & operator*=(Element val)
Multiply every element of the matrix with val.
virtual TMatrixTBase< Element > & ResizeTo(Int_t nrows, Int_t ncols, Int_t nr_nonzeros=-1)=0
template TMatrixFSym operator<< Float_t >(const TMatrixFSym &source1, const TMatrixFSym &source2)
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
TMatrixTSym< Element > & Rank1Update(const TVectorT< Element > &v, Element alpha=1.0)
Perform a rank 1 operation on the matrix: A += alpha * v * v^T.
double beta(double x, double y)
Calculates the beta function.
virtual Bool_t IsSymmetric() const
Check whether matrix is symmetric.
template TMatrixDSym & ElementDiv< Double_t >(TMatrixDSym &target, const TMatrixDSym &source)
TMatrixTSym< Element > & operator+=(Element val)
Add val to every element of the matrix.
virtual void Operation(Element &element) const =0
virtual Double_t Determinant() const
void AMultB(int n, int m, int k, const double *A, const double *B, double *C)
template TMatrixDSym & ElementMult< Double_t >(TMatrixDSym &target, const TMatrixDSym &source)
TMatrixTSym< Element > operator&&(const TMatrixTSym< Element > &source1, const TMatrixTSym< Element > &source2)
Logical AND.
static double p2(double t, double a, double b, double c)
TObject & operator=(const TObject &rhs)
TObject assignment operator.
Bool_t AreCompatible(const TMatrixTBase< Element1 > &m1, const TMatrixTBase< Element2 > &m2, Int_t verbose=0)
Check that matrice sm1 and m2 areboth valid and have identical shapes .
void TMult(const TMatrixT< Element > &a, const TMatrixT< Element > &b)
Create a matrix C such that C = A' * B.
virtual TMatrixTBase< Element > & SetMatrixArray(const Element *data, Option_t *option="")
Copy array data to matrix .
virtual void FillIn(TMatrixTSym< Element > &m) const =0
void Error(const char *location, const char *msgfmt,...)
void Minus(const TMatrixTSym< Element > &a, const TMatrixTSym< Element > &b)
Symmetric matrix summation. Create a matrix C such that C = A + B.
virtual const Element * GetMatrixArray() const
TMatrixTSym< Element > operator>(const TMatrixTSym< Element > &source1, const TMatrixTSym< Element > &source2)
source1 > source2
Int_t Memcpy_m(Element *newp, const Element *oldp, Int_t copySize, Int_t newSize, Int_t oldSize)
copy copySize doubles from *oldp to *newp .
Element * GetMatrixArray()
TMatrixTBase< Element > & Apply(const TElementActionT< Element > &action)
Apply action to each matrix element.
template TMatrixFSym & Add< Float_t >(TMatrixFSym &target, Float_t scalar, const TMatrixFSym &source)
template TMatrixDSym operator<=< Double_t >(const TMatrixDSym &source1, const TMatrixDSym &source2)
template TMatrixFSym & ElementDiv< Float_t >(TMatrixFSym &target, const TMatrixFSym &source)
virtual const Element * GetMatrixArray() const
static double p1(double t, double a, double b)
Bool_t operator==(const TMatrixTSym< Element > &m1, const TMatrixTSym< Element > &m2)
Check to see if two matrices are identical.
R__EXTERN Int_t gMatrixCheck
virtual TMatrixTBase< Element > & Randomize(Element alpha, Element beta, Double_t &seed)
randomize matrix element values but keep matrix symmetric
virtual void ReadFastArray(Bool_t *b, Int_t n)=0
virtual void WriteFastArray(const Bool_t *b, Int_t n)=0
TMatrixTSym< Element > & Transpose(const TMatrixTSym< Element > &source)
Transpose a matrix.
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
void Plus(const TMatrixTSym< Element > &a, const TMatrixTSym< Element > &b)
Symmetric matrix summation. Create a matrix C such that C = A + B.
TMatrixTSym< Element > & operator-=(Element val)
Subtract val from every element of the matrix.
const TMatrixD & GetEigenVectors() const
virtual TMatrixTSym< Element > & RandomizePD(Element alpha, Element beta, Double_t &seed)
randomize matrix element values but keep matrix symmetric positive definite
TMatrixTSym< Element > & InvertFast(Double_t *det=0)
Invert the matrix and calculate its determinant.
TMatrixTSym< Element > & SetSub(Int_t row_lwb, const TMatrixTBase< Element > &source)
Insert matrix source starting at [row_lwb][row_lwb], thereby overwriting the part [row_lwb...
TMatrixTSym< Element > & Similarity(const TMatrixT< Element > &n)
Calculate B * (*this) * B^T , final matrix will be (nrowsb x nrowsb) This is a similarity transform w...
virtual const Int_t * GetRowIndexArray() const
void Delete_m(Int_t size, Element *&)
delete data pointer m, if it was assigned on the heap
virtual void Operation(Element &element) const =0
TCppObject_t Allocate(TCppType_t type)
TMatrixT< Element > & Use(Int_t row_lwb, Int_t row_upb, Int_t col_lwb, Int_t col_upb, Element *data)
Use the array data to fill the matrix ([row_lwb..row_upb] x [col_lwb..col_upb])
TMatrixTSym< Element > & Invert(Double_t *det=0)
Invert the matrix and calculate its determinant Notice that the LU decomposition is used instead of B...
TMatrixTSym< Element > operator||(const TMatrixTSym< Element > &source1, const TMatrixTSym< Element > &source2)
Logical Or.
Int_t GetNoElements() const
virtual const Int_t * GetColIndexArray() const
TMatrixTSym< Element > operator+(const TMatrixTSym< Element > &source1, const TMatrixTSym< Element > &source2)
Short_t Max(Short_t a, Short_t b)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
template TMatrixDSym & Add< Double_t >(TMatrixDSym &target, Double_t scalar, const TMatrixDSym &source)
Element * New_m(Int_t size)
return data pointer .
TMatrixTSym< Element > operator*(const TMatrixTSym< Element > &source1, Element val)
template TMatrixFSym & ElementMult< Float_t >(TMatrixFSym &target, const TMatrixFSym &source)
Element * fElements
data container
Double_t Drand(Double_t &ix)
Random number generator [0....1] with seed ix.
TMatrixTSym< Element > operator-(const TMatrixTSym< Element > &source1, const TMatrixTSym< Element > &source2)
TMatrixTSym< Element > & GetSub(Int_t row_lwb, Int_t row_upb, TMatrixTSym< Element > &target, Option_t *option="S") const
Get submatrix [row_lwb..row_upb][row_lwb..row_upb]; The indexing range of the returned matrix depends...
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