บูรณาการเชิงตัวเลข - การจัดการ NaNs (C / Fortran)


12

ฉันกำลังจัดการกับอินทิกรัลยุ่งยากที่แสดง NaNs ที่ค่าบางค่าใกล้ศูนย์และในขณะนี้ฉันกำลังจัดการกับพวกเขาค่อนข้างโหดร้ายโดยใช้คำสั่ง ISNAN ซึ่งกำหนดให้ integrand เป็นศูนย์เมื่อเกิดเหตุการณ์นี้ขึ้น ฉันลองสิ่งนี้กับไลบรารี NMS ใน FORTRAN (รูทีน q1da - q1dax ไม่แตกต่างกัน) และกับไลบรารี GSL ใน C (ใช้รูทีน QAGS)

ฉันดู CQUAD (ส่วนหนึ่งของไลบรารี GSL สำหรับ C) ซึ่งออกแบบมาโดยเฉพาะเพื่อจัดการ NaNs และ INF ในอินทิเกรต แต่มีข้อมูลที่มีประโยชน์น้อยมากในการอ้างอิงและไม่มีตัวอย่างโปรแกรมออนไลน์ที่ฉันสามารถหาได้ ไม่มีใครรู้รูทีนการรวมตัวเลขอื่น ๆ สำหรับ C หรือ FORTRAN ซึ่งสามารถทำงานได้หรือไม่?


ข้ามโพสต์ในmath.stackexchange.com/questions/242771/ …

ฉันได้ลบโพสต์นั้นแล้ว
Josh

คำตอบ:


10

ฉันเป็นผู้เขียนCQUADใน GSL อินเทอร์เฟซเกือบจะเหมือนกับอินเทอร์เฟซของQAGSดังนั้นหากคุณเคยใช้อินเทอร์เฟซหลังมันก็ไม่ยากที่จะลองใช้ตัวเก่า เพียงจำไว้ว่าอย่าแปลงค่าของคุณNaNเป็นInfศูนย์ในปริพันธ์และรหัสจะจัดการกับสิ่งเหล่านี้เอง

กิจวัตรประจำวันยังมีอยู่ในคู่เป็นquadccและใน Matlab ที่นี่

คุณสามารถให้ตัวอย่างของอินทิกรัลที่คุณติดต่อด้วยได้หรือไม่?

ปรับปรุง

นี่คือตัวอย่างของการใช้CQUADเพื่อรวมฟังก์ชั่นที่มีภาวะเอกฐานที่หนึ่งในจุดสิ้นสุด:

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

    }

gcc -g -Wall cquad_test.c -lgsl -lcblasซึ่งผมรวบรวมกับ ผลลัพธ์คือ

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

0.94608307036718301494

โปรดทราบว่าไม่มีอะไรพิเศษที่นี่ไม่ต้องบอกCQUADว่าภาวะเอกฐานอยู่ที่ไหนหรือการดูแลเป็นพิเศษใด ๆ ภายในอินทิเกรตและตัวมันเอง ฉันแค่ปล่อยให้มันคืนNaNs และผู้รวบรวมจะดูแลพวกเขาโดยอัตโนมัติ

โปรดทราบว่ามีข้อผิดพลาดใน GSL เวอร์ชันล่าสุด 1.15 ซึ่งอาจส่งผลต่อการรักษาภาวะเอกฐาน มันได้รับการแก้ไขแล้ว แต่ยังไม่ได้ทำการแจกจ่ายอย่างเป็นทางการ bzr branch http://bzr.savannah.gnu.org/r/gsl/trunk/ผมใช้แหล่งที่มาล่าสุดกับการดาวน์โหลด


เยี่ยมมากขอบคุณสำหรับการตอบกลับ ฉันกำลังใช้ตัวรวมเพื่อค้นหาฟังก์ชั่นของกรีนและอินทิกรัลของฉันเกี่ยวข้องกับเลขชี้กำลังและไซน์ / โคไซน์ จากนั้นฉันก็รวมตัวแปรเหล่านี้อีกครั้งแล้วและนั่นคือจุดที่ฉันได้รับ NaN โผล่ขึ้นมา คุณรู้จักโปรแกรมตัวอย่างใด ๆ ที่ใช้ CQUAD หรือไม่ ฉันสับสนเกี่ยวกับวิธีการและตำแหน่งในการทำงานในพื้นที่ทำงาน ฉันควรจะพูดถึงว่าฉันเป็นมือใหม่ในประเภทนี้มาก!
Josh

@ Josh: จุดดีฉันคิดว่าใครบางคนจะต้องเป็นคนแรกที่จะใช้มันดังนั้นฉันจึงได้เพิ่มตัวอย่างเล็ก ๆ น้อย ๆ ของวิธีที่มันสามารถเรียกได้
เปโดร

3

คุณสามารถตรวจสอบสูตรการสร้างพื้นที่สี่เหลี่ยมจัตุรัสทวีคูณ พวกเขาทำการเปลี่ยนแปลง (โดยปริยาย) ของตัวแปรทำให้แน่ใจว่าพวกเขา "หลุดพ้น" เอกพจน์ขอบเขต ดีมาก (Fortran77 และ C) การดำเนินงานที่สามารถพบได้บนเว็บไซต์ของ Ooura

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.