假设f(x,y)
是一个双变量函数,如下所示:
function [ f ] = f(x,y)
UN=(g)1.6*(1-acos(g)/pi)-0.8;
f= 1+UN(cos(0.5*pi*x+y));
end
如何使用以下代码改善函数F(N)
的执行时间:
function [VAL] = F(N)
x=0:4/N:4;
y=0:2*pi/1000:2*pi;
VAL=zeros(N+1,3);
for i = 1:N+1
val = zeros(1,N+1);
for j = 1:N+1
val(j) = trapz(y,f(0,y).*f(x(i),y).*f(x(j),y))/2/pi;
end
val = fftshift(fft(val))/N;
l = (length(val)+1)/2;
VAL(i,:)= val(l-1:l+1);
end
VAL = fftshift(fft(VAL,[],1),1)/N;
L = (size(VAL,1)+1)/2;
VAL = VAL(L-1:L+1,:);
end
请注意N=2^p
p>10
,所以请在使用ndgrid
,arrayfun
等优化代码时考虑内存限制。
仅供参考:代码打算找到fftn
fun=@(a,b) trapz(y,f(0,y).*f(a,y).*f(b,y))/2/pi;
其中a,b
位于[0,4]
。关键的想法是,当N
非常大时,我们可以使用上面的代码特别节省内存。但由于嵌套循环,执行时间仍然是一个问题。请参阅下图中的N=2^2
:
答案 0 :(得分:1)
这不是一个完整的答案,但有些可能有用的提示:
0)琐碎:你确定需要数字吗?你不能分析计算吗?
1)不要使用功能句柄:
function [ f ] = f(x,y)
f= 1+1.6*(1-acos(cos(0.5*pi*x+y))/pi)-0.8
end
2)分析简化:acos(cos(x))
与abs(mod(x + pi, 2 * pi) - pi)
相同,后者的计算速度应稍快一些。或者,不是采样然后进行数值积分,而是首先进行分析整合并对结果进行采样。
3)FFT是计算完整DFT的一种非常有效的算法,但您不需要完整的DFT。由于您只需要中心3 x 3系数,因此直接应用DFT definition并仅针对您想要的系数计算公式可能更有效。这应该既快速又节省内存。
4)如果您反复进行此计算,预计算DFT系数可能会有所帮助。在这里,信号处理工具箱中的dftmtx
可以提供帮助。
5)为了摆脱循环,考虑问题不是以计算指令的形式,而是单个矩阵运算。如果您将输入N x N矩阵视为具有N 2个元素的向量,并将输出3 x 3矩阵视为9元素向量,则应用整个操作(通过trapz
进行数值积分并通过{{进行DFT 1}})似乎是一个简单的线性变换,应该可以表示为N²x9矩阵。