我正在尝试使用GSL求解器来解决(大型)ODE系统。当我使用驱动程序方法时,我收到could not allocate space for gsl_interp_accel
的错误消息,当我手动定义控件,错误和步进器时,我得到bad_alloc
异常,据我所知,这是由异常导致的在另一种情况下导致could not allocate space for gsl_interp_accel
的事情 - 缺乏记忆。
我咨询了其他bad_alloc
个问题,例如this one,但我没有找到任何有用的信息。此外,我尝试过其他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上测试(不知道哪个版本的OS)具有相同的结果。
问题是:有没有办法在解算器上“作弊”并让程序正常工作?
P.S。:ODEint求解器,它有更聪明的方法来获得中间结果,也会引发异常。
答案 0 :(得分:1)
我遇到了类似的问题。程序在某个final_time以bad_alloc错误终止。如果我缩短积分时间,程序将适当地终止,但这不是我想要的。然后我将epsabs从1e-9减少到1e-6,程序可以正常运行,直到我需要的final_time。
这不是解决方案,而是妥协。