std::bad_alloc和GSL ODE求解器

std::bad_alloc and GSL ODE solver

本文关键字:ODE GSL bad alloc std      更新时间:2023-10-16

我正在尝试用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上也测试过(不知道是哪个版本的操作系统),结果相同。

问题是:有没有办法在解算器上"作弊",使程序正常工作?

注:: ODEint求解器,有更聪明的方法获得中间结果,也抛出异常。

我也遇到过类似的问题。程序在特定的final_time以bad_alloc错误终止。如果我缩短积分时间,程序就会正常终止,但这不是我想要的。然后我将epsabs从1e-9减少到1e-6,程序可以正常运行,直到我需要的final_time。

这不是一个解决方案,而是一个妥协。