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