繁体   English   中英

如何在Matlab中改善FFT2,

[英]How to improve FFT2 in matlab,

我有下面的代码生成两个矩阵的卷积。 我的问题是卷积非常消耗内存。 关于如何使其更快的任何想法?

  1. 如何删除临时变量?
  2. 有没有更快的做ftf的方法?
  3. 有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。

综上所述:

  • 通过使用上述“不错的” FFT长度,您可能会获得一点点加速。
  • 正如一位评论者所建议的那样,您还可以查看基于GPU的FFT,它可以更快地评估FFT,但是您必须考虑将输入和输出复制到GPU或从GPU复制所需的时间。
  • 正如另一个建议,您还可以要求FFTW为您所需的确切尺寸生成经过仔细调整的计划,这可能比Matlab使用的默认计划要快几个百分点。
  • 最后,人们还编写了更快的FFT实现,例如FFTS,但是那里的代码尚不适合一般使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM