fft 相位谱_数值积分——使用FFT来降低计算量

本文探讨了数值积分计算中利用复合梯形公式和Fourier变换优化方法。通过引入Fourier变换,避免了对复杂函数的重复采样,降低了计算量。实验表明,对于一系列积分,使用傅里叶变换后的积分形式能有效提升计算效率,尤其是在处理高计算量的函数时。同时,通过Matlab的fft函数和样条插值,进一步提高了数值积分的精度。
摘要由CSDN通过智能技术生成

问题引入:

我们考虑如下积分的数值计算问题

我们假定

是有界的,因为
的快速下降性,我们知道上述积分的主要贡献来自于

这样的一个邻域(当然,

只是一个示例。)

因此,我们可以采用复合梯形公式来数值求解积分。

36f4c9d3652bdd2591ec3694f6a3db1a.png

为等距节点,则复合梯形公式给出数值积分近似

下面我们以

以及
为例来计算一下,首先这个积分的精确值为

数值上,我们分别改变数值积分节点个数

来看一下误差变化

3339f85d313ad1825b66e78894ae0f6d.png

代码如下

%% 被积函数
func = @(x) (x+1).^2.*exp(-x.^2);

m = 10;
err = zeros(1,m);
num_set = 4+3*(1:m);
for ii = 1:m
    N = num_set(ii);
    x = linspace(-10,10,N+1);
    % 步长
    h = mean(diff(x));
    Num_int = (func(x(1))/2+sum(func(x(2:end-1)))+func(x(end))/2)*h;
    err(ii) = abs(Num_int - 3/2* sqrt(pi));
end

figure; 
semilogy(num_set,err,'-o','LineWidth',2,'MarkerSize',10)

可以看到,当积分节点个数

增长的时候,误差在极速下降——这是因为对于光滑的周期函数,复合梯形公式收敛是谱精度的。

问题:如果我们不仅仅是对一个

进行计算,而是对一系列都要计算。

那么每次计算都需要对 f 进行重新的采样,如果函数 f 的计算很复杂的话,这会带来很大的计算量。

我们希望关于 f 的计算,只用做一次。这就可以利用 Fourier transform 重写积分形式。

进化版本

利用Fourier变换以及Paserval等式,我们有

其中

首先我们看一下

的傅里叶变换

因此

重复一下“优点”

利用Fourier变换得到的积分的形式相比于之前版本的好处:

在我们要对很多不同的

进行积分求解的时候,之前版本需要对每个
都要计算许多
的值

但是新的形式绕过了这一点。

这一点尤其在

的计算量很大的时候显得格外重要。

实验

和之前的版本相比,高斯函数的波包变宽了,变成了

我们仍旧近似使用

作为支撑集。

只不过这里不能再直接使用上面

的例子了,它不是
可积的,不好求傅里叶变换。

不过我们可以在最开始处理的时候,写成

配上一个指数衰减的因子进行调制。不过这还是会对我们后续的论述带来麻烦(Fourier变换不是那么简单)。

因此我们选取

上述结果对

是个复数也成立,使用留数定理证明。

新问题

我们遇到一个新问题,在对下面的积分数值求解的过程中

我们会像之前使用复合梯形公式那样,采用等距节点

那么问题来了,我们如何计算

通过 Matlab利用fft计算Fourier变换可以知道这可以通过 fft 以及一个相位因子实现。

实验

因为

所以我们在计算它的Fourier变换时可以将区间截断成

足以。

这样,我们通过Matlab利用fft计算Fourier变换中的方法计算

的值。

我们选取

,并且取
作为

在数值积分时的节点

我们将比较一下数值积分和精确值

在不同

时候的误差。

fb2f68c2c321e9b311ead737afa20ac1.png

当然,本身

在增大的时候,精确值就变得更小了。

不过这里的重点在于

  • 即使
    较小的时候,误差也有 1e-6 的量级
  • 该计算方法不过分依赖于 f 的取值运算

值得注意的一点是,在利用 fft 计算出Fourier变换在一些点上的值之后,使用样条插值的结果要远好于线性插值的结果。

代码如下:

g = @(x) exp(-x.^2);
c = -20; d = 20;
N = 80;
x = linspace(c,d,N+1);
x = x(1:end-1);

xx = 2*pi/(d-c)*([0:N/2 -N/2+1:-1]);
xxshift = [xx(N/2+2:end) xx(1:N/2+1)];

%% 计算g的傅里叶变换在对应点的值的近似
gxx = exp(-1i*c*xx)*(d-c)/N.*fft(g(x));
gxxshift = [gxx(N/2+2:end) gxx(1:N/2+1)];

% 积分节点和插值近似
xx_inter = linspace(-10,10,256);
h = mean(diff(xx_inter));
gxx_inter = interp1(xxshift,gxxshift,xx_inter,'spline','extrap');

alpha_set = 0:20;
err = zeros(size(alpha_set));
for ii = 1:length(alpha_set)
    alpha = alpha_set(ii);
    phase = exp(1i*alpha*xx_inter);
    integrand = phase.*gxx_inter.*exp(-xx_inter.^2/4);
    exact_val = exp(-alpha^2/2)*sqrt(pi/2);
    % 梯形公式
    Num_val = ((integrand(1)+integrand(end))/2+sum(integrand(2:end-1)))*h/(2*sqrt(pi));
    err(ii) = abs(Num_val-exact_val);
end

figure; 
semilogy(alpha_set,err,'-o','LineWidth',2,'MarkerSize',8);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值