2016-06-11 9 views
3

でテンプレートの解決に失敗しましたboost::multiprecisionからmutliprecision浮動小数点型の固有ベクトル分解を行うためにEigenを使用しようとしています。私は、さまざまなソースから一緒にコピーした非常に簡単な例から始めます。ここでは、コードです:倍精度浮動小数点型+ Eigen

#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; 
} 

私は(代わりにconvert_toメソッドを使用しboost::multiprecisionタイプ、のために不足しているint()オペレータのような)最初のいくつかの落とし穴を克服してきましたが、今私は、コンパイラだけでポイントに達しました失敗したテンプレート解決に関するエラーメッセージを吐き出します。

完全なエラーログが(私はペーストビンの上に置く: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) 

、4つのスカラーを取る機能を使用しようとEigenが、 boostは、最初の2つの式テンプレートを提供します(そして、コンパイラはそれらを暗黙的にスカラに変換することを拒否します)。

私は正しい道にいるのですか、それとも無駄ですか?どのようにタイプを利用するために教えるために進めるための任意の提案はEigen?この質問下記の有益なコメントに

更新

おかげで、私は式テンプレートをオフにすることで、問題を解決することができました。

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; 
     } 
    } 
    } 
} 
+1

別の複数精度データ型を試すこともできます。 'boost :: multiprecision :: mpf_float <>'や 'boost :: multiprecision :: mpfr_float <>'(結果として生じる依存関係やスピードアップに満足すれば) – Walter

+0

私はあまりにもそれに満足していないが、それが働く場合はそれに行くだろう。しかし、boost :: multiprecision :: number >を 'boost :: multiprecision :: mpf_float_100'に変更すると、同じエラーが発生します。私は何かを忘れていますか? – carsten

+0

私は今、問題を解決できました。ありがとうございました。式テンプレートについての発言を答えにまとめておきましょう。それを受け入れます。 – carsten

答えて

4

あなたのエラーがなく、単項マイナスオペレータからの発現テンプレートオブジェクトを返すために、boost::multiprecisionによって引き起こされました別のスカラー(つまり、数字の型のboost::multiprecision)と同じです。

明白な解決策は、表現テンプレートを避ける多精度タイプを使用することです。これは、別のタイプのために(とにかく高速かもしれません)、boost::multiprecisionの式テンプレートをオフに切り替えることです。hereを参照してください。

関連する問題