LASymMatrix.h

Go to the documentation of this file.
00001 // @(#)root/minuit2:$Id: LASymMatrix.h 23522 2008-04-24 15:09:19Z moneta $
00002 // Authors: M. Winkler, F. James, L. Moneta, A. Zsenei   2003-2005  
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2005 LCG ROOT Math team,  CERN/PH-SFT                *
00007  *                                                                    *
00008  **********************************************************************/
00009 
00010 #ifndef ROOT_Minuit2_LASymMatrix
00011 #define ROOT_Minuit2_LASymMatrix
00012 
00013 #include "Minuit2/MnConfig.h"
00014 #include "Minuit2/ABSum.h"
00015 #include "Minuit2/VectorOuterProduct.h"
00016 #include "Minuit2/MatrixInverse.h"
00017 
00018 #include <cassert>
00019 #include <memory>
00020 
00021 
00022 // #include <iostream>
00023 
00024 #include "Minuit2/StackAllocator.h"
00025 //extern StackAllocator StackAllocatorHolder::Get();
00026 
00027 // for memcopy
00028 #include <string.h>
00029 
00030 namespace ROOT {
00031 
00032    namespace Minuit2 {
00033 
00034 
00035 int Mndaxpy(unsigned int, double, const double*, int, double*, int);
00036 int Mndscal(unsigned int, double, double*, int);
00037 
00038 class LAVector;
00039 
00040 int Invert ( LASymMatrix & );
00041 
00042 /**
00043    Class describing a symmetric matrix of size n.  
00044    The size is specified as a run-time argument passed in the 
00045    constructor. 
00046    The class uses expression templates for the operations and functions. 
00047    Only the independent data are kept in the fdata array of size n*(n+1)/2
00048    containing the lower triangular data   
00049  */
00050 
00051 class LASymMatrix {
00052 
00053 private:
00054 
00055   LASymMatrix() : fSize(0), fNRow(0), fData(0) {}
00056 
00057 public:
00058 
00059   typedef sym Type;
00060 
00061   LASymMatrix(unsigned int n) : fSize(n*(n+1)/2), fNRow(n), fData((double*)StackAllocatorHolder::Get().Allocate(sizeof(double)*n*(n+1)/2)) {
00062 //     assert(fSize>0);
00063     memset(fData, 0, fSize*sizeof(double));
00064 //     std::cout<<"LASymMatrix(unsigned int n), n= "<<n<<std::endl;
00065   }
00066 
00067   ~LASymMatrix() {
00068 //     std::cout<<"~LASymMatrix()"<<std::endl;
00069 //     if(fData) std::cout<<"deleting "<<fSize<<std::endl;
00070 //     else std::cout<<"no delete"<<std::endl;
00071 //     if(fData) delete [] fData;
00072     if(fData) StackAllocatorHolder::Get().Deallocate(fData);
00073   }
00074 
00075   LASymMatrix(const LASymMatrix& v) : 
00076     fSize(v.size()), fNRow(v.Nrow()), fData((double*)StackAllocatorHolder::Get().Allocate(sizeof(double)*v.size())) {
00077 //     std::cout<<"LASymMatrix(const LASymMatrix& v)"<<std::endl;
00078     memcpy(fData, v.Data(), fSize*sizeof(double));
00079   }
00080 
00081   LASymMatrix& operator=(const LASymMatrix& v) {
00082 //     std::cout<<"LASymMatrix& operator=(const LASymMatrix& v)"<<std::endl;
00083 //     std::cout<<"fSize= "<<fSize<<std::endl;
00084 //     std::cout<<"v.size()= "<<v.size()<<std::endl;
00085     assert(fSize == v.size());
00086     memcpy(fData, v.Data(), fSize*sizeof(double));
00087     return *this;
00088   }
00089 
00090   template<class T>
00091   LASymMatrix(const ABObj<sym, LASymMatrix, T>& v) : 
00092     fSize(v.Obj().size()), fNRow(v.Obj().Nrow()), fData((double*)StackAllocatorHolder::Get().Allocate(sizeof(double)*v.Obj().size())) {
00093 //     std::cout<<"LASymMatrix(const ABObj<sym, LASymMatrix, T>& v)"<<std::endl;
00094     //std::cout<<"allocate "<<fSize<<std::endl;    
00095     memcpy(fData, v.Obj().Data(), fSize*sizeof(double));
00096     Mndscal(fSize, double(v.f()), fData, 1);
00097     //std::cout<<"fData= "<<fData[0]<<" "<<fData[1]<<std::endl;
00098   } 
00099 
00100   template<class A, class B, class T>
00101   LASymMatrix(const ABObj<sym, ABSum<ABObj<sym, A, T>, ABObj<sym, B, T> >,T>& sum) : fSize(0), fNRow(0), fData(0) {
00102 //     std::cout<<"template<class A, class B, class T> LASymMatrix(const ABObj<sym, ABSum<ABObj<sym, A, T>, ABObj<sym, B, T> > >& sum)"<<std::endl;
00103 //     recursive construction
00104     (*this) = sum.Obj().A();
00105     (*this) += sum.Obj().B();
00106     //std::cout<<"leaving template<class A, class B, class T> LASymMatrix(const ABObj..."<<std::endl;
00107   }
00108 
00109   template<class A, class T>
00110   LASymMatrix(const ABObj<sym, ABSum<ABObj<sym, LASymMatrix, T>, ABObj<sym, A, T> >,T>& sum) : fSize(0), fNRow(0), fData(0) {
00111 //     std::cout<<"template<class A, class T> LASymMatrix(const ABObj<sym, ABSum<ABObj<sym, LASymMatrix, T>, ABObj<sym, A, T> >,T>& sum)"<<std::endl;
00112 
00113     // recursive construction
00114     //std::cout<<"(*this)=sum.Obj().B();"<<std::endl;
00115     (*this)=sum.Obj().B();
00116     //std::cout<<"(*this)+=sum.Obj().A();"<<std::endl;
00117     (*this)+=sum.Obj().A();  
00118     //std::cout<<"leaving template<class A, class T> LASymMatrix(const ABObj<sym, ABSum<ABObj<sym, LASymMatrix,.."<<std::endl;
00119   }
00120 
00121   template<class A, class T>
00122   LASymMatrix(const ABObj<sym, ABObj<sym, A, T>, T>& something) : fSize(0), fNRow(0), fData(0) {
00123 //     std::cout<<"template<class A, class T> LASymMatrix(const ABObj<sym, ABObj<sym, A, T>, T>& something)"<<std::endl;
00124     (*this) = something.Obj();
00125     (*this) *= something.f();
00126     //std::cout<<"leaving template<class A, class T> LASymMatrix(const ABObj<sym, ABObj<sym, A, T>, T>& something)"<<std::endl;
00127   }
00128 
00129   template<class T>
00130   LASymMatrix(const ABObj<sym, MatrixInverse<sym, ABObj<sym, LASymMatrix, T>, T>, T>& inv) : fSize(inv.Obj().Obj().Obj().size()), fNRow(inv.Obj().Obj().Obj().Nrow()), fData((double*)StackAllocatorHolder::Get().Allocate(sizeof(double)*inv.Obj().Obj().Obj().size())) {
00131     memcpy(fData, inv.Obj().Obj().Obj().Data(), fSize*sizeof(double));
00132     Mndscal(fSize, double(inv.Obj().Obj().f()), fData, 1);
00133     Invert(*this);
00134     Mndscal(fSize, double(inv.f()), fData, 1);
00135   }
00136 
00137   template<class A, class T>
00138   LASymMatrix(const ABObj<sym, ABSum<ABObj<sym, MatrixInverse<sym, ABObj<sym, LASymMatrix, T>, T>, T>, ABObj<sym, A, T> >, T>& sum) : fSize(0), fNRow(0), fData(0) {
00139 //     std::cout<<"template<class A, class T> LASymMatrix(const ABObj<sym, ABSum<ABObj<sym, MatrixInverse<sym, ABObj<sym, LASymMatrix, T>, T>, T>, ABObj<sym, A, T> >, T>& sum)"<<std::endl;
00140 
00141     // recursive construction
00142     (*this)=sum.Obj().B();
00143     (*this)+=sum.Obj().A();  
00144     //std::cout<<"leaving template<class A, class T> LASymMatrix(const ABObj<sym, ABSum<ABObj<sym, LASymMatrix,.."<<std::endl;
00145   }
00146 
00147   LASymMatrix(const ABObj<sym, VectorOuterProduct<ABObj<vec, LAVector, double>, double>, double>&);
00148 
00149   template<class A, class T>
00150   LASymMatrix(const ABObj<sym, ABSum<ABObj<sym, VectorOuterProduct<ABObj<vec, LAVector, T>, T>, T>, ABObj<sym, A, T> >, T>& sum) : fSize(0), fNRow(0), fData(0) {
00151 //     std::cout<<"template<class A, class T> LASymMatrix(const ABObj<sym, ABSum<ABObj<sym, VectorOuterProduct<ABObj<vec, LAVector, T>, T>, T> ABObj<sym, A, T> >,T>& sum)"<<std::endl;
00152 
00153     // recursive construction
00154     (*this)=sum.Obj().B();
00155     (*this)+=sum.Obj().A();  
00156     //std::cout<<"leaving template<class A, class T> LASymMatrix(const ABObj<sym, ABSum<ABObj<sym, LASymMatrix,.."<<std::endl;
00157   }
00158 
00159   LASymMatrix& operator+=(const LASymMatrix& m) {
00160 //     std::cout<<"LASymMatrix& operator+=(const LASymMatrix& m)"<<std::endl;
00161     assert(fSize==m.size());
00162     Mndaxpy(fSize, 1., m.Data(), 1, fData, 1);
00163     return *this;
00164   }
00165 
00166   LASymMatrix& operator-=(const LASymMatrix& m) {
00167 //     std::cout<<"LASymMatrix& operator-=(const LASymMatrix& m)"<<std::endl;
00168     assert(fSize==m.size());
00169     Mndaxpy(fSize, -1., m.Data(), 1, fData, 1);
00170     return *this;
00171   }
00172 
00173   template<class T>
00174   LASymMatrix& operator+=(const ABObj<sym, LASymMatrix, T>& m) {
00175 //     std::cout<<"template<class T> LASymMatrix& operator+=(const ABObj<sym, LASymMatrix, T>& m)"<<std::endl;
00176     assert(fSize==m.Obj().size());
00177     if(m.Obj().Data()==fData) {
00178       Mndscal(fSize, 1.+double(m.f()), fData, 1);
00179     } else {
00180       Mndaxpy(fSize, double(m.f()), m.Obj().Data(), 1, fData, 1);
00181     }
00182     //std::cout<<"fData= "<<fData[0]<<" "<<fData[1]<<std::endl;
00183     return *this;
00184   }
00185 
00186   template<class A, class T>
00187   LASymMatrix& operator+=(const ABObj<sym, A, T>& m) {
00188 //     std::cout<<"template<class A, class T> LASymMatrix& operator+=(const ABObj<sym, A,T>& m)"<<std::endl;
00189     (*this) += LASymMatrix(m);
00190     return *this;
00191   }
00192 
00193   template<class T>
00194   LASymMatrix& operator+=(const ABObj<sym, MatrixInverse<sym, ABObj<sym, LASymMatrix, T>, T>, T>& m) {
00195 //     std::cout<<"template<class T> LASymMatrix& operator+=(const ABObj<sym, MatrixInverse<sym, ABObj<sym, LASymMatrix, T>, T>, T>& m)"<<std::endl;
00196     assert(fNRow > 0);
00197     LASymMatrix tmp(m.Obj().Obj());
00198     Invert(tmp);
00199     tmp *= double(m.f());
00200     (*this) += tmp;
00201     return *this;
00202   }
00203 
00204   template<class T>
00205   LASymMatrix& operator+=(const ABObj<sym, VectorOuterProduct<ABObj<vec, LAVector, T>, T>, T>& m) {
00206 //     std::cout<<"template<class T> LASymMatrix& operator+=(const ABObj<sym, VectorOuterProduct<ABObj<vec, LAVector, T>, T>, T>&"<<std::endl;
00207     assert(fNRow > 0);
00208     Outer_prod(*this, m.Obj().Obj().Obj(), m.f()*m.Obj().Obj().f()*m.Obj().Obj().f());
00209     return *this;
00210   }
00211   
00212   LASymMatrix& operator*=(double scal) {
00213     Mndscal(fSize, scal, fData, 1);
00214     return *this;
00215   }
00216 
00217   double operator()(unsigned int row, unsigned int col) const {
00218     assert(row<fNRow && col < fNRow);
00219     if(row > col) 
00220       return fData[col+row*(row+1)/2];
00221     else
00222       return fData[row+col*(col+1)/2];
00223   }
00224 
00225   double& operator()(unsigned int row, unsigned int col) {
00226     assert(row<fNRow && col < fNRow);
00227     if(row > col) 
00228       return fData[col+row*(row+1)/2];
00229     else
00230       return fData[row+col*(col+1)/2];
00231   }
00232   
00233   const double* Data() const {return fData;}
00234 
00235   double* Data() {return fData;}
00236   
00237   unsigned int size() const {return fSize;}
00238 
00239   unsigned int Nrow() const {return fNRow;}
00240   
00241   unsigned int Ncol() const {return Nrow();}
00242 
00243 private:
00244  
00245   unsigned int fSize;
00246   unsigned int fNRow;
00247   double* fData;
00248 
00249 public:
00250 
00251   template<class T>
00252   LASymMatrix& operator=(const ABObj<sym, LASymMatrix, T>& v)  {
00253     //std::cout<<"template<class T> LASymMatrix& operator=(ABObj<sym, LASymMatrix, T>& v)"<<std::endl;
00254     if(fSize == 0 && fData == 0) {
00255       fSize = v.Obj().size();
00256       fNRow = v.Obj().Nrow();
00257       fData = (double*)StackAllocatorHolder::Get().Allocate(sizeof(double)*fSize);
00258     } else {
00259       assert(fSize == v.Obj().size());
00260     }
00261     //std::cout<<"fData= "<<fData[0]<<" "<<fData[1]<<std::endl;
00262     memcpy(fData, v.Obj().Data(), fSize*sizeof(double));
00263     (*this) *= v.f();
00264     return *this;
00265   }
00266 
00267   template<class A, class T>
00268   LASymMatrix& operator=(const ABObj<sym, ABObj<sym, A, T>, T>& something) {
00269     //std::cout<<"template<class A, class T> LASymMatrix& operator=(const ABObj<sym, ABObj<sym, A, T>, T>& something)"<<std::endl;
00270     if(fSize == 0 && fData == 0) {
00271       (*this) = something.Obj();
00272       (*this) *= something.f();
00273     } else {
00274       LASymMatrix tmp(something.Obj());
00275       tmp *= something.f();
00276       assert(fSize == tmp.size());
00277       memcpy(fData, tmp.Data(), fSize*sizeof(double)); 
00278     }
00279     //std::cout<<"template<class A, class T> LASymMatrix& operator=(const ABObj<sym, ABObj<sym, A, T>, T>& something)"<<std::endl;
00280     return *this;
00281   }
00282 
00283   template<class A, class B, class T>
00284   LASymMatrix& operator=(const ABObj<sym, ABSum<ABObj<sym, A, T>, ABObj<sym, B, T> >,T>& sum) {
00285     //std::cout<<"template<class A, class B, class T> LASymMatrix& operator=(const ABObj<sym, ABSum<ABObj<sym, A, T>, ABObj<sym, B, T> >,T>& sum)"<<std::endl;
00286     // recursive construction
00287     if(fSize == 0 && fData == 0) {
00288       (*this) = sum.Obj().A();
00289       (*this) += sum.Obj().B();
00290       (*this) *= sum.f();
00291     } else {
00292       LASymMatrix tmp(sum.Obj().A());
00293       tmp += sum.Obj().B();
00294       tmp *= sum.f();
00295       assert(fSize == tmp.size());
00296       memcpy(fData, tmp.Data(), fSize*sizeof(double));
00297     }
00298     return *this;
00299   }
00300 
00301   template<class A, class T>
00302   LASymMatrix& operator=(const ABObj<sym, ABSum<ABObj<sym, LASymMatrix, T>, ABObj<sym, A, T> >,T>& sum)  {
00303     //std::cout<<"template<class A, class T> LASymMatrix& operator=(const ABObj<sym, ABSum<ABObj<sym, LASymMatrix, T>, ABObj<sym, A, T> >,T>& sum)"<<std::endl;
00304     
00305     if(fSize == 0 && fData == 0) {
00306       //std::cout<<"fSize == 0 && fData == 0"<<std::endl;
00307       (*this) = sum.Obj().B();
00308       (*this) += sum.Obj().A();
00309       (*this) *= sum.f();
00310     } else {
00311       //std::cout<<"creating tmp variable"<<std::endl;
00312       LASymMatrix tmp(sum.Obj().B());
00313       tmp += sum.Obj().A();
00314       tmp *= sum.f();
00315       assert(fSize == tmp.size());
00316       memcpy(fData, tmp.Data(), fSize*sizeof(double));
00317     }
00318     //std::cout<<"leaving LASymMatrix& operator=(const ABObj<sym, ABSum<ABObj<sym, LASymMatrix..."<<std::endl;
00319     return *this;
00320   }
00321 
00322   template<class T>
00323   LASymMatrix& operator=(const ABObj<sym, MatrixInverse<sym, ABObj<sym, LASymMatrix, T>, T>, T>& inv) {
00324     if(fSize == 0 && fData == 0) {
00325       fSize = inv.Obj().Obj().Obj().size();
00326       fNRow = inv.Obj().Obj().Obj().Nrow();
00327       fData = (double*)StackAllocatorHolder::Get().Allocate(sizeof(double)*fSize);
00328       memcpy(fData, inv.Obj().Obj().Obj().Data(), fSize*sizeof(double));
00329       (*this) *= inv.Obj().Obj().f();
00330       Invert(*this);
00331       (*this) *= inv.f();
00332     } else {
00333       LASymMatrix tmp(inv.Obj().Obj());
00334       Invert(tmp);
00335       tmp *= double(inv.f());
00336       assert(fSize == tmp.size());
00337       memcpy(fData, tmp.Data(), fSize*sizeof(double));
00338     }
00339     return *this;
00340   }
00341 
00342   LASymMatrix& operator=(const ABObj<sym, VectorOuterProduct<ABObj<vec, LAVector, double>, double>, double>&);
00343 };
00344 
00345   }  // namespace Minuit2
00346 
00347 }  // namespace ROOT
00348 
00349 #endif  // ROOT_Minuit2_LASymMatrix

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