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

Matlab 高斯函数不定积分的数值积分,matlab,continuous-integration,numerical-integration,Matlab,Continuous Integration,Numerical Integration,我的方法 fun = @(y) (1/sqrt(pi))*exp(-(y-1).^2).*log(1 + exp(-4*y)) integral(fun,-Inf,Inf) 这给了南 所以我试着策划它 y= -10:0.1:10; plot(y,exp(-(y-1).^2).*log(1 + exp(-4*y))) 然后理解域(重要部分)是从-4到+4 所以把限制改为 integral(fun,-10,10) 然而,我不想总是绘制图形,然后知道它的限制。那么有没有办法直接知道从-Inf到I

我的方法

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

所以我试着策划它

y= -10:0.1:10;
plot(y,exp(-(y-1).^2).*log(1 + exp(-4*y)))
然后理解域(重要部分)是从-4到+4

所以把限制改为

integral(fun,-10,10)

然而,我不想总是绘制图形,然后知道它的限制。那么有没有办法直接知道从-Inf到Inf的积分呢?

一个快速而肮脏的解决方案就是寻找一个函数足够小的位置,然后把它作为极限。这假设对于
x>0
而言,函数
fun
每月减少,并且
fun(x)
fun(-x)
的大小大致相同

%// A small number
epsilon = eps;
%// Stepsize for searching bound
stepTest = 1;
%// Starting position for searching bound
position = 0;
%// Not yet small enough
smallEnough = false;

%// Search bound
while ~smallEnough
   smallEnough = (fun(position) < eps);
   position = position + stepTest;
end

%// Calculate integral
integral(fun, -position, position)
%//一个小数字
epsilon=eps;
%//搜索边界的步长
逐步检验=1;
%//搜索边界的起始位置
位置=0;
%//还不够小
足够小=错误;
%//搜索范围
而我却足够小
足够小=(乐趣(位置)
如果您对绘制函数感到满意,并通过肉眼确定可以剪切的位置,那么我想这段代码就足够了。

如果你的积分总是

我会用高阶的。 它类似于Gauss-Legendre-Kronrod规则,该规则构成了标准高斯乘法器的基础,但专门针对实线上的积分

用替换x=y-1重写方程,我们得到

然后可以使用任意阶的高斯-厄米特规则(合理范围内)计算积分:

我要注意的是,下面的函数构建了一个完整的
顺序x顺序
矩阵来计算
节点
,因此它不应该太大。 有一种方法可以通过显式计算权重来避免这种情况,但我决定懒惰。 此外,在100阶事件中,高斯乘数约为
2E-98
,因此被积函数的贡献极小。 虽然这不是天生的适应性,但在大多数情况下,高阶规则应该足够了。。。我希望如此

代码
函数[节点,权重]=GaussHermiteRule(n)
% ------------------------------------------------------------------------------
%求Gauss-Hermite求积的节点和权重。
%
if(n<1)
错误('不存在阶数为0的高斯-埃尔米特规则');
elseif(n<0)| |(abs(n-round(n))>eps())
错误('给定的顺序“n”必须是严格的正整数');
其他的
n=圆形(n);
结束
%从Golub-Welsch函数中获取节点和权重
n=(0:n)';
b=n*0;
a=b+0.5;
c=n;
[节点,权重]=GolubWelsch(a,b,c,sqrt(pi));
结束
函数[xk,wk]=GolubWelsch(ak,bk,ck,mu0)
%高卢布尔希
%计算正交矩阵的近似*节点和权重(归一化为1)
%由形式的三项递归关系定义的多项式族
%x pk(x)=ak pkp1(x)+bk pk(x)+ck pkm1(x)
%   
%权重比例因子mu0是权重函数在
%正交域。
%
%计算多项式的正交版本的项
α=sqrt(ak(1:end-1)。*ck(2:end));
%建立对称三对角矩阵
T=满(spdiags([[alpha;0],bk[0;alpha]],[-1,0,+1],长度(alpha),长度(alpha));
%计算矩阵的特征向量和值
[V,xk]=eig(T,'vector');
%根据特征向量计算权重-技术上,Golub Welsch要求
%标准化,但由于MATLAB返回单位特征向量,因此省略了它。
wk=mu0*(V(1,:).^2)';
结束

我已经成功地使用数值变量转换来转换此类无限有界积分,如数值公式3e第4.5.3节所述。基本上,代入y=c*tan(t)+b,然后对t进行数值积分(-pi/2,pi/2),从而将y从-无穷大扫到无穷大。您可以调整c和b的值以优化流程。这种方法在很大程度上回避了试图在域中确定截止值的问题,但为了使用求积法可靠地工作,您必须知道被积函数没有远离y=b的特征。

您看到函数在[-25;-20]范围内时会发生什么吗?函数值非常小。。比如1.0e-190 at-20。在-25时,它几乎为零。很容易看出,对于
x>0
,函数实际上是单非的。我认为在这种情况下,
xin的单调性是的,但这个问题意味着任何函数都有一个通用的解决方案——缺少符号积分(可能有效,也可能无效),这将是很困难的IMO@bepracticalalwayz很抱歉,我最初误读了你的函数,它在-25发射,请忽略以下评论:)单调性是一个很强的假设!你是对的。为了使代码正常工作,假设存在一个点
x
,使得从
x
到无穷大的积分在
fun
上可以忽略不计。
>> order           = 10;
>> [nodes,weights] = GaussHermiteRule(order);
>> f               = @(x) log(1 + exp(-4*(x+1)))/sqrt(pi);
>> sum(f(nodes).*weights)
ans =
    0.1933
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