Integrazione numerica - gestione di NaN (C / Fortran)


12

Ho a che fare con un integrale complicato che mostra NaN a determinati valori vicini allo zero e al momento mi occupo piuttosto grossolanamente di loro usando un'istruzione ISNAN che imposta l'integrando a zero quando ciò si verifica. Ho provato questo con la libreria NMS in FORTRAN (la routine q1da - q1dax non è diversa) e con la libreria GSL in C (usando la routine QAGS).

Ho esaminato CQUAD (parte della libreria GSL per C) che è specificamente progettato per gestire NaNs e INF nell'integrando, ma ci sono pochissime informazioni utili nel riferimento e nessun programma di esempio online che ho trovato. Qualcuno conosce qualche altra routine di integrazione numerica per C o FORTRAN che potrebbe fare il lavoro?



^ Ho cancellato quel post.
Josh,

Risposte:


10

Sono l'autore della CQUADGSL. L'interfaccia è quasi identica a quella di QAGS, quindi se hai usato il secondo, non dovrebbe essere affatto difficile provare il primo. Ricorda solo di non convertire i tuoi NaNs e Infs in zeri nell'integrando: il codice gestirà questi stessi.

La routine è disponibile anche in Octave as quadcce in Matlab qui .

Potresti fornire un esempio degli integrandi con cui hai a che fare?

Aggiornare

Ecco un esempio dell'uso CQUADdi integrare una funzione con una singolarità in uno degli endpoint:

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

    }

con cui ho compilato gcc -g -Wall cquad_test.c -lgsl -lcblas. L'output è

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

0.94608307036718301494

Si noti che qui non c'è nulla di speciale, né per dire CQUADdove sia la singolarità, né alcun trattamento speciale all'interno dell'integrando stesso. Ho appena lasciato che restituisca NaNs, e l'integratore si prende cura di loro automaticamente.

Si noti inoltre che esiste un bug nell'ultima versione 1.15 di GSL che può influire sul trattamento delle singolarità. È stato risolto, ma non è arrivato alla distribuzione ufficiale. Ho usato la fonte più recente, scaricata con bzr branch http://bzr.savannah.gnu.org/r/gsl/trunk/.


Ottimo, grazie per la risposta. Sto usando l'integratore per trovare le funzioni di Green, e il mio integrando coinvolge esponenziali e alcuni seno / coseni. Poi li integro di nuovo con una variabile diversa ed è qui che spuntano le NaN. Conosci programmi di esempio che usano CQUAD? Sono confuso su come e dove inserire le funzioni dell'area di lavoro. Devo dire che sono praticamente un principiante in questo tipo di cose!
Josh,

@Josh: buon punto, immagino che qualcuno debba essere il primo ad usarlo, quindi ho aggiunto un esempio minimo di come può essere chiamato.
Pedro,

3

Puoi anche dare un'occhiata alle formule di quadratura a doppia esponenziale. Fanno un cambiamento (implicito) di variabili, assicurandosi di "allentare" le singolarità dei confini. Un'implementazione molto bella (Fortran77 e C) può essere trovata sul sito Web di Ooura .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.