intsimp.src

来自「没有说明」· SRC 代码 · 共 134 行

SRC
134
字号
/*
** intsimp.src
** (C) Copyright 1988-1998 by Aptech Systems, Inc.
** All Rights Reserved.
**
** This Software Product is PROPRIETARY SOURCE CODE OF APTECH
** SYSTEMS, INC.    This File Header must accompany all files using
** any portion, in whole or in part, of this Source Code.   In
** addition, the right to create such files is strictly limited by
** Section 2.A. of the GAUSS Applications License Agreement
** accompanying this Software Product.
**
** If you wish to distribute any portion of the proprietary Source
** Code, in whole or in part, you must first obtain written
** permission from Aptech Systems.
**
**> intsimp
**
**  Purpose:    Integrates a specified function using Simpson's
**              method with end correction. A single integral is
**              computed in one function call.
**
**  Format:     y = intsimp(&f,xl,tol);
**
**  Inputs:     &f    pointer to the procedure containing the function
**                    to be integrated.
**
**              xl    2x1 vector, the limits of x.
**
**                    The first element is the upper limit and the second
**                    element is the lower limit.
**
**              tol   scalar,  tolerance to be used in testing for
**                    convergence.
**
**  Output:      y    scalar, the  estimated integral of f(x) between
**                    x[1] and x[2].
**
**  Remarks:
**  The function f must be capable of function values.  intsimp will
**  pass to f a vector, and expect a vector in return.  Use ".*" instead
**  of "*".
**
**  Example:    proc f(x);
**                 retp( sin(x) );
**              endp;
**
**              let xl = { 1,
**                         0 };
**
**              y = intsimp(&f,xl,1E-8);
**
**              This will integrate the function between 0 and 1.
**
**  See Also:   intquad1, intquad2, and intquad3, intgrat2, intgrat3
*/

proc intsimp(&f,xl,tol);
    local f:proc;
    local sfa,sfb,tfa,area0,sdh,gfa,gfb,sn,iter,sda, sdx,sdxeven,sdxodd,
        area,endcor, converge;

    /* check for complex input */
    if iscplx(xl);
        if hasimag(xl);
            errorlog "ERROR: Not implemented for complex matrices.";
            end;
        else;
            xl = real(xl);
        endif;
    endif;

    if iscplx(tol);
        if hasimag(tol);
            errorlog "ERROR: Not implemented for complex matrices.";
            end;
        else;
            tol = real(tol);
        endif;
    endif;

    if xl[1] == xl[2];
        retp(0);
    endif;
    sfa = f(xl[2]);
    sfb = f(xl[1]);         /* function evaluations at end points */
    tfa = sfa + sfb;
    area0 = tfa*(xl[1]-xl[2])/2;    /* use trapezoidal first approx to area */

    sdh = 1e-4;     /* size of dx for computing derivatives */
    gfa = (sfa-f(xl[2]-sdh))/sdh;           /* derivatives at end points  */

    /* gfb = (sfb-f(xl[1]-sdh))/sdh;    Corrected below 12/15/88 SDJ */
    gfb = (f(xl[1]+sdh)-sfb)/sdh;

    endcor = gfa-gfb;       /* used for the end correction */

    sn = 16;        /* sn is the initial number of panels used in computing
                    :: approximation to integral
                    */
    iter = 1;
    sda = 1;

    /* values at initial sn */

    sdx = (xl[1]-xl[2])/sn;         /* width of panels */
    sdxeven = sumc( f(seqa(xl[2]+2*sdx,2*sdx,(sn/2)-1)) );
                                            /* compute value of x at
                                            :: boundaries of even panels
                                            */
    sdxodd = sumc( f( seqa(xl[2]+sdx,2*sdx,sn/2)) );
                                            /* compute value of x at
                                            :: boundaries of odd panels
                                            */
    converge = 0;
    do until converge or iter > 9;
        sn = sn*2;          /* double number of panels for this iteration  */
        sdx = (xl[1]-xl[2])/sn;
        sdxeven = sdxeven+sdxodd;           /* we do not need to recompute  */
        sdxodd = sumc( f( seqa(xl[2]+sdx,2*sdx,sn/2)) );
        /* the following statement computes the Simpson approximation  */
        area = (7*tfa + 14*sdxeven + 16*sdxodd + sdx*endcor)*(sdx/15);
        iter = iter+1;
        sda = (area-area0)/area0;
        area0 = area;
        converge = abs(sda) < tol;
    endo;
    if iter == 10 and not converge;
        errorlog "Integral could not be computed to specified tolerance";
        end;
    endif;
    retp(area);
endp;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?