2011-04-19 2 views
0

Je veux utiliser le GSL pour l'intégration http://www.gnu.org/software/gsl/manual/html_node/Numerical-Integration.html Cependant, je ne trouve pas moyen pratique comment la fonction intégréeGSL: rapports d'erreur

(la fonction f dans l'exemple http://www.gnu.org/software/gsl/manual/html_node/Numerical-integration-examples.html)

peut signaler une erreur à l'intégrateur. Je veux intégrer une fonction qui elle-même résulte d'une intégration qui pourrait échouer. Ceci est mon exemple de programme

#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; 
} 

entraînant la sortie status = 0 status = -1

Je pense que l'intégrateur devrait plutôt arrêter et retourner mon code d'erreur. Comment puis-je atteindre cet objectif?

Merci beaucoup pour votre aide !!!

2011-04-27: J'ai aussi essayé cette variante, après Brian Gough m'a dit,

#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; 
} 

il n'a pas aidé non plus. Je vais maintenant remplir un rapport de bug.

Répondre

3

Merci à Xuebin Wu de la liste de diffusion GSL le problème est résolu:

Salut,

GSL_ERROR est lui-même une macro, il ressemble à

 gsl_error (reason, __FILE__, __LINE__, gsl_errno); 
     return gsl_errno; 

La fonction retourne déjà avant votre retour NAN, parce GSL_ERROR a été appelé. En éteignant le gestionnaire, laissez simplement la première ligne faire rien. Le gestionnaire d'erreurs par défaut abandonne le programme après l'impression du message d'erreur .

Je ne pense pas que ce soit un bug. Peut-être que vous pouvez écrire votre propre gestionnaire d'erreur pour résoudre votre problème. Par exemple, vous pouvez utiliser "goto" pour sortir de gsl_integration_qags ou définir une variable globale pour indiquer que le résultat d'intégration est incorrect.

PS: Je crois que cette macro est ce que vous avez besoin,

Macro: GSL_ERROR_VAL (raison, gsl_errno, valeur) Cette macro est le même que GSL_ERROR mais retourne une valeur définie par l'utilisateur de la valeur au lieu d'une code d'erreur. Il peut être utilisé pour les fonctions mathématiques qui renvoient une valeur à virgule flottante.

L'exemple suivant montre comment retourner un NaN à une singularité mathématique en utilisant la macro GSL_ERROR_VAL,

if (x == 0) 
    { 
    GSL_ERROR_VAL("argument lies on singularity", 
        GSL_ERANGE, GSL_NAN); 
    } 

J'ajusté le code suivant

#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; 
} 

et tout fonctionne comme prévu. ..

0

Un peu hackish, mais j'aurais probablement votre fonction de stocker un drapeau. Quand il rencontre une erreur, il met le drapeau et renvoie zéro pour toutes les évaluations suivantes. Ensuite, après l'avoir intégré, vous pouvez vérifier ce drapeau pour voir si le résultat est valide.

+0

Bonjour Rhys, merci pour l'indice, c'est comme ça qu'un collègue le fait. Je pense qu'il serait préférable (aussi concernant la vitesse) d'arrêter réellement l'évaluation. Actuellement, je compile le GSL avec CFLAG -fexception et utilise la gestion des exceptions C++. Cependant, normalement le GSL ne supporte pas les exceptions et ils sont en C++, j'ai donc cherché un moyen plus direct. – 7asd23hasd

0

Que diriez-vous d'écrire un wrapper pour la fonction qui renvoie le pointeur vers une structure, contenant les résultats de la fonction et l'état de l'erreur? Ou si vous utilisez C++, cette encapsulation peut être fait avec l'utilisation d'objets ....

+0

Bonjour David, je veux juste que gsl_integration_qags s'arrête en raison de l'erreur signalée en f ... – 7asd23hasd