C++ 利用Matlab实现大数据量(16gB)的FFT

C++ 利用Matlab实现大数据量(16gB)的FFT,c++,matlab,fft,large-data,C++,Matlab,Fft,Large Data,我正试图计算一个快速傅立叶变换的一个大数据块从一个文本文件,这是大约16 gB的大小导入。我试图想办法在matlab中计算它的fft,但由于我的计算机内存(8gB),它给了我一个内存不足的错误。我尝试使用memmap、textscan,但无法应用于获得组合数据的FFT 有谁能告诉我如何得到傅里叶变换?我也尝试在远程服务器上使用C++代码获得傅立叶变换(使用定义),但是要花很长时间才能执行。有谁能给我一个关于如何处理这些大数据的正确见解吗?这取决于您需要的FFT分辨率。如果您只需要1024个点的F

我正试图计算一个快速傅立叶变换的一个大数据块从一个文本文件,这是大约16 gB的大小导入。我试图想办法在matlab中计算它的fft,但由于我的计算机内存(8gB),它给了我一个内存不足的错误。我尝试使用memmap、textscan,但无法应用于获得组合数据的FFT


有谁能告诉我如何得到傅里叶变换?我也尝试在远程服务器上使用C++代码获得傅立叶变换(使用定义),但是要花很长时间才能执行。有谁能给我一个关于如何处理这些大数据的正确见解吗?

这取决于您需要的FFT分辨率。如果您只需要1024个点的FFT,那么您可以将数据重塑为或按顺序读取为
nx1024
块。一旦采用这种格式,就可以将每个FFT结果的输出添加到1024点复数累加器中


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

最好使用自己的代码实现FFT

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

文件太大,普通pc无法处理。但FFT不需要同时获得所有数据。它总是可以从2点(也许8点更好)FFT开始,您可以通过级联级来构建。这意味着您可以一次进行一些计算,并将数据保存到磁盘。下次进行另一次迭代时,可以从磁盘读取保存的数据

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

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


我可以给你看一段伪代码。根据原始数据(16GB txt文件)的数据结构,实现将有所不同,但您可以轻松地操作该文件。我将从2点FFT开始,在中使用8点采样

1.在
x
上进行两点FFT,生成
y
,从左侧开始的第三列白色圆圈

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

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


基本上,设计的目的是使您能够分割数据并逐块计算,因此可以处理大量数据。我知道这不是一个常规的方式,但如果你能看看维基百科页面的中文版,你可能会发现一些图片,可以帮助你理解它是如何将这些点分开的

我也遇到了同样的问题。我最终在一篇论文中找到了解决方案: . 它本质上涉及加载较短的块,乘以相位因子并进行FFT运算,然后加载序列中的下一个块。这给出了完整信号的总FFT的采样值。然后使用不同的相位因子重复该过程多次,以填充剩余的点。我将尝试在这里进行总结(改编自文件中的表二):

  • 对于长度为
    N
    的总信号
    f(j)
    ,确定可以存储在内存中的
    m
    或长度为
    N/m
    的较短块数(如果需要,将信号归零,使
    N
    m
    的倍数)

  • 对于
    beta=0,1,2,m-1
    执行以下操作:

  • 将新序列划分为
    N/m
    连续点的
    m
    子区间

  • 对于每个子间隔,将每个第j个元素乘以exp(i*2*pi*j*beta/N)。这里,
    j
    根据点相对于整个数据流中第一个点的位置进行索引

  • 对每个子区间的第一个元素求和以生成单个数字,对第二个元素求和,依此类推。这可以通过从文件中读取点来实现,因此无需在内存中存储完整的
    N
    点集

  • 傅里叶变换结果序列,其中包含
    N/m

  • 对于
    k=ml+beta
    ,这将给出
    F(k)
    ,对于
    l=0,…,N/m-1
    。将这些值保存到磁盘

  • 转到2,继续下一个
    beta


  • 或者尝试将数据分割成较小的数据块,以便您的计算机能够处理它,或者获得更多内存。@JoachimPileborg但将数据分割成较小的数据块会使应用FFT变得困难。FFT需要访问所有数据我真的很想知道你要用FFT做什么?@user3821417:你真的想要一个有数十亿个点的FFT吗?因为通常对较长的信号计算频谱图(这只是在较短的时间间隔内重复计算FFT)@MSalters,正如应用程序的示例所示。应用程序是搜索脉冲星,他们在那篇论文中谈论的数据是从2^29到2^33。我不知道OP的应用,但有时需要对大数据集进行FFT。谢谢你,你能详细说明一下吗,我不太明白你的意思。我对matlab很陌生,谢谢你Yvon,我仍然不清楚如何分离数据,应用fft,重新组合它们。你能给我举个例子吗?我给你看了第一次迭代
    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
    ....