3 #include <Eigen/Eigenvalues>
4 #include "catch2/catch_all.hpp"
13 auto constexpr
N = 10;
15 Eigen::EigenSolver<Matrix<Scalar>> es;
17 std::iota(A.data(), A.data() + A.size(), 0);
18 es.compute(A.adjoint() * A,
true);
20 auto const eigenvalues = es.eigenvalues();
21 auto const eigenvectors = es.eigenvectors();
22 Eigen::DenseIndex index;
23 (eigenvalues.transpose() * eigenvalues).real().maxCoeff(&index);
24 auto const eigenvalue = eigenvalues(index);
32 auto const result = pm.AtA(lt, input);
35 CAPTURE(result.magnitude);
36 CAPTURE(result.eigenvector.transpose() * eigenvector);
37 CHECK(std::abs(result.magnitude - std::abs(eigenvalue)) < 1e-8);
41 auto const result = pm((A.adjoint() * A).cast<
t_complex>(), input);
44 CAPTURE(result.magnitude);
45 CAPTURE(result.eigenvector.transpose() * eigenvector);
46 CHECK(std::abs(result.magnitude - std::abs(eigenvalue)) < 1e-8);
53 auto constexpr
N = 10;
54 constexpr
t_uint power_iters = 100000;
55 constexpr
t_real power_tol = 1e-6;
56 Eigen::EigenSolver<Matrix<Scalar>> es;
58 std::iota(A.data(), A.data() + A.size(), 0);
59 es.compute(A.adjoint() * A,
true);
61 auto const eigenvalues = es.eigenvalues();
62 auto const eigenvectors = es.eigenvectors();
63 Eigen::DenseIndex index;
64 (eigenvalues.transpose() * eigenvalues).real().maxCoeff(&index);
65 auto const eigenvalue = eigenvalues(index);
72 out = A.adjoint() * in;
75 SECTION(
"Power Method") {
78 algorithm::power_method<Vector<t_complex>>(op, power_iters, power_tol, input);
79 const t_real op_norm = std::get<0>(result);
81 CHECK(op_eigen_vector_c.unaryExpr([](
t_complex x) { return std::arg(x); })
83 std::arg(op_eigen_vector_c(0))),
86 op_eigen_vector_c * std::polar<t_real>(1, -std::arg(op_eigen_vector_c(0)));
88 CAPTURE(op_norm * op_norm);
89 CAPTURE(op_eigen_vector);
91 CHECK(op_norm == Approx(std::sqrt(std::abs(eigenvalue))).
epsilon(power_tol));
92 CHECK(op_eigen_vector.isApprox(eigenvector, power_tol));
93 auto const norm_operator_result =
94 algorithm::normalise_operator<Vector<t_complex>>(op, power_iters, power_tol, input);
95 CHECK(std::get<0>(norm_operator_result) == Approx(op_norm).
epsilon(1e-12));
96 CHECK(std::get<1>(norm_operator_result).isApprox(op_eigen_vector_c, 1e-12));
97 CHECK(((op * input) / op_norm)
99 .isApprox((std::get<2>(norm_operator_result) * input).eval(), 1e-12));
100 CHECK(((op.
adjoint() * input) / op_norm)
102 .isApprox((std::get<2>(norm_operator_result).adjoint() * input).eval(), 1e-12));
Eigenvalue and eigenvector for eigenvalue with largest magnitude.
LinearTransform< VECTOR > linear_transform(OperatorFunction< VECTOR > const &direct, OperatorFunction< VECTOR > const &indirect, std::array< t_int, 3 > const &sizes={{1, 1, 0}})
double t_real
Root of the type hierarchy for real numbers.
size_t t_uint
Root of the type hierarchy for unsigned integers.
real_type< T >::type epsilon(sopt::LinearTransform< Vector< T >> const &sampling, sopt::Image< T > const &image)
Eigen::Matrix< T, Eigen::Dynamic, 1 > Vector
A vector of a given type.
std::complex< t_real > t_complex
Root of the type hierarchy for (real) complex numbers.
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > Matrix
A matrix of a given type.
TEST_CASE("Power Method")