Table of contents
1.
Introduction
2.
Understanding SVD decomposition
2.1.
Class BDCSVD
2.1.1.
Public Member Functions
2.1.2.
Constructor & Destructor
2.1.3.
Member Function Documentation
2.2.
Class JacobiSVD
2.2.1.
Public Member Functions
2.2.2.
Constructor & Destructor
2.2.3.
Member Function Documentation
3.
Frequently Asked Questions
3.1.
How do you find the decomposition of an SVD matrix?
3.2.
What do eigenvalues mean?
3.3.
Does every matrix have an eigen decomposition?
4.
Conclusion
Last Updated: Mar 27, 2024

Understanding SVD decomposition

Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Let's ensure we understand the foundational concepts before delving further into the subjects. Here is a brief introduction if you are unfamiliar with the Eigen.

Understanding SVD decomposition

The C++ template library Eigen is used for matrix and linear algebra operations. It supports all matrix sizes, including sparse matrices, small fixed-size matrices, and arbitrary huge dense matrices. We run our test suite against several compilers to ensure reliability and find any compiler bugs, and Eigen provides good support for these compilers.                                    

In this blog, We will explain the details of SVD decomposition for real and complex matrices, with BDCSVD and jacobiSVD with their primary member function, constructor and destructor, and member function.

Without further ado, let's get started.

Understanding SVD decomposition

In this part, We talk about SVD decomposition for matrices (both real and complex). There are two decomposition algorithms offered:

🎯 JacobiSVDFor small matrices, two-sided Jacobi iterations are quickly implemented, but for bigger matrices, they take a very long time. 

🎯 BDCSVD: Applying an upper-bidiagonalization that is still quick for large problems on top of a recursive divide-and-conquer approach.

💁 The corresponding classes and the following MatrixBase methods provide access to these decompositions:

  • MatrixBase::jacobiSvd()
  • MatrixBase::bdcSvd()

Class BDCSVD

Applying an upper-bidiagonalization that is still quick for large problems on top of a recursive divide-and-conquer approach.

template<typename MatrixType_, int Options_>
class Eigen::BDCSVD< MatrixType_, Options_ >

 

Template Parameters

☑️ Matrix Type_ which type of matrix  are we using to compute the SVD decomposition

☑️ Options_ The options for computing unitaries U and V can be specified using this optional argument. ComputeFullV are examples of possible values. U or V cannot be ordered in both the thin and full versions. Unitaries are, by default, not computed.

This class divide-and-conquer diagonalizes the input matrix after first reducing it to bi-diagonal form using class UpperBidiagonalization. Class JacobiSVD is used to diagonalize small blocks. With the setSwitchSize() method, you can modify the switching size; the default is 16. As a result, it is preferable to apply JacobiSVD directly for small matrices (16). BDCSVD is strongly advised for larger ones and can be orders of magnitude faster.

Public Member Functions

Table

Constructor & Destructor

✅ BDCSVD() [1/5]

template<typename MatrixType_ , int Options_>
Eigen::BDCSVD< MatrixType_, Options_ >::BDCSVD ( )

Default Constructor.

When using BDCSVD::compute to execute decompositions, the default function Object() { [native code] } can be handy (const MatrixType&).


 ✅ BDCSVD() [2/5]

template<typename MatrixType_ , int Options_>
Eigen::BDCSVD< MatrixType_, Options_ >::BDCSVD ( Index  rows,
Index  cols 
)

Preallocated memory in the default function Object() { [native code] }.

Similar to the default function Object() { [native code] }, but with internal data preallocated based on the problem size and Options template argument.

 

✅ BDCSVD() [3/5]

template<typename MatrixType_ , int Options_>
EIGEN_DEPRECATED Eigen::BDCSVD< MatrixType_, Options_ >::BDCSVD ( Index  rows,
Index  cols,
unsigned int  computationOptions 
)

Memory preallocation in the default function Object() { [native code] }.

Similar to the default function Object() { [native code] }, but with internal data preallocated by the supplied problem size and computationOptions.

The function Object() { [native code] } and the Options template parameter cannot both be used to request unitiaries. Preferably use the Options template parameter.

 

✅ BDCSVD() [4/5]

template<typename MatrixType_ , int Options_>
Eigen::BDCSVD< MatrixType_, Options_ >::BDCSVD ( const MatrixType &  matrix )

Decomposition of the given matrix is carried out by the function Object() { [native code] } using the custom options specified in the Options template parameter.

 

 ✅ BDCSVD() [5/5]

template<typename MatrixType_ , int Options_>
EIGEN_DEPRECATED Eigen::BDCSVD< MatrixType_, Options_ >::BDCSVD ( const MatrixType &  matrix,
unsigned int  computationOptions 
)

Decomposes a given matrix using options for computing unitaries that are specified by the function Object() { [native code] }.

The function Object() { [native code] } and the Options template parameter cannot both be used to request unitiaries. Preferably use the Options template parameter.

Member Function Documentation

✅ cols()

template
EIGEN_CONSTEXPR Index Eigen::EigenBase< Derived >::cols ( void )

return the number of columns.

 

✅ compute() [1/2]

template
BDCSVD& Eigen::BDCSVD< MatrixType_, Options_ >::compute (const MatrixType & matrix)

a process for decomposing the given matrix. Calculate Thin/Full unitaries U/V if provided as a parameter in the Options template or in the class constructor.

 

✅ compute() [2/2]

template
EIGEN_DEPRECATED BDCSVD & Eigen::BDCSVD< MatrixType_, Options_ >::compute (const MatrixType & matrix, unsigned int computationOptions)

According to the computationOptions parameter, a method is used to decompose the given matrix.

 

✅ rows()

template
EIGEN_CONSTEXPR Index Eigen::EigenBase< Derived >::rows (void )

return the number of rows

Class JacobiSVD

Two-sided Jacobi iterations are quickly implemented for small matrices, but for bigger matrices, they take a very long time.

template<typename MatrixType_, int Options_>
class Eigen::JacobiSVD< MatrixType_, Options_ >

 

Template Parameters

🎯 Matrix Type_ which type of matrix are we using to compute the SVD decomposition

🎯 Options_  This optional parameter enables one to specify the kind of internal QR decomposition for the R-SVD step for non-square matrices. Additionally, one can choose to compute U and V in a thin or full unitary fashion. Look at the discussion of potential values below.

Any n-by-p matrix A is broken down using the SVD decomposition method as a product.

The singular values of A are denoted by the diagonal entries of S, while the left and right singular vectors of A are denoted by the columns of U and V, respectively. U is a real positive n-by-n unitary, V is a p-by-p unitary, and S is a real positive n-by-p matrix with a zero diagonal.

Singular values are always sorted in decreasing order.

By default, this JacobiSVD decomposition just computes the singular values. You must expressly request U or V if you want them.

This JacobiSVD class uses a two-sided Jacobi R-SVD decomposition for maximum accuracy and dependability. The drawback is that for large square matrices, it runs slower than bidiagonalizing SVD algorithms; nonetheless, its complexity is still O(n2p), i.e., the order of complexity is the same as the quicker bidiagonalizing R-SVD methods. R-SVD methods. Because its complexity is only linear in the larger dimension, it benefits from non-squareness, just like any R-SVD.

The algorithm is guaranteed to end in a limited (and sensible) amount of time, even if the input matrix has inf or nan coefficients, even though the outcome is undefined.

Public Member Functions

Table

Constructor & Destructor

✅ JacobiSVD() [1/5]

template<typename MatrixType_ , int Options_>
Eigen::JacobiSVD< MatrixType_, Options_ >::JacobiSVD ( )

Default Constructor.
When using JacobiSVD::compute to produce decompositions, the default function Object() { [native code] } can be handy (const MatrixType&).

 

✅ JacobiSVD() [2/5]

template<typename MatrixType_ , int Options_>
Eigen::JacobiSVD< MatrixType_, Options_ >::JacobiSVD (Index  rows, Index   cols ) 

Preallocated memory in the default function Object() { [native code] }.

Similar to the default function Object() { [native code] }, but with internal data preallocated based on the problem size and Options template argument.

 

✅ JacobiSVD() [3/5]

template<typename MatrixType_ , int Options_>
EIGEN_DEPRECATED Eigen::JacobiSVD< MatrixType_, Options_ >::JacobiSVD (Index  rows,  Index  cols,
unsigned int  computationOptions)

Memory preallocation in the default function Object() { [native code] }.

Similar to the default function Object() { [native code] }, but with internal data preallocated by the supplied problem size and computationOptions.
The function Object() { [native code] } and the Options template parameter cannot both be used to request unitiaries. Preferably use the choice of the template parameter.

 

✅ JacobiSVD() [4/5]

template<typename MatrixType_ , int Options_>
Eigen::JacobiSVD< MatrixType_, Options_ >::JacobiSVD (const MatrixType &  matrix )

Decomposition of the given matrix is carried out by the function Object() { [native code] } using the custom options specified in the Options template parameter.

 

✅ JacobiSVD() [5/5]

template<typename MatrixType_ , int Options_>
Eigen::JacobiSVD< MatrixType_, Options_ >::JacobiSVD (const MatrixType &  matrix, unsigned int  computationOptions )

Decomposes a given matrix using options for computing unitaries that are specified by the function Object() { [native code] }.

The function Object() { [native code] } and the Options template parameter cannot both be used to request unitiaries. Preferably use the Options template parameter.

Member Function Documentation

✅ cols()

template
EIGEN_CONSTEXPR Index Eigen::EigenBase< Derived >::cols ( void )

return the number of columns.

 

✅ compute() [1/2]

template<typename MatrixType_ , int Options_>
JacobiSVD& Eigen::JacobiSVD< MatrixType_, Options_ >::compute ( const MatrixType &  matrix )

A process for decomposing the given matrix. If specified using the Options template parameter or the class constructor, compute Thin/Full unitaries U/V.

 

compute() [2/2]

template<typename MatrixType_ , int Options_>
EIGEN_DEPRECATED JacobiSVD& Eigen::JacobiSVD< MatrixType_, Options_ >::compute ( const MatrixType &  matrix, unsigned int  computationOptions )\ 

According to the computationOptions parameter, a method is used to decompose the given matrix.

 

✅ rows()

template
EIGEN_CONSTEXPR Index Eigen::EigenBase< Derived >::rows (void )

return the number of rows

Frequently Asked Questions

How do you find the decomposition of an SVD matrix?

The eigenvalues and eigenvectors of AAT and ATA must be determined in order to calculate the SVD. The columns of V are made up of the eigenvectors of A^TA, and the columns of U are made up of the eigenvectors of AAT. Additionally, the singular values in S are the square roots of AAT or ATA eigenvalues.

What do eigenvalues mean?

The unique set of scalar values known as eigenvalues is connected to the linear equations most likely found in matrix equations. The term "characteristic roots' ' also refers to the eigenvectors. After applying linear transformations, it is a non-zero vector, and its scalar factor can only change it.

Does every matrix have an eigen decomposition?

There is an eigenvalue for each real matrix. However, it could be complicated. If every matrix containing entries in field K has an eigenvalue, then field K is algebraically closed. The companion matrix can be used to demonstrate one direction.

Conclusion

Congratulations on finishing the blog! We have discussed the details of SVD decomposition for real and complex matrices, with BDCSVD and jacobiSVD with their primary member function, constructor, and destructor and member function.

We hope this blog has helped you enhance your Knowledge of understanding SVD decomposition. If you'd like to learn more, Check out the following links:

🔥 Eigenvalue Decomposition

🔥 Singular Value Decomposition

🔥 Eigenvalues and Eigenvectors

Please refer to our guided pathways on Code studio to learn more about DSACompetitive ProgrammingJavaScriptSystem Design, etc. Enroll in our courses, and use the accessible sample exams and questions as a guide. For placement preparations, look at the interview experiences and interview package.

Please vote 🏆 our blogs if you find them helpful and informative!

Happy coding🤗

Live masterclass