読者です 読者をやめる 読者になる 読者になる

Boost.Multiprecision uBLASとの組み合わせはまだ怪しい

C++

Boost.Multiprecisionの多倍長浮動小数点数型は、線形代数ライブラリであるBoost.uBLASでも使用できますが、式テンプレートがONだと、結果がおかしくなることがあるようです。以下、ベクトルでの簡単な「目的値に向かう処理」です。式テンプレートがオフの方から見てみます。

#include <iostream>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/io.hpp>

namespace mp = boost::multiprecision;
namespace ublas = boost::numeric::ublas;

using float_type = mp::number<mp::cpp_dec_float<50>, mp::et_off>;
using vec = ublas::vector<float_type>;

vec make_vector3(float_type x, float_type y, float_type z)
{
    vec v(3);
    v[0] = x;
    v[1] = y;
    v[2] = z;
    return v;
}

vec normalize(vec v)
{
    return v / ublas::norm_2(v);
}

int main()
{
    vec p = make_vector3(0.0f, 0.0f, 0.0f); // 現在位置
    vec q = make_vector3(3.0f, 0.0f, 6.0f); // 目的位置

    vec v = normalize(q - p); // ベクトルを求める
    std::cout << "vector : " << v << std::endl;

    // 少しずつ目的位置に向かう
    float_type speed = 0.1f; // 速度
    float_type accel = 0.1f; // 加速度
    for (int i = 0; i < 20; ++i) {
        p += v * speed;
        speed += accel;
    }

    std::cout << "result pos : " << p << std::endl;
}
vector : [3](0.447214,0,0.894427)
result pos : [3](9.39149,0,18.783)

式テンプレートがオフだと正常な結果が返ってきています。しかし、式テンプレートがオンだと、以下のような結果になります:

vector : [3](1,0,1)
result pos : [3](1,0,1)

全然違いますね・・・。


また、StackOverflowでの質問「Boost matrix product for multiprecision numbers」のように、式テンプレートがオンだと、まだいくつかの場面でうまくコンパイルが通らないケースがあるようです。これも式テンプレートをオフにしたら通りました。

#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/numeric/ublas/matrix.hpp>

using namespace boost::multiprecision;
using namespace boost::numeric::ublas;

int main(int, char**)
{
  matrix<number<cpp_dec_float<50>, et_off > > m (3, 3);
  matrix<number<cpp_dec_float<50>, et_off > > E (3, 3);

  E=prod(E,m); // OK : et_offにしたら通った

  return 0;
}

式テンプレートを使うライブラリ同士を組み合わせてるところで、何らかの不整合が起きてる気がします。Boostのバージョンは1.53.0です。


この問題は、バグレポしておきました。
#8292 et_on with uBLAS become bad result