openGPMP
Open Source Mathematics Package
Public Member Functions | Private Member Functions | Private Attributes | List of all members
gpmp::linalg::SVD Class Reference

#include <svd.hpp>

Public Member Functions

 SVD (std::vector< std::vector< double >> &matrix)
 Constructor to compute SVD for a given matrix. More...
 
std::vector< double > getSingularValues () const
 Get the singular values of the matrix. More...
 
std::vector< std::vector< double > > getLeftSingularVectors () const
 Get the left singular vectors of the matrix. More...
 
std::vector< std::vector< double > > getRightSingularVectors () const
 Get the right singular vectors of the matrix. More...
 

Private Member Functions

void computeSVD (std::vector< std::vector< double >> &matrix)
 
void bidiagonalize (std::vector< std::vector< double >> &matrix, std::vector< double > &diagonal, std::vector< double > &superdiagonal)
 
void computeHouseholderReflection (const std::vector< double > &x, std::vector< double > &v, double &beta)
 
void applyHouseholder (std::vector< std::vector< double >> &matrix, const std::vector< double > &v, double beta, size_t fromRow, size_t fromCol)
 

Private Attributes

std::vector< double > singularValues_
 
std::vector< std::vector< double > > leftSingularVectors_
 
std::vector< std::vector< double > > rightSingularVectors_
 

Detailed Description

Definition at line 44 of file svd.hpp.

Constructor & Destructor Documentation

◆ SVD()

gpmp::linalg::SVD::SVD ( std::vector< std::vector< double >> &  matrix)
explicit

Constructor to compute SVD for a given matrix.

Parameters
matrixThe input matrix for SVD
Exceptions
std::invalid_argumentif the matrix is empty

Definition at line 38 of file svd.cpp.

38  {
39  if (matrix.empty() || matrix[0].empty()) {
40  throw std::invalid_argument("Error: Matrix for SVD is empty.");
41  }
42 
43  computeSVD(matrix);
44 }
void computeSVD(std::vector< std::vector< double >> &matrix)
Definition: svd.cpp:60

References computeSVD().

Member Function Documentation

◆ applyHouseholder()

void gpmp::linalg::SVD::applyHouseholder ( std::vector< std::vector< double >> &  matrix,
const std::vector< double > &  v,
double  beta,
size_t  fromRow,
size_t  fromCol 
)
private

Definition at line 136 of file svd.cpp.

141  {
142  size_t m = matrix.size();
143  size_t n = matrix[0].size();
144 
145  for (size_t i = fromRow; i < m; ++i) {
146  double dotProduct = 0.0;
147  for (size_t j = fromCol; j < n; ++j) {
148  dotProduct += matrix[i][j] * v[j - fromCol];
149  }
150 
151  dotProduct *= beta;
152 
153  for (size_t j = fromCol; j < n; ++j) {
154  matrix[i][j] -= dotProduct * v[j - fromCol];
155  }
156  }
157 }

◆ bidiagonalize()

void gpmp::linalg::SVD::bidiagonalize ( std::vector< std::vector< double >> &  matrix,
std::vector< double > &  diagonal,
std::vector< double > &  superdiagonal 
)
private

Definition at line 86 of file svd.cpp.

88  {
89  size_t m = matrix.size();
90  size_t n = matrix[0].size();
91 
92  diagonal.resize(std::min(m, n));
93  superdiagonal.resize(std::min(m, n) - 1);
94 
95  for (size_t k = 0; k < std::min(m, n); ++k) {
96  double alpha = 0.0;
97  for (size_t i = k; i < m; ++i) {
98  alpha += matrix[i][k] * matrix[i][k];
99  }
100  alpha = (matrix[k][k] > 0) ? -std::sqrt(alpha) : std::sqrt(alpha);
101 
102  double beta = alpha * (alpha - matrix[k][k]);
103  diagonal[k] = -alpha;
104 
105  // make a copy of the current column of the matrix
106  std::vector<double> columnCopy(m - k);
107  for (size_t i = k; i < m; ++i) {
108  columnCopy[i - k] = matrix[i][k];
109  }
110 
111  computeHouseholderReflection(columnCopy, superdiagonal, beta);
112  applyHouseholder(matrix, superdiagonal, beta, k, k + 1);
113  }
114 }
void computeHouseholderReflection(const std::vector< double > &x, std::vector< double > &v, double &beta)
Definition: svd.cpp:116
void applyHouseholder(std::vector< std::vector< double >> &matrix, const std::vector< double > &v, double beta, size_t fromRow, size_t fromCol)
Definition: svd.cpp:136

◆ computeHouseholderReflection()

void gpmp::linalg::SVD::computeHouseholderReflection ( const std::vector< double > &  x,
std::vector< double > &  v,
double &  beta 
)
private

Definition at line 116 of file svd.cpp.

119  {
120  size_t n = x.size();
121  double sigma = 0.0;
122 
123  for (size_t i = 1; i < n; ++i) {
124  sigma += x[i] * x[i];
125  }
126 
127  v.resize(n);
128  v[0] = 1.0;
129  for (size_t i = 1; i < n; ++i) {
130  v[i] = x[i] / sigma;
131  }
132 
133  beta = 2.0 / (sigma + 1.0);
134 }

◆ computeSVD()

void gpmp::linalg::SVD::computeSVD ( std::vector< std::vector< double >> &  matrix)
private

Definition at line 60 of file svd.cpp.

60  {
61  size_t m = matrix.size();
62  size_t n = matrix[0].size();
63 
64  singularValues_.resize(std::min(m, n));
66  std::vector<std::vector<double>>(m, std::vector<double>(m, 0.0));
68  std::vector<std::vector<double>>(n, std::vector<double>(n, 0.0));
69 
70  std::vector<double> superdiagonal(n - 1, 0.0);
71 
72  bidiagonalize(const_cast<std::vector<std::vector<double>> &>(matrix),
74  superdiagonal);
75 
76  // left/right singular vectors as identity matrices
77  for (size_t i = 0; i < m; ++i) {
78  leftSingularVectors_[i][i] = 1.0;
79  }
80 
81  for (size_t i = 0; i < n; ++i) {
82  rightSingularVectors_[i][i] = 1.0;
83  }
84 }
std::vector< std::vector< double > > rightSingularVectors_
Definition: svd.hpp:74
void bidiagonalize(std::vector< std::vector< double >> &matrix, std::vector< double > &diagonal, std::vector< double > &superdiagonal)
Definition: svd.cpp:86
std::vector< std::vector< double > > leftSingularVectors_
Definition: svd.hpp:73
std::vector< double > singularValues_
Definition: svd.hpp:72

Referenced by SVD().

◆ getLeftSingularVectors()

std::vector< std::vector< double > > gpmp::linalg::SVD::getLeftSingularVectors ( ) const

Get the left singular vectors of the matrix.

Returns
Matrix containing left singular vectors as columns

Definition at line 51 of file svd.cpp.

51  {
52  return leftSingularVectors_;
53 }

◆ getRightSingularVectors()

std::vector< std::vector< double > > gpmp::linalg::SVD::getRightSingularVectors ( ) const

Get the right singular vectors of the matrix.

Returns
Matrix containing right singular vectors as columns

Definition at line 56 of file svd.cpp.

56  {
57  return rightSingularVectors_;
58 }

◆ getSingularValues()

std::vector< double > gpmp::linalg::SVD::getSingularValues ( ) const

Get the singular values of the matrix.

Returns
Vector containing singular values in descending order

Definition at line 46 of file svd.cpp.

46  {
47  return singularValues_;
48 }

Member Data Documentation

◆ leftSingularVectors_

std::vector<std::vector<double> > gpmp::linalg::SVD::leftSingularVectors_
private

Definition at line 73 of file svd.hpp.

◆ rightSingularVectors_

std::vector<std::vector<double> > gpmp::linalg::SVD::rightSingularVectors_
private

Definition at line 74 of file svd.hpp.

◆ singularValues_

std::vector<double> gpmp::linalg::SVD::singularValues_
private

Definition at line 72 of file svd.hpp.


The documentation for this class was generated from the following files: