Intégration numérique - manipulation des NaN (C / Fortran)


12

J'ai affaire à une intégrale délicate qui présente des NaN à certaines valeurs proches de zéro et pour le moment je les traite assez grossièrement en utilisant une instruction ISNAN qui met l'intégrande à zéro lorsque cela se produit. J'ai essayé cela avec la bibliothèque NMS de FORTRAN (la routine q1da - q1dax n'est pas différente) et avec la bibliothèque GSL en C (en utilisant la routine QAGS).

J'ai examiné CQUAD (qui fait partie de la bibliothèque GSL pour C) qui est spécifiquement conçu pour gérer les NaN et INF dans l'intégrande, mais il y a très peu d'informations utiles dans la référence et aucun exemple de programme en ligne que j'ai pu trouver. Quelqu'un connaît-il une autre routine d'intégration numérique pour C ou FORTRAN qui pourrait faire le travail?



^ J'ai supprimé ce message.
Josh

Réponses:


10

Je suis l'auteur du CQUADGSL. L'interface est presque identique à celle de QAGS, donc si vous avez utilisé ce dernier, il ne devrait pas être difficile du tout d'essayer le premier. N'oubliez pas de ne pas convertir vos NaNs et Infs en zéros dans l'intégrande - le code les traitera lui-même.

La routine est également disponible dans Octave as quadcc, et dans Matlab ici .

Pourriez-vous fournir un exemple des intégrandes avec lesquelles vous traitez?

Mise à jour

Voici un exemple d'utilisation CQUADpour intégrer une fonction avec une singularité à l'un des points de terminaison:

#include <stdio.h>
#include <gsl/gsl_integration.h>

/* Our test integrand. */
double thefunction ( double x , void *param ) {
    return sin(x) / x;
    }

/* Driver function. */
int main ( int argc , char *argv[] ) {

    gsl_function f;
    gsl_integration_cquad_workspace *ws = NULL;
    double res, abserr;
    size_t neval;

    /* Prepare the function. */
    f.function = &thefunction;
    f.params = NULL;

    /* Initialize the workspace. */
    if ( ( ws = gsl_integration_cquad_workspace_alloc( 200 ) ) == NULL ) {
        printf( "main: call to gsl_integration_cquad_workspace_alloc failed.\n" );
        abort();
        }

    /* Call the integrator. */
    if ( gsl_integration_cquad( &f, 0.0 , 1.0 , 1.0e-10 , 1.0e-10 , ws , &res , &abserr , &neval ) != 0 ) {
        printf( "main: call to gsl_integration_cquad failed.\n" );
        abort();
        }

    /* Print the result. */
    printf( "main: int of sin(x)/x in [0,1] is %.16e +/- %e (%i evals).\n" ,
        res , abserr , neval );

    /* Free the workspace. */
    gsl_integration_cquad_workspace_free( ws );

    /* Bye. */
    return 0;

    }

avec lequel j'ai compilé gcc -g -Wall cquad_test.c -lgsl -lcblas. La sortie est

main: int of sin(x)/x in [0,1] is 9.4608307036718275e-01 +/- 4.263988e-13 (63 evals).

0.94608307036718301494

Notez qu'il n'y a rien de spécial ici, ni pour dire CQUADoù se trouve la singularité, ni aucun traitement spécial au sein de l'intégrande elle-même. Je viens de le laisser revenir NaN, et l'intégrateur s'en charge automatiquement.

Notez également qu'il existe un bug dans la dernière version GSL 1.15 qui peut affecter le traitement des singularités. Il a été corrigé, mais n'est pas parvenu à la distribution officielle. J'ai utilisé la source la plus récente, téléchargée avec bzr branch http://bzr.savannah.gnu.org/r/gsl/trunk/.


Très bien, merci pour la réponse. J'utilise l'intégrateur pour trouver les fonctions de Green, et mon intégrand implique des exponentielles et des sinus / cosinus. Je les intègre ensuite à nouveau avec une variable différente et c'est là que je fais apparaître les NaN. Connaissez-vous des exemples de programmes utilisant CQUAD? Je ne sais pas trop comment et où mettre les fonctions de l'espace de travail. Je dois mentionner que je suis à peu près un débutant dans ce genre de chose!
Josh

@Josh: Bon point, je suppose que quelqu'un doit être le premier à l'utiliser, j'ai donc ajouté un exemple minimal de la façon dont il peut être appelé.
Pedro

3

Vous pouvez également consulter les formules de quadrature exponentielle double. Ils effectuent un changement (implicite) de variables, en s'assurant qu'ils "relâchent" les singularités des limites. Une très belle implémentation (Fortran77 et C) peut être trouvée sur le site Web d'Ooura .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.