00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <iostream>
00021 #include <typeinfo>
00022
00023 #include "TMatrixT.h"
00024 #include "TMatrixTSym.h"
00025 #include "TMatrixTLazy.h"
00026 #include "TMatrixTCramerInv.h"
00027 #include "TDecompLU.h"
00028 #include "TMatrixDEigen.h"
00029 #include "TClass.h"
00030 #include "TMath.h"
00031
00032 #ifndef R__ALPHA
00033 templateClassImp(TMatrixT)
00034 #endif
00035
00036 template<class Element>
00037 TMatrixT<Element>::TMatrixT(Int_t nrows,Int_t ncols)
00038 {
00039
00040
00041 Allocate(nrows,ncols,0,0,1);
00042 }
00043
00044
00045 template<class Element>
00046 TMatrixT<Element>::TMatrixT(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb)
00047 {
00048
00049
00050 Allocate(row_upb-row_lwb+1,col_upb-col_lwb+1,row_lwb,col_lwb,1);
00051 }
00052
00053
00054 template<class Element>
00055 TMatrixT<Element>::TMatrixT(Int_t no_rows,Int_t no_cols,const Element *elements,Option_t *option)
00056 {
00057
00058
00059
00060
00061
00062
00063
00064 Allocate(no_rows,no_cols);
00065 TMatrixTBase<Element>::SetMatrixArray(elements,option);
00066 }
00067
00068
00069 template<class Element>
00070 TMatrixT<Element>::TMatrixT(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,
00071 const Element *elements,Option_t *option)
00072 {
00073
00074
00075 Allocate(row_upb-row_lwb+1,col_upb-col_lwb+1,row_lwb,col_lwb);
00076 TMatrixTBase<Element>::SetMatrixArray(elements,option);
00077 }
00078
00079
00080 template<class Element>
00081 TMatrixT<Element>::TMatrixT(const TMatrixT<Element> &another) : TMatrixTBase<Element>(another)
00082 {
00083
00084
00085 R__ASSERT(another.IsValid());
00086 Allocate(another.GetNrows(),another.GetNcols(),another.GetRowLwb(),another.GetColLwb());
00087 *this = another;
00088 }
00089
00090
00091 template<class Element>
00092 TMatrixT<Element>::TMatrixT(const TMatrixTSym<Element> &another)
00093 {
00094
00095
00096 R__ASSERT(another.IsValid());
00097 Allocate(another.GetNrows(),another.GetNcols(),another.GetRowLwb(),another.GetColLwb());
00098 *this = another;
00099 }
00100
00101
00102 template<class Element>
00103 TMatrixT<Element>::TMatrixT(const TMatrixTSparse<Element> &another)
00104 {
00105
00106
00107 R__ASSERT(another.IsValid());
00108 Allocate(another.GetNrows(),another.GetNcols(),another.GetRowLwb(),another.GetColLwb());
00109 *this = another;
00110 }
00111
00112
00113 template<class Element>
00114 TMatrixT<Element>::TMatrixT(EMatrixCreatorsOp1 op,const TMatrixT<Element> &prototype)
00115 {
00116
00117
00118
00119
00120 R__ASSERT(prototype.IsValid());
00121
00122 switch(op) {
00123 case kZero:
00124 Allocate(prototype.GetNrows(),prototype.GetNcols(),
00125 prototype.GetRowLwb(),prototype.GetColLwb(),1);
00126 break;
00127
00128 case kUnit:
00129 Allocate(prototype.GetNrows(),prototype.GetNcols(),
00130 prototype.GetRowLwb(),prototype.GetColLwb(),1);
00131 this->UnitMatrix();
00132 break;
00133
00134 case kTransposed:
00135 Allocate(prototype.GetNcols(), prototype.GetNrows(),
00136 prototype.GetColLwb(),prototype.GetRowLwb());
00137 Transpose(prototype);
00138 break;
00139
00140 case kInverted:
00141 {
00142 Allocate(prototype.GetNrows(),prototype.GetNcols(),
00143 prototype.GetRowLwb(),prototype.GetColLwb(),1);
00144 *this = prototype;
00145
00146
00147 const Element oldTol = this->SetTol(std::numeric_limits<Element>::min());
00148 this->Invert();
00149 this->SetTol(oldTol);
00150 break;
00151 }
00152
00153 case kAtA:
00154 Allocate(prototype.GetNcols(),prototype.GetNcols(),prototype.GetColLwb(),prototype.GetColLwb(),1);
00155 TMult(prototype,prototype);
00156 break;
00157
00158 default:
00159 Error("TMatrixT(EMatrixCreatorOp1)", "operation %d not yet implemented", op);
00160 }
00161 }
00162
00163
00164 template<class Element>
00165 TMatrixT<Element>::TMatrixT(const TMatrixT<Element> &a,EMatrixCreatorsOp2 op,const TMatrixT<Element> &b)
00166 {
00167
00168
00169
00170
00171 R__ASSERT(a.IsValid());
00172 R__ASSERT(b.IsValid());
00173
00174 switch(op) {
00175 case kMult:
00176 Allocate(a.GetNrows(),b.GetNcols(),a.GetRowLwb(),b.GetColLwb(),1);
00177 Mult(a,b);
00178 break;
00179
00180 case kTransposeMult:
00181 Allocate(a.GetNcols(),b.GetNcols(),a.GetColLwb(),b.GetColLwb(),1);
00182 TMult(a,b);
00183 break;
00184
00185 case kMultTranspose:
00186 Allocate(a.GetNrows(),b.GetNrows(),a.GetRowLwb(),b.GetRowLwb(),1);
00187 MultT(a,b);
00188 break;
00189
00190 case kInvMult:
00191 {
00192 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb(),1);
00193 *this = a;
00194 const Element oldTol = this->SetTol(std::numeric_limits<Element>::min());
00195 this->Invert();
00196 this->SetTol(oldTol);
00197 *this *= b;
00198 break;
00199 }
00200
00201 case kPlus:
00202 {
00203 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb(),1);
00204 Plus(a,b);
00205 break;
00206 }
00207
00208 case kMinus:
00209 {
00210 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb(),1);
00211 Minus(a,b);
00212 break;
00213 }
00214
00215 default:
00216 Error("TMatrixT(EMatrixCreatorOp2)", "operation %d not yet implemented", op);
00217 }
00218 }
00219
00220
00221 template<class Element>
00222 TMatrixT<Element>::TMatrixT(const TMatrixT<Element> &a,EMatrixCreatorsOp2 op,const TMatrixTSym<Element> &b)
00223 {
00224
00225
00226
00227
00228 R__ASSERT(a.IsValid());
00229 R__ASSERT(b.IsValid());
00230
00231 switch(op) {
00232 case kMult:
00233 Allocate(a.GetNrows(),b.GetNcols(),a.GetRowLwb(),b.GetColLwb(),1);
00234 Mult(a,b);
00235 break;
00236
00237 case kTransposeMult:
00238 Allocate(a.GetNcols(),b.GetNcols(),a.GetColLwb(),b.GetColLwb(),1);
00239 TMult(a,b);
00240 break;
00241
00242 case kMultTranspose:
00243 Allocate(a.GetNrows(),b.GetNrows(),a.GetRowLwb(),b.GetRowLwb(),1);
00244 MultT(a,b);
00245 break;
00246
00247 case kInvMult:
00248 {
00249 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb(),1);
00250 *this = a;
00251 const Element oldTol = this->SetTol(std::numeric_limits<Element>::min());
00252 this->Invert();
00253 this->SetTol(oldTol);
00254 *this *= b;
00255 break;
00256 }
00257
00258 case kPlus:
00259 {
00260 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb(),1);
00261 Plus(a,b);
00262 break;
00263 }
00264
00265 case kMinus:
00266 {
00267 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb(),1);
00268 Minus(a,b);
00269 break;
00270 }
00271
00272 default:
00273 Error("TMatrixT(EMatrixCreatorOp2)", "operation %d not yet implemented", op);
00274 }
00275 }
00276
00277
00278 template<class Element>
00279 TMatrixT<Element>::TMatrixT(const TMatrixTSym<Element> &a,EMatrixCreatorsOp2 op,const TMatrixT<Element> &b)
00280 {
00281
00282
00283
00284
00285 R__ASSERT(a.IsValid());
00286 R__ASSERT(b.IsValid());
00287
00288 switch(op) {
00289 case kMult:
00290 Allocate(a.GetNrows(),b.GetNcols(),a.GetRowLwb(),b.GetColLwb(),1);
00291 Mult(a,b);
00292 break;
00293
00294 case kTransposeMult:
00295 Allocate(a.GetNcols(),b.GetNcols(),a.GetColLwb(),b.GetColLwb(),1);
00296 TMult(a,b);
00297 break;
00298
00299 case kMultTranspose:
00300 Allocate(a.GetNrows(),b.GetNrows(),a.GetRowLwb(),b.GetRowLwb(),1);
00301 MultT(a,b);
00302 break;
00303
00304 case kInvMult:
00305 {
00306 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb(),1);
00307 *this = a;
00308 const Element oldTol = this->SetTol(std::numeric_limits<Element>::min());
00309 this->Invert();
00310 this->SetTol(oldTol);
00311 *this *= b;
00312 break;
00313 }
00314
00315 case kPlus:
00316 {
00317 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb(),1);
00318 Plus(a,b);
00319 break;
00320 }
00321
00322 case kMinus:
00323 {
00324 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb(),1);
00325 Minus(a,b);
00326 break;
00327 }
00328
00329 default:
00330 Error("TMatrixT(EMatrixCreatorOp2)", "operation %d not yet implemented", op);
00331 }
00332 }
00333
00334
00335 template<class Element>
00336 TMatrixT<Element>::TMatrixT(const TMatrixTSym<Element> &a,EMatrixCreatorsOp2 op,const TMatrixTSym<Element> &b)
00337 {
00338
00339
00340
00341
00342 R__ASSERT(a.IsValid());
00343 R__ASSERT(b.IsValid());
00344
00345 switch(op) {
00346 case kMult:
00347 Allocate(a.GetNrows(),b.GetNcols(),a.GetRowLwb(),b.GetColLwb(),1);
00348 Mult(a,b);
00349 break;
00350
00351 case kTransposeMult:
00352 Allocate(a.GetNcols(),b.GetNcols(),a.GetColLwb(),b.GetColLwb(),1);
00353 TMult(a,b);
00354 break;
00355
00356 case kMultTranspose:
00357 Allocate(a.GetNrows(),b.GetNrows(),a.GetRowLwb(),b.GetRowLwb(),1);
00358 MultT(a,b);
00359 break;
00360
00361 case kInvMult:
00362 {
00363 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb(),1);
00364 *this = a;
00365 const Element oldTol = this->SetTol(std::numeric_limits<Element>::min());
00366 this->Invert();
00367 this->SetTol(oldTol);
00368 *this *= b;
00369 break;
00370 }
00371
00372 case kPlus:
00373 {
00374 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb(),1);
00375 Plus(*dynamic_cast<const TMatrixT<Element> *>(&a),b);
00376 break;
00377 }
00378
00379 case kMinus:
00380 {
00381 Allocate(a.GetNrows(),a.GetNcols(),a.GetRowLwb(),a.GetColLwb(),1);
00382 Minus(*dynamic_cast<const TMatrixT<Element> *>(&a),b);
00383 break;
00384 }
00385
00386 default:
00387 Error("TMatrixT(EMatrixCreatorOp2)", "operation %d not yet implemented", op);
00388 }
00389 }
00390
00391
00392 template<class Element>
00393 TMatrixT<Element>::TMatrixT(const TMatrixTLazy<Element> &lazy_constructor)
00394 {
00395
00396
00397 Allocate(lazy_constructor.GetRowUpb()-lazy_constructor.GetRowLwb()+1,
00398 lazy_constructor.GetColUpb()-lazy_constructor.GetColLwb()+1,
00399 lazy_constructor.GetRowLwb(),lazy_constructor.GetColLwb(),1);
00400 lazy_constructor.FillIn(*this);
00401 }
00402
00403
00404 template<class Element>
00405 void TMatrixT<Element>::Delete_m(Int_t size,Element *&m)
00406 {
00407
00408
00409 if (m) {
00410 if (size > this->kSizeMax)
00411 delete [] m;
00412 m = 0;
00413 }
00414 }
00415
00416
00417 template<class Element>
00418 Element* TMatrixT<Element>::New_m(Int_t size)
00419 {
00420
00421
00422
00423 if (size == 0) return 0;
00424 else {
00425 if ( size <= this->kSizeMax )
00426 return fDataStack;
00427 else {
00428 Element *heap = new Element[size];
00429 return heap;
00430 }
00431 }
00432 }
00433
00434
00435 template<class Element>
00436 Int_t TMatrixT<Element>::Memcpy_m(Element *newp,const Element *oldp,Int_t copySize,
00437 Int_t newSize,Int_t oldSize)
00438 {
00439
00440
00441
00442 if (copySize == 0 || oldp == newp)
00443 return 0;
00444 else {
00445 if ( newSize <= this->kSizeMax && oldSize <= this->kSizeMax ) {
00446
00447 if (newp > oldp) {
00448 for (Int_t i = copySize-1; i >= 0; i--)
00449 newp[i] = oldp[i];
00450 } else {
00451 for (Int_t i = 0; i < copySize; i++)
00452 newp[i] = oldp[i];
00453 }
00454 }
00455 else
00456 memcpy(newp,oldp,copySize*sizeof(Element));
00457 }
00458 return 0;
00459 }
00460
00461
00462 template<class Element>
00463 void TMatrixT<Element>::Allocate(Int_t no_rows,Int_t no_cols,Int_t row_lwb,Int_t col_lwb,
00464 Int_t init,Int_t )
00465 {
00466
00467
00468
00469 this->fIsOwner = kTRUE;
00470 this->fTol = std::numeric_limits<Element>::epsilon();
00471 fElements = 0;
00472 this->fNrows = 0;
00473 this->fNcols = 0;
00474 this->fRowLwb = 0;
00475 this->fColLwb = 0;
00476 this->fNelems = 0;
00477
00478 if (no_rows < 0 || no_cols < 0)
00479 {
00480 Error("Allocate","no_rows=%d no_cols=%d",no_rows,no_cols);
00481 this->Invalidate();
00482 return;
00483 }
00484
00485 this->MakeValid();
00486 this->fNrows = no_rows;
00487 this->fNcols = no_cols;
00488 this->fRowLwb = row_lwb;
00489 this->fColLwb = col_lwb;
00490 this->fNelems = this->fNrows*this->fNcols;
00491
00492 if (this->fNelems > 0) {
00493 fElements = New_m(this->fNelems);
00494 if (init)
00495 memset(fElements,0,this->fNelems*sizeof(Element));
00496 } else
00497 fElements = 0;
00498 }
00499
00500
00501 template<class Element>
00502 void TMatrixT<Element>::Plus(const TMatrixT<Element> &a,const TMatrixT<Element> &b)
00503 {
00504
00505
00506 if (gMatrixCheck) {
00507 if (!AreCompatible(a,b)) {
00508 Error("Plus","matrices not compatible");
00509 return;
00510 }
00511
00512 if (this->GetMatrixArray() == a.GetMatrixArray()) {
00513 Error("Plus","this->GetMatrixArray() == a.GetMatrixArray()");
00514 return;
00515 }
00516
00517 if (this->GetMatrixArray() == b.GetMatrixArray()) {
00518 Error("Plus","this->GetMatrixArray() == b.GetMatrixArray()");
00519 return;
00520 }
00521 }
00522
00523 const Element * ap = a.GetMatrixArray();
00524 const Element * bp = b.GetMatrixArray();
00525 Element * cp = this->GetMatrixArray();
00526 const Element * const cp_last = cp+this->fNelems;
00527
00528 while (cp < cp_last) {
00529 *cp = *ap++ + *bp++;
00530 cp++;
00531 }
00532 }
00533
00534
00535 template<class Element>
00536 void TMatrixT<Element>::Plus(const TMatrixT<Element> &a,const TMatrixTSym<Element> &b)
00537 {
00538
00539
00540 if (gMatrixCheck) {
00541 if (!AreCompatible(a,b)) {
00542 Error("Plus","matrices not compatible");
00543 return;
00544 }
00545
00546 if (this->GetMatrixArray() == a.GetMatrixArray()) {
00547 Error("Plus","this->GetMatrixArray() == a.GetMatrixArray()");
00548 return;
00549 }
00550
00551 if (this->GetMatrixArray() == b.GetMatrixArray()) {
00552 Error("Plus","this->GetMatrixArray() == b.GetMatrixArray()");
00553 return;
00554 }
00555 }
00556
00557 const Element * ap = a.GetMatrixArray();
00558 const Element * bp = b.GetMatrixArray();
00559 Element * cp = this->GetMatrixArray();
00560 const Element * const cp_last = cp+this->fNelems;
00561
00562 while (cp < cp_last) {
00563 *cp = *ap++ + *bp++;
00564 cp++;
00565 }
00566 }
00567
00568
00569 template<class Element>
00570 void TMatrixT<Element>::Minus(const TMatrixT<Element> &a,const TMatrixT<Element> &b)
00571 {
00572
00573
00574 if (gMatrixCheck) {
00575 if (!AreCompatible(a,b)) {
00576 Error("Minus","matrices not compatible");
00577 return;
00578 }
00579
00580 if (this->GetMatrixArray() == a.GetMatrixArray()) {
00581 Error("Minus","this->GetMatrixArray() == a.GetMatrixArray()");
00582 return;
00583 }
00584
00585 if (this->GetMatrixArray() == b.GetMatrixArray()) {
00586 Error("Minus","this->GetMatrixArray() == b.GetMatrixArray()");
00587 return;
00588 }
00589 }
00590
00591 const Element * ap = a.GetMatrixArray();
00592 const Element * bp = b.GetMatrixArray();
00593 Element * cp = this->GetMatrixArray();
00594 const Element * const cp_last = cp+this->fNelems;
00595
00596 while (cp < cp_last) {
00597 *cp = *ap++ - *bp++;
00598 cp++;
00599 }
00600 }
00601
00602
00603 template<class Element>
00604 void TMatrixT<Element>::Minus(const TMatrixT<Element> &a,const TMatrixTSym<Element> &b)
00605 {
00606
00607
00608 if (gMatrixCheck) {
00609 if (!AreCompatible(a,b)) {
00610 Error("Minus","matrices not compatible");
00611 return;
00612 }
00613
00614 if (this->GetMatrixArray() == a.GetMatrixArray()) {
00615 Error("Minus","this->GetMatrixArray() == a.GetMatrixArray()");
00616 return;
00617 }
00618
00619 if (this->GetMatrixArray() == b.GetMatrixArray()) {
00620 Error("Minus","this->GetMatrixArray() == b.GetMatrixArray()");
00621 return;
00622 }
00623 }
00624
00625 const Element * ap = a.GetMatrixArray();
00626 const Element * bp = b.GetMatrixArray();
00627 Element * cp = this->GetMatrixArray();
00628 const Element * const cp_last = cp+this->fNelems;
00629
00630 while (cp < cp_last) {
00631 *cp = *ap++ - *bp++;
00632 cp++;
00633 }
00634 }
00635
00636
00637 template<class Element>
00638 void TMatrixT<Element>::Mult(const TMatrixT<Element> &a,const TMatrixT<Element> &b)
00639 {
00640
00641
00642 if (gMatrixCheck) {
00643 if (a.GetNcols() != b.GetNrows() || a.GetColLwb() != b.GetRowLwb()) {
00644 Error("Mult","A rows and B columns incompatible");
00645 return;
00646 }
00647
00648 if (this->GetMatrixArray() == a.GetMatrixArray()) {
00649 Error("Mult","this->GetMatrixArray() == a.GetMatrixArray()");
00650 return;
00651 }
00652
00653 if (this->GetMatrixArray() == b.GetMatrixArray()) {
00654 Error("Mult","this->GetMatrixArray() == b.GetMatrixArray()");
00655 return;
00656 }
00657 }
00658
00659 #ifdef CBLAS
00660 const Element *ap = a.GetMatrixArray();
00661 const Element *bp = b.GetMatrixArray();
00662 Element *cp = this->GetMatrixArray();
00663 if (typeid(Element) == typeid(Double_t))
00664 cblas_dgemm (CblasRowMajor,CblasNoTrans,CblasNoTrans,fNrows,fNcols,a.GetNcols(),
00665 1.0,ap,a.GetNcols(),bp,b.GetNcols(),1.0,cp,fNcols);
00666 else if (typeid(Element) != typeid(Float_t))
00667 cblas_sgemm (CblasRowMajor,CblasNoTrans,CblasNoTrans,fNrows,fNcols,a.GetNcols(),
00668 1.0,ap,a.GetNcols(),bp,b.GetNcols(),1.0,cp,fNcols);
00669 else
00670 Error("Mult","type %s not implemented in BLAS library",typeid(Element));
00671 #else
00672 const Int_t na = a.GetNoElements();
00673 const Int_t nb = b.GetNoElements();
00674 const Int_t ncolsa = a.GetNcols();
00675 const Int_t ncolsb = b.GetNcols();
00676 const Element * const ap = a.GetMatrixArray();
00677 const Element * const bp = b.GetMatrixArray();
00678 Element * cp = this->GetMatrixArray();
00679
00680 AMultB(ap,na,ncolsa,bp,nb,ncolsb,cp);
00681 #endif
00682 }
00683
00684
00685 template<class Element>
00686 void TMatrixT<Element>::Mult(const TMatrixTSym<Element> &a,const TMatrixT<Element> &b)
00687 {
00688
00689
00690
00691 if (gMatrixCheck) {
00692 R__ASSERT(a.IsValid());
00693 R__ASSERT(b.IsValid());
00694 if (a.GetNcols() != b.GetNrows() || a.GetColLwb() != b.GetRowLwb()) {
00695 Error("Mult","A rows and B columns incompatible");
00696 return;
00697 }
00698
00699 if (this->GetMatrixArray() == a.GetMatrixArray()) {
00700 Error("Mult","this->GetMatrixArray() == a.GetMatrixArray()");
00701 return;
00702 }
00703
00704 if (this->GetMatrixArray() == b.GetMatrixArray()) {
00705 Error("Mult","this->GetMatrixArray() == b.GetMatrixArray()");
00706 return;
00707 }
00708 }
00709
00710 #ifdef CBLAS
00711 const Element *ap = a.GetMatrixArray();
00712 const Element *bp = b.GetMatrixArray();
00713 Element *cp = this->GetMatrixArray();
00714 if (typeid(Element) == typeid(Double_t))
00715 cblas_dsymm (CblasRowMajor,CblasLeft,CblasUpper,fNrows,fNcols,1.0,
00716 ap,a.GetNcols(),bp,b.GetNcols(),0.0,cp,fNcols);
00717 else if (typeid(Element) != typeid(Float_t))
00718 cblas_ssymm (CblasRowMajor,CblasLeft,CblasUpper,fNrows,fNcols,1.0,
00719 ap,a.GetNcols(),bp,b.GetNcols(),0.0,cp,fNcols);
00720 else
00721 Error("Mult","type %s not implemented in BLAS library",typeid(Element));
00722 #else
00723 const Int_t na = a.GetNoElements();
00724 const Int_t nb = b.GetNoElements();
00725 const Int_t ncolsa = a.GetNcols();
00726 const Int_t ncolsb = b.GetNcols();
00727 const Element * const ap = a.GetMatrixArray();
00728 const Element * const bp = b.GetMatrixArray();
00729 Element * cp = this->GetMatrixArray();
00730
00731 AMultB(ap,na,ncolsa,bp,nb,ncolsb,cp);
00732
00733 #endif
00734 }
00735
00736
00737 template<class Element>
00738 void TMatrixT<Element>::Mult(const TMatrixT<Element> &a,const TMatrixTSym<Element> &b)
00739 {
00740
00741
00742
00743 if (gMatrixCheck) {
00744 R__ASSERT(a.IsValid());
00745 R__ASSERT(b.IsValid());
00746 if (a.GetNcols() != b.GetNrows() || a.GetColLwb() != b.GetRowLwb()) {
00747 Error("Mult","A rows and B columns incompatible");
00748 return;
00749 }
00750
00751 if (this->GetMatrixArray() == a.GetMatrixArray()) {
00752 Error("Mult","this->GetMatrixArray() == a.GetMatrixArray()");
00753 return;
00754 }
00755
00756 if (this->GetMatrixArray() == b.GetMatrixArray()) {
00757 Error("Mult","this->GetMatrixArray() == b.GetMatrixArray()");
00758 return;
00759 }
00760 }
00761
00762 #ifdef CBLAS
00763 const Element *ap = a.GetMatrixArray();
00764 const Element *bp = b.GetMatrixArray();
00765 Element *cp = this->GetMatrixArray();
00766 if (typeid(Element) == typeid(Double_t))
00767 cblas_dsymm (CblasRowMajor,CblasRight,CblasUpper,fNrows,fNcols,1.0,
00768 bp,b.GetNcols(),ap,a.GetNcols(),0.0,cp,fNcols);
00769 else if (typeid(Element) != typeid(Float_t))
00770 cblas_ssymm (CblasRowMajor,CblasRight,CblasUpper,fNrows,fNcols,1.0,
00771 bp,b.GetNcols(),ap,a.GetNcols(),0.0,cp,fNcols);
00772 else
00773 Error("Mult","type %s not implemented in BLAS library",typeid(Element));
00774 #else
00775 const Int_t na = a.GetNoElements();
00776 const Int_t nb = b.GetNoElements();
00777 const Int_t ncolsa = a.GetNcols();
00778 const Int_t ncolsb = b.GetNcols();
00779 const Element * const ap = a.GetMatrixArray();
00780 const Element * const bp = b.GetMatrixArray();
00781 Element * cp = this->GetMatrixArray();
00782
00783 AMultB(ap,na,ncolsa,bp,nb,ncolsb,cp);
00784 #endif
00785 }
00786
00787
00788 template<class Element>
00789 void TMatrixT<Element>::Mult(const TMatrixTSym<Element> &a,const TMatrixTSym<Element> &b)
00790 {
00791
00792
00793
00794
00795 if (gMatrixCheck) {
00796 R__ASSERT(a.IsValid());
00797 R__ASSERT(b.IsValid());
00798 if (a.GetNcols() != b.GetNrows() || a.GetColLwb() != b.GetRowLwb()) {
00799 Error("Mult","A rows and B columns incompatible");
00800 return;
00801 }
00802
00803 if (this->GetMatrixArray() == a.GetMatrixArray()) {
00804 Error("Mult","this->GetMatrixArray() == a.GetMatrixArray()");
00805 return;
00806 }
00807
00808 if (this->GetMatrixArray() == b.GetMatrixArray()) {
00809 Error("Mult","this->GetMatrixArray() == b.GetMatrixArray()");
00810 return;
00811 }
00812 }
00813
00814 #ifdef CBLAS
00815 const Element *ap = a.GetMatrixArray();
00816 const Element *bp = b.GetMatrixArray();
00817 Element *cp = this->GetMatrixArray();
00818 if (typeid(Element) == typeid(Double_t))
00819 cblas_dsymm (CblasRowMajor,CblasLeft,CblasUpper,fNrows,fNcols,1.0,
00820 ap,a.GetNcols(),bp,b.GetNcols(),0.0,cp,fNcols);
00821 else if (typeid(Element) != typeid(Float_t))
00822 cblas_ssymm (CblasRowMajor,CblasLeft,CblasUpper,fNrows,fNcols,1.0,
00823 ap,a.GetNcols(),bp,b.GetNcols(),0.0,cp,fNcols);
00824 else
00825 Error("Mult","type %s not implemented in BLAS library",typeid(Element));
00826 #else
00827 const Int_t na = a.GetNoElements();
00828 const Int_t nb = b.GetNoElements();
00829 const Int_t ncolsa = a.GetNcols();
00830 const Int_t ncolsb = b.GetNcols();
00831 const Element * const ap = a.GetMatrixArray();
00832 const Element * const bp = b.GetMatrixArray();
00833 Element * cp = this->GetMatrixArray();
00834
00835 AMultB(ap,na,ncolsa,bp,nb,ncolsb,cp);
00836 #endif
00837 }
00838
00839
00840 template<class Element>
00841 void TMatrixT<Element>::TMult(const TMatrixT<Element> &a,const TMatrixT<Element> &b)
00842 {
00843
00844
00845
00846 if (gMatrixCheck) {
00847 R__ASSERT(a.IsValid());
00848 R__ASSERT(b.IsValid());
00849 if (a.GetNrows() != b.GetNrows() || a.GetRowLwb() != b.GetRowLwb()) {
00850 Error("TMult","A rows and B columns incompatible");
00851 return;
00852 }
00853
00854 if (this->GetMatrixArray() == a.GetMatrixArray()) {
00855 Error("TMult","this->GetMatrixArray() == a.GetMatrixArray()");
00856 return;
00857 }
00858
00859 if (this->GetMatrixArray() == b.GetMatrixArray()) {
00860 Error("TMult","this->GetMatrixArray() == b.GetMatrixArray()");
00861 return;
00862 }
00863 }
00864
00865 #ifdef CBLAS
00866 const Element *ap = a.GetMatrixArray();
00867 const Element *bp = b.GetMatrixArray();
00868 Element *cp = this->GetMatrixArray();
00869 if (typeid(Element) == typeid(Double_t))
00870 cblas_dgemm (CblasRowMajor,CblasTrans,CblasNoTrans,this->fNrows,this->fNcols,a.GetNrows(),
00871 1.0,ap,a.GetNcols(),bp,b.GetNcols(),1.0,cp,this->fNcols);
00872 else if (typeid(Element) != typeid(Float_t))
00873 cblas_sgemm (CblasRowMajor,CblasTrans,CblasNoTrans,fNrows,fNcols,a.GetNrows(),
00874 1.0,ap,a.GetNcols(),bp,b.GetNcols(),1.0,cp,fNcols);
00875 else
00876 Error("TMult","type %s not implemented in BLAS library",typeid(Element));
00877 #else
00878 const Int_t nb = b.GetNoElements();
00879 const Int_t ncolsa = a.GetNcols();
00880 const Int_t ncolsb = b.GetNcols();
00881 const Element * const ap = a.GetMatrixArray();
00882 const Element * const bp = b.GetMatrixArray();
00883 Element * cp = this->GetMatrixArray();
00884
00885 AtMultB(ap,ncolsa,bp,nb,ncolsb,cp);
00886 #endif
00887 }
00888
00889
00890 template<class Element>
00891 void TMatrixT<Element>::TMult(const TMatrixT<Element> &a,const TMatrixTSym<Element> &b)
00892 {
00893
00894
00895
00896 if (gMatrixCheck) {
00897 R__ASSERT(a.IsValid());
00898 R__ASSERT(b.IsValid());
00899 if (a.GetNrows() != b.GetNrows() || a.GetRowLwb() != b.GetRowLwb()) {
00900 Error("TMult","A rows and B columns incompatible");
00901 return;
00902 }
00903
00904 if (this->GetMatrixArray() == a.GetMatrixArray()) {
00905 Error("TMult","this->GetMatrixArray() == a.GetMatrixArray()");
00906 return;
00907 }
00908
00909 if (this->GetMatrixArray() == b.GetMatrixArray()) {
00910 Error("TMult","this->GetMatrixArray() == b.GetMatrixArray()");
00911 return;
00912 }
00913 }
00914
00915 #ifdef CBLAS
00916 const Element *ap = a.GetMatrixArray();
00917 const Element *bp = b.GetMatrixArray();
00918 Element *cp = this->GetMatrixArray();
00919 if (typeid(Element) == typeid(Double_t))
00920 cblas_dgemm (CblasRowMajor,CblasTrans,CblasNoTrans,fNrows,fNcols,a.GetNrows(),
00921 1.0,ap,a.GetNcols(),bp,b.GetNcols(),1.0,cp,fNcols);
00922 else if (typeid(Element) != typeid(Float_t))
00923 cblas_sgemm (CblasRowMajor,CblasTrans,CblasNoTrans,fNrows,fNcols,a.GetNrows(),
00924 1.0,ap,a.GetNcols(),bp,b.GetNcols(),1.0,cp,fNcols);
00925 else
00926 Error("TMult","type %s not implemented in BLAS library",typeid(Element));
00927 #else
00928 const Int_t nb = b.GetNoElements();
00929 const Int_t ncolsa = a.GetNcols();
00930 const Int_t ncolsb = b.GetNcols();
00931 const Element * const ap = a.GetMatrixArray();
00932 const Element * const bp = b.GetMatrixArray();
00933 Element * cp = this->GetMatrixArray();
00934
00935 AtMultB(ap,ncolsa,bp,nb,ncolsb,cp);
00936 #endif
00937 }
00938
00939
00940 template<class Element>
00941 void TMatrixT<Element>::MultT(const TMatrixT<Element> &a,const TMatrixT<Element> &b)
00942 {
00943
00944
00945 if (gMatrixCheck) {
00946 R__ASSERT(a.IsValid());
00947 R__ASSERT(b.IsValid());
00948
00949 if (a.GetNcols() != b.GetNcols() || a.GetColLwb() != b.GetColLwb()) {
00950 Error("MultT","A rows and B columns incompatible");
00951 return;
00952 }
00953
00954 if (this->GetMatrixArray() == a.GetMatrixArray()) {
00955 Error("MultT","this->GetMatrixArray() == a.GetMatrixArray()");
00956 return;
00957 }
00958
00959 if (this->GetMatrixArray() == b.GetMatrixArray()) {
00960 Error("MultT","this->GetMatrixArray() == b.GetMatrixArray()");
00961 return;
00962 }
00963 }
00964
00965 #ifdef CBLAS
00966 const Element *ap = a.GetMatrixArray();
00967 const Element *bp = b.GetMatrixArray();
00968 Element *cp = this->GetMatrixArray();
00969 if (typeid(Element) == typeid(Double_t))
00970 cblas_dgemm (CblasRowMajor,CblasNoTrans,CblasTrans,fNrows,fNcols,a.GetNcols(),
00971 1.0,ap,a.GetNcols(),bp,b.GetNcols(),1.0,cp,fNcols);
00972 else if (typeid(Element) != typeid(Float_t))
00973 cblas_sgemm (CblasRowMajor,CblasNoTrans,CblasTrans,fNrows,fNcols,a.GetNcols(),
00974 1.0,ap,a.GetNcols(),bp,b.GetNcols(),1.0,cp,fNcols);
00975 else
00976 Error("MultT","type %s not implemented in BLAS library",typeid(Element));
00977 #else
00978 const Int_t na = a.GetNoElements();
00979 const Int_t nb = b.GetNoElements();
00980 const Int_t ncolsa = a.GetNcols();
00981 const Int_t ncolsb = b.GetNcols();
00982 const Element * const ap = a.GetMatrixArray();
00983 const Element * const bp = b.GetMatrixArray();
00984 Element * cp = this->GetMatrixArray();
00985
00986 AMultBt(ap,na,ncolsa,bp,nb,ncolsb,cp);
00987 #endif
00988 }
00989
00990
00991 template<class Element>
00992 void TMatrixT<Element>::MultT(const TMatrixTSym<Element> &a,const TMatrixT<Element> &b)
00993 {
00994
00995
00996
00997 if (gMatrixCheck) {
00998 R__ASSERT(a.IsValid());
00999 R__ASSERT(b.IsValid());
01000 if (a.GetNcols() != b.GetNcols() || a.GetColLwb() != b.GetColLwb()) {
01001 Error("MultT","A rows and B columns incompatible");
01002 return;
01003 }
01004
01005 if (this->GetMatrixArray() == a.GetMatrixArray()) {
01006 Error("MultT","this->GetMatrixArray() == a.GetMatrixArray()");
01007 return;
01008 }
01009
01010 if (this->GetMatrixArray() == b.GetMatrixArray()) {
01011 Error("MultT","this->GetMatrixArray() == b.GetMatrixArray()");
01012 return;
01013 }
01014 }
01015
01016 #ifdef CBLAS
01017 const Element *ap = a.GetMatrixArray();
01018 const Element *bp = b.GetMatrixArray();
01019 Element *cp = this->GetMatrixArray();
01020 if (typeid(Element) == typeid(Double_t))
01021 cblas_dgemm (CblasRowMajor,CblasNoTrans,CblasTrans,this->fNrows,this->fNcols,a.GetNcols(),
01022 1.0,ap,a.GetNcols(),bp,b.GetNcols(),1.0,cp,this->fNcols);
01023 else if (typeid(Element) != typeid(Float_t))
01024 cblas_sgemm (CblasRowMajor,CblasNoTrans,CblasTrans,fNrows,fNcols,a.GetNcols(),
01025 1.0,ap,a.GetNcols(),bp,b.GetNcols(),1.0,cp,fNcols);
01026 else
01027 Error("MultT","type %s not implemented in BLAS library",typeid(Element));
01028 #else
01029 const Int_t na = a.GetNoElements();
01030 const Int_t nb = b.GetNoElements();
01031 const Int_t ncolsa = a.GetNcols();
01032 const Int_t ncolsb = b.GetNcols();
01033 const Element * const ap = a.GetMatrixArray();
01034 const Element * const bp = b.GetMatrixArray();
01035 Element * cp = this->GetMatrixArray();
01036
01037 AMultBt(ap,na,ncolsa,bp,nb,ncolsb,cp);
01038 #endif
01039 }
01040
01041
01042 template<class Element>
01043 TMatrixT<Element> &TMatrixT<Element>::Use(Int_t row_lwb,Int_t row_upb,
01044 Int_t col_lwb,Int_t col_upb,Element *data)
01045 {
01046
01047
01048 if (gMatrixCheck) {
01049 if (row_upb < row_lwb)
01050 {
01051 Error("Use","row_upb=%d < row_lwb=%d",row_upb,row_lwb);
01052 return *this;
01053 }
01054 if (col_upb < col_lwb)
01055 {
01056 Error("Use","col_upb=%d < col_lwb=%d",col_upb,col_lwb);
01057 return *this;
01058 }
01059 }
01060
01061 Clear();
01062 this->fNrows = row_upb-row_lwb+1;
01063 this->fNcols = col_upb-col_lwb+1;
01064 this->fRowLwb = row_lwb;
01065 this->fColLwb = col_lwb;
01066 this->fNelems = this->fNrows*this->fNcols;
01067 fElements = data;
01068 this->fIsOwner = kFALSE;
01069
01070 return *this;
01071 }
01072
01073
01074 template<class Element>
01075 TMatrixTBase<Element> &TMatrixT<Element>::GetSub(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,
01076 TMatrixTBase<Element> &target,Option_t *option) const
01077 {
01078
01079
01080
01081
01082
01083
01084 if (gMatrixCheck) {
01085 R__ASSERT(this->IsValid());
01086 if (row_lwb < this->fRowLwb || row_lwb > this->fRowLwb+this->fNrows-1) {
01087 Error("GetSub","row_lwb out of bounds");
01088 return target;
01089 }
01090 if (col_lwb < this->fColLwb || col_lwb > this->fColLwb+this->fNcols-1) {
01091 Error("GetSub","col_lwb out of bounds");
01092 return target;
01093 }
01094 if (row_upb < this->fRowLwb || row_upb > this->fRowLwb+this->fNrows-1) {
01095 Error("GetSub","row_upb out of bounds");
01096 return target;
01097 }
01098 if (col_upb < this->fColLwb || col_upb > this->fColLwb+this->fNcols-1) {
01099 Error("GetSub","col_upb out of bounds");
01100 return target;
01101 }
01102 if (row_upb < row_lwb || col_upb < col_lwb) {
01103 Error("GetSub","row_upb < row_lwb || col_upb < col_lwb");
01104 return target;
01105 }
01106 }
01107
01108 TString opt(option);
01109 opt.ToUpper();
01110 const Int_t shift = (opt.Contains("S")) ? 1 : 0;
01111
01112 const Int_t row_lwb_sub = (shift) ? 0 : row_lwb;
01113 const Int_t row_upb_sub = (shift) ? row_upb-row_lwb : row_upb;
01114 const Int_t col_lwb_sub = (shift) ? 0 : col_lwb;
01115 const Int_t col_upb_sub = (shift) ? col_upb-col_lwb : col_upb;
01116
01117 target.ResizeTo(row_lwb_sub,row_upb_sub,col_lwb_sub,col_upb_sub);
01118 const Int_t nrows_sub = row_upb_sub-row_lwb_sub+1;
01119 const Int_t ncols_sub = col_upb_sub-col_lwb_sub+1;
01120
01121 if (target.GetRowIndexArray() && target.GetColIndexArray()) {
01122 for (Int_t irow = 0; irow < nrows_sub; irow++) {
01123 for (Int_t icol = 0; icol < ncols_sub; icol++) {
01124 target(irow+row_lwb_sub,icol+col_lwb_sub) = (*this)(row_lwb+irow,col_lwb+icol);
01125 }
01126 }
01127 } else {
01128 const Element *ap = this->GetMatrixArray()+(row_lwb-this->fRowLwb)*this->fNcols+(col_lwb-this->fColLwb);
01129 Element *bp = target.GetMatrixArray();
01130
01131 for (Int_t irow = 0; irow < nrows_sub; irow++) {
01132 const Element *ap_sub = ap;
01133 for (Int_t icol = 0; icol < ncols_sub; icol++) {
01134 *bp++ = *ap_sub++;
01135 }
01136 ap += this->fNcols;
01137 }
01138 }
01139
01140 return target;
01141 }
01142
01143
01144 template<class Element>
01145 TMatrixTBase<Element> &TMatrixT<Element>::SetSub(Int_t row_lwb,Int_t col_lwb,const TMatrixTBase<Element> &source)
01146 {
01147
01148
01149
01150 if (gMatrixCheck) {
01151 R__ASSERT(this->IsValid());
01152 R__ASSERT(source.IsValid());
01153
01154 if (row_lwb < this->fRowLwb || row_lwb > this->fRowLwb+this->fNrows-1) {
01155 Error("SetSub","row_lwb outof bounds");
01156 return *this;
01157 }
01158 if (col_lwb < this->fColLwb || col_lwb > this->fColLwb+this->fNcols-1) {
01159 Error("SetSub","col_lwb outof bounds");
01160 return *this;
01161 }
01162 if (row_lwb+source.GetNrows() > this->fRowLwb+this->fNrows ||
01163 col_lwb+source.GetNcols() > this->fColLwb+this->fNcols) {
01164 Error("SetSub","source matrix too large");
01165 return *this;
01166 }
01167 }
01168
01169 const Int_t nRows_source = source.GetNrows();
01170 const Int_t nCols_source = source.GetNcols();
01171
01172 if (source.GetRowIndexArray() && source.GetColIndexArray()) {
01173 const Int_t rowlwb_s = source.GetRowLwb();
01174 const Int_t collwb_s = source.GetColLwb();
01175 for (Int_t irow = 0; irow < nRows_source; irow++) {
01176 for (Int_t icol = 0; icol < nCols_source; icol++) {
01177 (*this)(row_lwb+irow,col_lwb+icol) = source(rowlwb_s+irow,collwb_s+icol);
01178 }
01179 }
01180 } else {
01181 const Element *bp = source.GetMatrixArray();
01182 Element *ap = this->GetMatrixArray()+(row_lwb-this->fRowLwb)*this->fNcols+(col_lwb-this->fColLwb);
01183
01184 for (Int_t irow = 0; irow < nRows_source; irow++) {
01185 Element *ap_sub = ap;
01186 for (Int_t icol = 0; icol < nCols_source; icol++) {
01187 *ap_sub++ = *bp++;
01188 }
01189 ap += this->fNcols;
01190 }
01191 }
01192
01193 return *this;
01194 }
01195
01196
01197 template<class Element>
01198 TMatrixTBase<Element> &TMatrixT<Element>::ResizeTo(Int_t nrows,Int_t ncols,Int_t )
01199 {
01200
01201
01202
01203
01204 R__ASSERT(this->IsValid());
01205 if (!this->fIsOwner) {
01206 Error("ResizeTo(Int_t,Int_t)","Not owner of data array,cannot resize");
01207 return *this;
01208 }
01209
01210 if (this->fNelems > 0) {
01211 if (this->fNrows == nrows && this->fNcols == ncols)
01212 return *this;
01213 else if (nrows == 0 || ncols == 0) {
01214 this->fNrows = nrows; this->fNcols = ncols;
01215 Clear();
01216 return *this;
01217 }
01218
01219 Element *elements_old = GetMatrixArray();
01220 const Int_t nelems_old = this->fNelems;
01221 const Int_t nrows_old = this->fNrows;
01222 const Int_t ncols_old = this->fNcols;
01223
01224 Allocate(nrows,ncols);
01225 R__ASSERT(this->IsValid());
01226
01227 Element *elements_new = GetMatrixArray();
01228
01229
01230 if (this->fNelems > this->kSizeMax || nelems_old > this->kSizeMax)
01231 memset(elements_new,0,this->fNelems*sizeof(Element));
01232 else if (this->fNelems > nelems_old)
01233 memset(elements_new+nelems_old,0,(this->fNelems-nelems_old)*sizeof(Element));
01234
01235
01236 const Int_t ncols_copy = TMath::Min(this->fNcols,ncols_old);
01237 const Int_t nrows_copy = TMath::Min(this->fNrows,nrows_old);
01238
01239 const Int_t nelems_new = this->fNelems;
01240 if (ncols_old < this->fNcols) {
01241 for (Int_t i = nrows_copy-1; i >= 0; i--) {
01242 Memcpy_m(elements_new+i*this->fNcols,elements_old+i*ncols_old,ncols_copy,
01243 nelems_new,nelems_old);
01244 if (this->fNelems <= this->kSizeMax && nelems_old <= this->kSizeMax)
01245 memset(elements_new+i*this->fNcols+ncols_copy,0,(this->fNcols-ncols_copy)*sizeof(Element));
01246 }
01247 } else {
01248 for (Int_t i = 0; i < nrows_copy; i++)
01249 Memcpy_m(elements_new+i*this->fNcols,elements_old+i*ncols_old,ncols_copy,
01250 nelems_new,nelems_old);
01251 }
01252
01253 Delete_m(nelems_old,elements_old);
01254 } else {
01255 Allocate(nrows,ncols,0,0,1);
01256 }
01257
01258 return *this;
01259 }
01260
01261
01262 template<class Element>
01263 TMatrixTBase<Element> &TMatrixT<Element>::ResizeTo(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,
01264 Int_t )
01265 {
01266
01267
01268
01269
01270 R__ASSERT(this->IsValid());
01271 if (!this->fIsOwner) {
01272 Error("ResizeTo(Int_t,Int_t,Int_t,Int_t)","Not owner of data array,cannot resize");
01273 return *this;
01274 }
01275
01276 const Int_t new_nrows = row_upb-row_lwb+1;
01277 const Int_t new_ncols = col_upb-col_lwb+1;
01278
01279 if (this->fNelems > 0) {
01280
01281 if (this->fNrows == new_nrows && this->fNcols == new_ncols &&
01282 this->fRowLwb == row_lwb && this->fColLwb == col_lwb)
01283 return *this;
01284 else if (new_nrows == 0 || new_ncols == 0) {
01285 this->fNrows = new_nrows; this->fNcols = new_ncols;
01286 this->fRowLwb = row_lwb; this->fColLwb = col_lwb;
01287 Clear();
01288 return *this;
01289 }
01290
01291 Element *elements_old = GetMatrixArray();
01292 const Int_t nelems_old = this->fNelems;
01293 const Int_t nrows_old = this->fNrows;
01294 const Int_t ncols_old = this->fNcols;
01295 const Int_t rowLwb_old = this->fRowLwb;
01296 const Int_t colLwb_old = this->fColLwb;
01297
01298 Allocate(new_nrows,new_ncols,row_lwb,col_lwb);
01299 R__ASSERT(this->IsValid());
01300
01301 Element *elements_new = GetMatrixArray();
01302
01303
01304 if (this->fNelems > this->kSizeMax || nelems_old > this->kSizeMax)
01305 memset(elements_new,0,this->fNelems*sizeof(Element));
01306 else if (this->fNelems > nelems_old)
01307 memset(elements_new+nelems_old,0,(this->fNelems-nelems_old)*sizeof(Element));
01308
01309
01310 const Int_t rowLwb_copy = TMath::Max(this->fRowLwb,rowLwb_old);
01311 const Int_t colLwb_copy = TMath::Max(this->fColLwb,colLwb_old);
01312 const Int_t rowUpb_copy = TMath::Min(this->fRowLwb+this->fNrows-1,rowLwb_old+nrows_old-1);
01313 const Int_t colUpb_copy = TMath::Min(this->fColLwb+this->fNcols-1,colLwb_old+ncols_old-1);
01314
01315 const Int_t nrows_copy = rowUpb_copy-rowLwb_copy+1;
01316 const Int_t ncols_copy = colUpb_copy-colLwb_copy+1;
01317
01318 if (nrows_copy > 0 && ncols_copy > 0) {
01319 const Int_t colOldOff = colLwb_copy-colLwb_old;
01320 const Int_t colNewOff = colLwb_copy-this->fColLwb;
01321 if (ncols_old < this->fNcols) {
01322 for (Int_t i = nrows_copy-1; i >= 0; i--) {
01323 const Int_t iRowOld = rowLwb_copy+i-rowLwb_old;
01324 const Int_t iRowNew = rowLwb_copy+i-this->fRowLwb;
01325 Memcpy_m(elements_new+iRowNew*this->fNcols+colNewOff,
01326 elements_old+iRowOld*ncols_old+colOldOff,ncols_copy,this->fNelems,nelems_old);
01327 if (this->fNelems <= this->kSizeMax && nelems_old <= this->kSizeMax)
01328 memset(elements_new+iRowNew*this->fNcols+colNewOff+ncols_copy,0,
01329 (this->fNcols-ncols_copy)*sizeof(Element));
01330 }
01331 } else {
01332 for (Int_t i = 0; i < nrows_copy; i++) {
01333 const Int_t iRowOld = rowLwb_copy+i-rowLwb_old;
01334 const Int_t iRowNew = rowLwb_copy+i-this->fRowLwb;
01335 Memcpy_m(elements_new+iRowNew*this->fNcols+colNewOff,
01336 elements_old+iRowOld*ncols_old+colOldOff,ncols_copy,this->fNelems,nelems_old);
01337 }
01338 }
01339 }
01340
01341 Delete_m(nelems_old,elements_old);
01342 } else {
01343 Allocate(new_nrows,new_ncols,row_lwb,col_lwb,1);
01344 }
01345
01346 return *this;
01347 }
01348
01349
01350 template<class Element>
01351 Double_t TMatrixT<Element>::Determinant() const
01352 {
01353
01354
01355 const TMatrixT<Element> &tmp = *this;
01356 TDecompLU lu(tmp,this->fTol);
01357 Double_t d1,d2;
01358 lu.Det(d1,d2);
01359 return d1*TMath::Power(2.0,d2);
01360 }
01361
01362
01363 template<class Element>
01364 void TMatrixT<Element>::Determinant(Double_t &d1,Double_t &d2) const
01365 {
01366
01367
01368 const TMatrixT<Element> &tmp = *this;
01369 TDecompLU lu(tmp,Double_t(this->fTol));
01370 lu.Det(d1,d2);
01371 }
01372
01373
01374 template<class Element>
01375 TMatrixT<Element> &TMatrixT<Element>::Invert(Double_t *det)
01376 {
01377
01378
01379 R__ASSERT(this->IsValid());
01380 if (typeid(Element) == typeid(Double_t))
01381 TDecompLU::InvertLU(*dynamic_cast<TMatrixD *>(this),Double_t(this->fTol),det);
01382 else {
01383 TMatrixD tmp(*this);
01384 if (TDecompLU::InvertLU(tmp,Double_t(this->fTol),det)) {
01385 const Double_t *p1 = tmp.GetMatrixArray();
01386 Element *p2 = this->GetMatrixArray();
01387 for (Int_t i = 0; i < this->GetNoElements(); i++)
01388 p2[i] = p1[i];
01389 }
01390 }
01391
01392 return *this;
01393 }
01394
01395
01396 template<class Element>
01397 TMatrixT<Element> &TMatrixT<Element>::InvertFast(Double_t *det)
01398 {
01399
01400
01401
01402 R__ASSERT(this->IsValid());
01403
01404 const Char_t nRows = Char_t(this->GetNrows());
01405 switch (nRows) {
01406 case 1:
01407 {
01408 if (this->GetNrows() != this->GetNcols() || this->GetRowLwb() != this->GetColLwb()) {
01409 Error("Invert()","matrix should be square");
01410 } else {
01411 Element *pM = this->GetMatrixArray();
01412 if (*pM == 0.) {
01413 Error("InvertFast","matrix is singular");
01414 *det = 0;
01415 }
01416 else {
01417 *det = *pM;
01418 *pM = 1.0/(*pM);
01419 }
01420 }
01421 return *this;
01422 }
01423 case 2:
01424 {
01425 TMatrixTCramerInv::Inv2x2<Element>(*this,det);
01426 return *this;
01427 }
01428 case 3:
01429 {
01430 TMatrixTCramerInv::Inv3x3<Element>(*this,det);
01431 return *this;
01432 }
01433 case 4:
01434 {
01435 TMatrixTCramerInv::Inv4x4<Element>(*this,det);
01436 return *this;
01437 }
01438 case 5:
01439 {
01440 TMatrixTCramerInv::Inv5x5<Element>(*this,det);
01441 return *this;
01442 }
01443 case 6:
01444 {
01445 TMatrixTCramerInv::Inv6x6<Element>(*this,det);
01446 return *this;
01447 }
01448
01449 default:
01450 {
01451 if(typeid(Element) == typeid(Double_t))
01452 TDecompLU::InvertLU(*dynamic_cast<TMatrixD *>(this),Double_t(this->fTol),det);
01453 else {
01454 TMatrixD tmp(*this);
01455 if (TDecompLU::InvertLU(tmp,Double_t(this->fTol),det)) {
01456 const Double_t *p1 = tmp.GetMatrixArray();
01457 Element *p2 = this->GetMatrixArray();
01458 for (Int_t i = 0; i < this->GetNoElements(); i++)
01459 p2[i] = p1[i];
01460 }
01461 }
01462 return *this;
01463 }
01464 }
01465 }
01466
01467
01468 template<class Element>
01469 TMatrixT<Element> &TMatrixT<Element>::Transpose(const TMatrixT<Element> &source)
01470 {
01471
01472
01473 R__ASSERT(this->IsValid());
01474 R__ASSERT(source.IsValid());
01475
01476 if (this->GetMatrixArray() == source.GetMatrixArray()) {
01477 Element *ap = this->GetMatrixArray();
01478 if (this->fNrows == this->fNcols && this->fRowLwb == this->fColLwb) {
01479 for (Int_t i = 0; i < this->fNrows; i++) {
01480 const Int_t off_i = i*this->fNrows;
01481 for (Int_t j = i+1; j < this->fNcols; j++) {
01482 const Int_t off_j = j*this->fNcols;
01483 const Element tmp = ap[off_i+j];
01484 ap[off_i+j] = ap[off_j+i];
01485 ap[off_j+i] = tmp;
01486 }
01487 }
01488 } else {
01489 Element *oldElems = new Element[source.GetNoElements()];
01490 memcpy(oldElems,source.GetMatrixArray(),source.GetNoElements()*sizeof(Element));
01491 const Int_t nrows_old = this->fNrows;
01492 const Int_t ncols_old = this->fNcols;
01493 const Int_t rowlwb_old = this->fRowLwb;
01494 const Int_t collwb_old = this->fColLwb;
01495
01496 this->fNrows = ncols_old; this->fNcols = nrows_old;
01497 this->fRowLwb = collwb_old; this->fColLwb = rowlwb_old;
01498 for (Int_t irow = this->fRowLwb; irow < this->fRowLwb+this->fNrows; irow++) {
01499 for (Int_t icol = this->fColLwb; icol < this->fColLwb+this->fNcols; icol++) {
01500 const Int_t off = (icol-collwb_old)*ncols_old;
01501 (*this)(irow,icol) = oldElems[off+irow-rowlwb_old];
01502 }
01503 }
01504 delete [] oldElems;
01505 }
01506 } else {
01507 if (this->fNrows != source.GetNcols() || this->fNcols != source.GetNrows() ||
01508 this->fRowLwb != source.GetColLwb() || this->fColLwb != source.GetRowLwb())
01509 {
01510 Error("Transpose","matrix has wrong shape");
01511 return *this;
01512 }
01513
01514 const Element *sp1 = source.GetMatrixArray();
01515 const Element *scp = sp1;
01516 Element *tp = this->GetMatrixArray();
01517 const Element * const tp_last = this->GetMatrixArray()+this->fNelems;
01518
01519
01520
01521 while (tp < tp_last) {
01522 const Element *sp2 = scp++;
01523
01524
01525 while (sp2 < sp1+this->fNelems) {
01526 *tp++ = *sp2;
01527 sp2 += this->fNrows;
01528 }
01529 }
01530 R__ASSERT(tp == tp_last && scp == sp1+this->fNrows);
01531 }
01532
01533 return *this;
01534 }
01535
01536
01537 template<class Element>
01538 TMatrixT<Element> &TMatrixT<Element>::Rank1Update(const TVectorT<Element> &v,Element alpha)
01539 {
01540
01541
01542
01543 if (gMatrixCheck) {
01544 R__ASSERT(this->IsValid());
01545 R__ASSERT(v.IsValid());
01546 if (v.GetNoElements() < TMath::Max(this->fNrows,this->fNcols)) {
01547 Error("Rank1Update","vector too short");
01548 return *this;
01549 }
01550 }
01551
01552 const Element * const pv = v.GetMatrixArray();
01553 Element *mp = this->GetMatrixArray();
01554
01555 for (Int_t i = 0; i < this->fNrows; i++) {
01556 const Element tmp = alpha*pv[i];
01557 for (Int_t j = 0; j < this->fNcols; j++)
01558 *mp++ += tmp*pv[j];
01559 }
01560
01561 return *this;
01562 }
01563
01564
01565 template<class Element>
01566 TMatrixT<Element> &TMatrixT<Element>::Rank1Update(const TVectorT<Element> &v1,const TVectorT<Element> &v2,Element alpha)
01567 {
01568
01569
01570
01571 if (gMatrixCheck) {
01572 R__ASSERT(this->IsValid());
01573 R__ASSERT(v1.IsValid());
01574 R__ASSERT(v2.IsValid());
01575 if (v1.GetNoElements() < this->fNrows) {
01576 Error("Rank1Update","vector v1 too short");
01577 return *this;
01578 }
01579
01580 if (v2.GetNoElements() < this->fNcols) {
01581 Error("Rank1Update","vector v2 too short");
01582 return *this;
01583 }
01584 }
01585
01586 const Element * const pv1 = v1.GetMatrixArray();
01587 const Element * const pv2 = v2.GetMatrixArray();
01588 Element *mp = this->GetMatrixArray();
01589
01590 for (Int_t i = 0; i < this->fNrows; i++) {
01591 const Element tmp = alpha*pv1[i];
01592 for (Int_t j = 0; j < this->fNcols; j++)
01593 *mp++ += tmp*pv2[j];
01594 }
01595
01596 return *this;
01597 }
01598
01599
01600 template<class Element>
01601 Element TMatrixT<Element>::Similarity(const TVectorT<Element> &v) const
01602 {
01603
01604
01605 if (gMatrixCheck) {
01606 R__ASSERT(this->IsValid());
01607 R__ASSERT(v.IsValid());
01608 if (this->fNcols != this->fNrows || this->fColLwb != this->fRowLwb) {
01609 Error("Similarity(const TVectorT &)","matrix is not square");
01610 return -1.;
01611 }
01612
01613 if (this->fNcols != v.GetNrows() || this->fColLwb != v.GetLwb()) {
01614 Error("Similarity(const TVectorT &)","vector and matrix incompatible");
01615 return -1.;
01616 }
01617 }
01618
01619 const Element *mp = this->GetMatrixArray();
01620 const Element *vp = v.GetMatrixArray();
01621
01622 Element sum1 = 0;
01623 const Element * const vp_first = vp;
01624 const Element * const vp_last = vp+v.GetNrows();
01625 while (vp < vp_last) {
01626 Element sum2 = 0;
01627 for (const Element *sp = vp_first; sp < vp_last; )
01628 sum2 += *mp++ * *sp++;
01629 sum1 += sum2 * *vp++;
01630 }
01631
01632 R__ASSERT(mp == this->GetMatrixArray()+this->GetNoElements());
01633
01634 return sum1;
01635 }
01636
01637
01638 template<class Element>
01639 TMatrixT<Element> &TMatrixT<Element>::NormByColumn(const TVectorT<Element> &v,Option_t *option)
01640 {
01641
01642
01643
01644
01645
01646 if (gMatrixCheck) {
01647 R__ASSERT(this->IsValid());
01648 R__ASSERT(v.IsValid());
01649 if (v.GetNoElements() < this->fNrows) {
01650 Error("NormByColumn","vector shorter than matrix column");
01651 return *this;
01652 }
01653 }
01654
01655 TString opt(option);
01656 opt.ToUpper();
01657 const Int_t divide = (opt.Contains("D")) ? 1 : 0;
01658
01659 const Element *pv = v.GetMatrixArray();
01660 Element *mp = this->GetMatrixArray();
01661 const Element * const mp_last = mp+this->fNelems;
01662
01663 if (divide) {
01664 for ( ; mp < mp_last; pv++) {
01665 for (Int_t j = 0; j < this->fNcols; j++)
01666 {
01667 if (*pv != 0.0)
01668 *mp++ /= *pv;
01669 else {
01670 Error("NormbyColumn","vector element %ld is zero",Long_t(pv-v.GetMatrixArray()));
01671 mp++;
01672 }
01673 }
01674 }
01675 } else {
01676 for ( ; mp < mp_last; pv++)
01677 for (Int_t j = 0; j < this->fNcols; j++)
01678 *mp++ *= *pv;
01679 }
01680
01681 return *this;
01682 }
01683
01684
01685 template<class Element>
01686 TMatrixT<Element> &TMatrixT<Element>::NormByRow(const TVectorT<Element> &v,Option_t *option)
01687 {
01688
01689
01690
01691
01692
01693 if (gMatrixCheck) {
01694 R__ASSERT(this->IsValid());
01695 R__ASSERT(v.IsValid());
01696 if (v.GetNoElements() < this->fNcols) {
01697 Error("NormByRow","vector shorter than matrix column");
01698 return *this;
01699 }
01700 }
01701
01702 TString opt(option);
01703 opt.ToUpper();
01704 const Int_t divide = (opt.Contains("D")) ? 1 : 0;
01705
01706 const Element *pv0 = v.GetMatrixArray();
01707 const Element *pv = pv0;
01708 Element *mp = this->GetMatrixArray();
01709 const Element * const mp_last = mp+this->fNelems;
01710
01711 if (divide) {
01712 for ( ; mp < mp_last; pv = pv0 )
01713 for (Int_t j = 0; j < this->fNcols; j++) {
01714 if (*pv != 0.0)
01715 *mp++ /= *pv++;
01716 else {
01717 Error("NormbyRow","vector element %ld is zero",Long_t(pv-pv0));
01718 mp++;
01719 }
01720 }
01721 } else {
01722 for ( ; mp < mp_last; pv = pv0 )
01723 for (Int_t j = 0; j < this->fNcols; j++)
01724 *mp++ *= *pv++;
01725 }
01726
01727 return *this;
01728 }
01729
01730
01731 template<class Element>
01732 TMatrixT<Element> &TMatrixT<Element>::operator=(const TMatrixT<Element> &source)
01733 {
01734
01735
01736 if (gMatrixCheck && !AreCompatible(*this,source)) {
01737 Error("operator=(const TMatrixT &)","matrices not compatible");
01738 return *this;
01739 }
01740
01741 if (this->GetMatrixArray() != source.GetMatrixArray()) {
01742 TObject::operator=(source);
01743 memcpy(fElements,source.GetMatrixArray(),this->fNelems*sizeof(Element));
01744 this->fTol = source.GetTol();
01745 }
01746 return *this;
01747 }
01748
01749
01750 template<class Element>
01751 TMatrixT<Element> &TMatrixT<Element>::operator=(const TMatrixTSym<Element> &source)
01752 {
01753
01754
01755 if (gMatrixCheck && !AreCompatible(*this,source)) {
01756 Error("operator=(const TMatrixTSym &)","matrices not compatible");
01757 return *this;
01758 }
01759
01760 if (this->GetMatrixArray() != source.GetMatrixArray()) {
01761 TObject::operator=(source);
01762 memcpy(fElements,source.GetMatrixArray(),this->fNelems*sizeof(Element));
01763 this->fTol = source.GetTol();
01764 }
01765 return *this;
01766 }
01767
01768
01769 template<class Element>
01770 TMatrixT<Element> &TMatrixT<Element>::operator=(const TMatrixTSparse<Element> &source)
01771 {
01772
01773
01774 if ((gMatrixCheck &&
01775 this->GetNrows() != source.GetNrows()) || this->GetNcols() != source.GetNcols() ||
01776 this->GetRowLwb() != source.GetRowLwb() || this->GetColLwb() != source.GetColLwb()) {
01777 Error("operator=(const TMatrixTSparse &","matrices not compatible");
01778 return *this;
01779 }
01780
01781 if (this->GetMatrixArray() != source.GetMatrixArray()) {
01782 TObject::operator=(source);
01783 memset(fElements,0,this->fNelems*sizeof(Element));
01784
01785 const Element * const sp = source.GetMatrixArray();
01786 Element * tp = this->GetMatrixArray();
01787
01788 const Int_t * const pRowIndex = source.GetRowIndexArray();
01789 const Int_t * const pColIndex = source.GetColIndexArray();
01790
01791 for (Int_t irow = 0; irow < this->fNrows; irow++ ) {
01792 const Int_t off = irow*this->fNcols;
01793 const Int_t sIndex = pRowIndex[irow];
01794 const Int_t eIndex = pRowIndex[irow+1];
01795 for (Int_t index = sIndex; index < eIndex; index++)
01796 tp[off+pColIndex[index]] = sp[index];
01797 }
01798 this->fTol = source.GetTol();
01799 }
01800 return *this;
01801 }
01802
01803
01804 template<class Element>
01805 TMatrixT<Element> &TMatrixT<Element>::operator=(const TMatrixTLazy<Element> &lazy_constructor)
01806 {
01807
01808
01809 R__ASSERT(this->IsValid());
01810
01811 if (lazy_constructor.GetRowUpb() != this->GetRowUpb() ||
01812 lazy_constructor.GetColUpb() != this->GetColUpb() ||
01813 lazy_constructor.GetRowLwb() != this->GetRowLwb() ||
01814 lazy_constructor.GetColLwb() != this->GetColLwb()) {
01815 Error("operator=(const TMatrixTLazy&)", "matrix is incompatible with "
01816 "the assigned Lazy matrix");
01817 return *this;
01818 }
01819
01820 lazy_constructor.FillIn(*this);
01821 return *this;
01822 }
01823
01824
01825 template<class Element>
01826 TMatrixT<Element> &TMatrixT<Element>::operator=(Element val)
01827 {
01828
01829
01830 R__ASSERT(this->IsValid());
01831
01832 Element *ep = this->GetMatrixArray();
01833 const Element * const ep_last = ep+this->fNelems;
01834 while (ep < ep_last)
01835 *ep++ = val;
01836
01837 return *this;
01838 }
01839
01840
01841 template<class Element>
01842 TMatrixT<Element> &TMatrixT<Element>::operator+=(Element val)
01843 {
01844
01845
01846 R__ASSERT(this->IsValid());
01847
01848 Element *ep = this->GetMatrixArray();
01849 const Element * const ep_last = ep+this->fNelems;
01850 while (ep < ep_last)
01851 *ep++ += val;
01852
01853 return *this;
01854 }
01855
01856
01857 template<class Element>
01858 TMatrixT<Element> &TMatrixT<Element>::operator-=(Element val)
01859 {
01860
01861
01862 R__ASSERT(this->IsValid());
01863
01864 Element *ep = this->GetMatrixArray();
01865 const Element * const ep_last = ep+this->fNelems;
01866 while (ep < ep_last)
01867 *ep++ -= val;
01868
01869 return *this;
01870 }
01871
01872
01873 template<class Element>
01874 TMatrixT<Element> &TMatrixT<Element>::operator*=(Element val)
01875 {
01876
01877
01878 R__ASSERT(this->IsValid());
01879
01880 Element *ep = this->GetMatrixArray();
01881 const Element * const ep_last = ep+this->fNelems;
01882 while (ep < ep_last)
01883 *ep++ *= val;
01884
01885 return *this;
01886 }
01887
01888
01889 template<class Element>
01890 TMatrixT<Element> &TMatrixT<Element>::operator+=(const TMatrixT<Element> &source)
01891 {
01892
01893
01894 if (gMatrixCheck && !AreCompatible(*this,source)) {
01895 Error("operator+=(const TMatrixT &)","matrices not compatible");
01896 return *this;
01897 }
01898
01899 const Element *sp = source.GetMatrixArray();
01900 Element *tp = this->GetMatrixArray();
01901 const Element * const tp_last = tp+this->fNelems;
01902 while (tp < tp_last)
01903 *tp++ += *sp++;
01904
01905 return *this;
01906 }
01907
01908
01909 template<class Element>
01910 TMatrixT<Element> &TMatrixT<Element>::operator+=(const TMatrixTSym<Element> &source)
01911 {
01912
01913
01914 if (gMatrixCheck && !AreCompatible(*this,source)) {
01915 Error("operator+=(const TMatrixTSym &)","matrices not compatible");
01916 return *this;
01917 }
01918
01919 const Element *sp = source.GetMatrixArray();
01920 Element *tp = this->GetMatrixArray();
01921 const Element * const tp_last = tp+this->fNelems;
01922 while (tp < tp_last)
01923 *tp++ += *sp++;
01924
01925 return *this;
01926 }
01927
01928
01929 template<class Element>
01930 TMatrixT<Element> &TMatrixT<Element>::operator-=(const TMatrixT<Element> &source)
01931 {
01932
01933
01934 if (gMatrixCheck && !AreCompatible(*this,source)) {
01935 Error("operator=-(const TMatrixT &)","matrices not compatible");
01936 return *this;
01937 }
01938
01939 const Element *sp = source.GetMatrixArray();
01940 Element *tp = this->GetMatrixArray();
01941 const Element * const tp_last = tp+this->fNelems;
01942 while (tp < tp_last)
01943 *tp++ -= *sp++;
01944
01945 return *this;
01946 }
01947
01948
01949 template<class Element>
01950 TMatrixT<Element> &TMatrixT<Element>::operator-=(const TMatrixTSym<Element> &source)
01951 {
01952
01953
01954 if (gMatrixCheck && !AreCompatible(*this,source)) {
01955 Error("operator=-(const TMatrixTSym &)","matrices not compatible");
01956 return *this;
01957 }
01958
01959 const Element *sp = source.GetMatrixArray();
01960 Element *tp = this->GetMatrixArray();
01961 const Element * const tp_last = tp+this->fNelems;
01962 while (tp < tp_last)
01963 *tp++ -= *sp++;
01964
01965 return *this;
01966 }
01967
01968
01969 template<class Element>
01970 TMatrixT<Element> &TMatrixT<Element>::operator*=(const TMatrixT<Element> &source)
01971 {
01972
01973
01974
01975
01976 if (gMatrixCheck) {
01977 R__ASSERT(this->IsValid());
01978 R__ASSERT(source.IsValid());
01979 if (this->fNcols != source.GetNrows() || this->fColLwb != source.GetRowLwb() ||
01980 this->fNcols != source.GetNcols() || this->fColLwb != source.GetColLwb()) {
01981 Error("operator*=(const TMatrixT &)","source matrix has wrong shape");
01982 return *this;
01983 }
01984 }
01985
01986
01987 const Element *sp;
01988 TMatrixT<Element> tmp;
01989 if (this->GetMatrixArray() == source.GetMatrixArray()) {
01990 tmp.ResizeTo(source);
01991 tmp = source;
01992 sp = tmp.GetMatrixArray();
01993 }
01994 else
01995 sp = source.GetMatrixArray();
01996
01997
01998 Element work[kWorkMax];
01999 Bool_t isAllocated = kFALSE;
02000 Element *trp = work;
02001 if (this->fNcols > kWorkMax) {
02002 isAllocated = kTRUE;
02003 trp = new Element[this->fNcols];
02004 }
02005
02006 Element *cp = this->GetMatrixArray();
02007 const Element *trp0 = cp;
02008 const Element * const trp0_last = trp0+this->fNelems;
02009 while (trp0 < trp0_last) {
02010 memcpy(trp,trp0,this->fNcols*sizeof(Element));
02011 for (const Element *scp = sp; scp < sp+this->fNcols; ) {
02012
02013 Element cij = 0;
02014 for (Int_t j = 0; j < this->fNcols; j++) {
02015 cij += trp[j] * *scp;
02016 scp += this->fNcols;
02017 }
02018 *cp++ = cij;
02019 scp -= source.GetNoElements()-1;
02020 }
02021 trp0 += this->fNcols;
02022 R__ASSERT(trp0 == cp);
02023 }
02024
02025 R__ASSERT(cp == trp0_last && trp0 == trp0_last);
02026 if (isAllocated)
02027 delete [] trp;
02028
02029 return *this;
02030 }
02031
02032
02033 template<class Element>
02034 TMatrixT<Element> &TMatrixT<Element>::operator*=(const TMatrixTSym<Element> &source)
02035 {
02036
02037
02038
02039 if (gMatrixCheck) {
02040 R__ASSERT(this->IsValid());
02041 R__ASSERT(source.IsValid());
02042 if (this->fNcols != source.GetNrows() || this->fColLwb != source.GetRowLwb()) {
02043 Error("operator*=(const TMatrixTSym &)","source matrix has wrong shape");
02044 return *this;
02045 }
02046 }
02047
02048
02049 const Element *sp;
02050 TMatrixT<Element> tmp;
02051 if (this->GetMatrixArray() == source.GetMatrixArray()) {
02052 tmp.ResizeTo(source);
02053 tmp = source;
02054 sp = tmp.GetMatrixArray();
02055 }
02056 else
02057 sp = source.GetMatrixArray();
02058
02059
02060 Element work[kWorkMax];
02061 Bool_t isAllocated = kFALSE;
02062 Element *trp = work;
02063 if (this->fNcols > kWorkMax) {
02064 isAllocated = kTRUE;
02065 trp = new Element[this->fNcols];
02066 }
02067
02068 Element *cp = this->GetMatrixArray();
02069 const Element *trp0 = cp;
02070 const Element * const trp0_last = trp0+this->fNelems;
02071 while (trp0 < trp0_last) {
02072 memcpy(trp,trp0,this->fNcols*sizeof(Element));
02073 for (const Element *scp = sp; scp < sp+this->fNcols; ) {
02074
02075 Element cij = 0;
02076 for (Int_t j = 0; j < this->fNcols; j++) {
02077 cij += trp[j] * *scp;
02078 scp += this->fNcols;
02079 }
02080 *cp++ = cij;
02081 scp -= source.GetNoElements()-1;
02082 }
02083 trp0 += this->fNcols;
02084 R__ASSERT(trp0 == cp);
02085 }
02086
02087 R__ASSERT(cp == trp0_last && trp0 == trp0_last);
02088 if (isAllocated)
02089 delete [] trp;
02090
02091 return *this;
02092 }
02093
02094
02095 template<class Element>
02096 TMatrixT<Element> &TMatrixT<Element>::operator*=(const TMatrixTDiag_const<Element> &diag)
02097 {
02098
02099
02100
02101 if (gMatrixCheck) {
02102 R__ASSERT(this->IsValid());
02103 R__ASSERT(diag.GetMatrix()->IsValid());
02104 if (this->fNcols != diag.GetNdiags()) {
02105 Error("operator*=(const TMatrixTDiag_const &)","wrong diagonal length");
02106 return *this;
02107 }
02108 }
02109
02110 Element *mp = this->GetMatrixArray();
02111 const Element * const mp_last = mp+this->fNelems;
02112 const Int_t inc = diag.GetInc();
02113 while (mp < mp_last) {
02114 const Element *dp = diag.GetPtr();
02115 for (Int_t j = 0; j < this->fNcols; j++) {
02116 *mp++ *= *dp;
02117 dp += inc;
02118 }
02119 }
02120
02121 return *this;
02122 }
02123
02124
02125 template<class Element>
02126 TMatrixT<Element> &TMatrixT<Element>::operator/=(const TMatrixTDiag_const<Element> &diag)
02127 {
02128
02129
02130
02131 if (gMatrixCheck) {
02132 R__ASSERT(this->IsValid());
02133 R__ASSERT(diag.GetMatrix()->IsValid());
02134 if (this->fNcols != diag.GetNdiags()) {
02135 Error("operator/=(const TMatrixTDiag_const &)","wrong diagonal length");
02136 return *this;
02137 }
02138 }
02139
02140 Element *mp = this->GetMatrixArray();
02141 const Element * const mp_last = mp+this->fNelems;
02142 const Int_t inc = diag.GetInc();
02143 while (mp < mp_last) {
02144 const Element *dp = diag.GetPtr();
02145 for (Int_t j = 0; j < this->fNcols; j++) {
02146 if (*dp != 0.0)
02147 *mp++ /= *dp;
02148 else {
02149 Error("operator/=","%d-diagonal element is zero",j);
02150 mp++;
02151 }
02152 dp += inc;
02153 }
02154 }
02155
02156 return *this;
02157 }
02158
02159
02160 template<class Element>
02161 TMatrixT<Element> &TMatrixT<Element>::operator*=(const TMatrixTColumn_const<Element> &col)
02162 {
02163
02164
02165
02166 const TMatrixTBase<Element> *mt = col.GetMatrix();
02167
02168 if (gMatrixCheck) {
02169 R__ASSERT(this->IsValid());
02170 R__ASSERT(mt->IsValid());
02171 if (this->fNrows != mt->GetNrows()) {
02172 Error("operator*=(const TMatrixTColumn_const &)","wrong column length");
02173 return *this;
02174 }
02175 }
02176
02177 const Element * const endp = col.GetPtr()+mt->GetNoElements();
02178 Element *mp = this->GetMatrixArray();
02179 const Element * const mp_last = mp+this->fNelems;
02180 const Element *cp = col.GetPtr();
02181 const Int_t inc = col.GetInc();
02182 while (mp < mp_last) {
02183 R__ASSERT(cp < endp);
02184 for (Int_t j = 0; j < this->fNcols; j++)
02185 *mp++ *= *cp;
02186 cp += inc;
02187 }
02188
02189 return *this;
02190 }
02191
02192
02193 template<class Element>
02194 TMatrixT<Element> &TMatrixT<Element>::operator/=(const TMatrixTColumn_const<Element> &col)
02195 {
02196
02197
02198
02199 const TMatrixTBase<Element> *mt = col.GetMatrix();
02200
02201 if (gMatrixCheck) {
02202 R__ASSERT(this->IsValid());
02203 R__ASSERT(mt->IsValid());
02204 if (this->fNrows != mt->GetNrows()) {
02205 Error("operator/=(const TMatrixTColumn_const &)","wrong column matrix");
02206 return *this;
02207 }
02208 }
02209
02210 const Element * const endp = col.GetPtr()+mt->GetNoElements();
02211 Element *mp = this->GetMatrixArray();
02212 const Element * const mp_last = mp+this->fNelems;
02213 const Element *cp = col.GetPtr();
02214 const Int_t inc = col.GetInc();
02215 while (mp < mp_last) {
02216 R__ASSERT(cp < endp);
02217 if (*cp != 0.0) {
02218 for (Int_t j = 0; j < this->fNcols; j++)
02219 *mp++ /= *cp;
02220 } else {
02221 const Int_t icol = (cp-mt->GetMatrixArray())/inc;
02222 Error("operator/=","%d-row of matrix column is zero",icol);
02223 mp += this->fNcols;
02224 }
02225 cp += inc;
02226 }
02227
02228 return *this;
02229 }
02230
02231
02232 template<class Element>
02233 TMatrixT<Element> &TMatrixT<Element>::operator*=(const TMatrixTRow_const<Element> &row)
02234 {
02235
02236
02237
02238 const TMatrixTBase<Element> *mt = row.GetMatrix();
02239
02240 if (gMatrixCheck) {
02241 R__ASSERT(this->IsValid());
02242 R__ASSERT(mt->IsValid());
02243 if (this->fNcols != mt->GetNcols()) {
02244 Error("operator*=(const TMatrixTRow_const &)","wrong row length");
02245 return *this;
02246 }
02247 }
02248
02249 const Element * const endp = row.GetPtr()+mt->GetNoElements();
02250 Element *mp = this->GetMatrixArray();
02251 const Element * const mp_last = mp+this->fNelems;
02252 const Int_t inc = row.GetInc();
02253 while (mp < mp_last) {
02254 const Element *rp = row.GetPtr();
02255 for (Int_t j = 0; j < this->fNcols; j++) {
02256 R__ASSERT(rp < endp);
02257 *mp++ *= *rp;
02258 rp += inc;
02259 }
02260 }
02261
02262 return *this;
02263 }
02264
02265
02266 template<class Element>
02267 TMatrixT<Element> &TMatrixT<Element>::operator/=(const TMatrixTRow_const<Element> &row)
02268 {
02269
02270
02271
02272 const TMatrixTBase<Element> *mt = row.GetMatrix();
02273 R__ASSERT(this->IsValid());
02274 R__ASSERT(mt->IsValid());
02275
02276 if (this->fNcols != mt->GetNcols()) {
02277 Error("operator/=(const TMatrixTRow_const &)","wrong row length");
02278 return *this;
02279 }
02280
02281 const Element * const endp = row.GetPtr()+mt->GetNoElements();
02282 Element *mp = this->GetMatrixArray();
02283 const Element * const mp_last = mp+this->fNelems;
02284 const Int_t inc = row.GetInc();
02285 while (mp < mp_last) {
02286 const Element *rp = row.GetPtr();
02287 for (Int_t j = 0; j < this->fNcols; j++) {
02288 R__ASSERT(rp < endp);
02289 if (*rp != 0.0) {
02290 *mp++ /= *rp;
02291 } else {
02292 Error("operator/=","%d-col of matrix row is zero",j);
02293 mp++;
02294 }
02295 rp += inc;
02296 }
02297 }
02298
02299 return *this;
02300 }
02301
02302
02303 template<class Element>
02304 const TMatrixT<Element> TMatrixT<Element>::EigenVectors(TVectorT<Element> &eigenValues) const
02305 {
02306
02307
02308
02309
02310
02311 if (!this->IsSymmetric())
02312 Warning("EigenVectors(TVectorT &)","Only real part of eigen-values will be returned");
02313 TMatrixDEigen eigen(*this);
02314 eigenValues.ResizeTo(this->fNrows);
02315 eigenValues = eigen.GetEigenValuesRe();
02316 return eigen.GetEigenVectors();
02317 }
02318
02319
02320 template<class Element>
02321 TMatrixT<Element> operator+(const TMatrixT<Element> &source1,const TMatrixT<Element> &source2)
02322 {
02323
02324
02325 TMatrixT<Element> target(source1);
02326 target += source2;
02327 return target;
02328 }
02329
02330
02331 template<class Element>
02332 TMatrixT<Element> operator+(const TMatrixT<Element> &source1,const TMatrixTSym<Element> &source2)
02333 {
02334
02335
02336 TMatrixT<Element> target(source1);
02337 target += source2;
02338 return target;
02339 }
02340
02341
02342 template<class Element>
02343 TMatrixT<Element> operator+(const TMatrixTSym<Element> &source1,const TMatrixT<Element> &source2)
02344 {
02345
02346
02347 return operator+(source2,source1);
02348 }
02349
02350
02351 template<class Element>
02352 TMatrixT<Element> operator+(const TMatrixT<Element> &source,Element val)
02353 {
02354
02355
02356 TMatrixT<Element> target(source);
02357 target += val;
02358 return target;
02359 }
02360
02361
02362 template<class Element>
02363 TMatrixT<Element> operator+(Element val,const TMatrixT<Element> &source)
02364 {
02365
02366
02367 return operator+(source,val);
02368 }
02369
02370
02371 template<class Element>
02372 TMatrixT<Element> operator-(const TMatrixT<Element> &source1,const TMatrixT<Element> &source2)
02373 {
02374
02375
02376 TMatrixT<Element> target(source1);
02377 target -= source2;
02378 return target;
02379 }
02380
02381
02382 template<class Element>
02383 TMatrixT<Element> operator-(const TMatrixT<Element> &source1,const TMatrixTSym<Element> &source2)
02384 {
02385
02386
02387 TMatrixT<Element> target(source1);
02388 target -= source2;
02389 return target;
02390 }
02391
02392
02393 template<class Element>
02394 TMatrixT<Element> operator-(const TMatrixTSym<Element> &source1,const TMatrixT<Element> &source2)
02395 {
02396
02397
02398 return Element(-1.0)*(operator-(source2,source1));
02399 }
02400
02401
02402 template<class Element>
02403 TMatrixT<Element> operator-(const TMatrixT<Element> &source,Element val)
02404 {
02405
02406
02407 TMatrixT<Element> target(source);
02408 target -= val;
02409 return target;
02410 }
02411
02412
02413 template<class Element>
02414 TMatrixT<Element> operator-(Element val,const TMatrixT<Element> &source)
02415 {
02416
02417
02418 return Element(-1.0)*operator-(source,val);
02419 }
02420
02421
02422 template<class Element>
02423 TMatrixT<Element> operator*(Element val,const TMatrixT<Element> &source)
02424 {
02425
02426
02427 TMatrixT<Element> target(source);
02428 target *= val;
02429 return target;
02430 }
02431
02432
02433 template<class Element>
02434 TMatrixT<Element> operator*(const TMatrixT<Element> &source,Element val)
02435 {
02436
02437
02438 return operator*(val,source);
02439 }
02440
02441
02442 template<class Element>
02443 TMatrixT<Element> operator*(const TMatrixT<Element> &source1,const TMatrixT<Element> &source2)
02444 {
02445
02446
02447 TMatrixT<Element> target(source1,TMatrixT<Element>::kMult,source2);
02448 return target;
02449 }
02450
02451
02452 template<class Element>
02453 TMatrixT<Element> operator*(const TMatrixT<Element> &source1,const TMatrixTSym<Element> &source2)
02454 {
02455
02456
02457 TMatrixT<Element> target(source1,TMatrixT<Element>::kMult,source2);
02458 return target;
02459 }
02460
02461
02462 template<class Element>
02463 TMatrixT<Element> operator*(const TMatrixTSym<Element> &source1,const TMatrixT<Element> &source2)
02464 {
02465
02466
02467 TMatrixT<Element> target(source1,TMatrixT<Element>::kMult,source2);
02468 return target;
02469 }
02470
02471
02472 template<class Element>
02473 TMatrixT<Element> operator*(const TMatrixTSym<Element> &source1,const TMatrixTSym<Element> &source2)
02474 {
02475
02476
02477 TMatrixT<Element> target(source1,TMatrixT<Element>::kMult,source2);
02478 return target;
02479 }
02480
02481
02482 template<class Element>
02483 TMatrixT<Element> operator&&(const TMatrixT<Element> &source1,const TMatrixT<Element> &source2)
02484 {
02485
02486
02487 TMatrixT<Element> target;
02488
02489 if (gMatrixCheck && !AreCompatible(source1,source2)) {
02490 Error("operator&&(const TMatrixT&,const TMatrixT&)","matrices not compatible");
02491 return target;
02492 }
02493
02494 target.ResizeTo(source1);
02495
02496 const Element *sp1 = source1.GetMatrixArray();
02497 const Element *sp2 = source2.GetMatrixArray();
02498 Element *tp = target.GetMatrixArray();
02499 const Element * const tp_last = tp+target.GetNoElements();
02500 while (tp < tp_last)
02501 *tp++ = (*sp1++ != 0.0 && *sp2++ != 0.0);
02502
02503 return target;
02504 }
02505
02506
02507 template<class Element>
02508 TMatrixT<Element> operator&&(const TMatrixT<Element> &source1,const TMatrixTSym<Element> &source2)
02509 {
02510
02511
02512 TMatrixT<Element> target;
02513
02514 if (gMatrixCheck && !AreCompatible(source1,source2)) {
02515 Error("operator&&(const TMatrixT&,const TMatrixTSym&)","matrices not compatible");
02516 return target;
02517 }
02518
02519 target.ResizeTo(source1);
02520
02521 const Element *sp1 = source1.GetMatrixArray();
02522 const Element *sp2 = source2.GetMatrixArray();
02523 Element *tp = target.GetMatrixArray();
02524 const Element * const tp_last = tp+target.GetNoElements();
02525 while (tp < tp_last)
02526 *tp++ = (*sp1++ != 0.0 && *sp2++ != 0.0);
02527
02528 return target;
02529 }
02530
02531
02532 template<class Element>
02533 TMatrixT<Element> operator&&(const TMatrixTSym<Element> &source1,const TMatrixT<Element> &source2)
02534 {
02535
02536 return operator&&(source2,source1);
02537 }
02538
02539
02540 template<class Element>
02541 TMatrixT<Element> operator||(const TMatrixT<Element> &source1,const TMatrixT<Element> &source2)
02542 {
02543
02544
02545 TMatrixT<Element> target;
02546
02547 if (gMatrixCheck && !AreCompatible(source1,source2)) {
02548 Error("operator||(const TMatrixT&,const TMatrixT&)","matrices not compatible");
02549 return target;
02550 }
02551
02552 target.ResizeTo(source1);
02553
02554 const Element *sp1 = source1.GetMatrixArray();
02555 const Element *sp2 = source2.GetMatrixArray();
02556 Element *tp = target.GetMatrixArray();
02557 const Element * const tp_last = tp+target.GetNoElements();
02558 while (tp < tp_last)
02559 *tp++ = (*sp1++ != 0.0 || *sp2++ != 0.0);
02560
02561 return target;
02562 }
02563
02564
02565 template<class Element>
02566 TMatrixT<Element> operator||(const TMatrixT<Element> &source1,const TMatrixTSym<Element> &source2)
02567 {
02568
02569
02570 TMatrixT<Element> target;
02571
02572 if (gMatrixCheck && !AreCompatible(source1,source2)) {
02573 Error("operator||(const TMatrixT&,const TMatrixTSym&)","matrices not compatible");
02574 return target;
02575 }
02576
02577 target.ResizeTo(source1);
02578
02579 const Element *sp1 = source1.GetMatrixArray();
02580 const Element *sp2 = source2.GetMatrixArray();
02581 Element *tp = target.GetMatrixArray();
02582 const Element * const tp_last = tp+target.GetNoElements();
02583 while (tp < tp_last)
02584 *tp++ = (*sp1++ != 0.0 || *sp2++ != 0.0);
02585
02586 return target;
02587 }
02588
02589
02590 template<class Element>
02591 TMatrixT<Element> operator||(const TMatrixTSym<Element> &source1,const TMatrixT<Element> &source2)
02592 {
02593
02594
02595 return operator||(source2,source1);
02596 }
02597
02598
02599 template<class Element>
02600 TMatrixT<Element> operator>(const TMatrixT<Element> &source1,const TMatrixT<Element> &source2)
02601 {
02602
02603
02604 TMatrixT<Element> target;
02605
02606 if (gMatrixCheck && !AreCompatible(source1,source2)) {
02607 Error("operator|(const TMatrixT&,const TMatrixT&)","matrices not compatible");
02608 return target;
02609 }
02610
02611 target.ResizeTo(source1);
02612
02613 const Element *sp1 = source1.GetMatrixArray();
02614 const Element *sp2 = source2.GetMatrixArray();
02615 Element *tp = target.GetMatrixArray();
02616 const Element * const tp_last = tp+target.GetNoElements();
02617 while (tp < tp_last) {
02618 *tp++ = (*sp1) > (*sp2); sp1++; sp2++;
02619 }
02620
02621 return target;
02622 }
02623
02624
02625 template<class Element>
02626 TMatrixT<Element> operator>(const TMatrixT<Element> &source1,const TMatrixTSym<Element> &source2)
02627 {
02628
02629
02630 TMatrixT<Element> target;
02631
02632 if (gMatrixCheck && !AreCompatible(source1,source2)) {
02633 Error("operator>(const TMatrixT&,const TMatrixTSym&)","matrices not compatible");
02634 return target;
02635 }
02636
02637 target.ResizeTo(source1);
02638
02639 const Element *sp1 = source1.GetMatrixArray();
02640 const Element *sp2 = source2.GetMatrixArray();
02641 Element *tp = target.GetMatrixArray();
02642 const Element * const tp_last = tp+target.GetNoElements();
02643 while (tp < tp_last) {
02644 *tp++ = (*sp1) > (*sp2); sp1++; sp2++;
02645 }
02646
02647 return target;
02648 }
02649
02650
02651 template<class Element>
02652 TMatrixT<Element> operator>(const TMatrixTSym<Element> &source1,const TMatrixT<Element> &source2)
02653 {
02654
02655
02656 return operator<=(source2,source1);
02657 }
02658
02659
02660 template<class Element>
02661 TMatrixT<Element> operator>=(const TMatrixT<Element> &source1,const TMatrixT<Element> &source2)
02662 {
02663
02664
02665 TMatrixT<Element> target;
02666
02667 if (gMatrixCheck && !AreCompatible(source1,source2)) {
02668 Error("operator>=(const TMatrixT&,const TMatrixT&)","matrices not compatible");
02669 return target;
02670 }
02671
02672 target.ResizeTo(source1);
02673
02674 const Element *sp1 = source1.GetMatrixArray();
02675 const Element *sp2 = source2.GetMatrixArray();
02676 Element *tp = target.GetMatrixArray();
02677 const Element * const tp_last = tp+target.GetNoElements();
02678 while (tp < tp_last) {
02679 *tp++ = (*sp1) >= (*sp2); sp1++; sp2++;
02680 }
02681
02682 return target;
02683 }
02684
02685
02686 template<class Element>
02687 TMatrixT<Element> operator>=(const TMatrixT<Element> &source1,const TMatrixTSym<Element> &source2)
02688 {
02689
02690
02691 TMatrixT<Element> target;
02692
02693 if (gMatrixCheck && !AreCompatible(source1,source2)) {
02694 Error("operator>=(const TMatrixT&,const TMatrixTSym&)","matrices not compatible");
02695 return target;
02696 }
02697
02698 target.ResizeTo(source1);
02699
02700 const Element *sp1 = source1.GetMatrixArray();
02701 const Element *sp2 = source2.GetMatrixArray();
02702 Element *tp = target.GetMatrixArray();
02703 const Element * const tp_last = tp+target.GetNoElements();
02704 while (tp < tp_last) {
02705 *tp++ = (*sp1) >= (*sp2); sp1++; sp2++;
02706 }
02707
02708 return target;
02709 }
02710
02711
02712 template<class Element>
02713 TMatrixT<Element> operator>=(const TMatrixTSym<Element> &source1,const TMatrixT<Element> &source2)
02714 {
02715
02716
02717 return operator<(source2,source1);
02718 }
02719
02720
02721 template<class Element>
02722 TMatrixT<Element> operator<=(const TMatrixT<Element> &source1,const TMatrixT<Element> &source2)
02723 {
02724
02725
02726 TMatrixT<Element> target;
02727
02728 if (gMatrixCheck && !AreCompatible(source1,source2)) {
02729 Error("operator<=(const TMatrixT&,const TMatrixT&)","matrices not compatible");
02730 return target;
02731 }
02732
02733 target.ResizeTo(source1);
02734
02735 const Element *sp1 = source1.GetMatrixArray();
02736 const Element *sp2 = source2.GetMatrixArray();
02737 Element *tp = target.GetMatrixArray();
02738 const Element * const tp_last = tp+target.GetNoElements();
02739 while (tp < tp_last) {
02740 *tp++ = (*sp1) <= (*sp2); sp1++; sp2++;
02741 }
02742
02743 return target;
02744 }
02745
02746
02747 template<class Element>
02748 TMatrixT<Element> operator<=(const TMatrixT<Element> &source1,const TMatrixTSym<Element> &source2)
02749 {
02750
02751
02752 TMatrixT<Element> target;
02753
02754 if (gMatrixCheck && !AreCompatible(source1,source2)) {
02755 Error("operator<=(const TMatrixT&,const TMatrixTSym&)","matrices not compatible");
02756 return target;
02757 }
02758
02759 target.ResizeTo(source1);
02760
02761 const Element *sp1 = source1.GetMatrixArray();
02762 const Element *sp2 = source2.GetMatrixArray();
02763 Element *tp = target.GetMatrixArray();
02764 const Element * const tp_last = tp+target.GetNoElements();
02765 while (tp < tp_last) {
02766 *tp++ = (*sp1) <= (*sp2); sp1++; sp2++;
02767 }
02768
02769 return target;
02770 }
02771
02772
02773 template<class Element>
02774 TMatrixT<Element> operator<=(const TMatrixTSym<Element> &source1,const TMatrixT<Element> &source2)
02775 {
02776
02777
02778 return operator>(source2,source1);
02779 }
02780
02781
02782 template<class Element>
02783 TMatrixT<Element> operator<(const TMatrixT<Element> &source1,const TMatrixT<Element> &source2)
02784 {
02785
02786
02787 TMatrixT<Element> target;
02788
02789 if (gMatrixCheck && !AreCompatible(source1,source2)) {
02790 Error("operator<(const TMatrixT&,const TMatrixT&)","matrices not compatible");
02791 return target;
02792 }
02793
02794 const Element *sp1 = source1.GetMatrixArray();
02795 const Element *sp2 = source2.GetMatrixArray();
02796 Element *tp = target.GetMatrixArray();
02797 const Element * const tp_last = tp+target.GetNoElements();
02798 while (tp < tp_last) {
02799 *tp++ = (*sp1) < (*sp2); sp1++; sp2++;
02800 }
02801
02802 return target;
02803 }
02804
02805
02806 template<class Element>
02807 TMatrixT<Element> operator<(const TMatrixT<Element> &source1,const TMatrixTSym<Element> &source2)
02808 {
02809
02810
02811 TMatrixT<Element> target;
02812
02813 if (gMatrixCheck && !AreCompatible(source1,source2)) {
02814 Error("operator<(const TMatrixT&,const TMatrixTSym&)","matrices not compatible");
02815 return target;
02816 }
02817
02818 target.ResizeTo(source1);
02819
02820 const Element *sp1 = source1.GetMatrixArray();
02821 const Element *sp2 = source2.GetMatrixArray();
02822 Element *tp = target.GetMatrixArray();
02823 const Element * const tp_last = tp+target.GetNoElements();
02824 while (tp < tp_last) {
02825 *tp++ = (*sp1) < (*sp2); sp1++; sp2++;
02826 }
02827
02828 return target;
02829 }
02830
02831
02832 template<class Element>
02833 TMatrixT<Element> operator<(const TMatrixTSym<Element> &source1,const TMatrixT<Element> &source2)
02834 {
02835
02836
02837 return operator>=(source2,source1);
02838 }
02839
02840
02841 template<class Element>
02842 TMatrixT<Element> operator!=(const TMatrixT<Element> &source1,const TMatrixT<Element> &source2)
02843 {
02844
02845
02846 TMatrixT<Element> target;
02847
02848 if (gMatrixCheck && !AreCompatible(source1,source2)) {
02849 Error("operator!=(const TMatrixT&,const TMatrixT&)","matrices not compatible");
02850 return target;
02851 }
02852
02853 target.ResizeTo(source1);
02854
02855 const Element *sp1 = source1.GetMatrixArray();
02856 const Element *sp2 = source2.GetMatrixArray();
02857 Element *tp = target.GetMatrixArray();
02858 const Element * const tp_last = tp+target.GetNoElements();
02859 while (tp != tp_last) {
02860 *tp++ = (*sp1) != (*sp2); sp1++; sp2++;
02861 }
02862
02863 return target;
02864 }
02865
02866
02867 template<class Element>
02868 TMatrixT<Element> operator!=(const TMatrixT<Element> &source1,const TMatrixTSym<Element> &source2)
02869 {
02870
02871
02872 TMatrixT<Element> target;
02873
02874 if (gMatrixCheck && !AreCompatible(source1,source2)) {
02875 Error("operator!=(const TMatrixT&,const TMatrixTSym&)","matrices not compatible");
02876 return target;
02877 }
02878
02879 target.ResizeTo(source1);
02880
02881 const Element *sp1 = source1.GetMatrixArray();
02882 const Element *sp2 = source2.GetMatrixArray();
02883 Element *tp = target.GetMatrixArray();
02884 const Element * const tp_last = tp+target.GetNoElements();
02885 while (tp != tp_last) {
02886 *tp++ = (*sp1) != (*sp2); sp1++; sp2++;
02887 }
02888
02889 return target;
02890 }
02891
02892
02893 template<class Element>
02894 TMatrixT<Element> operator!=(const TMatrixTSym<Element> &source1,const TMatrixT<Element> &source2)
02895 {
02896
02897
02898 return operator!=(source2,source1);
02899 }
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931 template<class Element>
02932 TMatrixT<Element> &Add(TMatrixT<Element> &target,Element scalar,const TMatrixT<Element> &source)
02933 {
02934
02935
02936 if (gMatrixCheck && !AreCompatible(target,source)) {
02937 ::Error("Add(TMatrixT &,Element,const TMatrixT &)","matrices not compatible");
02938 return target;
02939 }
02940
02941 const Element *sp = source.GetMatrixArray();
02942 Element *tp = target.GetMatrixArray();
02943 const Element *ftp = tp+target.GetNoElements();
02944 if (scalar == 0) {
02945 while ( tp < ftp )
02946 *tp++ = scalar * (*sp++);
02947 } else if (scalar == 1.) {
02948 while ( tp < ftp )
02949 *tp++ = (*sp++);
02950 } else {
02951 while ( tp < ftp )
02952 *tp++ += scalar * (*sp++);
02953 }
02954
02955 return target;
02956 }
02957
02958
02959 template<class Element>
02960 TMatrixT<Element> &Add(TMatrixT<Element> &target,Element scalar,const TMatrixTSym<Element> &source)
02961 {
02962
02963
02964 if (gMatrixCheck && !AreCompatible(target,source)) {
02965 ::Error("Add(TMatrixT &,Element,const TMatrixTSym &)","matrices not compatible");
02966 return target;
02967 }
02968
02969 const Element *sp = source.GetMatrixArray();
02970 Element *tp = target.GetMatrixArray();
02971 const Element *ftp = tp+target.GetNoElements();
02972 while ( tp < ftp )
02973 *tp++ += scalar * (*sp++);
02974
02975 return target;
02976 }
02977
02978
02979 template<class Element>
02980 TMatrixT<Element> &ElementMult(TMatrixT<Element> &target,const TMatrixT<Element> &source)
02981 {
02982
02983
02984 if (gMatrixCheck && !AreCompatible(target,source)) {
02985 ::Error("ElementMult(TMatrixT &,const TMatrixT &)","matrices not compatible");
02986 return target;
02987 }
02988
02989 const Element *sp = source.GetMatrixArray();
02990 Element *tp = target.GetMatrixArray();
02991 const Element *ftp = tp+target.GetNoElements();
02992 while ( tp < ftp )
02993 *tp++ *= *sp++;
02994
02995 return target;
02996 }
02997
02998
02999 template<class Element>
03000 TMatrixT<Element> &ElementMult(TMatrixT<Element> &target,const TMatrixTSym<Element> &source)
03001 {
03002
03003
03004 if (gMatrixCheck && !AreCompatible(target,source)) {
03005 ::Error("ElementMult(TMatrixT &,const TMatrixTSym &)","matrices not compatible");
03006 return target;
03007 }
03008
03009 const Element *sp = source.GetMatrixArray();
03010 Element *tp = target.GetMatrixArray();
03011 const Element *ftp = tp+target.GetNoElements();
03012 while ( tp < ftp )
03013 *tp++ *= *sp++;
03014
03015 return target;
03016 }
03017
03018
03019 template<class Element>
03020 TMatrixT<Element> &ElementDiv(TMatrixT<Element> &target,const TMatrixT<Element> &source)
03021 {
03022
03023
03024 if (gMatrixCheck && !AreCompatible(target,source)) {
03025 ::Error("ElementDiv(TMatrixT &,const TMatrixT &)","matrices not compatible");
03026 return target;
03027 }
03028
03029 const Element *sp = source.GetMatrixArray();
03030 Element *tp = target.GetMatrixArray();
03031 const Element *ftp = tp+target.GetNoElements();
03032 while ( tp < ftp ) {
03033 if (*sp != 0.0)
03034 *tp++ /= *sp++;
03035 else {
03036 const Int_t irow = (sp-source.GetMatrixArray())/source.GetNcols();
03037 const Int_t icol = (sp-source.GetMatrixArray())%source.GetNcols();
03038 Error("ElementDiv","source (%d,%d) is zero",irow,icol);
03039 tp++;
03040 }
03041 }
03042
03043 return target;
03044 }
03045
03046
03047 template<class Element>
03048 TMatrixT<Element> &ElementDiv(TMatrixT<Element> &target,const TMatrixTSym<Element> &source)
03049 {
03050
03051
03052 if (gMatrixCheck && !AreCompatible(target,source)) {
03053 ::Error("ElementDiv(TMatrixT &,const TMatrixTSym &)","matrices not compatible");
03054 return target;
03055 }
03056
03057 const Element *sp = source.GetMatrixArray();
03058 Element *tp = target.GetMatrixArray();
03059 const Element *ftp = tp+target.GetNoElements();
03060 while ( tp < ftp ) {
03061 if (*sp != 0.0)
03062 *tp++ /= *sp++;
03063 else {
03064 const Int_t irow = (sp-source.GetMatrixArray())/source.GetNcols();
03065 const Int_t icol = (sp-source.GetMatrixArray())%source.GetNcols();
03066 Error("ElementDiv","source (%d,%d) is zero",irow,icol);
03067 *tp++ = 0.0;
03068 }
03069 }
03070
03071 return target;
03072 }
03073
03074
03075 template<class Element>
03076 void AMultB(const Element * const ap,Int_t na,Int_t ncolsa,
03077 const Element * const bp,Int_t nb,Int_t ncolsb,Element *cp)
03078 {
03079
03080
03081 const Element *arp0 = ap;
03082 while (arp0 < ap+na) {
03083 for (const Element *bcp = bp; bcp < bp+ncolsb; ) {
03084 const Element *arp = arp0;
03085 Element cij = 0;
03086 while (bcp < bp+nb) {
03087 cij += *arp++ * *bcp;
03088 bcp += ncolsb;
03089 }
03090 *cp++ = cij;
03091 bcp -= nb-1;
03092 }
03093 arp0 += ncolsa;
03094 }
03095 }
03096
03097
03098 template<class Element>
03099 void AtMultB(const Element * const ap,Int_t ncolsa,
03100 const Element * const bp,Int_t nb,Int_t ncolsb,Element *cp)
03101 {
03102
03103
03104 const Element *acp0 = ap;
03105 while (acp0 < ap+ncolsa) {
03106 for (const Element *bcp = bp; bcp < bp+ncolsb; ) {
03107 const Element *acp = acp0;
03108 Element cij = 0;
03109 while (bcp < bp+nb) {
03110 cij += *acp * *bcp;
03111 acp += ncolsa;
03112 bcp += ncolsb;
03113 }
03114 *cp++ = cij;
03115 bcp -= nb-1;
03116 }
03117 acp0++;
03118 }
03119 }
03120
03121
03122 template<class Element>
03123 void AMultBt(const Element * const ap,Int_t na,Int_t ncolsa,
03124 const Element * const bp,Int_t nb,Int_t ncolsb,Element *cp)
03125 {
03126
03127
03128 const Element *arp0 = ap;
03129 while (arp0 < ap+na) {
03130 const Element *brp0 = bp;
03131 while (brp0 < bp+nb) {
03132 const Element *arp = arp0;
03133 const Element *brp = brp0;
03134 Element cij = 0;
03135 while (brp < brp0+ncolsb)
03136 cij += *arp++ * *brp++;
03137 *cp++ = cij;
03138 brp0 += ncolsb;
03139 }
03140 arp0 += ncolsa;
03141 }
03142 }
03143
03144
03145 template<class Element>
03146 void TMatrixT<Element>::Streamer(TBuffer &R__b)
03147 {
03148
03149
03150 if (R__b.IsReading()) {
03151 UInt_t R__s, R__c;
03152 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
03153 if (R__v > 2) {
03154 Clear();
03155 R__b.ReadClassBuffer(TMatrixT<Element>::Class(),this,R__v,R__s,R__c);
03156 } else if (R__v == 2) {
03157 Clear();
03158 TObject::Streamer(R__b);
03159 this->MakeValid();
03160 R__b >> this->fNrows;
03161 R__b >> this->fNcols;
03162 R__b >> this->fNelems;
03163 R__b >> this->fRowLwb;
03164 R__b >> this->fColLwb;
03165 Char_t isArray;
03166 R__b >> isArray;
03167 if (isArray) {
03168 if (this->fNelems > 0) {
03169 fElements = new Element[this->fNelems];
03170 R__b.ReadFastArray(fElements,this->fNelems);
03171 } else
03172 fElements = 0;
03173 }
03174 R__b.CheckByteCount(R__s,R__c,TMatrixT<Element>::IsA());
03175 } else {
03176 TObject::Streamer(R__b);
03177 this->MakeValid();
03178 R__b >> this->fNrows;
03179 R__b >> this->fNcols;
03180 R__b >> this->fRowLwb;
03181 R__b >> this->fColLwb;
03182 this->fNelems = R__b.ReadArray(fElements);
03183 R__b.CheckByteCount(R__s,R__c,TMatrixT<Element>::IsA());
03184 }
03185
03186 if (R__v <= 2 && fElements) {
03187 for (Int_t i = 0; i < this->fNrows; i++) {
03188 const Int_t off_i = i*this->fNcols;
03189 for (Int_t j = i; j < this->fNcols; j++) {
03190 const Int_t off_j = j*this->fNrows;
03191 const Element tmp = fElements[off_i+j];
03192 fElements[off_i+j] = fElements[off_j+i];
03193 fElements[off_j+i] = tmp;
03194 }
03195 }
03196 }
03197 if (this->fNelems > 0 && this->fNelems <= this->kSizeMax) {
03198 if (fElements) {
03199 memcpy(fDataStack,fElements,this->fNelems*sizeof(Element));
03200 delete [] fElements;
03201 }
03202 fElements = fDataStack;
03203 } else if (this->fNelems < 0)
03204 this->Invalidate();
03205 } else {
03206 R__b.WriteClassBuffer(TMatrixT<Element>::Class(),this);
03207 }
03208 }
03209
03210 template class TMatrixT<Float_t>;
03211
03212 #ifndef ROOT_TMatrixFfwd
03213 #include "TMatrixFfwd.h"
03214 #endif
03215 #ifndef ROOT_TMatrixFSymfwd
03216 #include "TMatrixFSymfwd.h"
03217 #endif
03218
03219 template TMatrixF operator+ <Float_t>(const TMatrixF &source1,const TMatrixF &source2);
03220 template TMatrixF operator+ <Float_t>(const TMatrixF &source1,const TMatrixFSym &source2);
03221 template TMatrixF operator+ <Float_t>(const TMatrixFSym &source1,const TMatrixF &source2);
03222 template TMatrixF operator+ <Float_t>(const TMatrixF &source , Float_t val );
03223 template TMatrixF operator+ <Float_t>( Float_t val ,const TMatrixF &source );
03224 template TMatrixF operator- <Float_t>(const TMatrixF &source1,const TMatrixF &source2);
03225 template TMatrixF operator- <Float_t>(const TMatrixF &source1,const TMatrixFSym &source2);
03226 template TMatrixF operator- <Float_t>(const TMatrixFSym &source1,const TMatrixF &source2);
03227 template TMatrixF operator- <Float_t>(const TMatrixF &source , Float_t val );
03228 template TMatrixF operator- <Float_t>( Float_t val ,const TMatrixF &source );
03229 template TMatrixF operator* <Float_t>( Float_t val ,const TMatrixF &source );
03230 template TMatrixF operator* <Float_t>(const TMatrixF &source , Float_t val );
03231 template TMatrixF operator* <Float_t>(const TMatrixF &source1,const TMatrixF &source2);
03232 template TMatrixF operator* <Float_t>(const TMatrixF &source1,const TMatrixFSym &source2);
03233 template TMatrixF operator* <Float_t>(const TMatrixFSym &source1,const TMatrixF &source2);
03234 template TMatrixF operator* <Float_t>(const TMatrixFSym &source1,const TMatrixFSym &source2);
03235 template TMatrixF operator&& <Float_t>(const TMatrixF &source1,const TMatrixF &source2);
03236 template TMatrixF operator&& <Float_t>(const TMatrixF &source1,const TMatrixFSym &source2);
03237 template TMatrixF operator&& <Float_t>(const TMatrixFSym &source1,const TMatrixF &source2);
03238 template TMatrixF operator|| <Float_t>(const TMatrixF &source1,const TMatrixF &source2);
03239 template TMatrixF operator|| <Float_t>(const TMatrixF &source1,const TMatrixFSym &source2);
03240 template TMatrixF operator|| <Float_t>(const TMatrixFSym &source1,const TMatrixF &source2);
03241 template TMatrixF operator> <Float_t>(const TMatrixF &source1,const TMatrixF &source2);
03242 template TMatrixF operator> <Float_t>(const TMatrixF &source1,const TMatrixFSym &source2);
03243 template TMatrixF operator> <Float_t>(const TMatrixFSym &source1,const TMatrixF &source2);
03244 template TMatrixF operator>= <Float_t>(const TMatrixF &source1,const TMatrixF &source2);
03245 template TMatrixF operator>= <Float_t>(const TMatrixF &source1,const TMatrixFSym &source2);
03246 template TMatrixF operator>= <Float_t>(const TMatrixFSym &source1,const TMatrixF &source2);
03247 template TMatrixF operator<= <Float_t>(const TMatrixF &source1,const TMatrixF &source2);
03248 template TMatrixF operator<= <Float_t>(const TMatrixF &source1,const TMatrixFSym &source2);
03249 template TMatrixF operator<= <Float_t>(const TMatrixFSym &source1,const TMatrixF &source2);
03250 template TMatrixF operator< <Float_t>(const TMatrixF &source1,const TMatrixF &source2);
03251 template TMatrixF operator< <Float_t>(const TMatrixF &source1,const TMatrixFSym &source2);
03252 template TMatrixF operator< <Float_t>(const TMatrixFSym &source1,const TMatrixF &source2);
03253 template TMatrixF operator!= <Float_t>(const TMatrixF &source1,const TMatrixF &source2);
03254 template TMatrixF operator!= <Float_t>(const TMatrixF &source1,const TMatrixFSym &source2);
03255 template TMatrixF operator!= <Float_t>(const TMatrixFSym &source1,const TMatrixF &source2);
03256
03257 template TMatrixF &Add <Float_t>(TMatrixF &target, Float_t scalar,const TMatrixF &source);
03258 template TMatrixF &Add <Float_t>(TMatrixF &target, Float_t scalar,const TMatrixFSym &source);
03259 template TMatrixF &ElementMult<Float_t>(TMatrixF &target,const TMatrixF &source);
03260 template TMatrixF &ElementMult<Float_t>(TMatrixF &target,const TMatrixFSym &source);
03261 template TMatrixF &ElementDiv <Float_t>(TMatrixF &target,const TMatrixF &source);
03262 template TMatrixF &ElementDiv <Float_t>(TMatrixF &target,const TMatrixFSym &source);
03263
03264 template void AMultB <Float_t>(const Float_t * const ap,Int_t na,Int_t ncolsa,
03265 const Float_t * const bp,Int_t nb,Int_t ncolsb,Float_t *cp);
03266 template void AtMultB<Float_t>(const Float_t * const ap,Int_t ncolsa,
03267 const Float_t * const bp,Int_t nb,Int_t ncolsb,Float_t *cp);
03268 template void AMultBt<Float_t>(const Float_t * const ap,Int_t na,Int_t ncolsa,
03269 const Float_t * const bp,Int_t nb,Int_t ncolsb,Float_t *cp);
03270
03271 #ifndef ROOT_TMatrixDfwd
03272 #include "TMatrixDfwd.h"
03273 #endif
03274 #ifndef ROOT_TMatrixDSymfwd
03275 #include "TMatrixDSymfwd.h"
03276 #endif
03277
03278 template class TMatrixT<Double_t>;
03279
03280 template TMatrixD operator+ <Double_t>(const TMatrixD &source1,const TMatrixD &source2);
03281 template TMatrixD operator+ <Double_t>(const TMatrixD &source1,const TMatrixDSym &source2);
03282 template TMatrixD operator+ <Double_t>(const TMatrixDSym &source1,const TMatrixD &source2);
03283 template TMatrixD operator+ <Double_t>(const TMatrixD &source , Double_t val );
03284 template TMatrixD operator+ <Double_t>( Double_t val ,const TMatrixD &source );
03285 template TMatrixD operator- <Double_t>(const TMatrixD &source1,const TMatrixD &source2);
03286 template TMatrixD operator- <Double_t>(const TMatrixD &source1,const TMatrixDSym &source2);
03287 template TMatrixD operator- <Double_t>(const TMatrixDSym &source1,const TMatrixD &source2);
03288 template TMatrixD operator- <Double_t>(const TMatrixD &source , Double_t val );
03289 template TMatrixD operator- <Double_t>( Double_t val ,const TMatrixD &source );
03290 template TMatrixD operator* <Double_t>( Double_t val ,const TMatrixD &source );
03291 template TMatrixD operator* <Double_t>(const TMatrixD &source , Double_t val );
03292 template TMatrixD operator* <Double_t>(const TMatrixD &source1,const TMatrixD &source2);
03293 template TMatrixD operator* <Double_t>(const TMatrixD &source1,const TMatrixDSym &source2);
03294 template TMatrixD operator* <Double_t>(const TMatrixDSym &source1,const TMatrixD &source2);
03295 template TMatrixD operator* <Double_t>(const TMatrixDSym &source1,const TMatrixDSym &source2);
03296 template TMatrixD operator&& <Double_t>(const TMatrixD &source1,const TMatrixD &source2);
03297 template TMatrixD operator&& <Double_t>(const TMatrixD &source1,const TMatrixDSym &source2);
03298 template TMatrixD operator&& <Double_t>(const TMatrixDSym &source1,const TMatrixD &source2);
03299 template TMatrixD operator|| <Double_t>(const TMatrixD &source1,const TMatrixD &source2);
03300 template TMatrixD operator|| <Double_t>(const TMatrixD &source1,const TMatrixDSym &source2);
03301 template TMatrixD operator|| <Double_t>(const TMatrixDSym &source1,const TMatrixD &source2);
03302 template TMatrixD operator> <Double_t>(const TMatrixD &source1,const TMatrixD &source2);
03303 template TMatrixD operator> <Double_t>(const TMatrixD &source1,const TMatrixDSym &source2);
03304 template TMatrixD operator> <Double_t>(const TMatrixDSym &source1,const TMatrixD &source2);
03305 template TMatrixD operator>= <Double_t>(const TMatrixD &source1,const TMatrixD &source2);
03306 template TMatrixD operator>= <Double_t>(const TMatrixD &source1,const TMatrixDSym &source2);
03307 template TMatrixD operator>= <Double_t>(const TMatrixDSym &source1,const TMatrixD &source2);
03308 template TMatrixD operator<= <Double_t>(const TMatrixD &source1,const TMatrixD &source2);
03309 template TMatrixD operator<= <Double_t>(const TMatrixD &source1,const TMatrixDSym &source2);
03310 template TMatrixD operator<= <Double_t>(const TMatrixDSym &source1,const TMatrixD &source2);
03311 template TMatrixD operator< <Double_t>(const TMatrixD &source1,const TMatrixD &source2);
03312 template TMatrixD operator< <Double_t>(const TMatrixD &source1,const TMatrixDSym &source2);
03313 template TMatrixD operator< <Double_t>(const TMatrixDSym &source1,const TMatrixD &source2);
03314 template TMatrixD operator!= <Double_t>(const TMatrixD &source1,const TMatrixD &source2);
03315 template TMatrixD operator!= <Double_t>(const TMatrixD &source1,const TMatrixDSym &source2);
03316 template TMatrixD operator!= <Double_t>(const TMatrixDSym &source1,const TMatrixD &source2);
03317
03318 template TMatrixD &Add <Double_t>(TMatrixD &target, Double_t scalar,const TMatrixD &source);
03319 template TMatrixD &Add <Double_t>(TMatrixD &target, Double_t scalar,const TMatrixDSym &source);
03320 template TMatrixD &ElementMult<Double_t>(TMatrixD &target,const TMatrixD &source);
03321 template TMatrixD &ElementMult<Double_t>(TMatrixD &target,const TMatrixDSym &source);
03322 template TMatrixD &ElementDiv <Double_t>(TMatrixD &target,const TMatrixD &source);
03323 template TMatrixD &ElementDiv <Double_t>(TMatrixD &target,const TMatrixDSym &source);
03324
03325 template void AMultB <Double_t>(const Double_t * const ap,Int_t na,Int_t ncolsa,
03326 const Double_t * const bp,Int_t nb,Int_t ncolsb,Double_t *cp);
03327 template void AtMultB<Double_t>(const Double_t * const ap,Int_t ncolsa,
03328 const Double_t * const bp,Int_t nb,Int_t ncolsb,Double_t *cp);
03329 template void AMultBt<Double_t>(const Double_t * const ap,Int_t na,Int_t ncolsa,
03330 const Double_t * const bp,Int_t nb,Int_t ncolsb,Double_t *cp);