#include #include #include // #include "TClass.h" #include "TMath.h" #include "AliSymMatrix.h" // using namespace std; ClassImp(AliSymMatrix) AliSymMatrix* AliSymMatrix::fgBuffer = 0; Int_t AliSymMatrix::fgCopyCnt = 0; //___________________________________________________________ AliSymMatrix::AliSymMatrix() : fElems(0),fElemsAdd(0) { fSymmetric = kTRUE; fgCopyCnt++; } //___________________________________________________________ AliSymMatrix::AliSymMatrix(Int_t size) : AliMatrixSq(),fElems(0),fElemsAdd(0) { // fNrows = 0; fNrowIndex = fNcols = size; fElems = new Double_t[fNcols*(fNcols+1)/2]; fSymmetric = kTRUE; Reset(); fgCopyCnt++; // } //___________________________________________________________ AliSymMatrix::AliSymMatrix(const AliSymMatrix &src) : AliMatrixSq(src),fElems(0),fElemsAdd(0) { fNrowIndex = fNcols = src.GetSize(); fNrows = 0; if (fNcols) { int nmainel = fNcols*(fNcols+1)/2; fElems = new Double_t[nmainel]; nmainel = src.fNcols*(src.fNcols+1)/2; memcpy(fElems,src.fElems,nmainel*sizeof(Double_t)); if (src.fNrows) { // transfer extra rows to main matrix Double_t *pnt = fElems + nmainel; int ncl = src.fNcols + 1; for (int ir=0;irGetSize()!=GetSize()) { delete fgBuffer; try { fgBuffer = new AliSymMatrix(*this); } catch(bad_alloc&) { printf("Failed to allocate memory for Choleski decompostions\n"); return 0; } } else (*fgBuffer) = *this; // AliSymMatrix& mchol = *fgBuffer; // for (int i=0;i=0;k--) sum -= mchol(i,k)*mchol(j,k); if (i == j) { if (sum <= 0.0) { // not positive-definite printf("The matrix is not positive definite [%e]\n" "Choleski decomposition is not possible\n",sum); return 0; } mchol(i,i) = TMath::Sqrt(sum); // } else mchol(j,i) = sum/mchol(i,i); } } return fgBuffer; } //___________________________________________________________ Bool_t AliSymMatrix::InvertChol() { // Invert matrix using Choleski decomposition // AliSymMatrix* mchol = DecomposeChol(); if (!mchol) { printf("Failed to invert the matrix\n"); return kFALSE; } // InvertChol(mchol); return kTRUE; // } //___________________________________________________________ void AliSymMatrix::InvertChol(AliSymMatrix* pmchol) { // Invert matrix using Choleski decomposition, provided the Cholseki's L matrix Int_t i,j,k; Double_t sum; AliSymMatrix& mchol = *pmchol; // // Invert decomposed triangular L matrix (Lower triangle is filled) for (i=0;i=0;k--) sum -= mchol(i,k)*b[k]; b[i]=sum/mchol(i,i); } for (i=fNrowIndex-1;i>=0;i--) { for (sum=b[i],k=i+1;k rowMax[i]) rowMax[i] = vl; // Max elemt of row i if (vl > colMax[j]) colMax[j] = vl; // Max elemt of column j if (i==j) continue; if (vl > rowMax[j]) rowMax[j] = vl; // Max elemt of row j if (vl > colMax[i]) colMax[i] = vl; // Max elemt of column i } // for (Int_t i=nGlo; i--;) { if (0.0 != rowMax[i]) rowMax[i] = 1./rowMax[i]; // Max elemt of row i if (0.0 != colMax[i]) colMax[i] = 1./colMax[i]; // Max elemt of column i } // } // for (Int_t i=nGlo; i--;) bUnUsed[i] = true; // if (!fgBuffer || fgBuffer->GetSize()!=GetSize()) { delete fgBuffer; try { fgBuffer = new AliSymMatrix(*this); } catch(bad_alloc&) { printf("Failed to allocate memory for matrix inversion buffer\n"); return 0; } } else (*fgBuffer) = *this; // if (stabilize) for (int i=0;iSetEl(j,i,TMath::Sqrt(rowMax[i])*vl*TMath::Sqrt(colMax[j]) ); // Equilibrate the V matrix } } // for (Int_t j=nGlo; j--;) fgBuffer->DiagElem(j) = TMath::Abs(QuerryDiag(j)); // save diagonal elem absolute values // for (Int_t i=0; iTMath::Max(TMath::Abs(vPivot),eps*fgBuffer->QuerryDiag(j)))) { vPivot = vl; iPivot = j; } } // if (iPivot >= 0) { // pivot found nRank++; bUnUsed[iPivot] = false; // This value is used vPivot = 1.0/vPivot; DiagElem(iPivot) = -vPivot; // Replace pivot by its inverse // for (Int_t j=0; j=jj ? (*this)(j,jj) : (*fgBuffer)(jj,j); r -= vPivot* ( j>iPivot ? Querry(j,iPivot) : fgBuffer->Querry(iPivot,j) ) * ( iPivot>jj ? Querry(iPivot,jj) : fgBuffer->Querry(jj,iPivot)); } } } // for (Int_t j=0; j=j) (*this)(i,j) *= vl; else (*fgBuffer)(j,i) *= vl; } // for (Int_t j=0; j=jj) vl = (*this)(j,jj) = -Querry(j,jj); else vl = (*fgBuffer)(j,jj) = -fgBuffer->Querry(j,jj); rowMax[j] += vl*vecB[jj]; } } for (Int_t j=0; j