我正在尝试使用 GSL 求解器求解(大型)ODE 系统。当我使用驱动程序方法时,我收到一条错误消息could not allocate space for gsl_interp_accel
,当我手动定义控件、错误和步进器时,我得到bad_alloc
异常,据我了解,这是由在另一种情况下导致的相同原因引起could not allocate space for gsl_interp_accel
的 - 缺少的记忆。
我已经咨询过其他bad_alloc
查询,例如这个,但我没有发现任何对我的特定案例有用的东西。此外,我尝试过其他 ODE 求解器,但它们也最终会出现内存错误。我还用 valgrind 检查了我的程序,以确保除了求解器之外的其他任何地方都没有内存错误/泄漏。
任何求解器都有“积分限制”,在我的案例中,程序在大约 10% 的上限(与下限相比很大 - 我很确定这是我得到的错误的来源 - 但我确实需要在这些特定限制之间进行整合),然后以我上面引用的例外之一终止。我尝试了各种(固定/自适应)步长,但从未达到我想要的 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
。
我试图将循环拆分为几个(许多)循环,并在其间擦除内存,但这并没有太大帮助。
如果这很重要,我使用 Ubuntu 12.10,使用 GNU 编译器和 Intel C++ Composer 编译。还在 Mac 上进行了测试(不知道是哪个版本的操作系统),结果相同。
问题是:有没有办法“欺骗”求解器并使程序正常工作?
PS:ODEint 求解器,具有更智能的获取中间结果的方法,也会引发异常。