#ifndef ALISYMMATRIX_H
#define ALISYMMATRIX_H
#include <TVectorD.h>
#include "AliMatrixSq.h"
class AliSymMatrix : public AliMatrixSq {
public:
AliSymMatrix();
AliSymMatrix(Int_t size);
AliSymMatrix(const AliSymMatrix &mat);
virtual ~AliSymMatrix();
void Clear(Option_t* option="");
void Reset();
Int_t GetSize() const {return fNrowIndex;}
Int_t GetSizeUsed() const {return fRowLwb;}
Int_t GetSizeBooked() const {return fNcols;}
Int_t GetSizeAdded() const {return fNrows;}
Float_t GetDensity() const;
AliSymMatrix& operator=(const AliSymMatrix& src);
AliSymMatrix& operator+=(const AliSymMatrix& src);
Double_t operator()(Int_t rown, Int_t coln) const;
Double_t& operator()(Int_t rown, Int_t coln);
Double_t DiagElem(Int_t r) const {return (*(const AliSymMatrix*)this)(r,r);}
Double_t& DiagElem(Int_t r) {return (*this)(r,r);}
Double_t* GetRow(Int_t r);
void Print(const Option_t* option="") const;
void AddRows(int nrows=1);
void SetSizeUsed(Int_t sz) {fRowLwb = sz;}
void Scale(Double_t coeff);
void MultiplyByVec(const Double_t* vecIn, Double_t* vecOut) const;
void MultiplyByVec(const TVectorD &vecIn, TVectorD &vecOut) const;
void AddToRow(Int_t r, Double_t *valc, Int_t *indc,Int_t n);
virtual const Double_t *GetMatrixArray () const {return fElems;};
virtual Double_t *GetMatrixArray () {return (Double_t*)fElems;}
virtual const Int_t *GetRowIndexArray() const {Error("GetRowIndexArray","Dummy"); return 0;};
virtual Int_t *GetRowIndexArray() {Error("GetRowIndexArray","Dummy"); return 0;};
virtual const Int_t *GetColIndexArray() const {Error("GetColIndexArray","Dummy"); return 0;};
virtual Int_t *GetColIndexArray() {Error("GetColIndexArray","Dummy"); return 0;};
virtual TMatrixDBase &SetRowIndexArray(Int_t *) {Error("SetRowIndexArray","Dummy"); return *this;}
virtual TMatrixDBase &SetColIndexArray(Int_t *) {Error("SetColIndexArray","Dummy"); return *this;}
virtual TMatrixDBase &GetSub(Int_t,Int_t,Int_t,Int_t,TMatrixDBase &,Option_t *) const {Error("GetSub","Dummy"); return *((TMatrixDBase*)this);}
virtual TMatrixDBase &SetSub(Int_t,Int_t,const TMatrixDBase &) {Error("GetSub","Dummy"); return *this;}
virtual TMatrixDBase &ResizeTo (Int_t,Int_t,Int_t) {Error("ResizeTo","Dummy"); return *this;}
virtual TMatrixDBase &ResizeTo (Int_t,Int_t,Int_t,Int_t,Int_t) {Error("ResizeTo","Dummy"); return *this;}
AliSymMatrix* DecomposeChol();
void InvertChol(AliSymMatrix* mchol);
Bool_t InvertChol();
Bool_t SolveChol(Double_t *brhs, Bool_t invert=kFALSE);
Bool_t SolveChol(Double_t *brhs, Double_t *bsol,Bool_t invert=kFALSE);
Bool_t SolveChol(TVectorD &brhs, Bool_t invert=kFALSE);
Bool_t SolveChol(const TVectorD &brhs, TVectorD& bsol,Bool_t invert=kFALSE);
int SolveSpmInv(double *vecB, Bool_t stabilize=kTRUE);
protected:
virtual Int_t GetIndex(Int_t row,Int_t col) const;
Double_t GetEl(Int_t row, Int_t col) const {return operator()(row,col);}
void SetEl(Int_t row, Int_t col,Double_t val) {operator()(row,col) = val;}
protected:
Double_t* fElems;
Double_t** fElemsAdd;
static AliSymMatrix* fgBuffer;
static Int_t fgCopyCnt;
ClassDef(AliSymMatrix,0)
};
inline Int_t AliSymMatrix::GetIndex(Int_t row,Int_t col) const
{
return ((row*(row+1))>>1) + col;
}
inline Double_t AliSymMatrix::operator()(Int_t row, Int_t col) const
{
if (row<col) Swap(row,col);
if (row>=fNrowIndex) return 0;
return (const Double_t&) (row<fNcols ? fElems[GetIndex(row,col)] : (fElemsAdd[row-fNcols])[col]);
}
inline Double_t& AliSymMatrix::operator()(Int_t row, Int_t col)
{
if (row<col) Swap(row,col);
if (row>=fNrowIndex) AddRows(row-fNrowIndex+1);
return (row<fNcols ? fElems[GetIndex(row,col)] : (fElemsAdd[row-fNcols])[col]);
}
inline void AliSymMatrix::MultiplyByVec(const TVectorD &vecIn, TVectorD &vecOut) const
{
MultiplyByVec(vecIn.GetMatrixArray(), vecOut.GetMatrixArray());
}
inline void AliSymMatrix::Scale(Double_t coeff)
{
for (int i=fNrowIndex;i--;) for (int j=i;j--;) { double& el = operator()(i,j); if (el) el *= coeff;}
}
inline void AliSymMatrix::AddToRow(Int_t r, Double_t *valc, Int_t *indc,Int_t n)
{
for (int i=n;i--;) (*this)(indc[i],r) += valc[i];
}
#endif