blob: 4a8f2e6dc2190e2c4fcf644574e2a08f491d62cf [file] [edit]
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
#define EIGEN_JACOBI_SVD_BLOCKING_THRESHOLD 16
#include "main.h"
#include <Eigen/SVD>
template <typename MatrixType>
void jacobisvd_blocked(const MatrixType& input) {
using Scalar = typename MatrixType::Scalar;
using RealScalar = typename MatrixType::RealScalar;
const Index n = input.rows();
MatrixType matrix = input;
JacobiSVD<MatrixType, ComputeFullU | ComputeFullV> svd(n, n);
JacobiSVD<MatrixType> valuesOnly(n, n);
// O(n*eps) backward error and orthogonality bounds for accumulated rotations.
const RealScalar tolerance = RealScalar(64 * n) * NumTraits<RealScalar>::epsilon();
for (int pattern = 0; pattern < 4; ++pattern) {
if (pattern == 1) matrix.col(n - 1) = matrix.col(0);
if (pattern == 2) matrix.setIdentity();
if (pattern == 3) matrix.setZero();
svd.compute(matrix);
valuesOnly.compute(matrix);
VERIFY_IS_EQUAL(svd.info(), Success);
VERIFY_IS_EQUAL(valuesOnly.info(), Success);
const MatrixType reconstructed =
svd.matrixU() * svd.singularValues().template cast<Scalar>().asDiagonal() * svd.matrixV().adjoint();
VERIFY_LE((matrix - reconstructed).norm(), tolerance * matrix.norm());
VERIFY_LE((svd.matrixU().adjoint() * svd.matrixU() - MatrixType::Identity(n, n)).norm(), tolerance);
VERIFY_LE((svd.matrixV().adjoint() * svd.matrixV() - MatrixType::Identity(n, n)).norm(), tolerance);
VERIFY_LE((valuesOnly.singularValues() - svd.singularValues()).norm(), tolerance * matrix.norm());
}
}
EIGEN_DECLARE_TEST(jacobisvd_blocked) {
for (int repeat = 0; repeat < g_repeat; ++repeat) {
// Default block size is 32: cover scalar tails, contiguous blocks, and distant rows.
for (Index n : {31, 32, 33, 34, 65}) {
TEST_SET_BUT_UNUSED_VARIABLE(n);
CALL_SUBTEST_1(jacobisvd_blocked(MatrixXf(MatrixXf::Random(n, n))));
CALL_SUBTEST_2((jacobisvd_blocked(Matrix<double, Dynamic, Dynamic, RowMajor>::Random(n, n).eval())));
CALL_SUBTEST_3((jacobisvd_blocked(Matrix<std::complex<float>, Dynamic, Dynamic, RowMajor>::Random(n, n).eval())));
CALL_SUBTEST_4(jacobisvd_blocked(MatrixXcd(MatrixXcd::Random(n, n))));
CALL_SUBTEST_5((jacobisvd_blocked(Matrix<double, Dynamic, Dynamic, RowMajor, 65, 65>::Random(n, n).eval())));
}
CALL_SUBTEST_6((jacobisvd_blocked(Matrix<double, 34, 34>::Random().eval())));
}
}