// @(#)root/minuit2:$Id$ // Authors: M. Winkler, F. James, L. Moneta, A. Zsenei 2003-2005 /********************************************************************** * * * Copyright (c) 2005 LCG ROOT Math team, CERN/PH-SFT * * * **********************************************************************/ #ifndef ROOT_Minuit2_LASymMatrix #define ROOT_Minuit2_LASymMatrix #include "Minuit2/MnConfig.h" #include "Minuit2/ABSum.h" #include "Minuit2/VectorOuterProduct.h" #include "Minuit2/MatrixInverse.h" #include #include // #include #include "Minuit2/StackAllocator.h" //extern StackAllocator StackAllocatorHolder::Get(); // for memcopy #include namespace ROOT { namespace Minuit2 { int Mndaxpy(unsigned int, double, const double*, int, double*, int); int Mndscal(unsigned int, double, double*, int); class LAVector; int Invert ( LASymMatrix & ); /** Class describing a symmetric matrix of size n. The size is specified as a run-time argument passed in the constructor. The class uses expression templates for the operations and functions. Only the independent data are kept in the fdata array of size n*(n+1)/2 containing the lower triangular data */ class LASymMatrix { private: LASymMatrix() : fSize(0), fNRow(0), fData(0) {} public: typedef sym Type; LASymMatrix(unsigned int n) : fSize(n*(n+1)/2), fNRow(n), fData((double*)StackAllocatorHolder::Get().Allocate(sizeof(double)*n*(n+1)/2)) { // assert(fSize>0); memset(fData, 0, fSize*sizeof(double)); // std::cout<<"LASymMatrix(unsigned int n), n= "<& v)"< LASymMatrix(const ABObj, ABObj >,T>& sum) : fSize(0), fNRow(0), fData(0) { // std::cout<<"template LASymMatrix(const ABObj, ABObj > >& sum)"< LASymMatrix(const ABObj..."< LASymMatrix(const ABObj, ABObj >,T>& sum) : fSize(0), fNRow(0), fData(0) { // std::cout<<"template LASymMatrix(const ABObj, ABObj >,T>& sum)"< LASymMatrix(const ABObj LASymMatrix(const ABObj, T>& something) : fSize(0), fNRow(0), fData(0) { // std::cout<<"template LASymMatrix(const ABObj, T>& something)"< LASymMatrix(const ABObj, T>& something)"< LASymMatrix(const ABObj, 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())) { memcpy(fData, inv.Obj().Obj().Obj().Data(), fSize*sizeof(double)); Mndscal(fSize, double(inv.Obj().Obj().f()), fData, 1); Invert(*this); Mndscal(fSize, double(inv.f()), fData, 1); } template LASymMatrix(const ABObj, T>, T>, ABObj >, T>& sum) : fSize(0), fNRow(0), fData(0) { // std::cout<<"template LASymMatrix(const ABObj, T>, T>, ABObj >, T>& sum)"< LASymMatrix(const ABObj, double>, double>&); template LASymMatrix(const ABObj, T>, T>, ABObj >, T>& sum) : fSize(0), fNRow(0), fData(0) { // std::cout<<"template LASymMatrix(const ABObj, T>, T> ABObj >,T>& sum)"< LASymMatrix(const ABObj LASymMatrix& operator+=(const ABObj& m) { // std::cout<<"template LASymMatrix& operator+=(const ABObj& m)"< LASymMatrix& operator+=(const ABObj& m) { // std::cout<<"template LASymMatrix& operator+=(const ABObj& m)"< LASymMatrix& operator+=(const ABObj, T>, T>& m) { // std::cout<<"template LASymMatrix& operator+=(const ABObj, T>, T>& m)"< 0); LASymMatrix tmp(m.Obj().Obj()); Invert(tmp); tmp *= double(m.f()); (*this) += tmp; return *this; } template LASymMatrix& operator+=(const ABObj, T>, T>& m) { // std::cout<<"template LASymMatrix& operator+=(const ABObj, T>, T>&"< 0); Outer_prod(*this, m.Obj().Obj().Obj(), m.f()*m.Obj().Obj().f()*m.Obj().Obj().f()); return *this; } LASymMatrix& operator*=(double scal) { Mndscal(fSize, scal, fData, 1); return *this; } double operator()(unsigned int row, unsigned int col) const { assert(row col) return fData[col+row*(row+1)/2]; else return fData[row+col*(col+1)/2]; } double& operator()(unsigned int row, unsigned int col) { assert(row col) return fData[col+row*(row+1)/2]; else return fData[row+col*(col+1)/2]; } const double* Data() const {return fData;} double* Data() {return fData;} unsigned int size() const {return fSize;} unsigned int Nrow() const {return fNRow;} unsigned int Ncol() const {return Nrow();} private: unsigned int fSize; unsigned int fNRow; double* fData; public: template LASymMatrix& operator=(const ABObj& v) { //std::cout<<"template LASymMatrix& operator=(ABObj& v)"< LASymMatrix& operator=(const ABObj, T>& something) { //std::cout<<"template LASymMatrix& operator=(const ABObj, T>& something)"< LASymMatrix& operator=(const ABObj, T>& something)"< LASymMatrix& operator=(const ABObj, ABObj >,T>& sum) { //std::cout<<"template LASymMatrix& operator=(const ABObj, ABObj >,T>& sum)"< LASymMatrix& operator=(const ABObj, ABObj >,T>& sum) { //std::cout<<"template LASymMatrix& operator=(const ABObj, ABObj >,T>& sum)"< LASymMatrix& operator=(const ABObj, T>, T>& inv) { if(fSize == 0 && fData == 0) { fSize = inv.Obj().Obj().Obj().size(); fNRow = inv.Obj().Obj().Obj().Nrow(); fData = (double*)StackAllocatorHolder::Get().Allocate(sizeof(double)*fSize); memcpy(fData, inv.Obj().Obj().Obj().Data(), fSize*sizeof(double)); (*this) *= inv.Obj().Obj().f(); Invert(*this); (*this) *= inv.f(); } else { LASymMatrix tmp(inv.Obj().Obj()); Invert(tmp); tmp *= double(inv.f()); assert(fSize == tmp.size()); memcpy(fData, tmp.Data(), fSize*sizeof(double)); } return *this; } LASymMatrix& operator=(const ABObj, double>, double>&); }; } // namespace Minuit2 } // namespace ROOT #endif // ROOT_Minuit2_LASymMatrix