39 if (matrix.empty() || matrix[0].empty()) {
40 throw std::invalid_argument(
"Error: Matrix for SVD is empty.");
47 return singularValues_;
50 std::vector<std::vector<double>>
52 return leftSingularVectors_;
55 std::vector<std::vector<double>>
57 return rightSingularVectors_;
61 size_t m = matrix.size();
62 size_t n = matrix[0].size();
64 singularValues_.resize(std::min(m, n));
65 leftSingularVectors_ =
66 std::vector<std::vector<double>>(m, std::vector<double>(m, 0.0));
67 rightSingularVectors_ =
68 std::vector<std::vector<double>>(n, std::vector<double>(n, 0.0));
70 std::vector<double> superdiagonal(n - 1, 0.0);
72 bidiagonalize(
const_cast<std::vector<std::vector<double>
> &>(matrix),
77 for (
size_t i = 0; i < m; ++i) {
78 leftSingularVectors_[i][i] = 1.0;
81 for (
size_t i = 0; i < n; ++i) {
82 rightSingularVectors_[i][i] = 1.0;
87 std::vector<double> &diagonal,
88 std::vector<double> &superdiagonal) {
89 size_t m = matrix.size();
90 size_t n = matrix[0].size();
92 diagonal.resize(std::min(m, n));
93 superdiagonal.resize(std::min(m, n) - 1);
95 for (
size_t k = 0; k < std::min(m, n); ++k) {
97 for (
size_t i = k; i < m; ++i) {
98 alpha += matrix[i][k] * matrix[i][k];
100 alpha = (matrix[k][k] > 0) ? -std::sqrt(alpha) : std::sqrt(alpha);
102 double beta = alpha * (alpha - matrix[k][k]);
103 diagonal[k] = -alpha;
106 std::vector<double> columnCopy(m - k);
107 for (
size_t i = k; i < m; ++i) {
108 columnCopy[i - k] = matrix[i][k];
111 computeHouseholderReflection(columnCopy, superdiagonal, beta);
112 applyHouseholder(matrix, superdiagonal, beta, k, k + 1);
117 const std::vector<double> &x,
118 std::vector<double> &v,
123 for (
size_t i = 1; i < n; ++i) {
124 sigma += x[i] * x[i];
129 for (
size_t i = 1; i < n; ++i) {
133 beta = 2.0 / (sigma + 1.0);
137 std::vector<std::vector<double>> &matrix,
138 const std::vector<double> &v,
142 size_t m = matrix.size();
143 size_t n = matrix[0].size();
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];
153 for (
size_t j = fromCol; j < n; ++j) {
154 matrix[i][j] -= dotProduct * v[j - fromCol];
void computeHouseholderReflection(const std::vector< double > &x, std::vector< double > &v, double &beta)
std::vector< double > getSingularValues() const
Get the singular values of the matrix.
void bidiagonalize(std::vector< std::vector< double >> &matrix, std::vector< double > &diagonal, std::vector< double > &superdiagonal)
SVD(std::vector< std::vector< double >> &matrix)
Constructor to compute SVD for a given matrix.
std::vector< std::vector< double > > getLeftSingularVectors() const
Get the left singular vectors of the matrix.
void applyHouseholder(std::vector< std::vector< double >> &matrix, const std::vector< double > &v, double beta, size_t fromRow, size_t fromCol)
std::vector< std::vector< double > > getRightSingularVectors() const
Get the right singular vectors of the matrix.
void computeSVD(std::vector< std::vector< double >> &matrix)