Tích hợp số - xử lý NaN (C / Fortran)


12

Tôi đang xử lý một tích phân phức tạp thể hiện NaN ở các giá trị nhất định gần bằng 0 và hiện tại tôi đang xử lý chúng một cách khá thô bạo bằng cách sử dụng câu lệnh ISNAN đặt tích phân về 0 khi điều này xảy ra. Tôi đã thử điều này với thư viện NMS trong FORTRAN (thường trình q1da - q1dax không khác) và với thư viện GSL trong C (sử dụng thường trình QAGS).

Tôi đã xem xét CQUAD (một phần của thư viện GSL cho C) được thiết kế đặc biệt để xử lý NaN và INF trong tích phân, nhưng có rất ít thông tin hữu ích trong tài liệu tham khảo và không có chương trình ví dụ nào tôi có thể tìm thấy. Có ai biết bất kỳ thói quen tích hợp số nào khác cho C hoặc FORTRAN có thể thực hiện công việc không?



^ Tôi đã xóa bài đăng đó.
Josh

Câu trả lời:


10

Tôi là tác giả của CQUADGSL. Giao diện gần giống với giao diện QAGS, vì vậy nếu bạn đã sử dụng cái sau, thì không khó để thử cái trước. Chỉ cần nhớ không chuyển đổi NaNs và Infs của bạn thành số không trong tích phân - mã sẽ tự xử lý.

Các thói quen cũng có sẵn trong Octave như quadcc, và trong Matlab ở đây .

Bạn có thể cung cấp một ví dụ về các thương hiệu bạn đang giao dịch?

Cập nhật

Đây là một ví dụ về việc sử dụng CQUADđể tích hợp một chức năng với một điểm kỳ dị tại một trong các điểm cuối:

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

    }

mà tôi biên soạn với gcc -g -Wall cquad_test.c -lgsl -lcblas. Đầu ra là

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

0,94608307036718495494

Lưu ý rằng không có gì đặc biệt ở đây, cũng không cho biết CQUADđiểm kỳ dị ở đâu, hay bất kỳ sự đối xử đặc biệt nào trong chính thương hiệu. Tôi chỉ để nó trả về NaNs và bộ tích hợp sẽ tự động chăm sóc chúng.

Cũng lưu ý rằng có một lỗi trong phiên bản GSL mới nhất 1.15 có thể ảnh hưởng đến việc điều trị các điểm kỳ dị. Nó đã được sửa chữa, nhưng chưa được phân phối chính thức. Tôi đã sử dụng các nguồn gần đây nhất, tải về với bzr branch http://bzr.savannah.gnu.org/r/gsl/trunk/.


Tuyệt vời, cảm ơn đã trả lời. Tôi đang sử dụng bộ tích hợp để tìm Hàm của Green và tích phân của tôi liên quan đến số mũ và một số sin / cosin. Sau đó, tôi tích hợp các biến này một lần nữa vào một biến khác và đó là nơi tôi nhận được các NaN xuất hiện. Bạn có biết chương trình ví dụ nào sử dụng CQUAD không? Tôi bối rối về cách và nơi để đặt trong các chức năng không gian làm việc. Tôi nên đề cập rằng tôi khá nhiều người mới bắt đầu với loại điều này!
Josh

@Josh: Điểm hay, tôi đoán ai đó phải là người đầu tiên sử dụng nó, vì vậy tôi đã thêm một ví dụ tối thiểu về cách gọi nó.
Pedro

3

Bạn cũng có thể kiểm tra các công thức bậc hai theo cấp số nhân. Họ thực hiện thay đổi (ngầm) các biến, đảm bảo rằng chúng "dễ dàng" tách rời các điểm kỳ dị. Một triển khai rất hay (Fortran77 và C) có thể được tìm thấy trên trang web của Ooura .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.