62 fLU.ResizeTo(nrows,nrows);
70 const Int_t nrows = row_upb-row_lwb+1;
78 fLU.ResizeTo(row_lwb,row_lwb+nrows-1,row_lwb,row_lwb+nrows-1);
88 if (
a.GetNrows() !=
a.GetNcols() ||
a.GetRowLwb() !=
a.GetColLwb()) {
89 Error(
"TDecompLU(const TMatrixD &",
"matrix should be square");
130 Error(
"Decompose()",
"Matrix has not been set");
153 Error(
"GetMatrix()",
"Matrix is singular");
158 Error(
"GetMatrix()",
"Decomposition failed");
168 for (
Int_t irow = 0; irow <
n; irow++) {
169 const Int_t off_row = irow*
n;
170 for (
Int_t icol = 0; icol <
n; icol++) {
171 if (icol > irow) pL[off_row+icol] = 0.;
172 else if (icol < irow) pU[off_row+icol] = 0.;
173 else pL[off_row+icol] = 1.;
181 Double_t *
const pA =
a.GetMatrixArray();
182 for (
Int_t i =
n-1; i >= 0; i--) {
187 for (
Int_t k = 0; k <
n; k++) {
189 pA[off_j+k] = pA[off_i+k];
206 if (
a.GetNrows() !=
a.GetNcols() ||
a.GetRowLwb() !=
a.GetColLwb()) {
207 Error(
"TDecompLU(const TMatrixD &",
"matrix should be square");
236 Error(
"Solve()",
"Matrix is singular");
241 Error(
"Solve()",
"Decomposition failed");
246 if (
fLU.GetNrows() !=
b.GetNrows() ||
fLU.GetRowLwb() !=
b.GetLwb()) {
247 Error(
"Solve(TVectorD &",
"vector and matrix incompatible");
259 for (i = 0; i <
n ; i++) {
262 Error(
"Solve(TVectorD &b)",
"LU[%d,%d]=%.4e < %.4e",i,i,pLU[off_i+i],
fTol);
269 for (i = 0; i <
n; i++) {
275 for (
Int_t j = nonzero; j < i; j++)
276 r -= pLU[off_i+j]*pb[j];
283 for (i =
n-1; i >= 0; i--) {
286 for (
Int_t j = i+1; j <
n; j++)
287 r -= pLU[off_i+j]*pb[j];
288 pb[i] =
r/pLU[off_i+i];
303 Error(
"Solve()",
"Matrix is singular");
308 Error(
"Solve()",
"Decomposition failed");
313 if (
fLU.GetNrows() !=
b->GetNrows() ||
fLU.GetRowLwb() !=
b->GetRowLwb()) {
314 Error(
"Solve(TMatrixDColumn &",
"vector and matrix incompatible");
324 for (i = 0; i <
n ; i++) {
327 Error(
"Solve(TMatrixDColumn &cb)",
"LU[%d,%d]=%.4e < %.4e",i,i,pLU[off_i+i],
fTol);
337 for (i = 0; i <
n; i++) {
339 const Int_t off_i2 = i*inc;
341 const Int_t off_iperm = iperm*inc;
343 pcb[off_iperm] = pcb[off_i2];
345 for (
Int_t j = nonzero; j <= i-1; j++)
346 r -= pLU[off_i+j]*pcb[j*inc];
353 for (i =
n-1; i >= 0; i--) {
355 const Int_t off_i2 = i*inc;
357 for (
Int_t j = i+1; j <
n; j++)
358 r -= pLU[off_i+j]*pcb[j*inc];
359 pcb[off_i2] =
r/pLU[off_i+i];
374 Error(
"TransSolve()",
"Matrix is singular");
379 Error(
"TransSolve()",
"Decomposition failed");
384 if (
fLU.GetNrows() !=
b.GetNrows() ||
fLU.GetRowLwb() !=
b.GetLwb()) {
385 Error(
"TransSolve(TVectorD &",
"vector and matrix incompatible");
397 for (i = 0; i <
n ; i++) {
400 Error(
"TransSolve(TVectorD &b)",
"LU[%d,%d]=%.4e < %.4e",i,i,pLU[off_i+i],
fTol);
406 for (i = 0; i <
n; i++) {
409 for (
Int_t j = 0; j < i ; j++) {
411 r -= pLU[off_j+i]*pb[j];
413 pb[i] =
r/pLU[off_i+i];
418 for (i =
n-1 ; i >= 0; i--) {
421 for (
Int_t j = i+1; j <= nonzero; j++) {
423 r -= pLU[off_j+i]*pb[j];
444 Error(
"TransSolve()",
"Matrix is singular");
449 Error(
"TransSolve()",
"Decomposition failed");
454 if (
fLU.GetNrows() !=
b->GetNrows() ||
fLU.GetRowLwb() !=
b->GetRowLwb()) {
455 Error(
"TransSolve(TMatrixDColumn &",
"vector and matrix incompatible");
467 for (i = 0; i <
n ; i++) {
470 Error(
"TransSolve(TMatrixDColumn &cb)",
"LU[%d,%d]=%.4e < %.4e",i,i,pLU[off_i+i],
fTol);
476 for (i = 0; i <
n; i++) {
479 for (
Int_t j = 0; j < i ; j++) {
481 r -= pLU[off_j+i]*cb(j+lwb);
483 cb(i+lwb) =
r/pLU[off_i+i];
488 for (i =
n-1 ; i >= 0; i--) {
491 for (
Int_t j = i+1; j <= nonzero; j++) {
493 r -= pLU[off_j+i]*cb(j+lwb);
498 cb(i+lwb) = cb(iperm+lwb);
529 Error(
"Invert(TMatrixD &",
"Input matrix has wrong shape");
548 TMatrixD inv(rowLwb,rowUpb,rowLwb,rowUpb);
562 printf(
"fSign = %f\n",
fSign);
565 printf(
"[%d] = %d\n",i,
fIndex[i]);
574 if (
this != &source) {
615 for (
Int_t i = 0; i <
n ; i++) {
618 for (
Int_t j = 0; j <
n; j++) {
623 scale[i] = (max == 0.0 ? 0.0 : 1.0/max);
626 for (
Int_t j = 0; j <
n; j++) {
629 for (
Int_t i = 0; i < j; i++) {
632 for (
Int_t k = 0; k < i; k++) {
634 r -= pLU[off_i+k]*pLU[off_k+j];
646 for (
Int_t i = j; i <
n; i++) {
649 for (
Int_t k = 0; k < j; k++) {
651 r -= pLU[off_i+k]*pLU[off_k+j];
663 const Int_t off_imax = imax*
n;
664 for (
Int_t k = 0; k <
n; k++ ) {
665 const Double_t tmp = pLU[off_imax+k];
666 pLU[off_imax+k] = pLU[off_j+k];
670 scale[imax] = scale[j];
675 if (pLU[off_j+j] != 0.0) {
679 const Double_t tmp = 1.0/pLU[off_j+j];
680 for (
Int_t i = j+1; i <
n; i++) {
686 ::Error(
"TDecompLU::DecomposeLUCrout",
"matrix is singular");
687 if (allocated)
delete [] allocated;
717 for (
Int_t j = 0; j <
n-1; j++) {
725 for (
Int_t i = j+1; i <
n; i++) {
736 const Int_t off_ipov = i_pivot*
n;
737 for (
Int_t k = 0; k <
n; k++ ) {
738 const Double_t tmp = pLU[off_ipov+k];
739 pLU[off_ipov+k] = pLU[off_j+k];
746 const Double_t mLUjj = pLU[off_j+j];
751 for (
Int_t i = j+1; i <
n; i++) {
753 const Double_t mLUij = pLU[off_i+j]/mLUjj;
754 pLU[off_i+j] = mLUij;
756 for (
Int_t k = j+1; k <
n; k++) {
757 const Double_t mLUik = pLU[off_i+k];
758 const Double_t mLUjk = pLU[off_j+k];
759 pLU[off_i+k] = mLUik-mLUij*mLUjk;
763 ::Error(
"TDecompLU::DecomposeLUGauss",
"matrix is singular");
780 ::Error(
"TDecompLU::InvertLU",
"matrix should be square");
788 Int_t *allocatedI =
nullptr;
789 Int_t *index = worki;
791 allocatedI =
new Int_t[
n];
799 delete [] allocatedI;
800 ::Error(
"TDecompLU::InvertLU",
"matrix is singular, %d diag elements < tolerance of %.4e",nrZeros,tol);
817 for (j = 0; j <
n; j++) {
820 pLU[off_j+j] = 1./pLU[off_j+j];
821 const Double_t mLU_jj = -pLU[off_j+j];
827 for (k = 0; k <= j-1; k++) {
829 if ( pX[off_k] != 0.0 ) {
831 for (
Int_t i = 0; i <= k-1; i++) {
833 pX[off_i] += tmp*pLU[off_i+k];
835 pX[off_k] *= pLU[off_k+k];
838 for (k = 0; k <= j-1; k++) {
854 for (j =
n-1; j >= 0; j--) {
857 for (
Int_t i = j+1; i <
n; i++) {
859 pWorkD[i] = pLU[off_i+j];
869 for (
Int_t irow = 0; irow <
n; irow++) {
872 for (
Int_t icol = 0; icol <
n-1-j ; icol++)
873 sum += *mp++ * *sp++;
882 delete [] allocatedD;
885 for (j =
n-1; j >= 0; j--) {
886 const Int_t jperm = index[j];
888 for (
Int_t i = 0; i <
n; i++) {
890 const Double_t tmp = pLU[off_i+jperm];
891 pLU[off_i+jperm] = pLU[off_i+j];
898 delete [] allocatedI;
int Int_t
Signed integer 4 bytes (int).
bool Bool_t
Boolean (0=false, 1=true) (bool).
double Double_t
Double 8 bytes.
const char Option_t
Option string (const char).
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
TMatrixTBase< Double_t > TMatrixDBase
TMatrixTDiag_const< Double_t > TMatrixDDiag_const
TMatrixTColumn< Double_t > TMatrixDColumn
TMatrixT< Double_t > TMatrixD
TVectorT< Double_t > TVectorD
static void DiagProd(const TVectorD &diag, Double_t tol, Double_t &d1, Double_t &d2)
virtual Bool_t MultiSolve(TMatrixD &B)
Solve set of equations with RHS in columns of B.
TDecompBase & operator=(const TDecompBase &source)
Assignment operator.
TDecompBase()
Default constructor.
void Print(Option_t *opt="") const override
Print class members.
virtual void Det(Double_t &d1, Double_t &d2)
Matrix determinant det = d1*TMathPower(2.,d2).
Int_t GetNrows() const override
Bool_t TransSolve(TVectorD &b) override
Solve A^T x=b assuming the LU form of A^T is stored in fLU, but assume b has not been transformed.
Int_t GetNcols() const override
virtual void SetMatrix(const TMatrixD &a)
Set matrix to be decomposed.
static Bool_t DecomposeLUGauss(TMatrixD &lu, Int_t *index, Double_t &sign, Double_t tol, Int_t &nrZeros)
LU decomposition using Gaussian Elimination with partial pivoting (See Golub & Van Loan,...
TDecompLU()
Default constructor.
const TMatrixD GetMatrix()
Reconstruct the original matrix using the decomposition parts.
static Bool_t DecomposeLUCrout(TMatrixD &lu, Int_t *index, Double_t &sign, Double_t tol, Int_t &nrZeros)
Crout/Doolittle algorithm of LU decomposing a square matrix, with implicit partial pivoting.
void Det(Double_t &d1, Double_t &d2) override
Calculate determinant det = d1*TMathPower(2.,d2).
void Print(Option_t *opt="") const override
Print internals of this object.
static Bool_t InvertLU(TMatrixD &a, Double_t tol, Double_t *det=nullptr)
Calculate matrix inversion through in place forward/backward substitution.
Bool_t Solve(TVectorD &b) override
Solve Ax=b assuming the LU form of A is stored in fLU, but assume b has not been transformed.
Bool_t Decompose() override
Matrix A is decomposed in components U and L so that P * A = U * L If the decomposition succeeds,...
TDecompLU & operator=(const TDecompLU &source)
assignment operator
virtual TMatrixTBase< Element > & UnitMatrix()
Make a unit matrix (matrix need not be a square one).
const TMatrixTBase< Element > * GetMatrix() const
const Element * GetMatrixArray() const override
Bool_t TestBit(UInt_t f) const
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
static uint64_t sum(uint64_t i)