0

GSL ソルバーを使用して ODE の (大規模な) システムを解こうとしています。ドライバーメソッドを使用すると、エラーメッセージが表示さcould not allocate space for gsl_interp_accelれます。コントロール、エラー、ステッパーを手動で定義すると、bad_alloc例外が発生します。これは、私が理解している限りcould not allocate space for gsl_interp_accel、他のケースで発生するのと同じことが原因で発生します-欠落メモリの。

this onebad_allocなどの他のクエリに相談しましたが、私の特定のケースに役立つものは何も見つかりませんでした。また、他の ODE ソルバーも試しましたが、メモリ エラーが発生します。また、プログラムを valgrind でチェックして、ソルバー以外の場所にメモリ エラーやリークがないことを確認しました。

どのソルバーにも「統合の制限」があり、私の場合、プログラムは上限の約 10% で正常に動作します (これは下限に比べて大きいです。これがエラーの原因であると確信していますが、必要です)。これらの特定の制限の間を統合するため)、上で引用した例外の 1 つで終了します。さまざまな (固定/適応) ステップ サイズを試しましたが、希望の 10% を超えることはありませんでした。

例外を与えるコードは次のとおりです。

gsl_ode_struct inputstruct;  // Struct that contains parameters for ODEs 
gsl_odeiv2_system sys = {func, NULL, 2*G.getsize(), &inputstruct};
const gsl_odeiv2_step_type * T = gsl_odeiv2_step_rk8pd;
gsl_odeiv2_step * stepper = gsl_odeiv2_step_alloc (T, size_of_the_system);
gsl_odeiv2_control * control = gsl_odeiv2_control_standard_new (1.e-6, 0.0, 1., 0.);
gsl_odeiv2_evolve * error = gsl_odeiv2_evolve_alloc (size_of_the_system);
double hparam = 1.e-6; // Initial step size
double t = xspan[0]; // Initial time
while(t < final_time){
    // Here the excpection comes
    int status = gsl_odeiv2_evolve_apply (error, control, stepper, &sys, &t, final_time, &hparam, array);
    if(status != GSL_SUCCESS)
        break;
    // Do some stuff that includes reading all the intermediate results to a container as I need them later.
    }
    gsl_odeiv2_evolve_free (error);
    gsl_odeiv2_control_free (control);
    gsl_odeiv2_step_free (stepper);

したがって、コードを変更final_timeするとfinal_time/10実行されますが、結果は意味がありません。ソルバー後に何もしなくても例外はスローされcould not allocate space for gsl_interp_accelますが。

間にメモリを消去してループをいくつかの(多くの)ループに分割しようとしましたが、これはあまり役に立ちませんでした。

これが重要な場合は、GNU コンパイラーと Intel C++ Composer でコンパイルされた Ubuntu 12.10 を使用します。また、Mac (OS のバージョンがわからない) でもテストされ、同じ結果が得られました。

問題は、ソルバーを「チート」してプログラムを適切に動作させる方法はないかということです。

PS: 中間結果を取得するよりスマートな方法を持つ ODEint ソルバーも例外をスローします。

4

1 に答える 1