【问题标题】:std::bad_alloc and GSL ODE solverstd::bad_alloc 和 GSL ODE 求解器
【发布时间】:2013-03-13 14:41:25
【问题描述】:

我正在尝试使用 GSL 求解器求解(大型)ODE 系统。当我使用驱动程序方法时,我收到一条错误消息could not allocate space for gsl_interp_accel,当我手动定义控件、错误和步进器时,我收到bad_alloc 异常,据我了解,这是由导致@ 987654325@ 在另一种情况下 - 内存不足。

我已经咨询了其他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 编译器和英特尔 C++ Composer 编译。在 Mac 上也测试过(不知道是哪个版本的操作系统),结果相同。

问题是:有没有什么办法可以“欺骗”求解器并让程序正常运行?

P.S.:ODEint 求解器具有更智能的获取中间结果的方式,也会引发异常。

【问题讨论】:

  • 你能举一个发生错误的小例子吗? size_of_the_system 有多大?
  • size是8,但是最终时间很大,>1200,而初始时间是1。我找到了gsl_odeiv2_evolve_apply函数的代码,是here
  • 好的,这是否意味着您有一个由 8 个耦合 ODE 组成的小型系统,并且您执行了很多集成步骤并将每个步骤的结果存储在一个容器中?也许您应该尝试在不存储所有数据的情况下即时进行分析?
  • 是的,这是真的,如果我有点不清楚,对不起。我无法“即时”执行分析,因为我需要所有数据集进行插值。此外,即使我不注意中间值,程序仍然会崩溃。我什至尝试在每次应用“gsl_odeiv2_evolve_apply”之前/之后定义/释放(即在while循环内),但这并没有引导我到任何地方。

标签: c++ memory-management gsl ode bad-alloc


【解决方案1】:

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

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

【讨论】:

  • 对不起,我在 ODE 的右侧函数中发现了错误。我在那里使用“新”,但忘记了“删除”。
猜你喜欢
  • 1970-01-01
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多