[英]How to improve FFT2 in matlab,
我有下面的代码生成两个矩阵的卷积。 我的问题是卷积非常消耗内存。 关于如何使其更快的任何想法?
有Matlab的友好版本吗? 我可以预先分配一个地方吗?
function res = fftconv(data,query) N = size(data,1); R = size(query,1); C = size(query,2); query(end+1:N,end+1:N)=0; temp = ifft2(fft2(data).*fft2(query)); res = temp(R:end,C:end); end
您的方法可能会意外地计算“坏”长度(即具有大素数的数字)上的FFT。
另外,您的方法会进行循环卷积:如果没有零填充,则不会匹配Matlab内置conv2
的输出。 (回想一下,当将两个输入都零填充到nx + ny - 1
时,使用FFT进行的循环卷积等效于时域线性卷积。)
这是您可以使用的简单函数,该函数返回与conv2
相同的值:
function z = conv2fft(x, y, nfft)
nx = size(x);
ny = size(y);
nz = nx + ny - 1;
if ~exist('nfft', 'var') || isempty(nfft)
nfft = 2 .^ nextpow2(nz);
else
assert(all(nfft >= nz), 'nfft >= nx + ny - 1 for linear convolution');
end
zfull = ifft2(fft2(x, nfft(1), nfft(2)) .* fft2(y, nfft(1), nfft(2)));
z = zfull(1 : nz(1), 1 : nz(2));
检查一下,它可以正常工作:
>> x = randn(10, 11);
>> y = randn(4, 3);
>> z1 = conv2(x, y);
>> z2 = conv2fft(x, y);
>> max(abs(z2(:) - z1(:)))
ans =
2.2204e-15
即使对于矩形输入,两者之间的误差也很小。 您需要对数据进行基准测试,以确认速度更快。
关于速度的重要警告:如果未提供此功能,则此函数使用默认nfft
为2的幂。 有时候这不是最好的。 例如,如果nx + ny - 1
是[1025, 1025]
conv2
[1025, 1025]
(即conv2
的输出是1025乘1025),则默认值将导致2048 x 2048中间数组,这可能比1025 1025慢! 这是因为FFTW内部必须分配四倍的内存,并需要4倍长的FFT。 如果知道是这种情况,则可以给conv2fft
一个更好的nfft
,例如[1080, 1080]
nfft
[1080, 1080]
( [1080, 1080]
唯一因数是2、3和5)。 Julia有一个很好的函数,称为nextprod
,它使您可以找到具有某些因素的下一个整数。 这是nextprod
的免费Matlab版本 ,您可以像nextprod([2 3 5], 1025)
。 这将返回1080。
综上所述:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.