34 templateClassImp(TMatrixTSym);
39 template<
class Element>
40 TMatrixTSym<Element>::TMatrixTSym(Int_t no_rows)
42 Allocate(no_rows,no_rows,0,0,1);
47 template<
class Element>
48 TMatrixTSym<Element>::TMatrixTSym(Int_t row_lwb,Int_t row_upb)
50 const Int_t no_rows = row_upb-row_lwb+1;
51 Allocate(no_rows,no_rows,row_lwb,row_lwb,1);
63 template<
class Element>
64 TMatrixTSym<Element>::TMatrixTSym(Int_t no_rows,
const Element *elements,Option_t *option)
66 Allocate(no_rows,no_rows);
67 SetMatrixArray(elements,option);
68 if (!this->IsSymmetric()) {
69 Error(
"TMatrixTSym(Int_t,Element*,Option_t*)",
"matrix not symmetric");
76 template<
class Element>
77 TMatrixTSym<Element>::TMatrixTSym(Int_t row_lwb,Int_t row_upb,
const Element *elements,Option_t *option)
79 const Int_t no_rows = row_upb-row_lwb+1;
80 Allocate(no_rows,no_rows,row_lwb,row_lwb);
81 SetMatrixArray(elements,option);
82 if (!this->IsSymmetric()) {
83 Error(
"TMatrixTSym(Int_t,Int_t,Element*,Option_t*)",
"matrix not symmetric");
89 template<
class Element>
90 TMatrixTSym<Element>::TMatrixTSym(
const TMatrixTSym<Element> &another) : TMatrixTBase<Element>(another)
92 R__ASSERT(another.IsValid());
93 Allocate(another.GetNrows(),another.GetNcols(),another.GetRowLwb(),another.GetColLwb());
102 template<
class Element>
103 TMatrixTSym<Element>::TMatrixTSym(EMatrixCreatorsOp1 op,
const TMatrixTSym<Element> &prototype)
105 R__ASSERT(prototype.IsValid());
109 Allocate(prototype.GetNrows(),prototype.GetNcols(),
110 prototype.GetRowLwb(),prototype.GetColLwb(),1);
114 Allocate(prototype.GetNrows(),prototype.GetNcols(),
115 prototype.GetRowLwb(),prototype.GetColLwb(),1);
120 Allocate(prototype.GetNcols(), prototype.GetNrows(),
121 prototype.GetColLwb(),prototype.GetRowLwb());
122 Transpose(prototype);
127 Allocate(prototype.GetNrows(),prototype.GetNcols(),
128 prototype.GetRowLwb(),prototype.GetColLwb(),1);
132 const Element oldTol = this->SetTol(std::numeric_limits<Element>::min());
134 this->SetTol(oldTol);
139 Allocate(prototype.GetNcols(),prototype.GetNcols(),prototype.GetColLwb(),prototype.GetColLwb(),1);
144 Error(
"TMatrixTSym(EMatrixCreatorOp1,const TMatrixTSym)",
145 "operation %d not yet implemented", op);
151 template<
class Element>
152 TMatrixTSym<Element>::TMatrixTSym(EMatrixCreatorsOp1 op,
const TMatrixT<Element> &prototype)
154 R__ASSERT(prototype.IsValid());
158 Allocate(prototype.GetNcols(),prototype.GetNcols(),prototype.GetColLwb(),prototype.GetColLwb(),1);
163 Error(
"TMatrixTSym(EMatrixCreatorOp1,const TMatrixT)",
164 "operation %d not yet implemented", op);
170 template<
class Element>
171 TMatrixTSym<Element>::TMatrixTSym(
const TMatrixTSym<Element> &a,EMatrixCreatorsOp2 op,
const TMatrixTSym<Element> &b)
173 R__ASSERT(a.IsValid());
174 R__ASSERT(b.IsValid());
179 Allocate(a.GetNcols(),a.GetNcols(),a.GetColLwb(),a.GetColLwb(),1);
186 Allocate(a.GetNcols(),a.GetNcols(),a.GetColLwb(),a.GetColLwb(),1);
192 Error(
"TMatrixTSym(EMatrixCreatorOp2)",
"operation %d not yet implemented", op);
198 template<
class Element>
199 TMatrixTSym<Element>::TMatrixTSym(
const TMatrixTSymLazy<Element> &lazy_constructor)
201 Allocate(lazy_constructor.GetRowUpb()-lazy_constructor.GetRowLwb()+1,
202 lazy_constructor.GetRowUpb()-lazy_constructor.GetRowLwb()+1,
203 lazy_constructor.GetRowLwb(),lazy_constructor.GetRowLwb(),1);
204 lazy_constructor.FillIn(*
this);
205 if (!this->IsSymmetric()) {
206 Error(
"TMatrixTSym(TMatrixTSymLazy)",
"matrix not symmetric");
213 template<
class Element>
214 void TMatrixTSym<Element>::Delete_m(Int_t size,Element *&m)
217 if (size > this->kSizeMax)
227 template<
class Element>
228 Element* TMatrixTSym<Element>::New_m(Int_t size)
230 if (size == 0)
return 0;
232 if ( size <= this->kSizeMax )
235 Element *heap =
new Element[size];
245 template<
class Element>
246 Int_t TMatrixTSym<Element>::Memcpy_m(Element *newp,
const Element *oldp,Int_t copySize,
247 Int_t newSize,Int_t oldSize)
249 if (copySize == 0 || oldp == newp)
252 if ( newSize <= this->kSizeMax && oldSize <= this->kSizeMax ) {
255 for (Int_t i = copySize-1; i >= 0; i--)
258 for (Int_t i = 0; i < copySize; i++)
263 memcpy(newp,oldp,copySize*
sizeof(Element));
272 template<
class Element>
273 void TMatrixTSym<Element>::Allocate(Int_t no_rows,Int_t no_cols,Int_t row_lwb,Int_t col_lwb,
276 this->fIsOwner = kTRUE;
277 this->fTol = std::numeric_limits<Element>::epsilon();
285 if (no_rows < 0 || no_cols < 0)
287 Error(
"Allocate",
"no_rows=%d no_cols=%d",no_rows,no_cols);
293 this->fNrows = no_rows;
294 this->fNcols = no_cols;
295 this->fRowLwb = row_lwb;
296 this->fColLwb = col_lwb;
297 this->fNelems = this->fNrows*this->fNcols;
299 if (this->fNelems > 0) {
300 fElements = New_m(this->fNelems);
302 memset(fElements,0,this->fNelems*
sizeof(Element));
310 template<
class Element>
311 void TMatrixTSym<Element>::Plus(
const TMatrixTSym<Element> &a,
const TMatrixTSym<Element> &b)
314 if (!AreCompatible(a,b)) {
315 Error(
"Plus",
"matrices not compatible");
319 if (this->GetMatrixArray() == a.GetMatrixArray()) {
320 Error(
"Plus",
"this->GetMatrixArray() == a.GetMatrixArray()");
324 if (this->GetMatrixArray() == b.GetMatrixArray()) {
325 Error(
"Plus",
"this->GetMatrixArray() == b.GetMatrixArray()");
330 const Element * ap = a.GetMatrixArray();
331 const Element * bp = b.GetMatrixArray();
332 Element * cp = this->GetMatrixArray();
333 const Element *
const cp_last = cp+this->fNelems;
335 while (cp < cp_last) {
344 template<
class Element>
345 void TMatrixTSym<Element>::Minus(
const TMatrixTSym<Element> &a,
const TMatrixTSym<Element> &b)
348 if (!AreCompatible(a,b)) {
349 Error(
"Minus",
"matrices not compatible");
353 if (this->GetMatrixArray() == a.GetMatrixArray()) {
354 Error(
"Minus",
"this->GetMatrixArray() == a.GetMatrixArray()");
358 if (this->GetMatrixArray() == b.GetMatrixArray()) {
359 Error(
"Minus",
"this->GetMatrixArray() == b.GetMatrixArray()");
364 const Element * ap = a.GetMatrixArray();
365 const Element * bp = b.GetMatrixArray();
366 Element * cp = this->GetMatrixArray();
367 const Element *
const cp_last = cp+this->fNelems;
369 while (cp < cp_last) {
379 template<
class Element>
380 void TMatrixTSym<Element>::TMult(
const TMatrixT<Element> &a)
382 R__ASSERT(a.IsValid());
385 const Element *ap = a.GetMatrixArray();
386 Element *cp = this->GetMatrixArray();
387 if (
typeid(Element) ==
typeid(Double_t))
388 cblas_dgemm (CblasRowMajor,CblasTrans,CblasNoTrans,this->fNrows,this->fNcols,a.GetNrows(),
389 1.0,ap,a.GetNcols(),ap,a.GetNcols(),1.0,cp,this->fNcols);
390 else if (
typeid(Element) !=
typeid(Float_t))
391 cblas_sgemm (CblasRowMajor,CblasTrans,CblasNoTrans,fNrows,fNcols,a.GetNrows(),
392 1.0,ap,a.GetNcols(),ap,a.GetNcols(),1.0,cp,fNcols);
394 Error(
"TMult",
"type %s not implemented in BLAS library",
typeid(Element));
396 const Int_t nb = a.GetNoElements();
397 const Int_t ncolsa = a.GetNcols();
398 const Int_t ncolsb = ncolsa;
399 const Element *
const ap = a.GetMatrixArray();
400 const Element *
const bp = ap;
401 Element * cp = this->GetMatrixArray();
403 const Element *acp0 = ap;
404 while (acp0 < ap+a.GetNcols()) {
405 for (
const Element *bcp = bp; bcp < bp+ncolsb; ) {
406 const Element *acp = acp0;
408 while (bcp < bp+nb) {
419 R__ASSERT(cp == this->GetMatrixArray()+this->fNelems && acp0 == ap+ncolsa);
427 template<
class Element>
428 void TMatrixTSym<Element>::TMult(
const TMatrixTSym<Element> &a)
430 R__ASSERT(a.IsValid());
433 const Element *ap = a.GetMatrixArray();
434 Element *cp = this->GetMatrixArray();
435 if (
typeid(Element) ==
typeid(Double_t))
436 cblas_dsymm (CblasRowMajor,CblasLeft,CblasUpper,this->fNrows,this->fNcols,1.0,
437 ap,a.GetNcols(),ap,a.GetNcols(),0.0,cp,this->fNcols);
438 else if (
typeid(Element) !=
typeid(Float_t))
439 cblas_ssymm (CblasRowMajor,CblasLeft,CblasUpper,fNrows,fNcols,1.0,
440 ap1,a.GetNcols(),ap,a.GetNcols(),0.0,cp,fNcols);
442 Error(
"TMult",
"type %s not implemented in BLAS library",
typeid(Element));
444 const Int_t nb = a.GetNoElements();
445 const Int_t ncolsa = a.GetNcols();
446 const Int_t ncolsb = ncolsa;
447 const Element *
const ap = a.GetMatrixArray();
448 const Element *
const bp = ap;
449 Element * cp = this->GetMatrixArray();
451 const Element *acp0 = ap;
452 while (acp0 < ap+a.GetNcols()) {
453 for (
const Element *bcp = bp; bcp < bp+ncolsb; ) {
454 const Element *acp = acp0;
456 while (bcp < bp+nb) {
467 R__ASSERT(cp == this->GetMatrixArray()+this->fNelems && acp0 == ap+ncolsa);
473 template<
class Element>
474 TMatrixTSym<Element> &TMatrixTSym<Element>::Use(Int_t row_lwb,Int_t row_upb,Element *data)
476 if (gMatrixCheck && row_upb < row_lwb)
478 Error(
"Use",
"row_upb=%d < row_lwb=%d",row_upb,row_lwb);
483 this->fNrows = row_upb-row_lwb+1;
484 this->fNcols = this->fNrows;
485 this->fRowLwb = row_lwb;
486 this->fColLwb = row_lwb;
487 this->fNelems = this->fNrows*this->fNcols;
489 this->fIsOwner = kFALSE;
501 template<
class Element>
502 TMatrixTSym<Element> &TMatrixTSym<Element>::GetSub(Int_t row_lwb,Int_t row_upb,
503 TMatrixTSym<Element> &target,Option_t *option)
const
506 R__ASSERT(this->IsValid());
507 if (row_lwb < this->fRowLwb || row_lwb > this->fRowLwb+this->fNrows-1) {
508 Error(
"GetSub",
"row_lwb out of bounds");
511 if (row_upb < this->fRowLwb || row_upb > this->fRowLwb+this->fNrows-1) {
512 Error(
"GetSub",
"row_upb out of bounds");
515 if (row_upb < row_lwb) {
516 Error(
"GetSub",
"row_upb < row_lwb");
523 const Int_t shift = (opt.Contains(
"S")) ? 1 : 0;
529 row_upb_sub = row_upb-row_lwb;
531 row_lwb_sub = row_lwb;
532 row_upb_sub = row_upb;
535 target.ResizeTo(row_lwb_sub,row_upb_sub,row_lwb_sub,row_upb_sub);
536 const Int_t nrows_sub = row_upb_sub-row_lwb_sub+1;
538 if (target.GetRowIndexArray() && target.GetColIndexArray()) {
539 for (Int_t irow = 0; irow < nrows_sub; irow++) {
540 for (Int_t icol = 0; icol < nrows_sub; icol++) {
541 target(irow+row_lwb_sub,icol+row_lwb_sub) = (*this)(row_lwb+irow,row_lwb+icol);
545 const Element *ap = this->GetMatrixArray()+(row_lwb-this->fRowLwb)*this->fNrows+(row_lwb-this->fRowLwb);
546 Element *bp = target.GetMatrixArray();
548 for (Int_t irow = 0; irow < nrows_sub; irow++) {
549 const Element *ap_sub = ap;
550 for (Int_t icol = 0; icol < nrows_sub; icol++) {
567 template<
class Element>
568 TMatrixTBase<Element> &TMatrixTSym<Element>::GetSub(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,
569 TMatrixTBase<Element> &target,Option_t *option)
const
572 R__ASSERT(this->IsValid());
573 if (row_lwb < this->fRowLwb || row_lwb > this->fRowLwb+this->fNrows-1) {
574 Error(
"GetSub",
"row_lwb out of bounds");
577 if (col_lwb < this->fColLwb || col_lwb > this->fColLwb+this->fNcols-1) {
578 Error(
"GetSub",
"col_lwb out of bounds");
581 if (row_upb < this->fRowLwb || row_upb > this->fRowLwb+this->fNrows-1) {
582 Error(
"GetSub",
"row_upb out of bounds");
585 if (col_upb < this->fColLwb || col_upb > this->fColLwb+this->fNcols-1) {
586 Error(
"GetSub",
"col_upb out of bounds");
589 if (row_upb < row_lwb || col_upb < col_lwb) {
590 Error(
"GetSub",
"row_upb < row_lwb || col_upb < col_lwb");
597 const Int_t shift = (opt.Contains(
"S")) ? 1 : 0;
599 const Int_t row_lwb_sub = (shift) ? 0 : row_lwb;
600 const Int_t row_upb_sub = (shift) ? row_upb-row_lwb : row_upb;
601 const Int_t col_lwb_sub = (shift) ? 0 : col_lwb;
602 const Int_t col_upb_sub = (shift) ? col_upb-col_lwb : col_upb;
604 target.ResizeTo(row_lwb_sub,row_upb_sub,col_lwb_sub,col_upb_sub);
605 const Int_t nrows_sub = row_upb_sub-row_lwb_sub+1;
606 const Int_t ncols_sub = col_upb_sub-col_lwb_sub+1;
608 if (target.GetRowIndexArray() && target.GetColIndexArray()) {
609 for (Int_t irow = 0; irow < nrows_sub; irow++) {
610 for (Int_t icol = 0; icol < ncols_sub; icol++) {
611 target(irow+row_lwb_sub,icol+col_lwb_sub) = (*this)(row_lwb+irow,col_lwb+icol);
615 const Element *ap = this->GetMatrixArray()+(row_lwb-this->fRowLwb)*this->fNcols+(col_lwb-this->fColLwb);
616 Element *bp = target.GetMatrixArray();
618 for (Int_t irow = 0; irow < nrows_sub; irow++) {
619 const Element *ap_sub = ap;
620 for (Int_t icol = 0; icol < ncols_sub; icol++) {
634 template<
class Element>
635 TMatrixTSym<Element> &TMatrixTSym<Element>::SetSub(Int_t row_lwb,
const TMatrixTBase<Element> &source)
638 R__ASSERT(this->IsValid());
639 R__ASSERT(source.IsValid());
641 if (!source.IsSymmetric()) {
642 Error(
"SetSub",
"source matrix is not symmetric");
645 if (row_lwb < this->fRowLwb || row_lwb > this->fRowLwb+this->fNrows-1) {
646 Error(
"SetSub",
"row_lwb outof bounds");
649 if (row_lwb+source.GetNrows() > this->fRowLwb+this->fNrows) {
650 Error(
"SetSub",
"source matrix too large");
655 const Int_t nRows_source = source.GetNrows();
657 if (source.GetRowIndexArray() && source.GetColIndexArray()) {
658 const Int_t rowlwb_s = source.GetRowLwb();
659 for (Int_t irow = 0; irow < nRows_source; irow++) {
660 for (Int_t icol = 0; icol < nRows_source; icol++) {
661 (*this)(row_lwb+irow,row_lwb+icol) = source(rowlwb_s+irow,rowlwb_s+icol);
665 const Element *bp = source.GetMatrixArray();
666 Element *ap = this->GetMatrixArray()+(row_lwb-this->fRowLwb)*this->fNrows+(row_lwb-this->fRowLwb);
668 for (Int_t irow = 0; irow < nRows_source; irow++) {
669 Element *ap_sub = ap;
670 for (Int_t icol = 0; icol < nRows_source; icol++) {
684 template<
class Element>
685 TMatrixTBase<Element> &TMatrixTSym<Element>::SetSub(Int_t row_lwb,Int_t col_lwb,
const TMatrixTBase<Element> &source)
688 R__ASSERT(this->IsValid());
689 R__ASSERT(source.IsValid());
691 if (row_lwb < this->fRowLwb || row_lwb > this->fRowLwb+this->fNrows-1) {
692 Error(
"SetSub",
"row_lwb out of bounds");
695 if (col_lwb < this->fColLwb || col_lwb > this->fColLwb+this->fNcols-1) {
696 Error(
"SetSub",
"col_lwb out of bounds");
700 if (row_lwb+source.GetNrows() > this->fRowLwb+this->fNrows || col_lwb+source.GetNcols() > this->fRowLwb+this->fNrows) {
701 Error(
"SetSub",
"source matrix too large");
704 if (col_lwb+source.GetNcols() > this->fRowLwb+this->fNrows || row_lwb+source.GetNrows() > this->fRowLwb+this->fNrows) {
705 Error(
"SetSub",
"source matrix too large");
710 const Int_t nRows_source = source.GetNrows();
711 const Int_t nCols_source = source.GetNcols();
713 const Int_t rowlwb_s = source.GetRowLwb();
714 const Int_t collwb_s = source.GetColLwb();
715 if (row_lwb >= col_lwb) {
718 for (irow = 0; irow < nRows_source; irow++) {
719 for (Int_t icol = 0; col_lwb+icol <= row_lwb+irow &&
720 icol < nCols_source; icol++) {
721 (*this)(row_lwb+irow,col_lwb+icol) = source(irow+rowlwb_s,icol+collwb_s);
726 for (irow = 0; irow < nCols_source; irow++) {
727 for (Int_t icol = nRows_source-1; row_lwb+icol > irow+col_lwb &&
729 (*this)(col_lwb+irow,row_lwb+icol) = source(icol+rowlwb_s,irow+collwb_s);
741 template<
class Element>
742 TMatrixTBase<Element> &TMatrixTSym<Element>::SetMatrixArray(
const Element *data,Option_t *option)
744 TMatrixTBase<Element>::SetMatrixArray(data,option);
745 if (!this->IsSymmetric()) {
746 Error(
"SetMatrixArray",
"Matrix is not symmetric after Set");
754 template<
class Element>
755 TMatrixTBase<Element> &TMatrixTSym<Element>::Shift(Int_t row_shift,Int_t col_shift)
757 if (row_shift != col_shift) {
758 Error(
"Shift",
"row_shift != col_shift");
761 return TMatrixTBase<Element>::Shift(row_shift,col_shift);
769 template<
class Element>
770 TMatrixTBase<Element> &TMatrixTSym<Element>::ResizeTo(Int_t nrows,Int_t ncols,Int_t )
772 R__ASSERT(this->IsValid());
773 if (!this->fIsOwner) {
774 Error(
"ResizeTo(Int_t,Int_t)",
"Not owner of data array,cannot resize");
778 if (nrows != ncols) {
779 Error(
"ResizeTo(Int_t,Int_t)",
"nrows != ncols");
783 if (this->fNelems > 0) {
784 if (this->fNrows == nrows && this->fNcols == ncols)
786 else if (nrows == 0 || ncols == 0) {
787 this->fNrows = nrows; this->fNcols = ncols;
792 Element *elements_old = GetMatrixArray();
793 const Int_t nelems_old = this->fNelems;
794 const Int_t nrows_old = this->fNrows;
795 const Int_t ncols_old = this->fNcols;
797 Allocate(nrows,ncols);
798 R__ASSERT(this->IsValid());
800 Element *elements_new = GetMatrixArray();
803 if (this->fNelems > this->kSizeMax || nelems_old > this->kSizeMax)
804 memset(elements_new,0,this->fNelems*
sizeof(Element));
805 else if (this->fNelems > nelems_old)
806 memset(elements_new+nelems_old,0,(this->fNelems-nelems_old)*
sizeof(Element));
809 const Int_t ncols_copy = TMath::Min(this->fNcols,ncols_old);
810 const Int_t nrows_copy = TMath::Min(this->fNrows,nrows_old);
812 const Int_t nelems_new = this->fNelems;
813 if (ncols_old < this->fNcols) {
814 for (Int_t i = nrows_copy-1; i >= 0; i--) {
815 Memcpy_m(elements_new+i*this->fNcols,elements_old+i*ncols_old,ncols_copy,
816 nelems_new,nelems_old);
817 if (this->fNelems <= this->kSizeMax && nelems_old <= this->kSizeMax)
818 memset(elements_new+i*this->fNcols+ncols_copy,0,(this->fNcols-ncols_copy)*
sizeof(Element));
821 for (Int_t i = 0; i < nrows_copy; i++)
822 Memcpy_m(elements_new+i*this->fNcols,elements_old+i*ncols_old,ncols_copy,
823 nelems_new,nelems_old);
826 Delete_m(nelems_old,elements_old);
828 Allocate(nrows,ncols,0,0,1);
839 template<
class Element>
840 TMatrixTBase<Element> &TMatrixTSym<Element>::ResizeTo(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,
843 R__ASSERT(this->IsValid());
844 if (!this->fIsOwner) {
845 Error(
"ResizeTo(Int_t,Int_t,Int_t,Int_t)",
"Not owner of data array,cannot resize");
849 if (row_lwb != col_lwb) {
850 Error(
"ResizeTo(Int_t,Int_t,Int_t,Int_t)",
"row_lwb != col_lwb");
853 if (row_upb != col_upb) {
854 Error(
"ResizeTo(Int_t,Int_t,Int_t,Int_t)",
"row_upb != col_upb");
858 const Int_t new_nrows = row_upb-row_lwb+1;
859 const Int_t new_ncols = col_upb-col_lwb+1;
861 if (this->fNelems > 0) {
863 if (this->fNrows == new_nrows && this->fNcols == new_ncols &&
864 this->fRowLwb == row_lwb && this->fColLwb == col_lwb)
866 else if (new_nrows == 0 || new_ncols == 0) {
867 this->fNrows = new_nrows; this->fNcols = new_ncols;
868 this->fRowLwb = row_lwb; this->fColLwb = col_lwb;
873 Element *elements_old = GetMatrixArray();
874 const Int_t nelems_old = this->fNelems;
875 const Int_t nrows_old = this->fNrows;
876 const Int_t ncols_old = this->fNcols;
877 const Int_t rowLwb_old = this->fRowLwb;
878 const Int_t colLwb_old = this->fColLwb;
880 Allocate(new_nrows,new_ncols,row_lwb,col_lwb);
881 R__ASSERT(this->IsValid());
883 Element *elements_new = GetMatrixArray();
886 if (this->fNelems > this->kSizeMax || nelems_old > this->kSizeMax)
887 memset(elements_new,0,this->fNelems*
sizeof(Element));
888 else if (this->fNelems > nelems_old)
889 memset(elements_new+nelems_old,0,(this->fNelems-nelems_old)*
sizeof(Element));
892 const Int_t rowLwb_copy = TMath::Max(this->fRowLwb,rowLwb_old);
893 const Int_t colLwb_copy = TMath::Max(this->fColLwb,colLwb_old);
894 const Int_t rowUpb_copy = TMath::Min(this->fRowLwb+this->fNrows-1,rowLwb_old+nrows_old-1);
895 const Int_t colUpb_copy = TMath::Min(this->fColLwb+this->fNcols-1,colLwb_old+ncols_old-1);
897 const Int_t nrows_copy = rowUpb_copy-rowLwb_copy+1;
898 const Int_t ncols_copy = colUpb_copy-colLwb_copy+1;
900 if (nrows_copy > 0 && ncols_copy > 0) {
901 const Int_t colOldOff = colLwb_copy-colLwb_old;
902 const Int_t colNewOff = colLwb_copy-this->fColLwb;
903 if (ncols_old < this->fNcols) {
904 for (Int_t i = nrows_copy-1; i >= 0; i--) {
905 const Int_t iRowOld = rowLwb_copy+i-rowLwb_old;
906 const Int_t iRowNew = rowLwb_copy+i-this->fRowLwb;
907 Memcpy_m(elements_new+iRowNew*this->fNcols+colNewOff,
908 elements_old+iRowOld*ncols_old+colOldOff,ncols_copy,this->fNelems,nelems_old);
909 if (this->fNelems <= this->kSizeMax && nelems_old <= this->kSizeMax)
910 memset(elements_new+iRowNew*this->fNcols+colNewOff+ncols_copy,0,
911 (this->fNcols-ncols_copy)*
sizeof(Element));
914 for (Int_t i = 0; i < nrows_copy; i++) {
915 const Int_t iRowOld = rowLwb_copy+i-rowLwb_old;
916 const Int_t iRowNew = rowLwb_copy+i-this->fRowLwb;
917 Memcpy_m(elements_new+iRowNew*this->fNcols+colNewOff,
918 elements_old+iRowOld*ncols_old+colOldOff,ncols_copy,this->fNelems,nelems_old);
923 Delete_m(nelems_old,elements_old);
925 Allocate(new_nrows,new_ncols,row_lwb,col_lwb,1);
933 template<
class Element>
934 Double_t TMatrixTSym<Element>::Determinant()
const
936 const TMatrixT<Element> &tmp = *
this;
937 TDecompLU lu(tmp,this->fTol);
940 return d1*TMath::Power(2.0,d2);
945 template<
class Element>
946 void TMatrixTSym<Element>::Determinant(Double_t &d1,Double_t &d2)
const
948 const TMatrixT<Element> &tmp = *
this;
949 TDecompLU lu(tmp,this->fTol);
959 template<
class Element>
960 TMatrixTSym<Element> &TMatrixTSym<Element>::Invert(Double_t *det)
962 R__ASSERT(this->IsValid());
964 if (TDecompLU::InvertLU(tmp,Double_t(this->fTol),det)) {
965 const Double_t *p1 = tmp.GetMatrixArray();
966 Element *p2 = this->GetMatrixArray();
967 for (Int_t i = 0; i < this->GetNoElements(); i++)
977 template<
class Element>
978 TMatrixTSym<Element> &TMatrixTSym<Element>::InvertFast(Double_t *det)
980 R__ASSERT(this->IsValid());
982 const Char_t nRows = Char_t(this->GetNrows());
986 Element *pM = this->GetMatrixArray();
988 Error(
"InvertFast",
"matrix is singular");
998 TMatrixTSymCramerInv::Inv2x2<Element>(*
this,det);
1003 TMatrixTSymCramerInv::Inv3x3<Element>(*
this,det);
1008 TMatrixTSymCramerInv::Inv4x4<Element>(*
this,det);
1013 TMatrixTSymCramerInv::Inv5x5<Element>(*
this,det);
1018 TMatrixTSymCramerInv::Inv6x6<Element>(*
this,det);
1024 TMatrixD tmp(*
this);
1025 if (TDecompLU::InvertLU(tmp,Double_t(this->fTol),det)) {
1026 const Double_t *p1 = tmp.GetMatrixArray();
1027 Element *p2 = this->GetMatrixArray();
1028 for (Int_t i = 0; i < this->GetNoElements(); i++)
1039 template<
class Element>
1040 TMatrixTSym<Element> &TMatrixTSym<Element>::Transpose(
const TMatrixTSym<Element> &source)
1043 R__ASSERT(this->IsValid());
1044 R__ASSERT(source.IsValid());
1046 if (this->fNrows != source.GetNcols() || this->fRowLwb != source.GetColLwb())
1048 Error(
"Transpose",
"matrix has wrong shape");
1061 template<
class Element>
1062 TMatrixTSym<Element> &TMatrixTSym<Element>::Rank1Update(
const TVectorT<Element> &v,Element alpha)
1065 R__ASSERT(this->IsValid());
1066 R__ASSERT(v.IsValid());
1067 if (v.GetNoElements() < this->fNrows) {
1068 Error(
"Rank1Update",
"vector too short");
1073 const Element *
const pv = v.GetMatrixArray();
1074 Element *trp = this->GetMatrixArray();
1076 for (Int_t i = 0; i < this->fNrows; i++) {
1078 tcp += i*this->fNcols;
1079 const Element tmp = alpha*pv[i];
1080 for (Int_t j = i; j < this->fNcols; j++) {
1081 if (j > i) *tcp += tmp*pv[j];
1082 *trp++ += tmp*pv[j];
1083 tcp += this->fNcols;
1085 tcp -= this->fNelems-1;
1097 template<
class Element>
1098 TMatrixTSym<Element> &TMatrixTSym<Element>::Similarity(
const TMatrixT<Element> &b)
1101 R__ASSERT(this->IsValid());
1102 R__ASSERT(b.IsValid());
1103 if (this->fNcols != b.GetNcols() || this->fColLwb != b.GetColLwb()) {
1104 Error(
"Similarity(const TMatrixT &)",
"matrices incompatible");
1109 const Int_t ncolsa = this->fNcols;
1110 const Int_t nb = b.GetNoElements();
1111 const Int_t nrowsb = b.GetNrows();
1112 const Int_t ncolsb = b.GetNcols();
1114 const Element *
const bp = b.GetMatrixArray();
1116 Element work[kWorkMax];
1117 Bool_t isAllocated = kFALSE;
1118 Element *bap = work;
1119 if (nrowsb*ncolsa > kWorkMax) {
1120 isAllocated = kTRUE;
1121 bap =
new Element[nrowsb*ncolsa];
1124 AMultB(bp,nb,ncolsb,this->fElements,this->fNelems,this->fNcols,bap);
1126 if (nrowsb != this->fNrows)
1127 this->ResizeTo(nrowsb,nrowsb);
1130 Element *cp = this->GetMatrixArray();
1131 if (
typeid(Element) ==
typeid(Double_t))
1132 cblas_dgemm (CblasRowMajor,CblasNoTrans,CblasTrans,this->fNrows,this->fNcols,ba.GetNcols(),
1133 1.0,bap,ba.GetNcols(),bp,b.GetNcols(),1.0,cp,this->fNcols);
1134 else if (
typeid(Element) !=
typeid(Float_t))
1135 cblas_sgemm (CblasRowMajor,CblasNoTrans,CblasTrans,this->fNrows,this->fNcols,ba.GetNcols(),
1136 1.0,bap,ba.GetNcols(),bp,b.GetNcols(),1.0,cp,this->fNcols);
1138 Error(
"Similarity",
"type %s not implemented in BLAS library",
typeid(Element));
1140 const Int_t nba = nrowsb*ncolsa;
1141 const Int_t ncolsba = ncolsa;
1142 const Element * bi1p = bp;
1143 Element * cp = this->GetMatrixArray();
1144 Element *
const cp0 = cp;
1147 const Element *barp0 = bap;
1148 while (barp0 < bap+nba) {
1149 const Element *brp0 = bi1p;
1150 while (brp0 < bp+nb) {
1151 const Element *barp = barp0;
1152 const Element *brp = brp0;
1154 while (brp < brp0+ncolsb)
1155 cij += *barp++ * *brp++;
1164 R__ASSERT(cp == cp0+this->fNelems+ishift && barp0 == bap+nba);
1167 for (Int_t irow = 0; irow < this->fNrows; irow++) {
1168 const Int_t rowOff1 = irow*this->fNrows;
1169 for (Int_t icol = 0; icol < irow; icol++) {
1170 const Int_t rowOff2 = icol*this->fNrows;
1171 cp[rowOff1+icol] = cp[rowOff2+irow];
1188 template<
class Element>
1189 TMatrixTSym<Element> &TMatrixTSym<Element>::Similarity(
const TMatrixTSym<Element> &b)
1192 R__ASSERT(this->IsValid());
1193 R__ASSERT(b.IsValid());
1194 if (this->fNcols != b.GetNcols() || this->fColLwb != b.GetColLwb()) {
1195 Error(
"Similarity(const TMatrixTSym &)",
"matrices incompatible");
1201 const Int_t nrowsb = b.GetNrows();
1202 const Int_t ncolsa = this->GetNcols();
1204 Element work[kWorkMax];
1205 Bool_t isAllocated = kFALSE;
1206 Element *abtp = work;
1207 if (this->fNcols > kWorkMax) {
1208 isAllocated = kTRUE;
1209 abtp =
new Element[this->fNcols];
1212 const TMatrixT<Element> abt(*
this,TMatrixT<Element>::kMultTranspose,b);
1214 const Element *bp = b.GetMatrixArray();
1215 Element *cp = this->GetMatrixArray();
1216 if (
typeid(Element) ==
typeid(Double_t))
1217 cblas_dsymm (CblasRowMajor,CblasLeft,CblasUpper,this->fNrows,this->fNcols,1.0,
1218 bp,b.GetNcols(),abtp,abt.GetNcols(),0.0,cp,this->fNcols);
1219 else if (
typeid(Element) !=
typeid(Float_t))
1220 cblas_ssymm (CblasRowMajor,CblasLeft,CblasUpper,this->fNrows,this->fNcols,1.0,
1221 bp,b.GetNcols(),abtp,abt.GetNcols(),0.0,cp,this->fNcols);
1223 Error(
"Similarity",
"type %s not implemented in BLAS library",
typeid(Element));
1228 const Int_t ncolsa = this->GetNcols();
1229 const Int_t nb = b.GetNoElements();
1230 const Int_t nrowsb = b.GetNrows();
1231 const Int_t ncolsb = b.GetNcols();
1233 const Element *
const bp = b.GetMatrixArray();
1235 Element work[kWorkMax];
1236 Bool_t isAllocated = kFALSE;
1237 Element *bap = work;
1238 if (nrowsb*ncolsa > kWorkMax) {
1239 isAllocated = kTRUE;
1240 bap =
new Element[nrowsb*ncolsa];
1243 AMultB(bp,nb,ncolsb,this->fElements,this->fNelems,this->fNcols,bap);
1245 const Int_t nba = nrowsb*ncolsa;
1246 const Int_t ncolsba = ncolsa;
1247 const Element * bi1p = bp;
1248 Element * cp = this->GetMatrixArray();
1249 Element *
const cp0 = cp;
1252 const Element *barp0 = bap;
1253 while (barp0 < bap+nba) {
1254 const Element *brp0 = bi1p;
1255 while (brp0 < bp+nb) {
1256 const Element *barp = barp0;
1257 const Element *brp = brp0;
1259 while (brp < brp0+ncolsb)
1260 cij += *barp++ * *brp++;
1269 R__ASSERT(cp == cp0+this->fNelems+ishift && barp0 == bap+nba);
1272 for (Int_t irow = 0; irow < this->fNrows; irow++) {
1273 const Int_t rowOff1 = irow*this->fNrows;
1274 for (Int_t icol = 0; icol < irow; icol++) {
1275 const Int_t rowOff2 = icol*this->fNrows;
1276 cp[rowOff1+icol] = cp[rowOff2+irow];
1290 template<
class Element>
1291 Element TMatrixTSym<Element>::Similarity(
const TVectorT<Element> &v)
const
1294 R__ASSERT(this->IsValid());
1295 R__ASSERT(v.IsValid());
1296 if (this->fNcols != v.GetNrows() || this->fColLwb != v.GetLwb()) {
1297 Error(
"Similarity(const TVectorT &)",
"vector and matrix incompatible");
1302 const Element *mp = this->GetMatrixArray();
1303 const Element *vp = v.GetMatrixArray();
1306 const Element *
const vp_first = vp;
1307 const Element *
const vp_last = vp+v.GetNrows();
1308 while (vp < vp_last) {
1310 for (
const Element *sp = vp_first; sp < vp_last; )
1311 sum2 += *mp++ * *sp++;
1312 sum1 += sum2 * *vp++;
1315 R__ASSERT(mp == this->GetMatrixArray()+this->GetNoElements());
1325 template<
class Element>
1326 TMatrixTSym<Element> &TMatrixTSym<Element>::SimilarityT(
const TMatrixT<Element> &b)
1329 R__ASSERT(this->IsValid());
1330 R__ASSERT(b.IsValid());
1331 if (this->fNrows != b.GetNrows() || this->fRowLwb != b.GetRowLwb()) {
1332 Error(
"SimilarityT(const TMatrixT &)",
"matrices incompatible");
1337 const Int_t ncolsb = b.GetNcols();
1338 const Int_t ncolsa = this->GetNcols();
1340 Element work[kWorkMax];
1341 Bool_t isAllocated = kFALSE;
1342 Element *btap = work;
1343 if (ncolsb*ncolsa > kWorkMax) {
1344 isAllocated = kTRUE;
1345 btap =
new Element[ncolsb*ncolsa];
1348 TMatrixT<Element> bta; bta.Use(ncolsb,ncolsa,btap);
1351 if (ncolsb != this->fNcols)
1352 this->ResizeTo(ncolsb,ncolsb);
1355 const Element *bp = b.GetMatrixArray();
1356 Element *cp = this->GetMatrixArray();
1357 if (
typeid(Element) ==
typeid(Double_t))
1358 cblas_dgemm (CblasRowMajor,CblasNoTrans,CblasNoTrans,this->fNrows,this->fNcols,bta.GetNcols(),
1359 1.0,btap,bta.GetNcols(),bp,b.GetNcols(),1.0,cp,this->fNcols);
1360 else if (
typeid(Element) !=
typeid(Float_t))
1361 cblas_sgemm (CblasRowMajor,CblasNoTrans,CblasNoTrans,this->fNrows,this->fNcols,bta.GetNcols(),
1362 1.0,btap,bta.GetNcols(),bp,b.GetNcols(),1.0,cp,this->fNcols);
1364 Error(
"similarityT",
"type %s not implemented in BLAS library",
typeid(Element));
1366 const Int_t nbta = bta.GetNoElements();
1367 const Int_t nb = b.GetNoElements();
1368 const Int_t ncolsbta = bta.GetNcols();
1369 const Element *
const bp = b.GetMatrixArray();
1370 Element * cp = this->GetMatrixArray();
1371 Element *
const cp0 = cp;
1374 const Element *btarp0 = btap;
1375 const Element *bcp0 = bp;
1376 while (btarp0 < btap+nbta) {
1377 for (
const Element *bcp = bcp0; bcp < bp+ncolsb; ) {
1378 const Element *btarp = btarp0;
1380 while (bcp < bp+nb) {
1381 cij += *btarp++ * *bcp;
1392 R__ASSERT(cp == cp0+this->fNelems+ishift && btarp0 == btap+nbta);
1395 for (Int_t irow = 0; irow < this->fNrows; irow++) {
1396 const Int_t rowOff1 = irow*this->fNrows;
1397 for (Int_t icol = 0; icol < irow; icol++) {
1398 const Int_t rowOff2 = icol*this->fNrows;
1399 cp[rowOff1+icol] = cp[rowOff2+irow];
1412 template<
class Element>
1413 TMatrixTSym<Element> &TMatrixTSym<Element>::operator=(
const TMatrixTSym<Element> &source)
1415 if (gMatrixCheck && !AreCompatible(*
this,source)) {
1416 Error(
"operator=",
"matrices not compatible");
1420 if (this->GetMatrixArray() != source.GetMatrixArray()) {
1421 TObject::operator=(source);
1422 memcpy(this->GetMatrixArray(),source.fElements,this->fNelems*
sizeof(Element));
1429 template<
class Element>
1430 TMatrixTSym<Element> &TMatrixTSym<Element>::operator=(
const TMatrixTSymLazy<Element> &lazy_constructor)
1432 R__ASSERT(this->IsValid());
1434 if (lazy_constructor.fRowUpb != this->GetRowUpb() ||
1435 lazy_constructor.fRowLwb != this->GetRowLwb()) {
1436 Error(
"operator=(const TMatrixTSymLazy&)",
"matrix is incompatible with "
1437 "the assigned Lazy matrix");
1441 lazy_constructor.FillIn(*
this);
1448 template<
class Element>
1449 TMatrixTSym<Element> &TMatrixTSym<Element>::operator=(Element val)
1451 R__ASSERT(this->IsValid());
1453 Element *ep = fElements;
1454 const Element *
const ep_last = ep+this->fNelems;
1455 while (ep < ep_last)
1464 template<
class Element>
1465 TMatrixTSym<Element> &TMatrixTSym<Element>::operator+=(Element val)
1467 R__ASSERT(this->IsValid());
1469 Element *ep = fElements;
1470 const Element *
const ep_last = ep+this->fNelems;
1471 while (ep < ep_last)
1480 template<
class Element>
1481 TMatrixTSym<Element> &TMatrixTSym<Element>::operator-=(Element val)
1483 R__ASSERT(this->IsValid());
1485 Element *ep = fElements;
1486 const Element *
const ep_last = ep+this->fNelems;
1487 while (ep < ep_last)
1496 template<
class Element>
1497 TMatrixTSym<Element> &TMatrixTSym<Element>::operator*=(Element val)
1499 R__ASSERT(this->IsValid());
1501 Element *ep = fElements;
1502 const Element *
const ep_last = ep+this->fNelems;
1503 while (ep < ep_last)
1512 template<
class Element>
1513 TMatrixTSym<Element> &TMatrixTSym<Element>::operator+=(
const TMatrixTSym<Element> &source)
1515 if (gMatrixCheck && !AreCompatible(*
this,source)) {
1516 Error(
"operator+=",
"matrices not compatible");
1520 const Element *sp = source.GetMatrixArray();
1521 Element *tp = this->GetMatrixArray();
1522 const Element *
const tp_last = tp+this->fNelems;
1523 while (tp < tp_last)
1532 template<
class Element>
1533 TMatrixTSym<Element> &TMatrixTSym<Element>::operator-=(
const TMatrixTSym<Element> &source)
1535 if (gMatrixCheck && !AreCompatible(*
this,source)) {
1536 Error(
"operator-=",
"matrices not compatible");
1540 const Element *sp = source.GetMatrixArray();
1541 Element *tp = this->GetMatrixArray();
1542 const Element *
const tp_last = tp+this->fNelems;
1543 while (tp < tp_last)
1551 template<
class Element>
1552 TMatrixTBase<Element> &TMatrixTSym<Element>::Apply(
const TElementActionT<Element> &action)
1554 R__ASSERT(this->IsValid());
1557 Element *trp = this->GetMatrixArray();
1559 for (Int_t i = 0; i < this->fNrows; i++) {
1561 tcp += i*this->fNcols;
1562 for (Int_t j = i; j < this->fNcols; j++) {
1563 action.Operation(val);
1564 if (j > i) *tcp = val;
1566 tcp += this->fNcols;
1568 tcp -= this->fNelems-1;
1578 template<
class Element>
1579 TMatrixTBase<Element> &TMatrixTSym<Element>::Apply(
const TElementPosActionT<Element> &action)
1581 R__ASSERT(this->IsValid());
1584 Element *trp = this->GetMatrixArray();
1586 for (Int_t i = 0; i < this->fNrows; i++) {
1587 action.fI = i+this->fRowLwb;
1589 tcp += i*this->fNcols;
1590 for (Int_t j = i; j < this->fNcols; j++) {
1591 action.fJ = j+this->fColLwb;
1592 action.Operation(val);
1593 if (j > i) *tcp = val;
1595 tcp += this->fNcols;
1597 tcp -= this->fNelems-1;
1606 template<
class Element>
1607 TMatrixTBase<Element> &TMatrixTSym<Element>::Randomize(Element alpha,Element beta,Double_t &seed)
1610 R__ASSERT(this->IsValid());
1611 if (this->fNrows != this->fNcols || this->fRowLwb != this->fColLwb) {
1612 Error(
"Randomize(Element,Element,Element &",
"matrix should be square");
1617 const Element scale = beta-alpha;
1618 const Element shift = alpha/scale;
1620 Element *ep = GetMatrixArray();
1621 for (Int_t i = 0; i < this->fNrows; i++) {
1622 const Int_t off = i*this->fNcols;
1623 for (Int_t j = 0; j <= i; j++) {
1624 ep[off+j] = scale*(Drand(seed)+shift);
1626 ep[j*this->fNcols+i] = ep[off+j];
1637 template<
class Element>
1638 TMatrixTSym<Element> &TMatrixTSym<Element>::RandomizePD(Element alpha,Element beta,Double_t &seed)
1641 R__ASSERT(this->IsValid());
1642 if (this->fNrows != this->fNcols || this->fRowLwb != this->fColLwb) {
1643 Error(
"RandomizeSym(Element,Element,Element &",
"matrix should be square");
1648 const Element scale = beta-alpha;
1649 const Element shift = alpha/scale;
1651 Element *ep = GetMatrixArray();
1653 for (i = 0; i < this->fNrows; i++) {
1654 const Int_t off = i*this->fNcols;
1655 for (Int_t j = 0; j <= i; j++)
1656 ep[off+j] = scale*(Drand(seed)+shift);
1659 for (i = this->fNrows-1; i >= 0; i--) {
1660 const Int_t off1 = i*this->fNcols;
1661 for (Int_t j = i; j >= 0; j--) {
1662 const Int_t off2 = j*this->fNcols;
1663 ep[off1+j] *= ep[off2+j];
1664 for (Int_t k = j-1; k >= 0; k--) {
1665 ep[off1+j] += ep[off1+k]*ep[off2+k];
1668 ep[off2+i] = ep[off1+j];
1679 template<
class Element>
1680 const TMatrixT<Element> TMatrixTSym<Element>::EigenVectors(TVectorT<Element> &eigenValues)
const
1682 TMatrixDSym tmp = *
this;
1683 TMatrixDSymEigen eigen(tmp);
1684 eigenValues.ResizeTo(this->fNrows);
1685 eigenValues = eigen.GetEigenValues();
1686 return eigen.GetEigenVectors();
1692 template<
class Element>
1693 Bool_t operator==(
const TMatrixTSym<Element> &m1,
const TMatrixTSym<Element> &m2)
1695 if (!AreCompatible(m1,m2))
return kFALSE;
1696 return (memcmp(m1.GetMatrixArray(),m2.GetMatrixArray(),
1697 m1.GetNoElements()*
sizeof(Element)) == 0);
1702 template<
class Element>
1703 TMatrixTSym<Element> operator+(
const TMatrixTSym<Element> &source1,
const TMatrixTSym<Element> &source2)
1705 TMatrixTSym<Element> target(source1);
1712 template<
class Element>
1713 TMatrixTSym<Element> operator+(
const TMatrixTSym<Element> &source1,Element val)
1715 TMatrixTSym<Element> target(source1);
1722 template<
class Element>
1723 TMatrixTSym<Element> operator+(Element val,
const TMatrixTSym<Element> &source1)
1725 return operator+(source1,val);
1730 template<
class Element>
1731 TMatrixTSym<Element> operator-(
const TMatrixTSym<Element> &source1,
const TMatrixTSym<Element> &source2)
1733 TMatrixTSym<Element> target(source1);
1740 template<
class Element>
1741 TMatrixTSym<Element> operator-(
const TMatrixTSym<Element> &source1,Element val)
1743 TMatrixTSym<Element> target(source1);
1750 template<
class Element>
1751 TMatrixTSym<Element> operator-(Element val,
const TMatrixTSym<Element> &source1)
1753 return Element(-1.0)*operator-(source1,val);
1758 template<
class Element>
1759 TMatrixTSym<Element> operator*(
const TMatrixTSym<Element> &source1,Element val)
1761 TMatrixTSym<Element> target(source1);
1768 template<
class Element>
1769 TMatrixTSym<Element> operator*(Element val,
const TMatrixTSym<Element> &source1)
1771 return operator*(source1,val);
1777 template<
class Element>
1778 TMatrixTSym<Element> operator&&(
const TMatrixTSym<Element> &source1,
const TMatrixTSym<Element> &source2)
1780 TMatrixTSym<Element> target;
1782 if (gMatrixCheck && !AreCompatible(source1,source2)) {
1783 Error(
"operator&&(const TMatrixTSym&,const TMatrixTSym&)",
"matrices not compatible");
1787 target.ResizeTo(source1);
1789 const Element *sp1 = source1.GetMatrixArray();
1790 const Element *sp2 = source2.GetMatrixArray();
1791 Element *tp = target.GetMatrixArray();
1792 const Element *
const tp_last = tp+target.GetNoElements();
1793 while (tp < tp_last)
1794 *tp++ = (*sp1++ != 0.0 && *sp2++ != 0.0);
1802 template<
class Element>
1803 TMatrixTSym<Element> operator||(
const TMatrixTSym<Element> &source1,
const TMatrixTSym<Element> &source2)
1805 TMatrixTSym<Element> target;
1807 if (gMatrixCheck && !AreCompatible(source1,source2)) {
1808 Error(
"operator||(const TMatrixTSym&,const TMatrixTSym&)",
"matrices not compatible");
1812 target.ResizeTo(source1);
1814 const Element *sp1 = source1.GetMatrixArray();
1815 const Element *sp2 = source2.GetMatrixArray();
1816 Element *tp = target.GetMatrixArray();
1817 const Element *
const tp_last = tp+target.GetNoElements();
1818 while (tp < tp_last)
1819 *tp++ = (*sp1++ != 0.0 || *sp2++ != 0.0);
1827 template<
class Element>
1828 TMatrixTSym<Element> operator>(
const TMatrixTSym<Element> &source1,
const TMatrixTSym<Element> &source2)
1830 TMatrixTSym<Element> target;
1832 if (gMatrixCheck && !AreCompatible(source1,source2)) {
1833 Error(
"operator>(const TMatrixTSym&,const TMatrixTSym&)",
"matrices not compatible");
1837 target.ResizeTo(source1);
1839 const Element *sp1 = source1.GetMatrixArray();
1840 const Element *sp2 = source2.GetMatrixArray();
1841 Element *tp = target.GetMatrixArray();
1842 const Element *
const tp_last = tp+target.GetNoElements();
1843 while (tp < tp_last) {
1844 *tp++ = (*sp1) > (*sp2); sp1++; sp2++;
1853 template<
class Element>
1854 TMatrixTSym<Element> operator>=(
const TMatrixTSym<Element> &source1,
const TMatrixTSym<Element> &source2)
1856 TMatrixTSym<Element> target;
1858 if (gMatrixCheck && !AreCompatible(source1,source2)) {
1859 Error(
"operator>=(const TMatrixTSym&,const TMatrixTSym&)",
"matrices not compatible");
1863 target.ResizeTo(source1);
1865 const Element *sp1 = source1.GetMatrixArray();
1866 const Element *sp2 = source2.GetMatrixArray();
1867 Element *tp = target.GetMatrixArray();
1868 const Element *
const tp_last = tp+target.GetNoElements();
1869 while (tp < tp_last) {
1870 *tp++ = (*sp1) >= (*sp2); sp1++; sp2++;
1879 template<
class Element>
1880 TMatrixTSym<Element> operator<=(const TMatrixTSym<Element> &source1,
const TMatrixTSym<Element> &source2)
1882 TMatrixTSym<Element> target;
1884 if (gMatrixCheck && !AreCompatible(source1,source2)) {
1885 Error(
"operator<=(const TMatrixTSym&,const TMatrixTSym&)",
"matrices not compatible");
1889 target.ResizeTo(source1);
1891 const Element *sp1 = source1.GetMatrixArray();
1892 const Element *sp2 = source2.GetMatrixArray();
1893 Element *tp = target.GetMatrixArray();
1894 const Element *
const tp_last = tp+target.GetNoElements();
1895 while (tp < tp_last) {
1896 *tp++ = (*sp1) <= (*sp2); sp1++; sp2++;
1905 template<
class Element>
1906 TMatrixTSym<Element> operator<(const TMatrixTSym<Element> &source1,
const TMatrixTSym<Element> &source2)
1908 TMatrixTSym<Element> target;
1910 if (gMatrixCheck && !AreCompatible(source1,source2)) {
1911 Error(
"operator<(const TMatrixTSym&,const TMatrixTSym&)",
"matrices not compatible");
1915 target.ResizeTo(source1);
1917 const Element *sp1 = source1.GetMatrixArray();
1918 const Element *sp2 = source2.GetMatrixArray();
1919 Element *tp = target.GetMatrixArray();
1920 const Element *
const tp_last = tp+target.GetNoElements();
1921 while (tp < tp_last) {
1922 *tp++ = (*sp1) < (*sp2); sp1++; sp2++;
1931 template<
class Element>
1932 TMatrixTSym<Element> &Add(TMatrixTSym<Element> &target,Element scalar,
const TMatrixTSym<Element> &source)
1934 if (gMatrixCheck && !AreCompatible(target,source)) {
1935 ::Error(
"Add",
"matrices not compatible");
1939 const Int_t nrows = target.GetNrows();
1940 const Int_t ncols = target.GetNcols();
1941 const Int_t nelems = target.GetNoElements();
1942 const Element *sp = source.GetMatrixArray();
1943 Element *trp = target.GetMatrixArray();
1944 Element *tcp = target.GetMatrixArray();
1945 for (Int_t i = 0; i < nrows; i++) {
1949 for (Int_t j = i; j < ncols; j++) {
1950 const Element tmp = scalar * *sp++;
1951 if (j > i) *tcp += tmp;
1964 template<
class Element>
1965 TMatrixTSym<Element> &ElementMult(TMatrixTSym<Element> &target,
const TMatrixTSym<Element> &source)
1967 if (gMatrixCheck && !AreCompatible(target,source)) {
1968 ::Error(
"ElementMult",
"matrices not compatible");
1972 const Int_t nrows = target.GetNrows();
1973 const Int_t ncols = target.GetNcols();
1974 const Int_t nelems = target.GetNoElements();
1975 const Element *sp = source.GetMatrixArray();
1976 Element *trp = target.GetMatrixArray();
1977 Element *tcp = target.GetMatrixArray();
1978 for (Int_t i = 0; i < nrows; i++) {
1982 for (Int_t j = i; j < ncols; j++) {
1983 if (j > i) *tcp *= *sp;
1996 template<
class Element>
1997 TMatrixTSym<Element> &ElementDiv(TMatrixTSym<Element> &target,
const TMatrixTSym<Element> &source)
1999 if (gMatrixCheck && !AreCompatible(target,source)) {
2000 ::Error(
"ElementDiv",
"matrices not compatible");
2004 const Int_t nrows = target.GetNrows();
2005 const Int_t ncols = target.GetNcols();
2006 const Int_t nelems = target.GetNoElements();
2007 const Element *sp = source.GetMatrixArray();
2008 Element *trp = target.GetMatrixArray();
2009 Element *tcp = target.GetMatrixArray();
2010 for (Int_t i = 0; i < nrows; i++) {
2014 for (Int_t j = i; j < ncols; j++) {
2016 if (j > i) *tcp /= *sp;
2019 const Int_t irow = (sp-source.GetMatrixArray())/source.GetNcols();
2020 const Int_t icol = (sp-source.GetMatrixArray())%source.GetNcols();
2021 Error(
"ElementDiv",
"source (%d,%d) is zero",irow,icol);
2035 template<
class Element>
2036 void TMatrixTSym<Element>::Streamer(TBuffer &R__b)
2038 if (R__b.IsReading()) {
2040 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
2042 R__b.ReadClassBuffer(TMatrixTBase<Element>::Class(),
this,R__v,R__s,R__c);
2043 fElements =
new Element[this->fNelems];
2045 for (i = 0; i < this->fNrows; i++) {
2046 R__b.ReadFastArray(fElements+i*this->fNcols+i,this->fNcols-i);
2049 for (i = 0; i < this->fNrows; i++) {
2050 for (Int_t j = 0; j < i; j++) {
2051 fElements[i*this->fNcols+j] = fElements[j*this->fNrows+i];
2054 if (this->fNelems <= this->kSizeMax) {
2055 memcpy(fDataStack,fElements,this->fNelems*
sizeof(Element));
2056 delete [] fElements;
2057 fElements = fDataStack;
2060 R__b.WriteClassBuffer(TMatrixTBase<Element>::Class(),
this);
2062 for (Int_t i = 0; i < this->fNrows; i++) {
2063 R__b.WriteFastArray(fElements+i*this->fNcols+i,this->fNcols-i);
2070 template class TMatrixTSym<Float_t>;
2072 template Bool_t
operator== <Float_t>(
const TMatrixFSym &source1,
const TMatrixFSym &source2);
2073 template TMatrixFSym
operator+ <Float_t>(
const TMatrixFSym &source1,
const TMatrixFSym &source2);
2074 template TMatrixFSym
operator+ <Float_t>(
const TMatrixFSym &source1, Float_t val);
2075 template TMatrixFSym
operator+ <Float_t>( Float_t val ,
const TMatrixFSym &source2);
2076 template TMatrixFSym
operator- <Float_t>(
const TMatrixFSym &source1,
const TMatrixFSym &source2);
2077 template TMatrixFSym
operator- <Float_t>(
const TMatrixFSym &source1, Float_t val);
2078 template TMatrixFSym
operator- <Float_t>( Float_t val ,
const TMatrixFSym &source2);
2079 template TMatrixFSym
operator* <Float_t>(
const TMatrixFSym &source, Float_t val );
2080 template TMatrixFSym
operator* <Float_t>( Float_t val,
const TMatrixFSym &source );
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);
2086 template TMatrixFSym operator< <Float_t>(
const TMatrixFSym &source1,
const TMatrixFSym &source2);
2088 template TMatrixFSym &Add <Float_t>(TMatrixFSym &target, Float_t scalar,
const TMatrixFSym &source);
2089 template TMatrixFSym &ElementMult<Float_t>(TMatrixFSym &target,
const TMatrixFSym &source);
2090 template TMatrixFSym &ElementDiv <Float_t>(TMatrixFSym &target,
const TMatrixFSym &source);
2094 template class TMatrixTSym<Double_t>;
2096 template Bool_t
operator== <Double_t>(
const TMatrixDSym &source1,
const TMatrixDSym &source2);
2097 template TMatrixDSym
operator+ <Double_t>(
const TMatrixDSym &source1,
const TMatrixDSym &source2);
2098 template TMatrixDSym
operator+ <Double_t>(
const TMatrixDSym &source1, Double_t val);
2099 template TMatrixDSym
operator+ <Double_t>( Double_t val ,
const TMatrixDSym &source2);
2100 template TMatrixDSym
operator- <Double_t>(
const TMatrixDSym &source1,
const TMatrixDSym &source2);
2101 template TMatrixDSym
operator- <Double_t>(
const TMatrixDSym &source1, Double_t val);
2102 template TMatrixDSym
operator- <Double_t>( Double_t val ,
const TMatrixDSym &source2);
2103 template TMatrixDSym
operator* <Double_t>(
const TMatrixDSym &source, Double_t val );
2104 template TMatrixDSym
operator* <Double_t>( Double_t val,
const TMatrixDSym &source );
2105 template TMatrixDSym
operator&& <Double_t>(
const TMatrixDSym &source1,
const TMatrixDSym &source2);
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);
2110 template TMatrixDSym operator< <Double_t>(
const TMatrixDSym &source1,
const TMatrixDSym &source2);
2112 template TMatrixDSym &Add <Double_t>(TMatrixDSym &target, Double_t scalar,
const TMatrixDSym &source);
2113 template TMatrixDSym &ElementMult<Double_t>(TMatrixDSym &target,
const TMatrixDSym &source);
2114 template TMatrixDSym &ElementDiv <Double_t>(TMatrixDSym &target,
const TMatrixDSym &source);