TMatrixTUtils.cxx

Go to the documentation of this file.
00001 // @(#)root/matrix:$Id: TMatrixTUtils.cxx 34913 2010-08-20 19:18:35Z pcanal $
00002 // Authors: Fons Rademakers, Eddy Offermann  Nov 2003
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // Matrix utility classes.                                              //
00015 //                                                                      //
00016 // Templates of utility classes in the Linear Algebra Package.          //
00017 // The following classes are defined here:                              //
00018 //                                                                      //
00019 // Different matrix views without copying data elements :               //
00020 //   TMatrixTRow_const        TMatrixTRow                               //
00021 //   TMatrixTColumn_const     TMatrixTColumn                            //
00022 //   TMatrixTDiag_const       TMatrixTDiag                              //
00023 //   TMatrixTFlat_const       TMatrixTFlat                              //
00024 //   TMatrixTSub_const        TMatrixTSub                               //
00025 //   TMatrixTSparseRow_const  TMatrixTSparseRow                         //
00026 //   TMatrixTSparseDiag_const TMatrixTSparseDiag                        //
00027 //                                                                      //
00028 //   TElementActionT                                                    //
00029 //   TElementPosActionT                                                 //
00030 //                                                                      //
00031 //////////////////////////////////////////////////////////////////////////
00032 
00033 #include "TMatrixTUtils.h"
00034 #include "TMatrixT.h"
00035 #include "TMatrixTSym.h"
00036 #include "TMatrixTSparse.h"
00037 #include "TMath.h"
00038 #include "TVectorT.h"
00039 
00040 //______________________________________________________________________________
00041 template<class Element>
00042 TMatrixTRow_const<Element>::TMatrixTRow_const(const TMatrixT<Element> &matrix,Int_t row)
00043 {
00044 // Constructor with row "row" of matrix
00045 
00046    R__ASSERT(matrix.IsValid());
00047 
00048    fRowInd = row-matrix.GetRowLwb();
00049    if (fRowInd >= matrix.GetNrows() || fRowInd < 0) {
00050       Error("TMatrixTRow_const(const TMatrixT<Element> &,Int_t)","row index out of bounds");
00051       fMatrix = 0;
00052       fPtr = 0;
00053       fInc = 0;
00054       return;
00055    }
00056  
00057    fMatrix = &matrix;
00058    fPtr = matrix.GetMatrixArray()+fRowInd*matrix.GetNcols();
00059    fInc = 1;
00060 }
00061 
00062 //______________________________________________________________________________
00063 template<class Element>
00064 TMatrixTRow_const<Element>::TMatrixTRow_const(const TMatrixTSym<Element> &matrix,Int_t row)
00065 {
00066 // Constructor with row "row" of symmetric matrix
00067 
00068    R__ASSERT(matrix.IsValid());
00069 
00070    fRowInd = row-matrix.GetRowLwb();
00071    if (fRowInd >= matrix.GetNrows() || fRowInd < 0) {
00072       Error("TMatrixTRow_const(const TMatrixTSym &,Int_t)","row index out of bounds");
00073       fMatrix = 0;
00074       fPtr = 0;
00075       fInc = 0;
00076       return;
00077    }
00078 
00079    fMatrix = &matrix;
00080    fPtr = matrix.GetMatrixArray()+fRowInd*matrix.GetNcols();
00081    fInc = 1;
00082 }
00083 
00084 //______________________________________________________________________________
00085 template<class Element>
00086 TMatrixTRow<Element>::TMatrixTRow(TMatrixT<Element> &matrix,Int_t row)
00087             :TMatrixTRow_const<Element>(matrix,row)
00088 {
00089 // Constructor with row "row" of symmetric matrix
00090 }
00091 
00092 //______________________________________________________________________________
00093 template<class Element>
00094 TMatrixTRow<Element>::TMatrixTRow(TMatrixTSym<Element> &matrix,Int_t row)
00095             :TMatrixTRow_const<Element>(matrix,row)
00096 {
00097 // Constructor with row "row" of symmetric matrix
00098 }
00099 
00100 //______________________________________________________________________________
00101 template<class Element>
00102 TMatrixTRow<Element>::TMatrixTRow(const TMatrixTRow<Element> &mr) : TMatrixTRow_const<Element>(mr)
00103 {
00104 // Copy constructor
00105 
00106    *this = mr;
00107 }
00108 
00109 //______________________________________________________________________________
00110 template<class Element>
00111 void TMatrixTRow<Element>::operator=(Element val)
00112 {
00113 // Assign val to every element of the matrix row.
00114 
00115    R__ASSERT(this->fMatrix->IsValid());
00116    Element *rp = const_cast<Element *>(this->fPtr);
00117    for ( ; rp < this->fPtr+this->fMatrix->GetNcols(); rp += this->fInc)
00118       *rp = val;
00119 }
00120 
00121 //______________________________________________________________________________
00122 template<class Element>
00123 void TMatrixTRow<Element>::operator+=(Element val)
00124 {
00125 // Add val to every element of the matrix row.
00126 
00127    R__ASSERT(this->fMatrix->IsValid());
00128    Element *rp = const_cast<Element *>(this->fPtr);
00129    for ( ; rp < this->fPtr+this->fMatrix->GetNcols(); rp += this->fInc)
00130       *rp += val;
00131 }
00132 
00133 //______________________________________________________________________________
00134 template<class Element>
00135 void TMatrixTRow<Element>::operator*=(Element val)
00136 {
00137 // Multiply every element of the matrix row with val.
00138 
00139    R__ASSERT(this->fMatrix->IsValid());
00140    Element *rp = const_cast<Element *>(this->fPtr);
00141    for ( ; rp < this->fPtr + this->fMatrix->GetNcols(); rp += this->fInc)
00142       *rp *= val;
00143 }
00144 
00145 //______________________________________________________________________________
00146 template<class Element>
00147 void TMatrixTRow<Element>::operator=(const TMatrixTRow_const<Element> &mr)
00148 {
00149 // Assignment operator
00150 
00151    const TMatrixTBase<Element> *mt = mr.GetMatrix();
00152    if (this->fMatrix->GetMatrixArray() == mt->GetMatrixArray() && this->fRowInd == mr.GetRowIndex()) return;
00153 
00154    R__ASSERT(this->fMatrix->IsValid());
00155    R__ASSERT(mt->IsValid());
00156 
00157    if (this->fMatrix->GetNcols() != mt->GetNcols() || this->fMatrix->GetColLwb() != mt->GetColLwb()) {
00158       Error("operator=(const TMatrixTRow_const &)", "matrix rows not compatible");
00159       return;
00160    }
00161 
00162    Element *rp1 = const_cast<Element *>(this->fPtr);
00163    const Element *rp2 = mr.GetPtr();
00164    for ( ; rp1 < this->fPtr+this->fMatrix->GetNcols(); rp1 += this->fInc,rp2 += mr.GetInc())
00165       *rp1 = *rp2;
00166 }
00167 
00168 //______________________________________________________________________________
00169 template<class Element>
00170 void TMatrixTRow<Element>::operator=(const TVectorT<Element> &vec)
00171 {
00172 // Assign a vector to a matrix row. The vector is considered row-vector
00173 // to allow the assignment in the strict sense.
00174 
00175    R__ASSERT(this->fMatrix->IsValid());
00176    R__ASSERT(vec.IsValid());
00177 
00178    if (this->fMatrix->GetColLwb() != vec.GetLwb() || this->fMatrix->GetNcols() != vec.GetNrows()) {
00179       Error("operator=(const TVectorT &)","vector length != matrix-row length");
00180       return;
00181    }
00182 
00183    Element *rp = const_cast<Element *>(this->fPtr);
00184    const Element *vp = vec.GetMatrixArray();
00185    for ( ; rp < this->fPtr+this->fMatrix->GetNcols(); rp += this->fInc)
00186       *rp = *vp++;
00187 }
00188 
00189 //______________________________________________________________________________
00190 template<class Element>
00191 void TMatrixTRow<Element>::operator+=(const TMatrixTRow_const<Element> &r)
00192 {
00193 // Add to every element of the matrix row the corresponding element of row r.
00194 
00195   const TMatrixTBase<Element> *mt = r.GetMatrix();
00196 
00197    R__ASSERT(this->fMatrix->IsValid());
00198    R__ASSERT(mt->IsValid());
00199 
00200    if (this->fMatrix->GetColLwb() != mt->GetColLwb() || this->fMatrix->GetNcols() != mt->GetNcols()) {
00201       Error("operator+=(const TMatrixTRow_const &)","different row lengths");
00202       return;
00203    }
00204 
00205    Element *rp1 = const_cast<Element *>(this->fPtr);
00206    const Element *rp2 = r.GetPtr();
00207    for ( ; rp1 < this->fPtr+this->fMatrix->GetNcols(); rp1 += this->fInc,rp2 += r.GetInc())
00208      *rp1 += *rp2;
00209 }
00210 
00211 //______________________________________________________________________________
00212 template<class Element>
00213 void TMatrixTRow<Element>::operator*=(const TMatrixTRow_const<Element> &r)
00214 {
00215 // Multiply every element of the matrix row with the
00216 // corresponding element of row r.
00217 
00218    const TMatrixTBase<Element> *mt = r.GetMatrix();
00219 
00220    R__ASSERT(this->fMatrix->IsValid());
00221    R__ASSERT(mt->IsValid());
00222 
00223    if (this->fMatrix->GetColLwb() != mt->GetColLwb() || this->fMatrix->GetNcols() != mt->GetNcols()) {
00224       Error("operator*=(const TMatrixTRow_const &)","different row lengths");
00225       return;
00226    }
00227 
00228    Element *rp1 = const_cast<Element *>(this->fPtr);
00229    const Element *rp2 = r.GetPtr();
00230    for ( ; rp1 < this->fPtr+this->fMatrix->GetNcols(); rp1 += this->fInc,rp2 += r.GetInc())
00231       *rp1 *= *rp2;
00232 }
00233 
00234 //______________________________________________________________________________
00235 template<class Element>
00236 TMatrixTColumn_const<Element>::TMatrixTColumn_const(const TMatrixT<Element> &matrix,Int_t col)
00237 {
00238 // Constructor with column "col" of matrix
00239 
00240    R__ASSERT(matrix.IsValid());
00241 
00242    this->fColInd = col-matrix.GetColLwb();
00243    if (this->fColInd >= matrix.GetNcols() || this->fColInd < 0) {
00244       Error("TMatrixTColumn_const(const TMatrixT &,Int_t)","column index out of bounds");
00245       fMatrix = 0;
00246       fPtr = 0;
00247       fInc = 0;
00248       return;
00249    }
00250 
00251    fMatrix = &matrix;
00252    fPtr = matrix.GetMatrixArray()+fColInd;
00253    fInc = matrix.GetNcols();
00254 }
00255 
00256 //______________________________________________________________________________
00257 template<class Element>
00258 TMatrixTColumn_const<Element>::TMatrixTColumn_const(const TMatrixTSym<Element> &matrix,Int_t col)
00259 {
00260 // Constructor with column "col" of matrix
00261 
00262    R__ASSERT(matrix.IsValid());
00263 
00264    fColInd = col-matrix.GetColLwb();
00265    if (fColInd >= matrix.GetNcols() || fColInd < 0) {
00266       Error("TMatrixTColumn_const(const TMatrixTSym &,Int_t)","column index out of bounds");
00267       fMatrix = 0;
00268       fPtr = 0;
00269       fInc = 0;
00270       return;
00271    }
00272 
00273    fMatrix = &matrix;
00274    fPtr = matrix.GetMatrixArray()+fColInd;
00275    fInc = matrix.GetNcols();
00276 }
00277 
00278 //______________________________________________________________________________
00279 template<class Element>
00280 TMatrixTColumn<Element>::TMatrixTColumn(TMatrixT<Element> &matrix,Int_t col)
00281                :TMatrixTColumn_const<Element>(matrix,col)
00282 {
00283 // Constructor with column "col" of matrix
00284 }
00285 
00286 //______________________________________________________________________________
00287 template<class Element>
00288 TMatrixTColumn<Element>::TMatrixTColumn(TMatrixTSym<Element> &matrix,Int_t col)
00289                :TMatrixTColumn_const<Element>(matrix,col)
00290 {
00291 // Constructor with column "col" of matrix
00292 }
00293 
00294 //______________________________________________________________________________
00295 template<class Element>
00296 TMatrixTColumn<Element>::TMatrixTColumn(const TMatrixTColumn<Element> &mc) : TMatrixTColumn_const<Element>(mc)
00297 {
00298 // Copy constructor
00299 
00300    *this = mc;
00301 }
00302 
00303 //______________________________________________________________________________
00304 template<class Element>
00305 void TMatrixTColumn<Element>::operator=(Element val)
00306 {
00307 // Assign val to every element of the matrix column.
00308 
00309    R__ASSERT(this->fMatrix->IsValid());
00310    Element *cp = const_cast<Element *>(this->fPtr);
00311    for ( ; cp < this->fPtr+this->fMatrix->GetNoElements(); cp += this->fInc)
00312       *cp = val;
00313 }
00314 
00315 //______________________________________________________________________________
00316 template<class Element>
00317 void TMatrixTColumn<Element>::operator+=(Element val)
00318 {
00319 // Add val to every element of the matrix column.
00320 
00321    R__ASSERT(this->fMatrix->IsValid());
00322    Element *cp = const_cast<Element *>(this->fPtr);
00323    for ( ; cp < this->fPtr+this->fMatrix->GetNoElements(); cp += this->fInc)
00324       *cp += val;
00325 }
00326 
00327 //______________________________________________________________________________
00328 template<class Element>
00329 void TMatrixTColumn<Element>::operator*=(Element val)
00330 {
00331 // Multiply every element of the matrix column with val.
00332 
00333    R__ASSERT(this->fMatrix->IsValid());
00334    Element *cp = const_cast<Element *>(this->fPtr);
00335    for ( ; cp < this->fPtr+this->fMatrix->GetNoElements(); cp += this->fInc)
00336       *cp *= val;
00337 }
00338 
00339 //______________________________________________________________________________
00340 template<class Element>
00341 void TMatrixTColumn<Element>::operator=(const TMatrixTColumn_const<Element> &mc)
00342 {
00343 // Assignment operator
00344 
00345    const TMatrixTBase<Element> *mt = mc.GetMatrix();
00346    if (this->fMatrix->GetMatrixArray() == mt->GetMatrixArray() && this->fColInd == mc.GetColIndex()) return;
00347 
00348    R__ASSERT(this->fMatrix->IsValid());
00349    R__ASSERT(mt->IsValid());
00350 
00351    if (this->fMatrix->GetNrows() != mt->GetNrows() || this->fMatrix->GetRowLwb() != mt->GetRowLwb()) {
00352       Error("operator=(const TMatrixTColumn_const &)", "matrix columns not compatible");
00353       return;
00354    }
00355 
00356    Element *cp1 = const_cast<Element *>(this->fPtr);
00357    const Element *cp2 = mc.GetPtr();
00358    for ( ; cp1 < this->fPtr+this->fMatrix->GetNoElements(); cp1 += this->fInc,cp2 += mc.GetInc())
00359       *cp1 = *cp2;
00360 }
00361 
00362 //______________________________________________________________________________
00363 template<class Element>
00364 void TMatrixTColumn<Element>::operator=(const TVectorT<Element> &vec)
00365 {
00366 // Assign a vector to a matrix column.
00367 
00368    R__ASSERT(this->fMatrix->IsValid());
00369    R__ASSERT(vec.IsValid());
00370 
00371    if (this->fMatrix->GetRowLwb() != vec.GetLwb() || this->fMatrix->GetNrows() != vec.GetNrows()) {
00372       Error("operator=(const TVectorT &)","vector length != matrix-column length");
00373       return;
00374    }
00375 
00376    Element *cp = const_cast<Element *>(this->fPtr);
00377    const Element *vp = vec.GetMatrixArray();
00378    for ( ; cp < this->fPtr+this->fMatrix->GetNoElements(); cp += this->fInc)
00379       *cp = *vp++;
00380 
00381    R__ASSERT(vp == vec.GetMatrixArray()+vec.GetNrows());
00382 }
00383 
00384 //______________________________________________________________________________
00385 template<class Element>
00386 void TMatrixTColumn<Element>::operator+=(const TMatrixTColumn_const<Element> &mc)
00387 {
00388 // Add to every element of the matrix row the corresponding element of row mc.
00389 
00390    const TMatrixTBase<Element> *mt = mc.GetMatrix();
00391 
00392    R__ASSERT(this->fMatrix->IsValid());
00393    R__ASSERT(mt->IsValid());
00394 
00395    if (this->fMatrix->GetRowLwb() != mt->GetRowLwb() || this->fMatrix->GetNrows() != mt->GetNrows()) {
00396       Error("operator+=(const TMatrixTColumn_const &)","different row lengths");
00397       return;
00398    }
00399 
00400    Element *cp1 = const_cast<Element *>(this->fPtr);
00401    const Element *cp2 = mc.GetPtr();
00402    for ( ; cp1 < this->fPtr+this->fMatrix->GetNoElements(); cp1 += this->fInc,cp2 += mc.GetInc())
00403       *cp1 += *cp2;
00404 }
00405 
00406 //______________________________________________________________________________
00407 template<class Element>
00408 void TMatrixTColumn<Element>::operator*=(const TMatrixTColumn_const<Element> &mc)
00409 {
00410 // Multiply every element of the matrix column with the
00411 // corresponding element of column mc.
00412 
00413    const TMatrixTBase<Element> *mt = mc.GetMatrix();
00414 
00415    R__ASSERT(this->fMatrix->IsValid());
00416    R__ASSERT(mt->IsValid());
00417 
00418    if (this->fMatrix->GetRowLwb() != mt->GetRowLwb() || this->fMatrix->GetNrows() != mt->GetNrows()) {
00419       Error("operator*=(const TMatrixTColumn_const &)","different row lengths");
00420       return;
00421    }
00422 
00423    Element *cp1 = const_cast<Element *>(this->fPtr);
00424    const Element *cp2 = mc.GetPtr();
00425    for ( ; cp1 < this->fPtr+this->fMatrix->GetNoElements(); cp1 += this->fInc,cp2 += mc.GetInc())
00426       *cp1 *= *cp2;
00427 }
00428 
00429 //______________________________________________________________________________
00430 template<class Element>
00431 TMatrixTDiag_const<Element>::TMatrixTDiag_const(const TMatrixT<Element> &matrix)
00432 {
00433 // Constructor
00434 
00435    R__ASSERT(matrix.IsValid());
00436 
00437    fMatrix = &matrix;
00438    fNdiag  = TMath::Min(matrix.GetNrows(),matrix.GetNcols());
00439    fPtr    = matrix.GetMatrixArray();
00440    fInc    = matrix.GetNcols()+1;
00441 }
00442 
00443 //______________________________________________________________________________
00444 template<class Element>
00445 TMatrixTDiag_const<Element>::TMatrixTDiag_const(const TMatrixTSym<Element> &matrix)
00446 {
00447 // Constructor
00448 
00449    R__ASSERT(matrix.IsValid());
00450 
00451    fMatrix = &matrix;
00452    fNdiag  = TMath::Min(matrix.GetNrows(),matrix.GetNcols());
00453    fPtr    = matrix.GetMatrixArray();
00454    fInc    = matrix.GetNcols()+1;
00455 }
00456 
00457 //______________________________________________________________________________
00458 template<class Element>
00459 TMatrixTDiag<Element>::TMatrixTDiag(TMatrixT<Element> &matrix)
00460              :TMatrixTDiag_const<Element>(matrix)
00461 {
00462 // Constructor
00463 }
00464 
00465 //______________________________________________________________________________
00466 template<class Element>
00467 TMatrixTDiag<Element>::TMatrixTDiag(TMatrixTSym<Element> &matrix)
00468              :TMatrixTDiag_const<Element>(matrix)
00469 {
00470 // Constructor
00471 }
00472 
00473 //______________________________________________________________________________
00474 template<class Element>
00475 TMatrixTDiag<Element>::TMatrixTDiag(const TMatrixTDiag<Element> &md) : TMatrixTDiag_const<Element>(md)
00476 {
00477 // Copy constructor
00478 
00479    *this = md;
00480 }
00481 
00482 //______________________________________________________________________________
00483 template<class Element>
00484 void TMatrixTDiag<Element>::operator=(Element val)
00485 {
00486 // Assign val to every element of the matrix diagonal.
00487 
00488    R__ASSERT(this->fMatrix->IsValid());
00489    Element *dp = const_cast<Element *>(this->fPtr);
00490    for (Int_t i = 0; i < this->fNdiag; i++, dp += this->fInc)
00491       *dp = val;
00492 }
00493 
00494 //______________________________________________________________________________
00495 template<class Element>
00496 void TMatrixTDiag<Element>::operator+=(Element val)
00497 {
00498 // Assign val to every element of the matrix diagonal.
00499 
00500    R__ASSERT(this->fMatrix->IsValid());
00501    Element *dp = const_cast<Element *>(this->fPtr);
00502    for (Int_t i = 0; i < this->fNdiag; i++, dp += this->fInc)
00503       *dp += val;
00504 }
00505 
00506 //______________________________________________________________________________
00507 template<class Element>
00508 void TMatrixTDiag<Element>::operator*=(Element val)
00509 {
00510 // Assign val to every element of the matrix diagonal.
00511 
00512    R__ASSERT(this->fMatrix->IsValid());
00513    Element *dp = const_cast<Element *>(this->fPtr);
00514    for (Int_t i = 0; i < this->fNdiag; i++, dp += this->fInc)
00515       *dp *= val;
00516 }
00517 
00518 //______________________________________________________________________________
00519 template<class Element>
00520 void TMatrixTDiag<Element>::operator=(const TMatrixTDiag_const<Element> &md)
00521 {
00522 // Assignment operator
00523 
00524    const TMatrixTBase<Element> *mt = md.GetMatrix();
00525    if (this->fMatrix == mt) return;
00526 
00527    R__ASSERT(this->fMatrix->IsValid());
00528    R__ASSERT(mt->IsValid());
00529 
00530    if (this->GetNdiags() != md.GetNdiags()) {
00531       Error("operator=(const TMatrixTDiag_const &)","diagonals not compatible");
00532       return;
00533    }
00534 
00535    Element *dp1 = const_cast<Element *>(this->fPtr);
00536    const Element *dp2 = md.GetPtr();
00537    for (Int_t i = 0; i < this->fNdiag; i++, dp1 += this->fInc, dp2 += md.GetInc())
00538       *dp1 = *dp2;
00539 }
00540 
00541 //______________________________________________________________________________
00542 template<class Element>
00543 void TMatrixTDiag<Element>::operator=(const TVectorT<Element> &vec)
00544 {
00545 // Assign a vector to the matrix diagonal.
00546 
00547    R__ASSERT(this->fMatrix->IsValid());
00548    R__ASSERT(vec.IsValid());
00549 
00550    if (this->fNdiag != vec.GetNrows()) {
00551       Error("operator=(const TVectorT &)","vector length != matrix-diagonal length");
00552       return;
00553    }
00554 
00555    Element *dp = const_cast<Element *>(this->fPtr);
00556    const Element *vp = vec.GetMatrixArray();
00557    for ( ; vp < vec.GetMatrixArray()+vec.GetNrows(); dp += this->fInc)
00558       *dp = *vp++;
00559 }
00560 
00561 //______________________________________________________________________________
00562 template<class Element>
00563 void TMatrixTDiag<Element>::operator+=(const TMatrixTDiag_const<Element> &md)
00564 {
00565 // Add to every element of the matrix diagonal the
00566 // corresponding element of diagonal md.
00567 
00568    const TMatrixTBase<Element> *mt = md.GetMatrix();
00569 
00570    R__ASSERT(this->fMatrix->IsValid());
00571    R__ASSERT(mt->IsValid());
00572    if (this->fNdiag != md.GetNdiags()) {
00573       Error("operator=(const TMatrixTDiag_const &)","matrix-diagonal's different length");
00574       return;
00575    }
00576 
00577    Element *dp1 = const_cast<Element *>(this->fPtr);
00578    const Element *dp2 = md.GetPtr();
00579    for (Int_t i = 0; i < this->fNdiag; i++, dp1 += this->fInc, dp2 += md.GetInc())
00580       *dp1 += *dp2;
00581 }
00582 
00583 //______________________________________________________________________________
00584 template<class Element>
00585 void TMatrixTDiag<Element>::operator*=(const TMatrixTDiag_const<Element> &md)
00586 {
00587 // Multiply every element of the matrix diagonal with the
00588 // corresponding element of diagonal md.
00589 
00590    const TMatrixTBase<Element> *mt = md.GetMatrix();
00591 
00592    R__ASSERT(this->fMatrix->IsValid());
00593    R__ASSERT(mt->IsValid());
00594    if (this->fNdiag != md.GetNdiags()) {
00595       Error("operator*=(const TMatrixTDiag_const &)","matrix-diagonal's different length");
00596       return;
00597    }
00598 
00599    Element *dp1 = const_cast<Element *>(this->fPtr);
00600    const Element *dp2 = md.GetPtr();
00601    for (Int_t i = 0; i < this->fNdiag; i++, dp1 += this->fInc, dp2 += md.GetInc())
00602       *dp1 *= *dp2;
00603 }
00604 
00605 //______________________________________________________________________________
00606 template<class Element>
00607 TMatrixTFlat_const<Element>::TMatrixTFlat_const(const TMatrixT<Element> &matrix)
00608 {
00609 // Constructor
00610 
00611    R__ASSERT(matrix.IsValid());
00612 
00613    fMatrix = &matrix;
00614    fPtr    = matrix.GetMatrixArray();
00615    fNelems = matrix.GetNoElements();
00616 }
00617 
00618 //______________________________________________________________________________
00619 template<class Element>
00620 TMatrixTFlat_const<Element>::TMatrixTFlat_const(const TMatrixTSym<Element> &matrix)
00621 {
00622 // Constructor
00623 
00624    R__ASSERT(matrix.IsValid());
00625 
00626    fMatrix = &matrix;
00627    fPtr    = matrix.GetMatrixArray();
00628    fNelems = matrix.GetNoElements();
00629 }
00630 
00631 //______________________________________________________________________________
00632 template<class Element>
00633 TMatrixTFlat<Element>::TMatrixTFlat(TMatrixT<Element> &matrix)
00634              :TMatrixTFlat_const<Element>(matrix)
00635 {
00636 // Constructor
00637 }
00638 
00639 //______________________________________________________________________________
00640 template<class Element>
00641 TMatrixTFlat<Element>::TMatrixTFlat(TMatrixTSym<Element> &matrix)
00642              :TMatrixTFlat_const<Element>(matrix)
00643 {
00644 // Constructor
00645 }
00646 
00647 //______________________________________________________________________________
00648 template<class Element>
00649 TMatrixTFlat<Element>::TMatrixTFlat(const TMatrixTFlat<Element> &mf) : TMatrixTFlat_const<Element>(mf)
00650 {
00651 // Copy constructor
00652 
00653    *this = mf;
00654 }
00655 
00656 //______________________________________________________________________________
00657 template<class Element>
00658 void TMatrixTFlat<Element>::operator=(Element val)
00659 {
00660 // Assign val to every element of the matrix.
00661 
00662    R__ASSERT(this->fMatrix->IsValid());
00663    Element *fp = const_cast<Element *>(this->fPtr);
00664    while (fp < this->fPtr+this->fMatrix->GetNoElements())
00665       *fp++ = val;
00666 }
00667 
00668 //______________________________________________________________________________
00669 template<class Element>
00670 void TMatrixTFlat<Element>::operator+=(Element val)
00671 {
00672 // Add val to every element of the matrix.
00673 
00674    R__ASSERT(this->fMatrix->IsValid());
00675    Element *fp = const_cast<Element *>(this->fPtr);
00676    while (fp < this->fPtr+this->fMatrix->GetNoElements())
00677       *fp++ += val;
00678 }
00679 
00680 //______________________________________________________________________________
00681 template<class Element>
00682 void TMatrixTFlat<Element>::operator*=(Element val)
00683 {
00684 // Multiply every element of the matrix with val.
00685 
00686    R__ASSERT(this->fMatrix->IsValid());
00687    Element *fp = const_cast<Element *>(this->fPtr);
00688    while (fp < this->fPtr+this->fMatrix->GetNoElements())
00689       *fp++ *= val;
00690 }
00691 
00692 //______________________________________________________________________________
00693 template<class Element>
00694 void TMatrixTFlat<Element>::operator=(const TMatrixTFlat_const<Element> &mf)
00695 {
00696 // Assignment operator
00697 
00698    const TMatrixTBase<Element> *mt = mf.GetMatrix();
00699    if (this->fMatrix->GetMatrixArray() == mt->GetMatrixArray()) return;
00700 
00701    R__ASSERT(this->fMatrix->IsValid());
00702    R__ASSERT(mt->IsValid());
00703    if (this->fMatrix->GetNoElements() != mt->GetNoElements()) {
00704       Error("operator=(const TMatrixTFlat_const &)","matrix lengths different");
00705       return;
00706    }
00707 
00708    Element *fp1 = const_cast<Element *>(this->fPtr);
00709    const Element *fp2 = mf.GetPtr();
00710    while (fp1 < this->fPtr+this->fMatrix->GetNoElements())
00711       *fp1++ = *fp2++;
00712 }
00713 
00714 //______________________________________________________________________________
00715 template<class Element>
00716 void TMatrixTFlat<Element>::operator=(const TVectorT<Element> &vec)
00717 {
00718 // Assign a vector to the matrix. The matrix is traversed row-wise
00719 
00720    R__ASSERT(vec.IsValid());
00721 
00722    if (this->fMatrix->GetNoElements() != vec.GetNrows()) {
00723       Error("operator=(const TVectorT &)","vector length != # matrix-elements");
00724       return;
00725    }
00726 
00727    Element *fp = const_cast<Element *>(this->fPtr);
00728    const Element *vp = vec.GetMatrixArray();
00729    while (fp < this->fPtr+this->fMatrix->GetNoElements())
00730        *fp++ = *vp++;
00731 }
00732 
00733 //______________________________________________________________________________
00734 template<class Element>
00735 void TMatrixTFlat<Element>::operator+=(const TMatrixTFlat_const<Element> &mf)
00736 {
00737 // Add to every element of the matrix the corresponding element of matrix mf.
00738 
00739    const TMatrixTBase<Element> *mt = mf.GetMatrix();
00740 
00741    R__ASSERT(this->fMatrix->IsValid());
00742    R__ASSERT(mt->IsValid());
00743    if (this->fMatrix->GetNoElements() != mt->GetNoElements()) {
00744       Error("operator+=(const TMatrixTFlat_const &)","matrices lengths different");
00745       return;
00746    }
00747 
00748    Element *fp1 = const_cast<Element *>(this->fPtr);
00749    const Element *fp2 = mf.GetPtr();
00750    while (fp1 < this->fPtr + this->fMatrix->GetNoElements())
00751       *fp1++ += *fp2++;
00752 }
00753 
00754 //______________________________________________________________________________
00755 template<class Element>
00756 void TMatrixTFlat<Element>::operator*=(const TMatrixTFlat_const<Element> &mf)
00757 {
00758 // Multiply every element of the matrix with the corresponding element of diagonal mf.
00759 
00760    const TMatrixTBase<Element> *mt = mf.GetMatrix();
00761 
00762    R__ASSERT(this->fMatrix->IsValid());
00763    R__ASSERT(mt->IsValid());
00764    if (this->fMatrix->GetNoElements() != mt->GetNoElements()) {
00765       Error("operator*=(const TMatrixTFlat_const &)","matrices lengths different");
00766       return;
00767    }
00768 
00769    Element *fp1 = const_cast<Element *>(this->fPtr);
00770    const Element *fp2 = mf.GetPtr();
00771    while (fp1 < this->fPtr + this->fMatrix->GetNoElements())
00772       *fp1++ *= *fp2++;
00773 }
00774 
00775 //______________________________________________________________________________
00776 template<class Element>
00777 TMatrixTSub_const<Element>::TMatrixTSub_const(const TMatrixT<Element> &matrix,Int_t row_lwbs,Int_t row_upbs,
00778                                               Int_t col_lwbs,Int_t col_upbs)
00779 {
00780 // make a reference to submatrix [row_lwbs..row_upbs][col_lwbs..col_upbs];
00781 // The indexing range of the reference is
00782 // [0..row_upbs-row_lwbs+1][0..col_upb-col_lwbs+1] (default)
00783 
00784    R__ASSERT(matrix.IsValid());
00785 
00786    fRowOff    = 0;
00787    fColOff    = 0;
00788    fNrowsSub  = 0;
00789    fNcolsSub  = 0;
00790    fMatrix = &matrix;
00791 
00792    if (row_upbs < row_lwbs) {
00793       Error("TMatrixTSub_const","Request sub-matrix with row_upbs(%d) < row_lwbs(%d)",row_upbs,row_lwbs);
00794       return;
00795    }
00796    if (col_upbs < col_lwbs) {
00797       Error("TMatrixTSub_const","Request sub-matrix with col_upbs(%d) < col_lwbs(%d)",col_upbs,col_lwbs);
00798       return;
00799    }
00800 
00801    const Int_t rowLwb = matrix.GetRowLwb();
00802    const Int_t rowUpb = matrix.GetRowUpb();
00803    const Int_t colLwb = matrix.GetColLwb();
00804    const Int_t colUpb = matrix.GetColUpb();
00805 
00806    if (row_lwbs < rowLwb || row_lwbs > rowUpb) {
00807       Error("TMatrixTSub_const","Request row_lwbs sub-matrix(%d) outside matrix range of %d - %d",row_lwbs,rowLwb,rowUpb);
00808       return;
00809    }
00810    if (col_lwbs < colLwb || col_lwbs > colUpb) {
00811       Error("TMatrixTSub_const","Request col_lwbs sub-matrix(%d) outside matrix range of %d - %d",col_lwbs,colLwb,colUpb);
00812       return;
00813    }
00814    if (row_upbs < rowLwb || row_upbs > rowUpb) {
00815       Error("TMatrixTSub_const","Request row_upbs sub-matrix(%d) outside matrix range of %d - %d",row_upbs,rowLwb,rowUpb);
00816       return;
00817    }
00818    if (col_upbs < colLwb || col_upbs > colUpb) {
00819       Error("TMatrixTSub_const","Request col_upbs sub-matrix(%d) outside matrix range of %d - %d",col_upbs,colLwb,colUpb);
00820       return;
00821    }
00822 
00823    fRowOff    = row_lwbs-rowLwb;
00824    fColOff    = col_lwbs-colLwb;
00825    fNrowsSub  = row_upbs-row_lwbs+1;
00826    fNcolsSub  = col_upbs-col_lwbs+1;
00827 }
00828 
00829 //______________________________________________________________________________
00830 template<class Element>
00831 TMatrixTSub_const<Element>::TMatrixTSub_const(const TMatrixTSym<Element> &matrix,Int_t row_lwbs,Int_t row_upbs,
00832                                               Int_t col_lwbs,Int_t col_upbs)
00833 {
00834 // make a reference to submatrix [row_lwbs..row_upbs][col_lwbs..col_upbs];
00835 // The indexing range of the reference is
00836 // [0..row_upbs-row_lwbs+1][0..col_upb-col_lwbs+1] (default)
00837 
00838    R__ASSERT(matrix.IsValid());
00839 
00840    fRowOff    = 0;
00841    fColOff    = 0;
00842    fNrowsSub  = 0;
00843    fNcolsSub  = 0;
00844    fMatrix    = &matrix;
00845 
00846    if (row_upbs < row_lwbs) {
00847       Error("TMatrixTSub_const","Request sub-matrix with row_upbs(%d) < row_lwbs(%d)",row_upbs,row_lwbs);
00848       return;
00849    }
00850    if (col_upbs < col_lwbs) {
00851       Error("TMatrixTSub_const","Request sub-matrix with col_upbs(%d) < col_lwbs(%d)",col_upbs,col_lwbs);
00852       return;
00853    }
00854 
00855    const Int_t rowLwb = matrix.GetRowLwb();
00856    const Int_t rowUpb = matrix.GetRowUpb();
00857    const Int_t colLwb = matrix.GetColLwb();
00858    const Int_t colUpb = matrix.GetColUpb();
00859 
00860    if (row_lwbs < rowLwb || row_lwbs > rowUpb) {
00861       Error("TMatrixTSub_const","Request row_lwbs sub-matrix(%d) outside matrix range of %d - %d",row_lwbs,rowLwb,rowUpb);
00862       return;
00863    }
00864    if (col_lwbs < colLwb || col_lwbs > colUpb) {
00865       Error("TMatrixTSub_const","Request col_lwbs sub-matrix(%d) outside matrix range of %d - %d",col_lwbs,colLwb,colUpb);
00866       return;
00867    }
00868    if (row_upbs < rowLwb || row_upbs > rowUpb) {
00869       Error("TMatrixTSub_const","Request row_upbs sub-matrix(%d) outside matrix range of %d - %d",row_upbs,rowLwb,rowUpb);
00870       return;
00871    }
00872    if (col_upbs < colLwb || col_upbs > colUpb) {
00873       Error("TMatrixTSub_const","Request col_upbs sub-matrix(%d) outside matrix range of %d - %d",col_upbs,colLwb,colUpb);
00874       return;
00875    }
00876 
00877    fRowOff    = row_lwbs-rowLwb;
00878    fColOff    = col_lwbs-colLwb;
00879    fNrowsSub  = row_upbs-row_lwbs+1;
00880    fNcolsSub  = col_upbs-col_lwbs+1;
00881 }
00882 
00883 //______________________________________________________________________________
00884 template<class Element>
00885 TMatrixTSub<Element>::TMatrixTSub(TMatrixT<Element> &matrix,Int_t row_lwbs,Int_t row_upbs,
00886                                   Int_t col_lwbs,Int_t col_upbs)
00887             :TMatrixTSub_const<Element>(matrix,row_lwbs,row_upbs,col_lwbs,col_upbs)
00888 {
00889 // Constructor
00890 }
00891 
00892 //______________________________________________________________________________
00893 template<class Element>
00894 TMatrixTSub<Element>::TMatrixTSub(TMatrixTSym<Element> &matrix,Int_t row_lwbs,Int_t row_upbs,
00895                                   Int_t col_lwbs,Int_t col_upbs)
00896             :TMatrixTSub_const<Element>(matrix,row_lwbs,row_upbs,col_lwbs,col_upbs)
00897 {
00898 // Constructor
00899 }
00900 
00901 //______________________________________________________________________________
00902 template<class Element>
00903 TMatrixTSub<Element>::TMatrixTSub(const TMatrixTSub<Element> &ms) : TMatrixTSub_const<Element>(ms)
00904 {
00905 // Copy constructor
00906 
00907    *this = ms;
00908 }
00909 
00910 //______________________________________________________________________________
00911 template<class Element>
00912 void TMatrixTSub<Element>::Rank1Update(const TVectorT<Element> &v,Element alpha)
00913 {
00914 // Perform a rank 1 operation on the matrix:
00915 //     A += alpha * v * v^T
00916 
00917    R__ASSERT(this->fMatrix->IsValid());
00918    R__ASSERT(v.IsValid());
00919 
00920    if (v.GetNoElements() < TMath::Max(this->fNrowsSub,this->fNcolsSub)) {
00921       Error("Rank1Update","vector too short");
00922       return;
00923    }
00924 
00925    const Element * const pv = v.GetMatrixArray();
00926          Element *mp = (const_cast<TMatrixTBase<Element> *>(this->fMatrix))->GetMatrixArray();
00927 
00928    const Int_t ncols = this->fMatrix->GetNcols();
00929    for (Int_t irow = 0; irow < this->fNrowsSub; irow++) {
00930       const Int_t off = (irow+this->fRowOff)*ncols+this->fColOff;
00931       const Element tmp = alpha*pv[irow];
00932       for (Int_t icol = 0; icol < this->fNcolsSub; icol++)
00933          mp[off+icol] += tmp*pv[icol];
00934    }
00935 }
00936 
00937 //______________________________________________________________________________
00938 template<class Element>
00939 void TMatrixTSub<Element>::operator=(Element val)
00940 {
00941 // Assign val to every element of the sub matrix.
00942 
00943    R__ASSERT(this->fMatrix->IsValid());
00944 
00945    Element *p = (const_cast<TMatrixTBase<Element> *>(this->fMatrix))->GetMatrixArray();
00946    const Int_t ncols = this->fMatrix->GetNcols();
00947    for (Int_t irow = 0; irow < this->fNrowsSub; irow++) {
00948       const Int_t off = (irow+this->fRowOff)*ncols+this->fColOff;
00949       for (Int_t icol = 0; icol < this->fNcolsSub; icol++)
00950          p[off+icol] = val;
00951    }
00952 }
00953 
00954 //______________________________________________________________________________
00955 template<class Element>
00956 void TMatrixTSub<Element>::operator+=(Element val)
00957 {
00958 // Add val to every element of the sub matrix.
00959 
00960    R__ASSERT(this->fMatrix->IsValid());
00961 
00962    Element *p = (const_cast<TMatrixTBase<Element> *>(this->fMatrix))->GetMatrixArray();
00963    const Int_t ncols = this->fMatrix->GetNcols();
00964    for (Int_t irow = 0; irow < this->fNrowsSub; irow++) {
00965       const Int_t off = (irow+this->fRowOff)*ncols+this->fColOff;
00966       for (Int_t icol = 0; icol < this->fNcolsSub; icol++)
00967          p[off+icol] += val;
00968    }
00969 }
00970 
00971 //______________________________________________________________________________
00972 template<class Element>
00973 void TMatrixTSub<Element>::operator*=(Element val)
00974 {
00975 // Multiply every element of the sub matrix by val .
00976 
00977    R__ASSERT(this->fMatrix->IsValid());
00978 
00979    Element *p = (const_cast<TMatrixTBase<Element> *>(this->fMatrix))->GetMatrixArray();
00980    const Int_t ncols = this->fMatrix->GetNcols();
00981    for (Int_t irow = 0; irow < this->fNrowsSub; irow++) {
00982       const Int_t off = (irow+this->fRowOff)*ncols+this->fColOff;
00983       for (Int_t icol = 0; icol < this->fNcolsSub; icol++)
00984          p[off+icol] *= val;
00985    }
00986 }
00987 
00988 //______________________________________________________________________________
00989 template<class Element>
00990 void TMatrixTSub<Element>::operator=(const TMatrixTSub_const<Element> &ms)
00991 {
00992 // Assignment operator
00993 
00994    const TMatrixTBase<Element> *mt = ms.GetMatrix();
00995 
00996    R__ASSERT(this->fMatrix->IsValid());
00997    R__ASSERT(mt->IsValid());
00998 
00999    if (this->fMatrix == mt &&
01000        (this->GetNrows()  == ms.GetNrows () && this->GetNcols()  == ms.GetNcols () &&
01001         this->GetRowOff() == ms.GetRowOff() && this->GetColOff() == ms.GetColOff()) )
01002      return;
01003 
01004    if (this->GetNrows() != ms.GetNrows() || this->GetNcols() != ms.GetNcols()) {
01005      Error("operator=(const TMatrixTSub_const &)","sub matrices have different size");
01006       return;
01007    }
01008 
01009    const Int_t rowOff2 = ms.GetRowOff();
01010    const Int_t colOff2 = ms.GetColOff();
01011 
01012    Bool_t overlap = (this->fMatrix == mt) &&
01013                     ( (rowOff2 >= this->fRowOff && rowOff2 < this->fRowOff+this->fNrowsSub) ||
01014                       (colOff2 >= this->fColOff && colOff2 < this->fColOff+this->fNcolsSub) );
01015 
01016    Element *p1 = const_cast<Element *>(this->fMatrix->GetMatrixArray());
01017    if (!overlap) {
01018       const Element *p2 = mt->GetMatrixArray();
01019 
01020       const Int_t ncols1 = this->fMatrix->GetNcols();
01021       const Int_t ncols2 = mt->GetNcols();
01022       for (Int_t irow = 0; irow < this->fNrowsSub; irow++) {
01023          const Int_t off1 = (irow+this->fRowOff)*ncols1+this->fColOff;
01024          const Int_t off2 = (irow+rowOff2)*ncols2+colOff2;
01025          for (Int_t icol = 0; icol < this->fNcolsSub; icol++)
01026             p1[off1+icol] = p2[off2+icol];
01027       }
01028    } else {
01029       const Int_t row_lwbs = rowOff2+mt->GetRowLwb();
01030       const Int_t row_upbs = row_lwbs+this->fNrowsSub-1;
01031       const Int_t col_lwbs = colOff2+mt->GetColLwb();
01032       const Int_t col_upbs = col_lwbs+this->fNcolsSub-1;
01033       TMatrixT<Element> tmp; mt->GetSub(row_lwbs,row_upbs,col_lwbs,col_upbs,tmp);
01034       const Element *p2 = tmp.GetMatrixArray();
01035 
01036       const Int_t ncols1 = this->fMatrix->GetNcols();
01037       const Int_t ncols2 = tmp.GetNcols();
01038       for (Int_t irow = 0; irow < this->fNrowsSub; irow++) {
01039          const Int_t off1 = (irow+this->fRowOff)*ncols1+this->fColOff;
01040          const Int_t off2 = irow*ncols2;
01041          for (Int_t icol = 0; icol < this->fNcolsSub; icol++)
01042             p1[off1+icol] = p2[off2+icol];
01043       }
01044    }
01045 }
01046 
01047 //______________________________________________________________________________
01048 template<class Element>
01049 void TMatrixTSub<Element>::operator=(const TMatrixTBase<Element> &m)
01050 {
01051 // Assignment operator
01052 
01053    R__ASSERT(this->fMatrix->IsValid());
01054    R__ASSERT(m.IsValid());
01055 
01056    if (this->fMatrix->GetMatrixArray() == m.GetMatrixArray()) return;
01057 
01058    if (this->fNrowsSub != m.GetNrows() || this->fNcolsSub != m.GetNcols()) {
01059       Error("operator=(const TMatrixTBase<Element> &)","sub matrices and matrix have different size");
01060       return;
01061    }
01062    const Int_t row_lwbs = this->fRowOff+this->fMatrix->GetRowLwb();
01063    const Int_t col_lwbs = this->fColOff+this->fMatrix->GetColLwb();
01064    (const_cast<TMatrixTBase<Element> *>(this->fMatrix))->SetSub(row_lwbs,col_lwbs,m);
01065 }
01066 
01067 //______________________________________________________________________________
01068 template<class Element>
01069 void TMatrixTSub<Element>::operator+=(const TMatrixTSub_const<Element> &ms)
01070 {
01071 // Add to every element of the submatrix the corresponding element of submatrix ms.
01072 
01073    const TMatrixTBase<Element> *mt = ms.GetMatrix();
01074 
01075    R__ASSERT(this->fMatrix->IsValid());
01076    R__ASSERT(mt->IsValid());
01077 
01078    if (this->GetNrows() != ms.GetNrows() || this->GetNcols() != ms.GetNcols()) {
01079       Error("operator+=(const TMatrixTSub_const &)","sub matrices have different size");
01080       return;
01081    }
01082 
01083    const Int_t rowOff2 = ms.GetRowOff();
01084    const Int_t colOff2 = ms.GetColOff();
01085 
01086    Bool_t overlap = (this->fMatrix == mt) &&
01087                     ( (rowOff2 >= this->fRowOff && rowOff2 < this->fRowOff+this->fNrowsSub) ||
01088                       (colOff2 >= this->fColOff && colOff2 < this->fColOff+this->fNcolsSub) );
01089 
01090    Element *p1 = const_cast<Element *>(this->fMatrix->GetMatrixArray());
01091    if (!overlap) {
01092       const Element *p2 = mt->GetMatrixArray();
01093 
01094       const Int_t ncols1 = this->fMatrix->GetNcols();
01095       const Int_t ncols2 = mt->GetNcols();
01096       for (Int_t irow = 0; irow < this->fNrowsSub; irow++) {
01097          const Int_t off1 = (irow+this->fRowOff)*ncols1+this->fColOff;
01098          const Int_t off2 = (irow+rowOff2)*ncols2+colOff2;
01099          for (Int_t icol = 0; icol < this->fNcolsSub; icol++)
01100             p1[off1+icol] += p2[off2+icol];
01101       }
01102    } else {
01103       const Int_t row_lwbs = rowOff2+mt->GetRowLwb();
01104       const Int_t row_upbs = row_lwbs+this->fNrowsSub-1;
01105       const Int_t col_lwbs = colOff2+mt->GetColLwb();
01106       const Int_t col_upbs = col_lwbs+this->fNcolsSub-1;
01107       TMatrixT<Element> tmp; mt->GetSub(row_lwbs,row_upbs,col_lwbs,col_upbs,tmp);
01108       const Element *p2 = tmp.GetMatrixArray();
01109 
01110       const Int_t ncols1 = this->fMatrix->GetNcols();
01111       const Int_t ncols2 = tmp.GetNcols();
01112       for (Int_t irow = 0; irow < this->fNrowsSub; irow++) {
01113          const Int_t off1 = (irow+this->fRowOff)*ncols1+this->fColOff;
01114          const Int_t off2 = irow*ncols2;
01115          for (Int_t icol = 0; icol < this->fNcolsSub; icol++)
01116             p1[off1+icol] += p2[off2+icol];
01117       }
01118    }
01119 }
01120 
01121 //______________________________________________________________________________
01122 template<class Element>
01123 void TMatrixTSub<Element>::operator*=(const TMatrixTSub_const<Element> &ms)
01124 {
01125 // Multiply submatrix with submatrix ms.
01126 
01127    if (this->fNcolsSub != ms.GetNrows() || this->fNcolsSub != ms.GetNcols()) {
01128       Error("operator*=(const TMatrixTSub_const &)","source sub matrix has wrong shape");
01129       return;
01130    }
01131 
01132    const TMatrixTBase<Element> *source = ms.GetMatrix();
01133 
01134    TMatrixT<Element> source_sub;
01135    {
01136       const Int_t row_lwbs = ms.GetRowOff()+source->GetRowLwb();
01137       const Int_t row_upbs = row_lwbs+this->fNrowsSub-1;
01138       const Int_t col_lwbs = ms.GetColOff()+source->GetColLwb();
01139       const Int_t col_upbs = col_lwbs+this->fNcolsSub-1;
01140       source->GetSub(row_lwbs,row_upbs,col_lwbs,col_upbs,source_sub);
01141    }
01142 
01143    const Element *sp = source_sub.GetMatrixArray();
01144    const Int_t ncols = this->fMatrix->GetNcols();
01145 
01146    // One row of the old_target matrix
01147    Element work[kWorkMax];
01148    Bool_t isAllocated = kFALSE;
01149    Element *trp = work;
01150    if (this->fNcolsSub > kWorkMax) {
01151       isAllocated = kTRUE;
01152       trp = new Element[this->fNcolsSub];
01153    }
01154 
01155          Element *cp   = const_cast<Element *>(this->fMatrix->GetMatrixArray())+this->fRowOff*ncols+this->fColOff;
01156    const Element *trp0 = cp; // Pointer to  target[i,0];
01157    const Element * const trp0_last = trp0+this->fNrowsSub*ncols;
01158    while (trp0 < trp0_last) {
01159       memcpy(trp,trp0,this->fNcolsSub*sizeof(Element));         // copy the i-th row of target, Start at target[i,0]
01160       for (const Element *scp = sp; scp < sp+this->fNcolsSub; ) {  // Pointer to the j-th column of source,
01161                                                                  // Start scp = source[0,0]
01162          Element cij = 0;
01163          for (Int_t j = 0; j < this->fNcolsSub; j++) {
01164             cij += trp[j] * *scp;                            // the j-th col of source
01165             scp += this->fNcolsSub;
01166          }
01167          *cp++ = cij;
01168          scp -= source_sub.GetNoElements()-1;               // Set bcp to the (j+1)-th col
01169       }
01170       cp   += ncols-this->fNcolsSub;
01171       trp0 += ncols;                                      // Set trp0 to the (i+1)-th row
01172       R__ASSERT(trp0 == cp);
01173    }
01174 
01175    R__ASSERT(cp == trp0_last && trp0 == trp0_last);
01176    if (isAllocated)
01177       delete [] trp;
01178 }
01179 
01180 //______________________________________________________________________________
01181 template<class Element>
01182 void TMatrixTSub<Element>::operator+=(const TMatrixTBase<Element> &mt)
01183 {
01184 // Add to every element of the submatrix the corresponding element of matrix mt.
01185 
01186    R__ASSERT(this->fMatrix->IsValid());
01187    R__ASSERT(mt.IsValid());
01188 
01189    if (this->GetNrows() != mt.GetNrows() || this->GetNcols() != mt.GetNcols()) {
01190       Error("operator+=(const TMatrixTBase<Element> &)","sub matrix and matrix have different size");
01191       return;
01192    }
01193 
01194    Element *p1 = const_cast<Element *>(this->fMatrix->GetMatrixArray());
01195    const Element *p2 = mt.GetMatrixArray();
01196 
01197    const Int_t ncols1 = this->fMatrix->GetNcols();
01198    const Int_t ncols2 = mt.GetNcols();
01199    for (Int_t irow = 0; irow < this->fNrowsSub; irow++) {
01200       const Int_t off1 = (irow+this->fRowOff)*ncols1+this->fColOff;
01201       const Int_t off2 = irow*ncols2;
01202       for (Int_t icol = 0; icol < this->fNcolsSub; icol++)
01203          p1[off1+icol] += p2[off2+icol];
01204    }
01205 }
01206 
01207 //______________________________________________________________________________
01208 template<class Element>
01209 void TMatrixTSub<Element>::operator*=(const TMatrixT<Element> &source)
01210 {
01211 // Multiply submatrix with matrix source.
01212 
01213    if (this->fNcolsSub != source.GetNrows() || this->fNcolsSub != source.GetNcols()) {
01214       Error("operator*=(const TMatrixT<Element> &)","source matrix has wrong shape");
01215       return;
01216    }
01217 
01218    // Check for A *= A;
01219    const Element *sp;
01220    TMatrixT<Element> tmp;
01221    if (this->fMatrix->GetMatrixArray() == source.GetMatrixArray()) {
01222       tmp.ResizeTo(source);
01223       tmp = source;
01224       sp = tmp.GetMatrixArray();
01225    }
01226    else
01227       sp = source.GetMatrixArray();
01228 
01229    const Int_t ncols = this->fMatrix->GetNcols();
01230 
01231    // One row of the old_target matrix
01232    Element work[kWorkMax];
01233    Bool_t isAllocated = kFALSE;
01234     Element *trp = work;
01235    if (this->fNcolsSub > kWorkMax) {
01236       isAllocated = kTRUE;
01237       trp = new Element[this->fNcolsSub];
01238    }
01239 
01240          Element *cp   = const_cast<Element *>(this->fMatrix->GetMatrixArray())+this->fRowOff*ncols+this->fColOff;
01241    const Element *trp0 = cp;                               // Pointer to  target[i,0];
01242    const Element * const trp0_last = trp0+this->fNrowsSub*ncols;
01243    while (trp0 < trp0_last) {
01244       memcpy(trp,trp0,this->fNcolsSub*sizeof(Element));           // copy the i-th row of target, Start at target[i,0]
01245       for (const Element *scp = sp; scp < sp+this->fNcolsSub; ) { // Pointer to the j-th column of source,
01246                                                                   // Start scp = source[0,0]
01247          Element cij = 0;
01248          for (Int_t j = 0; j < this->fNcolsSub; j++) {
01249             cij += trp[j] * *scp;                              // the j-th col of source
01250             scp += this->fNcolsSub;
01251          }
01252          *cp++ = cij;
01253          scp -= source.GetNoElements()-1;                    // Set bcp to the (j+1)-th col
01254       }
01255       cp   += ncols-this->fNcolsSub;
01256       trp0 += ncols;                                        // Set trp0 to the (i+1)-th row
01257       R__ASSERT(trp0 == cp);
01258    }
01259  
01260    R__ASSERT(cp == trp0_last && trp0 == trp0_last);
01261    if (isAllocated)
01262       delete [] trp;
01263 }
01264 
01265 //______________________________________________________________________________
01266 template<class Element>
01267 void TMatrixTSub<Element>::operator*=(const TMatrixTSym<Element> &source)
01268 {
01269 // Multiply submatrix with matrix source.
01270 
01271    if (this->fNcolsSub != source.GetNrows() || this->fNcolsSub != source.GetNcols()) {
01272       Error("operator*=(const TMatrixTSym<Element> &)","source matrix has wrong shape");
01273       return;
01274    }
01275 
01276    // Check for A *= A;
01277    const Element *sp;
01278    TMatrixTSym<Element> tmp;
01279    if (this->fMatrix->GetMatrixArray() == source.GetMatrixArray()) {
01280       tmp.ResizeTo(source);
01281       tmp = source;
01282       sp = tmp.GetMatrixArray();
01283    }
01284    else
01285       sp = source.GetMatrixArray();
01286 
01287    const Int_t ncols = this->fMatrix->GetNcols();
01288 
01289    // One row of the old_target matrix
01290    Element work[kWorkMax];
01291    Bool_t isAllocated = kFALSE;
01292    Element *trp = work;
01293    if (this->fNcolsSub > kWorkMax) {
01294       isAllocated = kTRUE;
01295       trp = new Element[this->fNcolsSub];
01296    }
01297 
01298          Element *cp   = const_cast<Element *>(this->fMatrix->GetMatrixArray())+this->fRowOff*ncols+this->fColOff;
01299    const Element *trp0 = cp;                               // Pointer to  target[i,0];
01300    const Element * const trp0_last = trp0+this->fNrowsSub*ncols;
01301    while (trp0 < trp0_last) {
01302       memcpy(trp,trp0,this->fNcolsSub*sizeof(Element));           // copy the i-th row of target, Start at target[i,0]
01303       for (const Element *scp = sp; scp < sp+this->fNcolsSub; ) { // Pointer to the j-th column of source,
01304                                                                 // Start scp = source[0,0]
01305          Element cij = 0;
01306          for (Int_t j = 0; j < this->fNcolsSub; j++) {
01307             cij += trp[j] * *scp;                              // the j-th col of source
01308             scp += this->fNcolsSub;
01309          }
01310          *cp++ = cij;
01311          scp -= source.GetNoElements()-1;                     // Set bcp to the (j+1)-th col
01312       }
01313       cp   += ncols-this->fNcolsSub;
01314       trp0 += ncols;                                         // Set trp0 to the (i+1)-th row
01315       R__ASSERT(trp0 == cp);
01316    }
01317 
01318    R__ASSERT(cp == trp0_last && trp0 == trp0_last);
01319    if (isAllocated)
01320       delete [] trp;
01321 }
01322 
01323 //______________________________________________________________________________
01324 template<class Element>
01325 TMatrixTSparseRow_const<Element>::TMatrixTSparseRow_const(const TMatrixTSparse<Element> &matrix,Int_t row)
01326 {
01327 // Constructor with row "row" of matrix
01328 
01329    R__ASSERT(matrix.IsValid());
01330 
01331    fRowInd = row-matrix.GetRowLwb();
01332    if (fRowInd >= matrix.GetNrows() || fRowInd < 0) {
01333       Error("TMatrixTSparseRow_const(const TMatrixTSparse &,Int_t)","row index out of bounds");
01334       fMatrix  = 0;
01335       fNindex  = 0;
01336       fColPtr  = 0;
01337       fDataPtr = 0;
01338       return;
01339    }
01340 
01341    const Int_t sIndex = matrix.GetRowIndexArray()[fRowInd];
01342    const Int_t eIndex = matrix.GetRowIndexArray()[fRowInd+1];
01343    fMatrix  = &matrix;
01344    fNindex  = eIndex-sIndex;
01345    fColPtr  = matrix.GetColIndexArray()+sIndex;
01346    fDataPtr = matrix.GetMatrixArray()+sIndex;
01347 }
01348 
01349 //______________________________________________________________________________
01350 template<class Element>
01351 Element TMatrixTSparseRow_const<Element>::operator()(Int_t i) const
01352 {
01353   R__ASSERT(fMatrix->IsValid());
01354   const Int_t acoln = i-fMatrix->GetColLwb();
01355   if (acoln < fMatrix->GetNcols() && acoln >= 0) {
01356      const Int_t index = TMath::BinarySearch(fNindex,fColPtr,acoln);
01357      if (index >= 0 && fColPtr[index] == acoln) return fDataPtr[index];
01358      else                                       return 0.0;
01359   } else {
01360      Error("operator()","Request col(%d) outside matrix range of %d - %d",
01361                         i,fMatrix->GetColLwb(),fMatrix->GetColLwb()+fMatrix->GetNcols());
01362      return 0.0;
01363   }
01364  }
01365 
01366 //______________________________________________________________________________
01367 template<class Element>
01368 TMatrixTSparseRow<Element>::TMatrixTSparseRow(TMatrixTSparse<Element> &matrix,Int_t row)
01369                                     : TMatrixTSparseRow_const<Element>(matrix,row)
01370 {
01371 // Constructor with row "row" of matrix
01372 }
01373 
01374 //______________________________________________________________________________
01375 template<class Element>
01376 TMatrixTSparseRow<Element>::TMatrixTSparseRow(const TMatrixTSparseRow<Element> &mr)
01377                                     : TMatrixTSparseRow_const<Element>(mr)
01378 {
01379 // Copy constructor
01380 
01381    *this = mr;
01382 }
01383 
01384 //______________________________________________________________________________
01385 template<class Element>
01386 Element TMatrixTSparseRow<Element>::operator()(Int_t i) const
01387 {
01388   R__ASSERT(this->fMatrix->IsValid());
01389   const Int_t acoln = i-this->fMatrix->GetColLwb();
01390   if (acoln < this->fMatrix->GetNcols() && acoln >= 0) {
01391      const Int_t index = TMath::BinarySearch(this->fNindex,this->fColPtr,acoln);
01392      if (index >= 0 && this->fColPtr[index] == acoln) return this->fDataPtr[index];
01393      else                                             return 0.0;
01394   } else {
01395      Error("operator()","Request col(%d) outside matrix range of %d - %d",
01396                         i,this->fMatrix->GetColLwb(),this->fMatrix->GetColLwb()+this->fMatrix->GetNcols());
01397      return 0.0;
01398   }
01399 }
01400 
01401 //______________________________________________________________________________
01402 template<class Element>
01403 Element &TMatrixTSparseRow<Element>::operator()(Int_t i)
01404 {
01405 // operator() : pick element row(i)
01406 
01407    R__ASSERT(this->fMatrix->IsValid());
01408 
01409    const Int_t acoln = i-this->fMatrix->GetColLwb();
01410    if (acoln >= this->fMatrix->GetNcols() || acoln < 0) {
01411       Error("operator()(Int_t","Requested element %d outside range : %d - %d",i,
01412             this->fMatrix->GetColLwb(),this->fMatrix->GetColLwb()+this->fMatrix->GetNcols());
01413       return (const_cast<Element*>(this->fDataPtr))[0];
01414    }
01415 
01416    Int_t index = TMath::BinarySearch(this->fNindex,this->fColPtr,acoln);
01417    if (index >= 0 && this->fColPtr[index] == acoln)
01418       return (const_cast<Element*>(this->fDataPtr))[index];
01419    else {
01420       TMatrixTBase<Element> *mt = const_cast<TMatrixTBase<Element> *>(this->fMatrix);
01421       const Int_t row = this->fRowInd+mt->GetRowLwb();
01422       Element val = 0.;
01423       mt->InsertRow(row,i,&val,1);
01424       const Int_t sIndex = mt->GetRowIndexArray()[this->fRowInd];
01425       const Int_t eIndex = mt->GetRowIndexArray()[this->fRowInd+1];
01426       this->fNindex  = eIndex-sIndex;
01427       this->fColPtr  = mt->GetColIndexArray()+sIndex;
01428       this->fDataPtr = mt->GetMatrixArray()+sIndex;
01429       index = TMath::BinarySearch(this->fNindex,this->fColPtr,acoln);
01430       if (index >= 0 && this->fColPtr[index] == acoln)
01431          return (const_cast<Element*>(this->fDataPtr))[index];
01432       else {
01433          Error("operator()(Int_t","Insert row failed");
01434          return (const_cast<Element*>(this->fDataPtr))[0];
01435       }
01436    }
01437 }
01438 
01439 //______________________________________________________________________________
01440 template<class Element>
01441 void TMatrixTSparseRow<Element>::operator=(Element val)
01442 {
01443 // Assign val to every non-zero (!) element of the matrix row.
01444 
01445    R__ASSERT(this->fMatrix->IsValid());
01446    Element *rp = const_cast<Element *>(this->fDataPtr);
01447    for ( ; rp < this->fDataPtr+this->fNindex; rp++)
01448       *rp = val;
01449 }
01450 
01451 //______________________________________________________________________________
01452 template<class Element>
01453 void TMatrixTSparseRow<Element>::operator+=(Element val)
01454 {
01455 // Add val to every non-zero (!) element of the matrix row.
01456 
01457    R__ASSERT(this->fMatrix->IsValid());
01458    Element *rp = const_cast<Element *>(this->fDataPtr);
01459    for ( ; rp < this->fDataPtr+this->fNindex; rp++)
01460       *rp += val;
01461 }
01462 
01463 //______________________________________________________________________________
01464 template<class Element>
01465 void TMatrixTSparseRow<Element>::operator*=(Element val)
01466 {
01467 // Multiply every element of the matrix row by val.
01468 
01469    R__ASSERT(this->fMatrix->IsValid());
01470    Element *rp = const_cast<Element *>(this->fDataPtr);
01471    for ( ; rp < this->fDataPtr+this->fNindex; rp++)
01472       *rp *= val;
01473 }
01474 
01475 //______________________________________________________________________________
01476 template<class Element>
01477 void TMatrixTSparseRow<Element>::operator=(const TMatrixTSparseRow_const<Element> &mr)
01478 {
01479 // Assignment operator
01480 
01481    const TMatrixTBase<Element> *mt = mr.GetMatrix();
01482    if (this->fMatrix == mt) return;
01483 
01484    R__ASSERT(this->fMatrix->IsValid());
01485    R__ASSERT(mt->IsValid());
01486    if (this->fMatrix->GetColLwb() != mt->GetColLwb() || this->fMatrix->GetNcols() != mt->GetNcols()) {
01487       Error("operator=(const TMatrixTSparseRow_const &)","matrix rows not compatible");
01488       return;
01489    }
01490 
01491    const Int_t ncols = this->fMatrix->GetNcols();
01492    const Int_t row1  = this->fRowInd+this->fMatrix->GetRowLwb();
01493    const Int_t row2  = mr.GetRowIndex()+mt->GetRowLwb();
01494    const Int_t col   = this->fMatrix->GetColLwb();
01495 
01496    TVectorT<Element> v(ncols);
01497    mt->ExtractRow(row2,col,v.GetMatrixArray());
01498    const_cast<TMatrixTBase<Element> *>(this->fMatrix)->InsertRow(row1,col,v.GetMatrixArray());
01499 
01500    const Int_t sIndex = this->fMatrix->GetRowIndexArray()[this->fRowInd];
01501    const Int_t eIndex = this->fMatrix->GetRowIndexArray()[this->fRowInd+1];
01502    this->fNindex  = eIndex-sIndex;
01503    this->fColPtr  = this->fMatrix->GetColIndexArray()+sIndex;
01504    this->fDataPtr = this->fMatrix->GetMatrixArray()+sIndex;
01505 }
01506 
01507 //______________________________________________________________________________
01508 template<class Element>
01509 void TMatrixTSparseRow<Element>::operator=(const TVectorT<Element> &vec)
01510 {
01511 // Assign a vector to a matrix row. The vector is considered row-vector
01512 // to allow the assignment in the strict sense.
01513 
01514    R__ASSERT(this->fMatrix->IsValid());
01515    R__ASSERT(vec.IsValid());
01516 
01517    if (this->fMatrix->GetColLwb() != vec.GetLwb() || this->fMatrix->GetNcols() != vec.GetNrows()) {
01518       Error("operator=(const TVectorT &)","vector length != matrix-row length");
01519       return;
01520    }
01521 
01522    const Element *vp = vec.GetMatrixArray();
01523    const Int_t row = this->fRowInd+this->fMatrix->GetRowLwb();
01524    const Int_t col = this->fMatrix->GetColLwb();
01525    const_cast<TMatrixTBase<Element> *>(this->fMatrix)->InsertRow(row,col,vp,vec.GetNrows());
01526 
01527    const Int_t sIndex = this->fMatrix->GetRowIndexArray()[this->fRowInd];
01528    const Int_t eIndex = this->fMatrix->GetRowIndexArray()[this->fRowInd+1];
01529    this->fNindex  = eIndex-sIndex;
01530    this->fColPtr  = this->fMatrix->GetColIndexArray()+sIndex;
01531    this->fDataPtr = this->fMatrix->GetMatrixArray()+sIndex;
01532 }
01533 
01534 //______________________________________________________________________________
01535 template<class Element>
01536 void TMatrixTSparseRow<Element>::operator+=(const TMatrixTSparseRow_const<Element> &r)
01537 {
01538 // Add to every element of the matrix row the corresponding element of row r.
01539 
01540    const TMatrixTBase<Element> *mt = r.GetMatrix();
01541 
01542    R__ASSERT(this->fMatrix->IsValid());
01543    R__ASSERT(mt->IsValid());
01544    if (this->fMatrix->GetColLwb() != mt->GetColLwb() || this->fMatrix->GetNcols() != mt->GetNcols()) {
01545       Error("operator+=(const TMatrixTRow_const &)","different row lengths");
01546       return;
01547    }
01548 
01549    const Int_t ncols = this->fMatrix->GetNcols();
01550    const Int_t row1  = this->fRowInd+this->fMatrix->GetRowLwb();
01551    const Int_t row2  = r.GetRowIndex()+mt->GetRowLwb();
01552    const Int_t col   = this->fMatrix->GetColLwb();
01553 
01554    TVectorT<Element> v1(ncols);
01555    TVectorT<Element> v2(ncols);
01556    this->fMatrix->ExtractRow(row1,col,v1.GetMatrixArray());
01557    mt           ->ExtractRow(row2,col,v2.GetMatrixArray());
01558    v1 += v2;
01559    const_cast<TMatrixTBase<Element> *>(this->fMatrix)->InsertRow(row1,col,v1.GetMatrixArray());
01560 
01561    const Int_t sIndex = this->fMatrix->GetRowIndexArray()[this->fRowInd];
01562    const Int_t eIndex = this->fMatrix->GetRowIndexArray()[this->fRowInd+1];
01563    this->fNindex  = eIndex-sIndex;
01564    this->fColPtr  = this->fMatrix->GetColIndexArray()+sIndex;
01565    this->fDataPtr = this->fMatrix->GetMatrixArray()+sIndex;
01566 }
01567 
01568 //______________________________________________________________________________
01569 template<class Element>
01570 void TMatrixTSparseRow<Element>::operator*=(const TMatrixTSparseRow_const<Element> &r)
01571 {
01572 // Multiply every element of the matrix row with the
01573 // corresponding element of row r.
01574 
01575    const TMatrixTBase<Element> *mt = r.GetMatrix();
01576 
01577    R__ASSERT(this->fMatrix->IsValid());
01578    R__ASSERT(mt->IsValid());
01579    if (this->fMatrix->GetColLwb() != mt->GetColLwb() || this->fMatrix->GetNcols() != mt->GetNcols()) {
01580       Error("operator+=(const TMatrixTRow_const &)","different row lengths");
01581       return;
01582    }
01583 
01584    const Int_t ncols = this->fMatrix->GetNcols();
01585    const Int_t row1  = r.GetRowIndex()+mt->GetRowLwb();
01586    const Int_t row2  = r.GetRowIndex()+mt->GetRowLwb();
01587    const Int_t col   = this->fMatrix->GetColLwb();
01588 
01589    TVectorT<Element> v1(ncols);
01590    TVectorT<Element> v2(ncols);
01591    this->fMatrix->ExtractRow(row1,col,v1.GetMatrixArray());
01592    mt           ->ExtractRow(row2,col,v2.GetMatrixArray());
01593 
01594    ElementMult(v1,v2);
01595    const_cast<TMatrixTBase<Element> *>(this->fMatrix)->InsertRow(row1,col,v1.GetMatrixArray());
01596 
01597    const Int_t sIndex = this->fMatrix->GetRowIndexArray()[this->fRowInd];
01598    const Int_t eIndex = this->fMatrix->GetRowIndexArray()[this->fRowInd+1];
01599    this->fNindex  = eIndex-sIndex;
01600    this->fColPtr  = this->fMatrix->GetColIndexArray()+sIndex;
01601    this->fDataPtr = this->fMatrix->GetMatrixArray()+sIndex;
01602 }
01603 
01604 //______________________________________________________________________________
01605 template<class Element>
01606 TMatrixTSparseDiag_const<Element>::TMatrixTSparseDiag_const(const TMatrixTSparse<Element> &matrix)
01607 {
01608 // Constructor
01609 
01610    R__ASSERT(matrix.IsValid());
01611 
01612    fMatrix  = &matrix;
01613    fNdiag   = TMath::Min(matrix.GetNrows(),matrix.GetNcols());
01614    fDataPtr = matrix.GetMatrixArray();
01615 }
01616 
01617 //______________________________________________________________________________
01618 template<class Element>
01619 Element TMatrixTSparseDiag_const<Element>::operator()(Int_t i) const
01620 {
01621   R__ASSERT(fMatrix->IsValid());
01622   if (i < fNdiag && i >= 0) {
01623      const Int_t   * const pR = fMatrix->GetRowIndexArray();
01624      const Int_t   * const pC = fMatrix->GetColIndexArray();
01625      const Element * const pD = fMatrix->GetMatrixArray();
01626      const Int_t sIndex = pR[i];
01627      const Int_t eIndex = pR[i+1];
01628      const Int_t index = TMath::BinarySearch(eIndex-sIndex,pC+sIndex,i)+sIndex;
01629      if (index >= sIndex && pC[index] == i) return pD[index];
01630      else                                   return 0.0;
01631   } else {
01632      Error("operator()","Request diagonal(%d) outside matrix range of 0 - %d",i,fNdiag);
01633      return 0.0;
01634   }
01635   return 0.0;
01636 }
01637 
01638 //______________________________________________________________________________
01639 template<class Element>
01640 TMatrixTSparseDiag<Element>::TMatrixTSparseDiag(TMatrixTSparse<Element> &matrix)
01641                    :TMatrixTSparseDiag_const<Element>(matrix)
01642 {
01643 // Constructor
01644 }
01645 
01646 //______________________________________________________________________________
01647 template<class Element>
01648 TMatrixTSparseDiag<Element>::TMatrixTSparseDiag(const TMatrixTSparseDiag<Element> &md)
01649                   : TMatrixTSparseDiag_const<Element>(md)
01650 {
01651 // Constructor
01652 
01653    *this = md;
01654 }
01655 
01656 //______________________________________________________________________________
01657 template<class Element>
01658 Element TMatrixTSparseDiag<Element>::operator()(Int_t i) const
01659 {
01660     R__ASSERT(this->fMatrix->IsValid());
01661     if (i < this->fNdiag && i >= 0) {
01662        const Int_t   * const pR = this->fMatrix->GetRowIndexArray();
01663        const Int_t   * const pC = this->fMatrix->GetColIndexArray();
01664        const Element * const pD = this->fMatrix->GetMatrixArray();
01665        const Int_t sIndex = pR[i];
01666        const Int_t eIndex = pR[i+1];
01667        const Int_t index = TMath::BinarySearch(eIndex-sIndex,pC+sIndex,i)+sIndex;
01668        if (index >= sIndex && pC[index] == i) return pD[index];
01669        else                                   return 0.0;
01670     } else {
01671        Error("operator()","Request diagonal(%d) outside matrix range of 0 - %d",i,this->fNdiag);
01672        return 0.0;
01673     }
01674     return 0.0;
01675  }
01676 
01677 //______________________________________________________________________________
01678 template<class Element>
01679 Element &TMatrixTSparseDiag<Element>::operator()(Int_t i)
01680 {
01681 // operator() : pick element diag(i)
01682 
01683    R__ASSERT(this->fMatrix->IsValid());
01684 
01685    if (i < 0 || i >= this->fNdiag) {
01686       Error("operator()(Int_t","Requested element %d outside range : 0 - %d",i,this->fNdiag);
01687       return (const_cast<Element*>(this->fDataPtr))[0];
01688    }
01689 
01690    TMatrixTBase<Element> *mt = const_cast<TMatrixTBase<Element> *>(this->fMatrix);
01691    const Int_t *pR = mt->GetRowIndexArray();
01692    const Int_t *pC = mt->GetColIndexArray();
01693    Int_t sIndex = pR[i];
01694    Int_t eIndex = pR[i+1];
01695    Int_t index = TMath::BinarySearch(eIndex-sIndex,pC+sIndex,i)+sIndex;
01696    if (index >= sIndex && pC[index] == i)
01697       return (const_cast<Element*>(this->fDataPtr))[index];
01698    else {
01699       const Int_t row = i+mt->GetRowLwb();
01700       const Int_t col = i+mt->GetColLwb();
01701       Element val = 0.;
01702       mt->InsertRow(row,col,&val,1);
01703       this->fDataPtr = mt->GetMatrixArray();
01704       pR = mt->GetRowIndexArray();
01705       pC = mt->GetColIndexArray();
01706       sIndex = pR[i];
01707       eIndex = pR[i+1];
01708       index = TMath::BinarySearch(eIndex-sIndex,pC+sIndex,i)+sIndex;
01709       if (index >= sIndex && pC[index] == i)
01710          return (const_cast<Element*>(this->fDataPtr))[index];
01711       else {
01712          Error("operator()(Int_t","Insert row failed");
01713          return (const_cast<Element*>(this->fDataPtr))[0];
01714       }
01715    }
01716 }
01717 
01718 //______________________________________________________________________________
01719 template<class Element>
01720 void TMatrixTSparseDiag<Element>::operator=(Element val)
01721 {
01722 // Assign val to every element of the matrix diagonal.
01723 
01724    R__ASSERT(this->fMatrix->IsValid());
01725    for (Int_t i = 0; i < this->fNdiag; i++)
01726       (*this)(i) = val;
01727 }
01728 
01729 //______________________________________________________________________________
01730 template<class Element>
01731 void TMatrixTSparseDiag<Element>::operator+=(Element val)
01732 {
01733 // Add val to every element of the matrix diagonal.
01734 
01735    R__ASSERT(this->fMatrix->IsValid());
01736    for (Int_t i = 0; i < this->fNdiag; i++)
01737       (*this)(i) += val;
01738 }
01739 
01740 //______________________________________________________________________________
01741 template<class Element>
01742 void TMatrixTSparseDiag<Element>::operator*=(Element val)
01743 {
01744 // Multiply every element of the matrix diagonal by val.
01745 
01746    R__ASSERT(this->fMatrix->IsValid());
01747    for (Int_t i = 0; i < this->fNdiag; i++)
01748       (*this)(i) *= val;
01749 }
01750 
01751 //______________________________________________________________________________
01752 template<class Element>
01753 void TMatrixTSparseDiag<Element>::operator=(const TMatrixTSparseDiag_const<Element> &md)
01754 {
01755 // Assignment operator
01756 
01757    const TMatrixTBase<Element> *mt = md.GetMatrix();
01758    if (this->fMatrix == mt) return;
01759 
01760    R__ASSERT(this->fMatrix->IsValid());
01761    R__ASSERT(mt->IsValid());
01762    if (this->fNdiag != md.GetNdiags()) {
01763       Error("operator=(const TMatrixTSparseDiag_const &)","matrix-diagonal's different length");
01764       return;
01765    }
01766 
01767    for (Int_t i = 0; i < this->fNdiag; i++)
01768       (*this)(i) = md(i);
01769 }
01770 
01771 //______________________________________________________________________________
01772 template<class Element>
01773 void TMatrixTSparseDiag<Element>::operator=(const TVectorT<Element> &vec)
01774 {
01775 // Assign a vector to the matrix diagonal.
01776 
01777    R__ASSERT(this->fMatrix->IsValid());
01778    R__ASSERT(vec.IsValid());
01779 
01780    if (this->fNdiag != vec.GetNrows()) {
01781       Error("operator=(const TVectorT &)","vector length != matrix-diagonal length");
01782       return;
01783    }
01784 
01785    const Element *vp = vec.GetMatrixArray();
01786    for (Int_t i = 0; i < this->fNdiag; i++)
01787       (*this)(i) = vp[i];
01788 }
01789 
01790 //______________________________________________________________________________
01791 template<class Element>
01792 void TMatrixTSparseDiag<Element>::operator+=(const TMatrixTSparseDiag_const<Element> &md)
01793 {
01794 // Add to every element of the matrix diagonal the
01795 // corresponding element of diagonal md.
01796 
01797    const TMatrixTBase<Element> *mt = md.GetMatrix();
01798 
01799    R__ASSERT(this->fMatrix->IsValid());
01800    R__ASSERT(mt->IsValid());
01801    if (this->fNdiag != md.GetNdiags()) {
01802       Error("operator+=(const TMatrixTSparseDiag_const &)","matrix-diagonal's different length");
01803       return;
01804    }
01805 
01806    for (Int_t i = 0; i < this->fNdiag; i++)
01807       (*this)(i) += md(i);
01808 }
01809 
01810 //______________________________________________________________________________
01811 template<class Element>
01812 void TMatrixTSparseDiag<Element>::operator*=(const TMatrixTSparseDiag_const<Element> &md)
01813 {
01814 // Multiply every element of the matrix diagonal with the
01815 // corresponding element of diagonal md.
01816 
01817    const TMatrixTBase<Element> *mt = md.GetMatrix();
01818 
01819    R__ASSERT(this->fMatrix->IsValid());
01820    R__ASSERT(mt->IsValid());
01821    if (this->fNdiag != md.GetNdiags()) {
01822       Error("operator*=(const TMatrixTSparseDiag_const &)","matrix-diagonal's different length");
01823       return;
01824    }
01825 
01826    for (Int_t i = 0; i < this->fNdiag; i++)
01827       (*this)(i) *= md(i);
01828 }
01829 
01830 //______________________________________________________________________________
01831 Double_t Drand(Double_t &ix)
01832 {
01833 // Random number generator [0....1] with seed ix
01834 
01835    const Double_t a   = 16807.0;
01836    const Double_t b15 = 32768.0;
01837    const Double_t b16 = 65536.0;
01838    const Double_t p   = 2147483647.0;
01839    Double_t xhi = ix/b16;
01840    Int_t xhiint = (Int_t) xhi;
01841    xhi = xhiint;
01842    Double_t xalo = (ix-xhi*b16)*a;
01843 
01844    Double_t leftlo = xalo/b16;
01845    Int_t leftloint = (int) leftlo;
01846    leftlo = leftloint;
01847    Double_t fhi = xhi*a+leftlo;
01848    Double_t k = fhi/b15;
01849    Int_t kint = (Int_t) k;
01850    k = kint;
01851    ix = (((xalo-leftlo*b16)-p)+(fhi-k*b15)*b16)+k;
01852    if (ix < 0.0) ix = ix+p;
01853 
01854    return (ix*4.656612875e-10);
01855 }
01856 
01857 template class TMatrixTRow_const       <Float_t>;
01858 template class TMatrixTColumn_const    <Float_t>;
01859 template class TMatrixTDiag_const      <Float_t>;
01860 template class TMatrixTFlat_const      <Float_t>;
01861 template class TMatrixTSub_const       <Float_t>;
01862 template class TMatrixTSparseRow_const <Float_t>;
01863 template class TMatrixTSparseDiag_const<Float_t>;
01864 template class TMatrixTRow             <Float_t>;
01865 template class TMatrixTColumn          <Float_t>;
01866 template class TMatrixTDiag            <Float_t>;
01867 template class TMatrixTFlat            <Float_t>;
01868 template class TMatrixTSub             <Float_t>;
01869 template class TMatrixTSparseRow       <Float_t>;
01870 template class TMatrixTSparseDiag      <Float_t>;
01871 template class TElementActionT         <Float_t>;
01872 template class TElementPosActionT      <Float_t>;
01873 
01874 template class TMatrixTRow_const       <Double_t>;
01875 template class TMatrixTColumn_const    <Double_t>;
01876 template class TMatrixTDiag_const      <Double_t>;
01877 template class TMatrixTFlat_const      <Double_t>;
01878 template class TMatrixTSub_const       <Double_t>;
01879 template class TMatrixTSparseRow_const <Double_t>;
01880 template class TMatrixTSparseDiag_const<Double_t>;
01881 template class TMatrixTRow             <Double_t>;
01882 template class TMatrixTColumn          <Double_t>;
01883 template class TMatrixTDiag            <Double_t>;
01884 template class TMatrixTFlat            <Double_t>;
01885 template class TMatrixTSub             <Double_t>;
01886 template class TMatrixTSparseRow       <Double_t>;
01887 template class TMatrixTSparseDiag      <Double_t>;
01888 template class TElementActionT         <Double_t>;
01889 template class TElementPosActionT      <Double_t>;

Generated on Tue Jul 5 14:36:36 2011 for ROOT_528-00b_version by  doxygen 1.5.1