高斯函数的数值积分 - 不定积分

时间:2015-10-14 07:02:17

标签: matlab continuous-integration numerical-integration

enter image description here

我的方法

public void StartupJob()
{
    this.Job = new Job(#params); //create the object
    this.Job.JobCompleted += Job_JobCompleted; //hookup the event
    this.Job.Run(); //do some work
}

public override void SendNotification(string content)
{
    //Invoke your event (always see if it is hooked up)
    if(Job.JobCompleted != null)
        Job.JobCompleted(this, new JobCompletionData(content));
}

这给了NaN。

所以我尝试绘制它。

fun = @(y) (1/sqrt(pi))*exp(-(y-1).^2).*log(1 + exp(-4*y))
integral(fun,-Inf,Inf)

然后理解域(siginificant部分)是从-4到+4。

因此将限制更改为

y= -10:0.1:10;
plot(y,exp(-(y-1).^2).*log(1 + exp(-4*y)))

但是我不想总是绘制图表,然后知道它的极限。那么有没有办法直接从-Inf知道积分。

3 个答案:

答案 0 :(得分:2)

Discussion

If your integrals are always of the form

integral from negative infinity to infinity of f of x times e to the negative x squared

I would use a high-order Gauss–Hermite quadrature rule. It's similar to the Gauss-Legendre-Kronrod rule that forms the basis for quadgk but is specifically tailored for integrals over the real line with a standard Gaussian multiplier.

Rewriting your equation with the substitution x = y-1, we get

integral from negative  infinity to infinity of the user's function times e to the negative x squared.

The integral can then be computed using the Gauss-Hermite rule of arbitrary order (within reason):

>> order           = 10;
>> [nodes,weights] = GaussHermiteRule(order);
>> f               = @(x) log(1 + exp(-4*(x+1)))/sqrt(pi);
>> sum(f(nodes).*weights)
ans =
    0.1933

I'd note that the function below builds a full order x order matrix to compute nodes, so it shouldn't be made too large. There is a way to avoid this by explicitly computing the weights, but I decided to be lazy. Besides, event at order 100, the Gaussian multiplier is about 2E-98, so the integrand's contribution is extremely minimal. And while this isn't inherently adaptive, a high-order rule should be sufficient in most cases ... I hope.

Code

function [nodes,weights] = GaussHermiteRule(n)
    % ------------------------------------------------------------------------------
    %  Find the nodes and weights for a Gauss-Hermite Quadrature integration.
    %

    if (n < 1)
        error('There is no Gauss-Hermite rule of order 0.');
    elseif  (n < 0) || (abs(n - round(n)) > eps())
        error('Given order ''n'' must be a strictly positive integer.');
    else
        n = round(n);
    end

    %   Get the nodes and weights from the Golub-Welsch function
    n = (0:n)'  ;
    b = n*0     ;
    a = b + 0.5 ;
    c = n       ;
    [nodes,weights] = GolubWelsch(a,b,c,sqrt(pi));

end


function [xk,wk] = GolubWelsch(ak,bk,ck,mu0)
    %GolubWelsch
    %   Calculate the approximate* nodes and weights (normalized to 1) of an orthogonal 
    %   polynomial family defined by a three-term reccurence relation of the form
    %       x pk(x) = ak pkp1(x) + bk pk(x) + ck pkm1(x)
    %   
    %   The weight scale factor mu0 is the integral of the weight function over the
    %   orthogonal domain.
    %

    %   Calculate the terms for the orthonormal version of the polynomials
    alpha = sqrt(ak(1:end-1) .* ck(2:end));

    %   Build the symmetric tridiagonal matrix
    T = full(spdiags([[alpha;0],bk,[0;alpha]],[-1,0,+1],length(alpha),length(alpha)));

    %   Calculate the eigenvectors and values of the matrix
    [V,xk] = eig(T,'vector');

    %   Calculate the weights from the eigenvectors - technically, Golub-Welsch requires
    %   a normalization, but since MATLAB returns unit eigenvectors, it is omitted.
    wk = mu0*(V(1,:).^2)';

end

答案 1 :(得分:0)

我已经成功地使用数值变量转换来转换这种无限有界积分,如数值配方3e,第4.5.3节中所述。基本上,你用y = c * tan(t)+ b代替,然后用数字积分t(-pi / 2,pi / 2),它将y从-infinity扫描到无穷大。您可以调整c和b的值以优化过程。这种方法很大程度上避免了尝试确定域中的截止值的问题,但为了使用正交可靠地工作,你必须知道被积函数不具有远离y = b的特征。

答案 2 :(得分:-1)

快速而肮脏的解决方案是寻找一个位置,你的功能足够小,然后将其作为限制。这假设对于x>0,函数fun以字母方式减少,fun(x)fun(-x)的{​​{1}}的大小基本相同。

x

如果你对绘制函数很满意,可以用眼睛决定你可以剪切的地方,那么这个代码就足够了,我猜。