std :: bad_alloc и GSL ODE решатель

Я пытаюсь решить (большую) систему ODE с помощью решателей GSL. Когда я использую метод драйвера, я получаю сообщение об ошибке 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, который имеет более умный способ получения промежуточных результатов, также вызывает исключение.

0

Решение

Я столкнулся с похожими проблемами. Программа завершается с ошибкой bad_alloc в определенное время final_time. Если бы я сократил время интегрирования, программа завершилась бы должным образом, но я этого не хочу. Затем я уменьшаю epsabs с 1e-9 до 1e-6, программа может работать должным образом до нужного мне конечного времени.

Это не решение, а компромисс.

1

Другие решения

Других решений пока нет …