boost multiprecision+Eigen的模板解析失败
template resolution fails with boost multiprecision + Eigen
我正试图使用Eigen
对boost::multiprecision
中的多精度浮点类型进行特征向量分解。我从一个非常简单的例子开始,我从不同的来源复制到一起。这是代码:
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <eigen3/Eigen/Dense>
#include <eigen3/Eigen/LU>
#include <eigen3/Eigen/Eigenvalues>
#include <iostream>
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<100> > SuperFloat;
typedef std::complex<SuperFloat> SuperComplex;
// this is the first fix I came up with to overcome the problem
// that multiprecision doesn't come with an int() operator
namespace Eigen {
namespace internal {
template<typename NewType>
struct cast_impl<SuperFloat,NewType> {
static inline NewType run(const SuperFloat& x) {
return x.convert_to<NewType>();
}
};
}
}
typedef Eigen::Matrix<SuperFloat, Eigen::Dynamic, Eigen::Dynamic> EigenMatrixR;
typedef Eigen::Matrix<SuperFloat, Eigen::Dynamic, 1 > EigenVectorR;
typedef Eigen::Matrix<SuperComplex, Eigen::Dynamic, Eigen::Dynamic> EigenMatrixC;
typedef Eigen::Matrix<SuperComplex, Eigen::Dynamic, 1 > EigenVectorC;
int main(){
int size = 10;
EigenMatrixR A = EigenMatrixR::Identity(size, size);
Eigen::EigenSolver<EigenMatrixR> es(A);
std::cout << "The eigenvalues of A are:" << std::endl << es.eigenvalues() << std::endl;
std::cout << "The matrix of eigenvectors, V, is:" << std::endl << es.eigenvectors() << std::endl << std::endl;
SuperComplex lambda = es.eigenvalues()[0];
std::cout << "Consider the first eigenvalue, lambda = " << lambda << std::endl;
EigenVectorC v = es.eigenvectors().col(0);
std::cout << "If v is the corresponding eigenvector, then lambda * v = " << std::endl << lambda * v << std::endl;
std::cout << "... and A * v = " << std::endl << A.cast<SuperComplex>() * v << std::endl << std::endl;
EigenMatrixC D = es.eigenvalues().asDiagonal();
EigenMatrixC V = es.eigenvectors();
std::cout << "Finally, V * D * V^(-1) = " << std::endl << V * D * V.inverse() << std::endl;
return 0;
}
我已经克服了最初的几个陷阱(比如boost::multiprecision
类型缺少int()
运算符,而是使用convert_to
方法),但现在我已经到了编译器只会抛出有关模板解析失败的错误消息的地步。
完整的错误日志相当长(我把它放在pastebin上:http://pastebin.com/a2R0NDSA),但第一个错误是:
/usr/include/eigen3/Eigen/src/Eigenvalues/EigenSolver.h:549:43: error: no matching function for call to ‘cdiv(boost::multiprecision::detail::expression<boost::multiprecision::detail::negate, boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >, void, void, void>, boost::multiprecision::detail::expression<boost::multiprecision::detail::negate, boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >, void, void, void>, Eigen::EigenSolver<Eigen::Matrix<boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >, -1, -1> >::Scalar&, Eigen::EigenSolver<Eigen::Matrix<boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100u> >, -1, -1> >::Scalar&)’
std::complex<Scalar> cc = cdiv(-ra,-sa,w,q);
^
/usr/include/eigen3/Eigen/src/Eigenvalues/EigenSolver.h:422:22: note: candidate: template<class Scalar> std::complex<_Tp> Eigen::cdiv(const Scalar&, const Scalar&, const Scalar&, const Scalar&)
std::complex<Scalar> cdiv(const Scalar& xr, const Scalar& xi, const Scalar& yr, const Scalar& yi)
换句话说,Eigen
试图使用一个取四个标量的函数,但boost
为前两个提供了表达式模板(编译器拒绝隐式地将这些模板转换为标量)。
我是走在正确的道路上,还是这种努力是徒劳的?关于如何继续教授Eigen
如何使用boost::multiprecision
类型,有什么建议吗?
更新
感谢这个问题下面的有用评论,我已经能够通过关闭表达式模板来解决这个问题。
typedef boost::multiprecision::cpp_dec_float<50> mp_backend;
typedef boost::multiprecision::number<mp_backend, boost::multiprecision::et_off> SuperFloat;
关于check_in_range
模板解析失败的剩余错误消息可以这样修复:
namespace boost{
namespace multiprecision {
namespace default_ops{
template <> inline bool check_in_range<SuperComplex,long double>(const long double& t){
return false;
}
}
}
}
您的错误是由boost::multiprecision
从一元减号运算符返回表达式模板对象而不是另一个标量(即相同的boost::multiprecision
数字类型)引起的。
显而易见的解决方案是使用避免表达式模板的多精度类型,方法是完全使用另一种类型(无论如何可能更快),或者关闭boost::multiprecision
的表达式模板,请参阅此处。
相关文章:
- 如果没有malloc,链表实现将失败
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 视图中的参数推导失败:take_while
- 链接到自行创建的dll失败
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- gcc和c++17的过载解析失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在WSL:configure_file上对config_file的每次调用都失败:配置文件时出现问题
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- 从父数组测试用例构造二叉树失败
- LibGit2 SSH身份验证失败
- 如何让LLDB在成功时退出,在失败时等待
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- 生成MRPT库时cmake配置失败
- 为什么除非添加括号,否则构造函数上的模板替换会失败?
- variadic模板中的模板参数推导失败