使用Matlab进行大数据FFT(16gB)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Matlab进行大数据FFT(16gB)相关的知识,希望对你有一定的参考价值。

我正在尝试计算从文本文件导入的大块数据的快速傅立叶变换,该文件大小约为16 gB。我试图想办法在matlab中计算它的fft,但是由于我的计算机内存(8gB),它给了我一个内存不足的错误。我尝试使用memmap,textscan,但无法应用于获取组合数据的FFT。任何人都可以指导我如何进行傅里叶变换?我也试图在远程服务器上使用C ++代码进行傅里叶变换(使用定义),但是它需要很长时间才能执行。任何人都可以给我一个正确的见解,我应该如何处理这些大数据?谢谢,

答案

这取决于您需要的FFT分辨率。如果您只需要1024点的FFT,那么您可以将数据重新整形为或者按N x 1024块顺序读取。一旦以这种格式获得它,就可以将每个FFT结果的输出添加到1024点复数累加器。

如果在FFT之后你需要相同的分辨率,那么你需要更多的内存,或者一个未包含在Matlab中的特殊fft例程(但是我不确定在数学上是否可以通过缓冲小块来进行部分FFT全分辨率)。

另一答案

使用您自己的代码实现FFT可能更好。

FFT算法具有“butterfly”操作。因此,您可以将整个步骤拆分为更小的块。

文件大小太大,无法处理典型的pc。但FFT不需要同时使用所有数据。它总是以2点(可能是8点更好)FFT开始,你可以通过级联阶段来建立。这意味着您可以一次read only a few points,进行一些计算,并将数据保存到磁盘。下次进行另一次迭代时,可以从磁盘读取已保存的数据。

根据您构建数据结构的方式,您可以将所有数据存储在一个文件中,并使用指针读取/保存它(在Matlab中它只是一个数字);或者您可以将每个点存储在一个单独的文件中,生成数十亿个文件并通过文件名区分它们。

您的想法是可以将计算转储到磁盘而不是内存。当然,它需要这么大的磁盘空间,这是更可行的。


我可以给你看一段伪代码。根据原始数据(16GB txt文件)的数据结构,实现方式会有所不同,但您可以轻松地按照您拥有的文件进行操作。我将从2点FFT开始,并使用this wikipedia picture中的8点样本。

1.在x上进行2点FFT,生成y,左起第3列白色圆圈。

read x[0], x[4] from file 'origin'
y[0] = x[0] + x[4]*W(N,0);
y[1] = x[0] - x[4]*W(N,0);
save y[0], y[1] to file 'temp'
remove x[0], x[4], y[0], y[1] from memory
read x[2], x[6] from file 'origin'
y[2] = x[2] + x[6]*W(N,0);
y[3] = x[2] - x[6]*W(N,0);
save y[2], y[3] to file 'temp'
remove x[2], x[6], y[2], y[3] from memory
....

2.在y上进行2点FFT,生成z,第5列白色圆圈。

3.在z上进行2点FFT,产生最终结果,X

基本上Cooley–Tukey FFT algorithm旨在使您能够切割数据并逐个计算,因此可以处理大量数据。我知道这不是一种常规方式,但如果您可以查看该维基百科页面的中文版本,您可能会发现许多图片可以帮助您了解它如何分割点数。

另一答案

我遇到过同样的问题。我最终在一篇论文中找到了一个解决方案:Extending sizes of effective convolution algorithms。它主要涉及加载较短的块,乘以相位因子和FFT,然后加载系列中的下一个块。这给出了完整信号的总FFT的采样。然后用不同的相位因子多次重复该过程以填充剩余的点。我将在这里总结一下(改编自论文中的表II):

  1. 对于长度为f(j)的总信号N,决定你可以存储在存储器中的每个长度m的数字N/m或更短的块(如果需要,零填充信号使得Nm的倍数)
  2. 对于beta = 0, 1, 2, ... ,m - 1,请执行以下操作:
  3. 将新系列划分为m连续点的N/m子区间。
  4. 对于每个子区间,将每个第j个元素乘以exp(i*2*pi*j*beta/N)。这里,j根据整个数据流中相对于第一个点的位置进行索引。
  5. 求和每个子区间的第一个元素以产生单个数字,对第二个元素求和,等等。这可以在从文件中读取点时完成,因此不需要在内存中拥有完整的N点集。
  6. 傅里叶变换得到的系列,其中包含N/m点。
  7. 这将为F(k)k = ml + beta提供l = 0, ..., N/m-1。将这些值保存到磁盘。
  8. 转到2,继续beta的下一个值。

以上是关于使用Matlab进行大数据FFT(16gB)的主要内容,如果未能解决你的问题,请参考以下文章

matlab怎样进行频谱分析

如何在matlab的powergui里面进行fft分析

谐波乘积谱的 MATLAB 代码

使用 MATLAB 对任意图进行傅里叶变换和 FFT

基于matlab的声音信号采集与处理

matlab中powergui中的fft分析怎么用