54 Error(
"TDecompSVD(Int_t,Int_t",
"matrix rows should be >= columns");
57 fU.ResizeTo(nrows,nrows);
59 fV.ResizeTo(nrows,ncols);
67 const Int_t nrows = row_upb-row_lwb+1;
68 const Int_t ncols = col_upb-col_lwb+1;
71 Error(
"TDecompSVD(Int_t,Int_t,Int_t,Int_t",
"matrix rows should be >= columns");
76 fU.ResizeTo(nrows,nrows);
78 fV.ResizeTo(nrows,ncols);
87 if (
a.GetNrows() <
a.GetNcols()) {
88 Error(
"TDecompSVD(const TMatrixD &",
"matrix rows should be >= columns");
99 const Int_t nRow =
a.GetNrows();
100 const Int_t nCol =
a.GetNcols();
102 fU.ResizeTo(nRow,nRow);
104 fV.ResizeTo(nRow,nCol);
107 memcpy(
fV.GetMatrixArray(),
a.GetMatrixArray(),nRow*nCol*
sizeof(
Double_t));
127 Error(
"Decompose()",
"Matrix has not been set");
138 else offDiag.
Use(nCol,work);
150 fV.ResizeTo(nCol,nCol);
fV.Shift(colLwb,colLwb);
152 fU.Transpose(
fU);
fU.Shift(rowLwb,colLwb);
193 const Int_t nRow_v =
v.GetNrows();
194 const Int_t nCol_v =
v.GetNcols();
200 for (
Int_t i = 0; i < nCol_v; i++) {
204 if (i < nCol_v-1 || nRow_v > nCol_v) {
211 for (
Int_t j = i; j < nCol_v; j++) {
217 for (
Int_t j = 0; j < nCol_u; j++)
236 for (
Int_t j = i; j < nRow_v; j++) {
242 for (
Int_t k = i+2; k < nCol_v; k++)
251 for (
Int_t i = 1; i < nCol_v; i++)
260 for (
Int_t i = nCol_v-1; i >= 0; i--) {
267 for (
Int_t k = i; k < nCol_v; k++) {
312 const Int_t nCol_v =
v.GetNcols();
315 for (
Int_t i = 1; i < nCol_v; i++)
319 const Double_t eps = std::numeric_limits<double>::epsilon();
321 const Int_t niterm = 10*nCol_v;
322 for (
Int_t k = nCol_v-1; k >= 0; k--) {
336 for (
Int_t ll = k; ll >= 0 ; ll--) {
347 if (
l > 0 && !elzero)
353 if (niter <= niterm)
goto loop;
354 ::Error(
"TDecompSVD::Diagonalize",
"no convergence after %d steps",niter);
361 sDiag(k) = -sDiag(k);
375 const Int_t nCol_v =
v.GetNcols();
378 for (
Int_t i = k-1; i >= 0; i--) {
389 for (
Int_t j = 0; j < nCol_v; j++)
399 for (
Int_t i =
l; i <= k; i++) {
429 if (psl == 0.0 || pok == 0.0 || psk1 == 0.0) {
430 const Double_t b = ((psk1-psk)*(psk1+psk)+pok1*pok1)/2.0;
431 const Double_t c = (psk*pok1)*(psk*pok1);
434 if ((
b != 0.0) | (
c != 0.0)) {
441 f = (psl+psk)*(psl-psk)+shift;
443 f = ((psk1-psk)*(psk1+psk)+(pok1-pok)*(pok1+pok))/(2.*pok*psk1);
447 f = ((psl-psk)*(psl+psk)+pok*(psk1/t-pok))/psl;
450 const Int_t nCol_v =
v.GetNcols();
455 for (
Int_t i =
l; i <= k-1; i++) {
469 for (j = 0; j < nCol_v; j++)
481 for (j = 0; j < nCol_u; j++)
498 const Int_t nCol_v =
v.GetNcols();
512 while (!found && i < nCol_v) {
519 for (i = 1; i < nCol_v; i++) {
522 for (j = i; j < nCol_v; j++) {
533 for (j = 0; j < nCol_v; j++) {
534 const Int_t off_j = j*nCol_v;
536 pV[off_j+k] = pV[off_j+i-1];
540 for (j = 0; j < nCol_u; j++) {
541 const Int_t off_k = k*nCol_u;
542 const Int_t off_i1 = (i-1)*nCol_u;
544 pU[off_k+j] = pU[off_i1+j];
559 Error(
"GetMatrix()",
"Matrix is singular");
564 Error(
"GetMatrix()",
"Decomposition failed");
569 const Int_t nRows =
fU.GetNrows();
570 const Int_t nCols =
fV.GetNcols();
586 if (
a.GetNrows() <
a.GetNcols()) {
587 Error(
"TDecompSVD(const TMatrixD &",
"matrix rows should be >= columns");
596 const Int_t nRow =
a.GetNrows();
597 const Int_t nCol =
a.GetNcols();
599 fU.ResizeTo(nRow,nRow);
601 fV.ResizeTo(nRow,nCol);
604 memcpy(
fV.GetMatrixArray(),
a.GetMatrixArray(),nRow*nCol*
sizeof(
Double_t));
626 if (
fU.GetNrows() !=
b.GetNrows() ||
fU.GetRowLwb() !=
b.GetLwb())
628 Error(
"Solve(TVectorD &",
"vector and matrix incompatible");
636 const Int_t lwb =
fU.GetColLwb();
637 const Int_t upb = lwb+
fV.GetNcols()-1;
641 for (
Int_t irow = lwb; irow <= upb; irow++) {
643 if (
fSig(irow) > threshold) {
651 if (
b.GetNrows() >
fV.GetNrows()) {
653 tmp2.
Use(lwb,upb,
b.GetMatrixArray());
682 if (
fU.GetNrows() !=
b->GetNrows() ||
fU.GetRowLwb() !=
b->GetRowLwb())
684 Error(
"Solve(TMatrixDColumn &",
"vector and matrix incompatible");
692 const Int_t lwb =
fU.GetColLwb();
693 const Int_t upb = lwb+
fV.GetNcols()-1;
698 for (
Int_t irow = lwb; irow <= upb; irow++) {
700 if (
fSig(irow) > threshold) {
708 if (
b->GetNrows() >
fV.GetNrows()) {
734 if (
fU.GetNrows() !=
fV.GetNrows() ||
fU.GetRowLwb() !=
fV.GetRowLwb()) {
735 Error(
"TransSolve(TVectorD &",
"matrix should be square");
739 if (
fV.GetNrows() !=
b.GetNrows() ||
fV.GetRowLwb() !=
b.GetLwb())
741 Error(
"TransSolve(TVectorD &",
"vector and matrix incompatible");
749 const Int_t lwb =
fU.GetColLwb();
750 const Int_t upb = lwb+
fV.GetNcols()-1;
754 for (
Int_t i = lwb; i <= upb; i++) {
756 if (
fSig(i) > threshold) {
784 if (
fU.GetNrows() !=
fV.GetNrows() ||
fU.GetRowLwb() !=
fV.GetRowLwb()) {
785 Error(
"TransSolve(TMatrixDColumn &",
"matrix should be square");
789 if (
fV.GetNrows() !=
b->GetNrows() ||
fV.GetRowLwb() !=
b->GetRowLwb())
791 Error(
"TransSolve(TMatrixDColumn &",
"vector and matrix incompatible");
799 const Int_t lwb =
fU.GetColLwb();
800 const Int_t upb = lwb+
fV.GetNcols()-1;
805 for (
Int_t i = lwb; i <= upb; i++) {
807 if (
fSig(i) > threshold) {
866 return fU.GetNrows();
871 return fV.GetNcols();
884 const Int_t nRows =
fU.GetNrows();
888 Error(
"Invert(TMatrixD &",
"Input matrix has wrong shape");
906 const Int_t rowUpb = rowLwb+
fU.GetNrows()-1;
907 TMatrixD inv(rowLwb,rowUpb,colLwb,colLwb+
fU.GetNrows()-1);
910 inv.
ResizeTo(rowLwb,rowLwb+
fV.GetNcols()-1,colLwb,colLwb+
fU.GetNrows()-1);
931 if (
this != &source) {
933 fU.ResizeTo(source.
fU);
935 fV.ResizeTo(source.
fV);
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).
Bool_t DefHouseHolder(const TVectorD &vc, Int_t lp, Int_t l, Double_t &up, Double_t &b, Double_t tol=0.0)
Define a Householder-transformation through the parameters up and b .
void ApplyGivens(Double_t &z1, Double_t &z2, Double_t c, Double_t s)
Apply a Givens transformation as defined by c and s to the vector components v1 and v2 .
void ApplyHouseHolder(const TVectorD &vc, Double_t up, Double_t b, Int_t lp, Int_t l, TMatrixDRow &cr)
Apply Householder-transformation.
void DefGivens(Double_t v1, Double_t v2, Double_t &c, Double_t &s)
Defines a Givens-rotation by calculating 2 rotation parameters c and s.
void DefAplGivens(Double_t &v1, Double_t &v2, Double_t &c, Double_t &s)
Define and apply a Givens-rotation by calculating 2 rotation parameters c and s.
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
TMatrixTBase< Double_t > TMatrixDBase
TMatrixTRow< Double_t > TMatrixDRow
TMatrixTColumn_const< Double_t > TMatrixDColumn_const
TMatrixTDiag< Double_t > TMatrixDDiag
TMatrixTRow_const< Double_t > TMatrixDRow_const
TMatrixTColumn< Double_t > TMatrixDColumn
TMatrixT< Double_t > TMatrixD
TVectorT< Double_t > TVectorD
Array of doubles (64 bits per element).
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.
void Det(Double_t &d1, Double_t &d2) override
Matrix determinant det = d1*TMathPower(2.,d2).
static void Diag_3(TMatrixD &v, TMatrixD &u, TVectorD &sDiag, TVectorD &oDiag, Int_t k, Int_t l)
Step 3 in the matrix diagonalization.
static void Diag_2(TVectorD &sDiag, TVectorD &oDiag, Int_t k, Int_t l)
Step 2 in the matrix diagonalization.
TDecompSVD & operator=(const TDecompSVD &source)
Assignment operator.
Bool_t Solve(TVectorD &b) override
Solve Ax=b assuming the SVD form of A is stored .
static Bool_t Bidiagonalize(TMatrixD &v, TMatrixD &u, TVectorD &sDiag, TVectorD &oDiag)
Bidiagonalize the (m x n) - matrix a (stored in v) through a series of Householder transformations ap...
static void Diag_1(TMatrixD &v, TVectorD &sDiag, TVectorD &oDiag, Int_t k)
Step 1 in the matrix diagonalization.
static Bool_t Diagonalize(TMatrixD &v, TMatrixD &u, TVectorD &sDiag, TVectorD &oDiag)
Diagonalizes in an iterative fashion the bidiagonal matrix C as described through sDiag and oDiag,...
Double_t Condition() override
Matrix condition number.
Bool_t Decompose() override
SVD decomposition of matrix If the decomposition succeeds, bit kDecomposed is set ,...
Int_t GetNrows() const override
const TMatrixD GetMatrix()
Reconstruct the original matrix using the decomposition parts.
Bool_t TransSolve(TVectorD &b) override
Solve A^T x=b assuming the SVD form of A is stored . Solution returned in b.
virtual void SetMatrix(const TMatrixD &a)
Set matrix to be decomposed.
Int_t GetNcols() const override
static void SortSingular(TMatrixD &v, TMatrixD &u, TVectorD &sDiag)
Perform a permutation transformation on the diagonal matrix S', so that matrix S'' = U''^T .
void Print(Option_t *opt="") const override
Print class members.
virtual TMatrixTBase< Element > & UnitMatrix()
Make a unit matrix (matrix need not be a square one).
virtual TMatrixTBase< Element > & Shift(Int_t row_shift, Int_t col_shift)
Shift the row index by adding row_shift and the column index by adding col_shift, respectively.
const TMatrixTBase< Element > * GetMatrix() const
void Assign(Element val)
Assign val to every element of the matrix row.
const Element * GetMatrixArray() const override
TMatrixTBase< Element > & ResizeTo(Int_t nrows, Int_t ncols, Int_t=-1) override
Set size of the matrix to nrows x ncols New dynamic elements are created, the overlapping part of the...
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.
TVectorT< Element > & ResizeTo(Int_t lwb, Int_t upb)
Resize the vector to [lwb:upb] .
TVectorT< Element > & SetSub(Int_t row_lwb, const TVectorT< Element > &source)
Insert vector source starting at [row_lwb], thereby overwriting the part [row_lwb....
TVectorT< Element > & Use(Int_t lwb, Int_t upb, Element *data)
Use the array data to fill the vector lwb..upb].
Element * GetMatrixArray()
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Double_t Sqrt(Double_t x)
Returns the square root of x.
Double_t Hypot(Double_t x, Double_t y)
Returns sqrt(x*x + y*y).
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.