GSL: сообщение об ошибке - PullRequest
0 голосов
/ 19 апреля 2011

Я хочу использовать 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 = &f;

gsl_set_error_handler_off();
int status = gsl_integration_qags (&F, 0, 1, 0, 1e-7, 1000,
                     w, &result, &error); 

printf ("status          = %d\n", status);
status  = GSL_FAILURE;
printf ("status          = %d\n", 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 = &f;

gsl_set_error_handler_off();
int status = gsl_integration_qags (&F, 0, 1, 0, 1e-7, 1000,
                     w, &result, &error); 

printf ("status          = %d\n", status);
status  = GSL_FAILURE;
printf ("status          = %d\n", status);


gsl_integration_workspace_free (w);

return 0;
}

он тоже не помог. Теперь я заполню отчет об ошибке.

Ответы [ 3 ]

4 голосов
/ 28 апреля 2011

Благодаря 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, но возвращает определяемое пользователем значение значения вместо кода ошибки.Его можно использовать для математических функций, которые возвращают значение с плавающей запятой.

В следующем примере показано, как вернуть 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 = &f;

gsl_set_error_handler_off();
int status = gsl_integration_qags (&F, 0, 1, 0, 1e-7, 1000,
                     w, &result, &error); 

printf ("status          = %d\n", status);
status  = GSL_FAILURE;
printf ("status          = %d\n", status);


gsl_integration_workspace_free (w);

return 0;
}

и все работает как положено ...

0 голосов
/ 19 апреля 2011

Как насчет написания оболочки для функции, которая возвращает указатель на структуру, содержащую результаты функции и статус ошибки?Или, если вы используете c ++, эта инкапсуляция может быть выполнена с использованием объектов ....

0 голосов
/ 19 апреля 2011

Немного хакерский, но я бы, наверное, попросил вашу функцию сохранить флаг. Когда он сталкивается с ошибкой, он устанавливает флаг и возвращает ноль для всех последующих оценок. Затем, после того, как вы интегрировали его, вы можете проверить этот флаг, чтобы увидеть, является ли результат действительным.

...