倍精度(double)変数では15桁の数値が計算できますが, それでは不足する場合があります.計算が遅いですが,桁数を上げて計算できますよ.
用意するものは,もちろんBoostと, あとGMP, MPFR, それとGMPFRXXですね.Eigenと共に利用するのであれば, GMPFRXXでは動作しないですのでMPfrC++を利用するらしいんですが,実は unsupported (著者がプレゼントして,維持管理なし)ですので,現状では動かせてないです.
*よくわからないのですが, MacOSであると, Boostとgmpfrxxが喧嘩してうまくいかないことがあります.
GMPFRXXの使い方
#include <iostream> #include <Eigen/Dense> #include <Eigen/LU> #include <boost/math/bindings/mpfr.hpp> ... using MyMatrix2d=Eigen::Matrix<double,2,2>; using SuMatrix2d=Eigen::Matrix<mpfr_class,2,2>; ... MyMatrix2d A; A<< 1+1e-10,1,1,1-1e-10; std::cout << "det A= " << A.determinant() << std::endl; ... mpfr_class::set_dprec(500);//500ビットに設定 SuMatrix2d S; S << 1+1e-10,1,1,1-1e-10; std::cout << "det S= " << S(0,0)*S(1,1)-S(0,1)*S(1,0) << std::endl;
ところで行列式の値は (1+1e-10)(1-1e-10)-1 = 1 - 1e-20 -1 = -1e-20 なのであるが, 倍精度で計算すると0になってしまう.mpfr_class では正しく計算できる.ところが std::cout << S ができない
ビルドするときには,
g++ eigen-mpfr.cpp -o em -lmpfr -lgmpfrxx -lgmp
とはいえ, S.inverse() や S.determinant() は計算できる.
SuMatrix2d S; S << 1+1e-10,1,1,1-1e-10; double X=S.determinant().get_d();
この get_d() というのは, 任意精度クラスを倍精度に丸めて返却する関数です.
MPFRC++の使い方
だれか動かしてくんろ.