Boost.Multiprecision/Eigen interop challenges
Summary
Currently, Eigen's Eigensolver cannot interoperate with Boost.Multiprecision.
Environment
- Operating System : Mac
- Architecture : Arm64
- Eigen Version : 3.4.0
- Compiler Version : clang
- Compile Flags : -O0
- Vector Extension : NEON
Minimal Example
#include <Eigen/Dense>
#include <Eigen/Eigenvalues>
#include <boost/multiprecision/eigen.hpp>
#include <boost/multiprecision/cpp_bin_float.hpp>
using boost::multiprecision::cpp_bin_float_100;
int main() {
Eigen::Matrix<cpp_bin_float_100, Eigen::Dynamic, Eigen::Dynamic> A = Eigen::Matrix<cpp_bin_float_100, Eigen::Dynamic, Eigen::Dynamic>::Identity(3,3);
Eigen::EigenSolver<decltype(A)> es;
es.compute(A, /*computeEigenvectors=*/ false);
auto eigs = es.eigenvalues();
for (auto eig : eigs) {
std::cout << eig << "\n";
}
}
Steps to reproduce
- Attempt to compile the reproducer
What is the current bug behavior?
The compile fails with:
/opt/homebrew/opt/llvm/bin/clang++ -O0 -g --std=c++17 -Wfatal-errors -fsanitize=address -fsanitize=undefined -I./include -I/opt/homebrew/Cellar/eigen/3.4.0_1/include/eigen3/ -I/opt/homebrew/opt/llvm/include -I/opt/homebrew/opt/boost@1.85/include main.cpp
In file included from main.cpp:2:
In file included from /opt/homebrew/Cellar/eigen/3.4.0_1/include/eigen3/Eigen/Dense:1:
In file included from /opt/homebrew/Cellar/eigen/3.4.0_1/include/eigen3/Eigen/Core:50:
/opt/homebrew/opt/llvm/bin/../include/c++/v1/complex:730:62: fatal error: no matching function for call to '__constexpr_fabs'
730 | _Tp __logbw = std::__constexpr_logb(std::__constexpr_fmax(std::__constexpr_fabs(__c), std::__constexpr_fabs(__d)));
| ^~~~~~~~~~~~~~~~~~~~~
/opt/homebrew/Cellar/eigen/3.4.0_1/include/eigen3/Eigen/src/Eigenvalues/EigenSolver.h:542:74: note: in instantiation of function template specialization 'std::operator/<boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<100>>>' requested here
542 | ComplexScalar cc = ComplexScalar(Scalar(0),-m_matT.coeff(n-1,n)) / ComplexScalar(m_matT.coeff(n-1,n-1)-p,q);
| ^
What is the expected correct behavior?
The compilation succeeds.
Anything else that might help
We have discussed this issue in boost.math. Basically, std::complex
cannot be instantiated with types that are not float
, double
, or long double
, so we need ADL.