C++ 利用Matlab实现大数据量(16gB)的FFT
我正试图计算一个快速傅立叶变换的一个大数据块从一个文本文件,这是大约16 gB的大小导入。我试图想办法在matlab中计算它的fft,但由于我的计算机内存(8gB),它给了我一个内存不足的错误。我尝试使用memmap、textscan,但无法应用于获得组合数据的FFTC++ 利用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
有谁能告诉我如何得到傅里叶变换?我也尝试在远程服务器上使用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
根据点相对于整个数据流中第一个点的位置进行索引N
点集N/m
点k=ml+beta
,这将给出F(k)
,对于l=0,…,N/m-1
。将这些值保存到磁盘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
....