# class TDecompSVD: public TDecompBase

```
Single Value Decomposition class

For an (m x n) matrix A with m >= n, the singular value decomposition
is
an (m x m) orthogonal matrix fU, an (m x n) diagonal matrix fS, and
an (n x n) orthogonal matrix fV so that A = U*S*V'.

If the row/column index of A starts at (rowLwb,colLwb) then the
decomposed matrices/vectors start at :
fU   : (rowLwb,colLwb)
fV   : (colLwb,colLwb)
fSig : (colLwb)

The diagonal matrix fS is stored in the singular values vector fSig .
The singular values, fSig[k] = S[k][k], are ordered so that
fSig[0] >= fSig[1] >= ... >= fSig[n-1].

The singular value decompostion always exists, so the decomposition
will (as long as m >=n) never fail. If m < n, the user should add
sufficient zero rows to A , so that m == n

Here fTol is used to set the threshold on the minimum allowed value
of the singular values:
min_singular = fTol*max(fSig[i])

```

## Function Members (Methods)

public:
 TDecompSVD() TDecompSVD(const TDecompSVD& another) TDecompSVD(Int_t nrows, Int_t ncols) TDecompSVD(const TMatrixD& m, Double_t tol = 0.0) TDecompSVD(Int_t row_lwb, Int_t row_upb, Int_t col_lwb, Int_t col_upb) virtual ~TDecompSVD() void TObject::AbstractMethod(const char* method) const virtual void TObject::AppendPad(Option_t* option = "") virtual void TObject::Browse(TBrowser* b) static TClass* Class() virtual const char* TObject::ClassName() const virtual void TObject::Clear(Option_t* = "") virtual TObject* TObject::Clone(const char* newname = "") const virtual Int_t TObject::Compare(const TObject* obj) const virtual Double_t Condition() virtual void TObject::Copy(TObject& object) const virtual Bool_t Decompose() virtual void TObject::Delete(Option_t* option = "")MENU virtual void Det(Double_t& d1, Double_t& d2) virtual Int_t TObject::DistancetoPrimitive(Int_t px, Int_t py) virtual void TObject::Draw(Option_t* option = "") virtual void TObject::DrawClass() constMENU virtual TObject* TObject::DrawClone(Option_t* option = "") constMENU virtual void TObject::Dump() constMENU virtual void TObject::Error(const char* method, const char* msgfmt) const virtual void TObject::Execute(const char* method, const char* params, Int_t* error = 0) virtual void TObject::Execute(TMethod* method, TObjArray* params, Int_t* error = 0) virtual void TObject::ExecuteEvent(Int_t event, Int_t px, Int_t py) virtual void TObject::Fatal(const char* method, const char* msgfmt) const virtual TObject* TObject::FindObject(const char* name) const virtual TObject* TObject::FindObject(const TObject* obj) const Int_t TDecompBase::GetColLwb() const Double_t TDecompBase::GetCondition() const Double_t TDecompBase::GetDet1() const Double_t TDecompBase::GetDet2() const virtual Option_t* TObject::GetDrawOption() const static Long_t TObject::GetDtorOnly() virtual const char* TObject::GetIconName() const const TMatrixD GetMatrix() virtual const char* TObject::GetName() const virtual Int_t GetNcols() const virtual Int_t GetNrows() const virtual char* TObject::GetObjectInfo(Int_t px, Int_t py) const static Bool_t TObject::GetObjectStat() virtual Option_t* TObject::GetOption() const Int_t TDecompBase::GetRowLwb() const const TVectorD& GetSig() virtual const char* TObject::GetTitle() const Double_t TDecompBase::GetTol() const const TMatrixD& GetU() virtual UInt_t TObject::GetUniqueID() const const TMatrixD& GetV() virtual Bool_t TObject::HandleTimer(TTimer* timer) virtual ULong_t TObject::Hash() const virtual void TObject::Info(const char* method, const char* msgfmt) const virtual Bool_t TObject::InheritsFrom(const char* classname) const virtual Bool_t TObject::InheritsFrom(const TClass* cl) const virtual void TObject::Inspect() constMENU TMatrixD Invert() Bool_t Invert(TMatrixD& inv) TMatrixD Invert(Bool_t& status) void TObject::InvertBit(UInt_t f) virtual TClass* IsA() const virtual Bool_t TObject::IsEqual(const TObject* obj) const virtual Bool_t TObject::IsFolder() const Bool_t TObject::IsOnHeap() const virtual Bool_t TObject::IsSortable() const Bool_t TObject::IsZombie() const virtual void TObject::ls(Option_t* option = "") const void TObject::MayNotUse(const char* method) const virtual Bool_t TDecompBase::MultiSolve(TMatrixD& B) virtual Bool_t TObject::Notify() void TObject::Obsolete(const char* method, const char* asOfVers, const char* removedFromVers) const static void TObject::operator delete(void* ptr) static void TObject::operator delete(void* ptr, void* vp) static void TObject::operator delete[](void* ptr) static void TObject::operator delete[](void* ptr, void* vp) void* TObject::operator new(size_t sz) void* TObject::operator new(size_t sz, void* vp) void* TObject::operator new[](size_t sz) void* TObject::operator new[](size_t sz, void* vp) TDecompSVD& operator=(const TDecompSVD& source) virtual void TObject::Paint(Option_t* option = "") virtual void TObject::Pop() virtual void Print(Option_t* opt = "") constMENU virtual Int_t TObject::Read(const char* name) virtual void TObject::RecursiveRemove(TObject* obj) void TObject::ResetBit(UInt_t f) virtual void TObject::SaveAs(const char* filename = "", Option_t* option = "") constMENU virtual void TObject::SavePrimitive(ostream& out, Option_t* option = "") void TObject::SetBit(UInt_t f) void TObject::SetBit(UInt_t f, Bool_t set) virtual void TObject::SetDrawOption(Option_t* option = "")MENU static void TObject::SetDtorOnly(void* obj) virtual void SetMatrix(const TMatrixD& a) static void TObject::SetObjectStat(Bool_t stat) Double_t TDecompBase::SetTol(Double_t newTol) virtual void TObject::SetUniqueID(UInt_t uid) virtual void ShowMembers(TMemberInspector& insp) virtual Bool_t Solve(TVectorD& b) virtual Bool_t Solve(TMatrixDColumn& b) virtual TVectorD Solve(const TVectorD& b, Bool_t& ok) virtual void Streamer(TBuffer& b) void StreamerNVirtual(TBuffer& b) virtual void TObject::SysError(const char* method, const char* msgfmt) const Bool_t TObject::TestBit(UInt_t f) const Int_t TObject::TestBits(UInt_t f) const virtual Bool_t TransSolve(TVectorD& b) virtual Bool_t TransSolve(TMatrixDColumn& b) virtual TVectorD TransSolve(const TVectorD& b, Bool_t& ok) virtual void TObject::UseCurrentStyle() virtual void TObject::Warning(const char* method, const char* msgfmt) const virtual Int_t TObject::Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0) virtual Int_t TObject::Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0) const
protected:
 static Bool_t Bidiagonalize(TMatrixD& v, TMatrixD& u, TVectorD& sDiag, TVectorD& oDiag) static void Diag_1(TMatrixD& v, TVectorD& sDiag, TVectorD& oDiag, Int_t k) static void Diag_2(TVectorD& sDiag, TVectorD& oDiag, Int_t k, Int_t l) static void Diag_3(TMatrixD& v, TMatrixD& u, TVectorD& sDiag, TVectorD& oDiag, Int_t k, Int_t l) static Bool_t Diagonalize(TMatrixD& v, TMatrixD& u, TVectorD& sDiag, TVectorD& oDiag) static void TDecompBase::DiagProd(const TVectorD& diag, Double_t tol, Double_t& d1, Double_t& d2) virtual void TObject::DoError(int level, const char* location, const char* fmt, va_list va) const virtual const TMatrixDBase& GetDecompMatrix() const Int_t TDecompBase::Hager(Double_t& est, Int_t iter = 5) void TObject::MakeZombie() void TDecompBase::ResetStatus() static void SortSingular(TMatrixD& v, TMatrixD& u, TVectorD& sDiag)

## Data Members

public:
 enum { kWorkMax }; enum TDecompBase::EMatrixDecompStat { kInit kPatternSet kValuesSet kMatrixSet kDecomposed kDetermined kCondition kSingular }; enum TDecompBase::[unnamed] { kWorkMax }; enum TObject::EStatusBits { kCanDelete kMustCleanup kObjInCanvas kIsReferenced kHasUUID kCannotPick kNoContextMenu kInvalidObject }; enum TObject::[unnamed] { kIsOnHeap kNotDeleted kZombie kBitMask kSingleKey kOverwrite kWriteDelete };
protected:
 Int_t TDecompBase::fColLwb Column lower bound of decomposed matrix Double_t TDecompBase::fCondition matrix condition number Double_t TDecompBase::fDet1 determinant mantissa Double_t TDecompBase::fDet2 determinant exponent for powers of 2 Int_t TDecompBase::fRowLwb Row lower bound of decomposed matrix TVectorD fSig diagonal of diagonal matrix Double_t TDecompBase::fTol sqrt(epsilon); epsilon is smallest number number so that 1+epsilon > 1 TMatrixD fU orthogonal matrix TMatrixD fV orthogonal matrix

## Function documentation

TDecompSVD(Int_t nrows, Int_t ncols)
``` Constructor for (nrows x ncols) matrix
```
TDecompSVD(Int_t row_lwb, Int_t row_upb, Int_t col_lwb, Int_t col_upb)
``` Constructor for ([row_lwb..row_upb] x [col_lwb..col_upb]) matrix
```
TDecompSVD(const TMatrixD& m, Double_t tol = 0.0)
``` Constructor for general matrix A .
```
TDecompSVD(const TDecompSVD& another)
``` Copy constructor
```

``` SVD decomposition of matrix
If the decomposition succeeds, bit kDecomposed is set , otherwise kSingular
```
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 applied to the left (Q^T) and to the right (H) of a ,
so that A = Q . C . H^T with matrix C bidiagonal. Q and H are orthogonal matrices .

Output:
v     - (n x n) - matrix H in the (n x n) part of v
u     - (m x m) - matrix Q^T
sDiag - diagonal of the (m x n) C
oDiag - off-diagonal elements of matrix C

Test code for the output:
const Int_t nRow = v.GetNrows();
const Int_t nCol = v.GetNcols();
TMatrixD H(v); H.ResizeTo(nCol,nCol);
TMatrixD E1(nCol,nCol); E1.UnitMatrix();
TMatrixD Ht(TMatrixDBase::kTransposed,H);
Bool_t ok = kTRUE;
ok &= VerifyMatrixIdentity(Ht * H,E1,kTRUE,1.0e-13);
ok &= VerifyMatrixIdentity(H * Ht,E1,kTRUE,1.0e-13);
TMatrixD E2(nRow,nRow); E2.UnitMatrix();
TMatrixD Qt(u);
TMatrixD Q(TMatrixDBase::kTransposed,Qt);
ok &= VerifyMatrixIdentity(Q * Qt,E2,kTRUE,1.0e-13);
TMatrixD C(nRow,nCol);
TMatrixDDiag(C) = sDiag;
for (Int_t i = 0; i < nCol-1; i++)
C(i,i+1) = oDiag(i+1);
TMatrixD A = Q*C*Ht;
ok &= VerifyMatrixIdentity(A,a,kTRUE,1.0e-13);
```
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, so that S' = U'^T . C . V' is diagonal. U' and V' are orthogonal
matrices .

Output:
v     - (n x n) - matrix H . V' in the (n x n) part of v
u     - (m x m) - matrix U'^T . Q^T
sDiag - diagonal of the (m x n) S'

return convergence flag:  0 -> no convergence
1 -> convergence

Test code for the output:
const Int_t nRow = v.GetNrows();
const Int_t nCol = v.GetNcols();
TMatrixD tmp = v; tmp.ResizeTo(nCol,nCol);
TMatrixD Vprime  = Ht*tmp;
TMatrixD Vprimet(TMatrixDBase::kTransposed,Vprime);
TMatrixD Uprimet = u*Q;
TMatrixD Uprime(TMatrixDBase::kTransposed,Uprimet);
TMatrixD Sprime(nRow,nCol);
TMatrixDDiag(Sprime) = sDiag;
ok &= VerifyMatrixIdentity(Uprimet * C * Vprime,Sprime,kTRUE,1.0e-13);
ok &= VerifyMatrixIdentity(Q*Uprime * Sprime * Vprimet * Ht,a,kTRUE,1.0e-13);
```
void Diag_1(TMatrixD& v, TVectorD& sDiag, TVectorD& oDiag, Int_t k)
``` Step 1 in the matrix diagonalization
```
void Diag_2(TVectorD& sDiag, TVectorD& oDiag, Int_t k, Int_t l)
``` Step 2 in the matrix diagonalization
```
void Diag_3(TMatrixD& v, TMatrixD& u, TVectorD& sDiag, TVectorD& oDiag, Int_t k, Int_t l)
``` Step 3 in the matrix diagonalization
```
void SortSingular(TMatrixD& v, TMatrixD& u, TVectorD& sDiag)
``` Perform a permutation transformation on the diagonal matrix S', so that
matrix S'' = U''^T . S' . V''  has diagonal elements ordered such that they
do not increase.

Output:
v     - (n x n) - matrix H . V' . V'' in the (n x n) part of v
u     - (m x m) - matrix U''^T . U'^T . Q^T
sDiag - diagonal of the (m x n) S''
```
const TMatrixD GetMatrix()
``` Reconstruct the original matrix using the decomposition parts
```
void SetMatrix(const TMatrixD& a)
``` Set matrix to be decomposed
```
Bool_t Solve(TVectorD& b)
``` Solve Ax=b assuming the SVD form of A is stored . Solution returned in b.
If A is of size (m x n), input vector b should be of size (m), however,
the solution, returned in b, will be in the first (n) elements .

For m > n , x  is the least-squares solution of min(A . x - b)
```

``` Solve Ax=b assuming the SVD form of A is stored . Solution returned in the
matrix column cb b.
If A is of size (m x n), input vector b should be of size (m), however,
the solution, returned in b, will be in the first (n) elements .

For m > n , x  is the least-squares solution of min(A . x - b)
```

``` Solve A^T x=b assuming the SVD form of A is stored . Solution returned in b.
```

``` Solve A^T x=b assuming the SVD form of A is stored . Solution returned in b.
```

``` Matrix condition number
```
void Det(Double_t& d1, Double_t& d2)
``` Matrix determinant det = d1*TMath::Power(2.,d2)
```
Int_t GetNrows() const
Int_t GetNcols() const
Bool_t Invert(TMatrixD& inv)
``` For a matrix A(m,n), its inverse A_inv is defined as A * A_inv = A_inv * A = unit
The user should always supply a matrix of size (m x m) !
If m > n , only the (n x m) part of the returned (pseudo inverse) matrix
should be used .
```
TMatrixD Invert(Bool_t& status)
``` For a matrix A(m,n), its inverse A_inv is defined as A * A_inv = A_inv * A = unit
(n x m) Ainv is returned .
```
void Print(Option_t* opt = "") const
``` Print class members
```
TDecompSVD & operator=(const TDecompSVD& source)
``` Assignment operator
```
const TMatrixDBase & GetDecompMatrix() const
`{ return fU; }`

`{}`
virtual ~TDecompSVD()
`{}`
const TMatrixD & GetU()
const TMatrixD & GetV()
const TVectorD & GetSig()
Bool_t Solve(TVectorD& b)

Bool_t Invert(TMatrixD& inv)