Integración numérica - manejo de NaNs (C / Fortran)

12

Estoy tratando con una integral complicada que exhibe NaNs a ciertos valores cercanos a cero y en este momento estoy tratando con ellos de manera bastante cruda usando una declaración ISNAN que establece el integrando a cero cuando esto ocurre. He intentado esto con la biblioteca NMS en FORTRAN (la rutina q1da - q1dax no es diferente) y con la biblioteca GSL en C (usando la rutina QAGS).

Miré en CQUAD (parte de la biblioteca GSL para C) que está específicamente diseñado para manejar NaNs e INF en el integrando, pero hay muy poca información útil en la referencia y no hay programas de ejemplo en línea que pueda encontrar. ¿Alguien conoce alguna otra rutina de integración numérica para C o FORTRAN que pueda hacer el trabajo?

Josh
fuente
^ He eliminado esa publicación.
Josh

Respuestas:

10

Soy el autor de CQUADla GSL. La interfaz es casi idéntica a la de QAGS, por lo que si ha utilizado la última, no debería ser difícil probar la primera. Sólo recuerda no convertir sus NaNs y Infs a ceros en el integrando - el código se ocupará de éstos en sí.

La rutina también está disponible en Octave as quadcc, y en Matlab aquí .

¿Podría dar un ejemplo de los integrandos con los que está tratando?

Actualizar

Aquí hay un ejemplo de uso CQUADpara integrar una función con una singularidad en uno de los puntos finales:

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

    }

lo que he realizado con gcc -g -Wall cquad_test.c -lgsl -lcblas. La salida es

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

0.94608307036718301494

Tenga en cuenta que no hay nada especial aquí, ni para decir CQUADdónde está la singularidad, ni ningún tratamiento especial dentro del propio integrando. Solo dejo que devuelva NaNs, y el integrador se encarga de ellos automáticamente.

Tenga en cuenta también que hay un error en la última versión 1.15 de GSL que puede afectar el tratamiento de las singularidades. Se ha solucionado, pero no ha llegado a la distribución oficial. Utilicé la fuente más reciente, descargada con bzr branch http://bzr.savannah.gnu.org/r/gsl/trunk/.

Pedro
fuente
Genial, gracias por la respuesta. Estoy usando el integrador para encontrar las funciones de Green, y mi integrando involucra exponenciales y algunos seno / cosenos. Luego los integro nuevamente con una variable diferente y ahí es donde obtengo los NaNs apareciendo. ¿Conoces algún programa de ejemplo que use CQUAD? Estoy confundido acerca de cómo y dónde colocar las funciones del espacio de trabajo. ¡Debo mencionar que soy un principiante en este tipo de cosas!
Josh el
@ Josh: Buen punto, supongo que alguien tiene que ser el primero en usarlo, así que he agregado un ejemplo mínimo de cómo se puede llamar.
Pedro
3

También puede consultar las fórmulas de cuadratura doble exponencial. Realizan un cambio (implícito) de variables, asegurándose de que "facilitan" las singularidades de los límites. Una implementación muy agradable (Fortran77 y C) se puede encontrar en el sitio web de Ooura .

GertVdE
fuente