#error-handling #integration #gsl
#обработка ошибок #интеграция #gsl
Вопрос:
Я хочу использовать GSL для интеграцииhttp://www.gnu.org/software/gsl/manual/html_node/Numerical-Integration.html Однако я не нахожу удобного способа, как интегрированная функция
(функция f в примере http://www.gnu.org/software/gsl/manual/html_node/Numerical-integration-examples.html )
может сообщать об ошибке интегратору. Я хочу интегрировать функцию, которая сама является результатом интеграции, которая может завершиться неудачей. Это мой пример программы
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_integration.h>
#include <gsl/gsl_errno.h>
double f (double x, void * params) {
GSL_ERROR("test error",GSL_FAILURE);
return 0.0;
}
int main (void)
{
gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000);
double result, error;
gsl_function F;
F.function = amp;f;
gsl_set_error_handler_off();
int status = gsl_integration_qags (amp;F, 0, 1, 0, 1e-7, 1000,
w, amp;result, amp;error);
printf ("status = %dn", status);
status = GSL_FAILURE;
printf ("status = %dn", status);
gsl_integration_workspace_free (w);
return 0;
}
в результате на выходе
статус = 0
статус = -1
Я думаю, интегратору лучше остановиться и вернуть мой код ошибки. Как я могу этого добиться?
Большое вам спасибо за вашу помощь!!!
2011-04-27: Я также попробовал этот вариант, после того как Брайан Гоф сказал мне,
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_integration.h>
#include <gsl/gsl_errno.h>
double f (double x, void * params) {
GSL_ERROR("test error",GSL_FAILURE);
return GSL_NAN;
}
int main (void)
{
gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000);
double result, error;
gsl_function F;
F.function = amp;f;
gsl_set_error_handler_off();
int status = gsl_integration_qags (amp;F, 0, 1, 0, 1e-7, 1000,
w, amp;result, amp;error);
printf ("status = %dn", status);
status = GSL_FAILURE;
printf ("status = %dn", status);
gsl_integration_workspace_free (w);
return 0;
}
это тоже не помогло. Теперь я заполню отчет об ошибке.
Ответ №1:
Благодаря Xuebin Wu из списка рассылки GSL проблема решена:
Привет,
GSL_ERROR сам по себе является макросом, он выглядит как
gsl_error (reason, __FILE__, __LINE__, gsl_errno);
return gsl_errno;
Функция уже возвращается до того, как вы вернете NAN, потому что GSL_ERROR
был вызван. Выключая обработчик, просто позвольте первой строке выполнить
ничего. Обработчик ошибок по умолчанию прерывает программу после печати
сообщение об ошибке.
Я не думаю, что это ошибка. Возможно, вы можете написать свой собственный обработчик ошибок для решения вашей проблемы. Например, вы можете использовать «goto» для перехода из gsl_integration_qags или задать некоторую глобальную переменную, чтобы указать, что результат интеграции неверен.
PS: Я считаю, что этот макрос — то, что вам нужно,
Макрос: GSL_ERROR_VAL (причина, gsl_errno, значение) Этот макрос такой же, как GSL_ERROR, но возвращает определенное пользователем значение value вместо кода ошибки. Его можно использовать для математических функций, которые возвращают значение с плавающей запятой.
В следующем примере показано, как вернуть NaN при математической особенности, используя макрос GSL_ERROR_VAL,
if (x == 0)
{
GSL_ERROR_VAL("argument lies on singularity",
GSL_ERANGE, GSL_NAN);
}
Итак, я скорректировал код в соответствии с
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_integration.h>
#include <gsl/gsl_errno.h>
double f (double x, void * params) {
// return GSL_NAN;
GSL_ERROR_VAL ("argument lies on singularity", GSL_ERANGE, GSL_NAN);
}
int main (void)
{
gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000);
double result, error;
gsl_function F;
F.function = amp;f;
gsl_set_error_handler_off();
int status = gsl_integration_qags (amp;F, 0, 1, 0, 1e-7, 1000,
w, amp;result, amp;error);
printf ("status = %dn", status);
status = GSL_FAILURE;
printf ("status = %dn", status);
gsl_integration_workspace_free (w);
return 0;
}
и все работает так, как ожидалось…
Ответ №2:
Немного по-хакерски, но я бы, вероятно, попросил вашу функцию сохранить какой-нибудь флаг. Когда он обнаруживает ошибку, он устанавливает флаг и возвращает ноль для всех последующих вычислений. Затем, после того как вы интегрировали его, вы можете проверить этот флаг, чтобы увидеть, является ли результат действительным.
Комментарии:
1. Привет, Рис, спасибо за подсказку, именно так это делает коллега. Я думаю, было бы лучше (также в отношении скорости) действительно остановить оценку. В настоящее время я компилирую GSL с CFLAG -fexception и использую обработку исключений C . Однако, обычно GSL не поддерживает исключения, и они написаны на C , поэтому я искал более прямой способ.
Ответ №3:
Как насчет того, чтобы написать оболочку для функции, которая возвращает указатель на структуру, содержащую результаты функции и состояние ошибки? Или, если вы используете c , эта инкапсуляция может быть выполнена с использованием объектов ….
Комментарии:
1. Привет, Дэвид, я просто хочу, чтобы gsl_integration_qags остановился из-за ошибки, о которой сообщается в f…