私は数値積分(求積)のための独自の小さなサブルーチンを持っています。これは、Bulirsch&Stoerによって1967年に公開されたALGOLプログラムのC ++適応です(Numerische Mathematik、9、271-278)。
より近代的な(アダプティブ)アルゴリズムにアップグレードし、そのような(無料の)C ++ライブラリが提供されているかどうか疑問に思います。私はGSL(Cです)のように見えましたが、恐ろしいAPIが付属しています(数値は良いかもしれませんが)。他に何かありますか?
便利なAPIは次のようになります。
double quadrature(double lower_integration_limit,
double upper_integration_limit,
std::function<double(double)> const&func,
double desired_error_bound_relative=1.e-12,
double desired_error_bound_absolute=0,
double*error_estimate=nullptr);
7
余談ですが、計算科学における最良の実装の多くは、他のソフトウェアの数か月または数年ではなく、数十年にわたって開発されてきたという理由だけで「悪い」APIを持っていることがわかります。ラッパーAPIを記述して、あまりクリーンでないAPIを内部的に呼び出すことは、許容可能であり、非常に役立つと思います。これにより、プライマリコードで優れたAPIの利点が得られ、単一の関数を書き換えるだけで、異なる直交ライブラリを簡単に切り替えることができます。
—
Godric Seer
@GodricSeerそれがそんなに簡単だったら、私はそうするでしょう。ただし、そうではありません。GSL APIには事前に割り当てられたバッファーが必要ですが、そのバッファーは何も使用されていない可能性がありますが、小さすぎる可能性があります(より多くのメモリを使用して別の呼び出しが必要)。適切な実装は再帰的であり、割り当てを必要とせず、すべてのデータをスタックに保持し、クリーンなAPIを提供します。
—
Walter
@GodricSeer GSL APIのもう1つの深刻な問題は、状態を持たない関数しか受け入れないことです(単純な関数ポインターを使用するため)。これから状態を持つ関数のスレッドセーフAPIを生成することは、必ずしも非効率的です。
—
Walter
Godric Seerに同意します。ラッパーを作成するのが最善の方法です。「GSLは状態のない関数のみを受け入れる」というのは正しくないと思います。ドキュメントでは、a
—
Kirill、2015
gsl_function
は関数ポインタであり、不透明なデータポインタであり、状態を含むことができると述べています。第2に、任意の大きさの作業バッファーを(再)割り当てることには、いくつかの効率の問題があります。そのため、その部分には、少なくともある程度の正当な理由があります。
GSLの事前割り当てバッファに関する別のコメント。ワークスペースのサイズは、間隔の最大数で定義されます。アダプティブバイセクションが多すぎる場合でも、求積法ルーチンを失敗させるため、ワークスペースのサイズをバイセクションの数の上限に設定します。「適切な」実装について話すと、GSLはここで「正しい」ことを行います。これは、現在最大のエラーがある間隔を二分するため、これまでのすべての間隔を追跡する必要があります。すべてのデータをスタックに保持すると、スタックメモリが不足する可能性があります。
—
Kirill