1

一般的な基数が与えられた数値の対数を取得するために、次のコードがあります。

#include <boost/math/special_functions/powm1.hpp>
#include <boost/math/special_functions/log1p.hpp>
#include <boost/math/special_functions/sqrt1pm1.hpp>
// ...
// Boost Log returns boost::math::log1p(x) = log(e, x + 1)
double res = (double)(boost::math::log1p(arg - 1));
// Base conversion: log(new, y) = log(old, y) / log(old, new)
// Then ==> log(base, arg) = log(e, arg) / log(e, base)
res = (double)(res / ((double)boost::math::log1p(base - 1)));
return res;

ご覧のとおり、ブート ライブラリは neperian ログのみを定義しており、そのログを取得するためのトリッキーな方法もあります。なぜなら、そのライブラリが返すのは log(x) ではなく log(x+1) だからです。ご覧のとおり、この問題は引数 arg - 1 を指定することで解決され、すべてが機能するはずです。

うまく機能しますが、ネペリアンログだけは問題ありません。つまり、次のコードを実行すると:

#include <boost/math/special_functions/powm1.hpp>
#include <boost/math/special_functions/log1p.hpp>
#include <boost/math/special_functions/sqrt1pm1.hpp>
// ...
// Boost Log returns boost::math::log1p(x) = log(e, x + 1)
double res = (double)(boost::math::log1p(arg - 1));
// Base conversion: log(new, y) = log(old, y) / log(old, new)
// Then ==> log(base, arg) = log(e, arg) / log(e, base)
//res = (double)(res / ((double)boost::math::log1p(base - 1)));
return res;

すべては問題ありませんが、ベースの変更を実行すると、すべてがうまくいかず、間違った結果が返されます...わかりません。おそらく数学の問題です... log(basea, x) = log (baseb, x)/log(baseb, basea)...

どこで間違っていますか??

まあ、それは数値安定性などに関する数学の問題かもしれません...別のベースでログを取得するには、ベストプラクティスは何ですか???????

4

2 に答える 2

1

正確に何が起こっているのかわかりませんが、丸めの問題が発生している可能性があります。デルタが小さい場合の 1 + デルタの問題は、1 が非常に支配的であり、デルタが重要でないと見なされるため、デルタをあまり正確に保持するために double が構築されないことです。

ブースト ライブラリの目的は、1 とデルタを別々に渡して、ログを取得するときにデルタの精度を失わないようにすることです。これにより、0 に近い数値が得られます。

例はあなたです delta = 0.00000000123456789

それを1に追加してから再度1を引くと、倍精度は約15桁しか保持できないため、これらすべての数値は表示されませんが、+1を超える数値には17が必要ですが、印刷した数値は先行ゼロのため9桁しか使用しません数えないでください。

于 2010-12-02T09:23:23.223 に答える
0

引数の型が何であるかは明確ではありません。あなたはいくつかのことを試すことができます

  1. boost::math::log1p( ) が期待される結果を出力することを確認します。

  2. arg - 1 が本当に double であることを確認し、出力します。代わりに試しましたか: arg - 1.0

于 2015-10-13T18:42:35.783 に答える