| // SPDX-FileCopyrightText: The Eigen Authors |
| // SPDX-License-Identifier: MPL-2.0 |
| |
| #include "main.h" |
| #include <Eigen/SVD> |
| |
| EIGEN_DECLARE_TEST(bdcsvd_fastmath) { |
| typedef Matrix<double, 6, 6> Matrix6d; |
| const double kTolerance = 16 * Matrix6d::RowsAtCompileTime * NumTraits<double>::epsilon(); |
| |
| // A finite singular-vector coefficient grows to about 2^570. Its ordinary |
| // squared norm overflows, and GCC's -ffast-math assumes isfinite() is true. |
| Matrix6d matrix = Matrix6d::Zero(); |
| using std::ldexp; |
| matrix.diagonal() << 0.0, 0.0, ldexp(1.0, -487), -1.0, 0.0, 0.0; |
| matrix.diagonal(1) << 0.0, ldexp(1.0, -453), -ldexp(1.0, -627), 0.0, 0.0; |
| |
| BDCSVD<Matrix6d, ComputeFullU | ComputeFullV> svd; |
| svd.setSwitchSize(3); |
| svd.compute(matrix); |
| |
| VERIFY(svd.info() == Success); |
| const Matrix6d reconstruction = svd.matrixU() * svd.singularValues().asDiagonal() * svd.matrixV().transpose(); |
| VERIFY((reconstruction - matrix).stableNorm() <= kTolerance * matrix.stableNorm()); |
| |
| const Matrix6d identity = Matrix6d::Identity(); |
| VERIFY((svd.matrixU().transpose() * svd.matrixU() - identity).stableNorm() <= kTolerance); |
| VERIFY((svd.matrixV().transpose() * svd.matrixV() - identity).stableNorm() <= kTolerance); |
| } |