- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我是从事电信项目的计算机程序员。
在我们的项目中,我必须将一系列复数更改为它们的傅立叶变换。因此我需要一个高效的 FFT
代码来满足 C89
标准。
我正在使用以下代码,它运行良好:
short FFT(short int dir,long m,double *x,double *y)
{
long n,i,i1,j,k,i2,l,l1,l2;
double c1,c2,tx,ty,t1,t2,u1,u2,z;
/* Calculate the number of points */
n = 1;
for (i=0;i<m;i++)
n *= 2;
/* Do the bit reversal */
i2 = n >> 1;
j = 0;
for (i=0;i<n-1;i++) {
if (i < j) {
tx = x[i];
ty = y[i];
x[i] = x[j];
y[i] = y[j];
x[j] = tx;
y[j] = ty;
}
k = i2;
while (k <= j) {
j -= k;
k >>= 1;
}
j += k;
}
/* Compute the FFT */
c1 = -1.0;
c2 = 0.0;
l2 = 1;
for (l=0;l<m;l++) {
l1 = l2;
l2 <<= 1;
u1 = 1.0;
u2 = 0.0;
for (j=0;j<l1;j++) {
for (i=j;i<n;i+=l2) {
i1 = i + l1;
t1 = u1 * x[i1] - u2 * y[i1];
t2 = u1 * y[i1] + u2 * x[i1];
x[i1] = x[i] - t1;
y[i1] = y[i] - t2;
x[i] += t1;
y[i] += t2;
}
z = u1 * c1 - u2 * c2;
u2 = u1 * c2 + u2 * c1;
u1 = z;
}
c2 = sqrt((1.0 - c1) / 2.0);
if (dir == 1)
c2 = -c2;
c1 = sqrt((1.0 + c1) / 2.0);
}
/* Scaling for forward transform */
if (dir == 1) {
for (i=0;i<n;i++) {
x[i] /= n;
y[i] /= n;
}
}
return(true);
}
但是这段代码,只支持大小为2^m
的数组。如CLRS
书本代码。
我们应该转换的数组不在这个范围内,添加零会很昂贵,所以我正在寻找另一种解决方案来帮助我输入任何大小。
类似于 IT++
和 matlab
所做的事情。但正如我们希望在纯 C 中使用它们是不可能的。此外,IT++
代码在我检查时被阻止
最佳答案
如果您正在使用任何大众市场计算平台(带有 Windows 或 OS X、iOS 等的英特尔),那么供应商或制造商会提供高性能 FFT 实现。
否则,你应该评估FFTW .
为除 2 的幂以外的大小编写高性能 FFT 是一项复杂的任务。
如果您要使用自己的实现,那么,关于二次方大小:
您展示的实现在 FFT 期间计算 sqrt
。大多数高性能 FFT 实现提前计算常量并将它们存储在表中。
缩放包含除法运算,在 x[i]/= n
和 y[i]/= n
中。编译器很可能将这些实现为除法指令。除法在普通处理器上通常是一条缓慢的指令。计算一次 scale = 1./n
并乘以 scale
而不是除以 n
会更好。
更好的办法是完全省略比例。转换通常在没有比例的情况下很有用,或者可以从单个转换中省略比例并仅作为聚合比例应用一次。 (例如,与其执行两个缩放操作,一个在正向 FFT 中,一个在反向 FFT 中,将缩放操作从 FFT 例程中移除,并在正向 FFT 和反向 FFT 之后只执行一次。)
如果可以接受按位反转顺序排列频域数据,则您可以省略位反转排列。
如果保留位反转排列,则可以对其进行优化。执行此操作的技术取决于平台。某些平台有反转整数位的指令(例如,ARM 有 rbit
)。如果您的平台没有,您可能希望将位反转索引保存在表中或研究比当前代码更快地计算它们的方法。
如果同时保留位反转排列和缩放,则应考虑同时进行。排列使用大量内存运动,缩放使用处理器的算术单元。大多数现代处理器可以同时执行这两项操作,因此您可以从重叠操作中获益。
您当前的代码使用 radix-2 butterfly。 Radix-4 通常更好,因为它从以下事实中获得了一些优势:只需更改使用的数据片段并将一些加法更改为减法,反之亦然即可完成与 i 的乘法。
如果您的数组长度接近处理器上一级内存缓存的大小,FFT 实现的某些部分将扰动缓存并显着降低速度,除非您设计适当的代码来处理这个问题(通常通过将数组的部分复制到一个临时缓冲区)。
如果您的目标处理器具有 SIMD 功能,您绝对应该在 FFT 中使用这些功能;它们极大地加快了 FFT 性能。
以上内容应该告诉您,编写高效的 FFT 是一项复杂的任务。除非您想为此花费大量精力,否则最好使用 FFTW 或其他现有实现。
关于c - FFT 和 FFT 的逆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18341613/
FFT 库(例如 FFTW 或 numpy.fft)通常提供两个函数 fft() 和 ifft()(及其用于实值输入的特殊版本)。这些功能似乎被定义为 ifft(fft(X)) == X 和 fft(
如果我有一个特定大小 M(2 的幂)的 FFT 实现,我如何计算一组大小 P=k*M 的 FFT,其中 k 也是 2 的幂? #define M 256 #define P 1024 comple
下午好! 我正在尝试基于我已有的简单递归 FFT 实现来开发 NTT 算法。 考虑以下代码(coefficients'的长度,让它为m,是2的精确幂): /// /// Calculates the
我正在分析时间序列数据,并希望提取 5 个主要频率分量并将其用作训练机器学习模型的特征。我的数据集是 921 x 10080 。每行是一个时间序列,总共有 921 个。 在探索可能的方法时,我遇到了各
我找不到任何官方文档来证明 scipy.fft 实际上是 numpy.fft.fftpack.fft 的链接。这是显示链接的 iPython session : In [1]: import scip
文档说 np.fft.fft 这样做: Compute the one-dimensional discrete Fourier Transform. 和 np.fft.rfft 这样做: Compu
近一个月来,我一直在与一个非常奇怪的错误作斗争。问你们是我最后的希望。我用 C 编写了一个程序,它集成了 2d Cahn–Hilliard equation在傅里叶(或倒数)空间中使用隐式欧拉 (IE
我一直在制作一个例程,使用 NumPy/Scipy 测量两个光谱之间的相位差。 我已经有了Matlab写的例程,所以我基本上是用NumPy重新实现了函数和相应的单元测试。但是,我发现单元测试失败了,因
我正在研究使用 Renderscript 对大型复杂输入数组执行 FFT。 FFT 是相当标准的,因为它涉及三个循环,但内部循环执行 FFT 中的蝶形运算。因为每个蝴蝶使用数组的不同部分,所以没有明显
我需要通过修改 FFT 结果来均衡音乐样本。 我知道如何获得每个输出虚数的频率,问题是修改这个值以获得“均衡器效果”。 我需要知道如何缩放这个值。 条目大小为 4096 个样本,采样率为 44100
我将在 kiss-fft 之前制定几个计划同时(平行),我可以这样做吗,或者换句话说,kiss-fft 线程安全吗? 谢谢 最佳答案 自述文件: No static data is used. Th
要在频域中插入信号,可以在时域中填充零并执行 FFT。 假设给定向量 X 中的元素数为 N 并且 Y 与 X 相同但在一侧用 N 零填充。然后下面给出相同的结果。 $$\hat{x}(k)=\sum_
我通过相关了解了 DFT 的工作原理,并将其用作理解 FFT 结果的基础。如果我有一个以 44.1kHz 采样的离散信号,那么这意味着如果我要获取 1 秒的数据,我将有 44,100 个样本。为了对其
有人知道 Mayer FFT 的实现吗(我不必花很多时间研究代码)? 我正在尝试执行卷积,ifft 似乎产生了我称之为“镜像”的输出。换句话说,我的内核+信号长度被限制为 N/2 并且占据 n=0..
有人知道 Mayer FFT 的实现吗(我不必花很多时间研究代码)? 我正在尝试执行卷积,ifft 似乎产生了我称之为“镜像”的输出。换句话说,我的内核+信号长度被限制为 N/2 并且占据 n=0..
我有以下代码...请注意#生成正弦曲线下的两行。一个使用比另一个更高的 2pi 精度值,但它们仍然应该给出几乎相同的结果。 import numpy as np import matplotlib.p
我正在努力确保 FFTW 做我认为它应该做的事情,但我遇到了问题。我正在使用 OpenCV 的 cv::Mat。我制作了一个测试程序,给定一个 Mat f,计算 ifft(fft(f)) 并将结果与
我是从事电信项目的计算机程序员。 在我们的项目中,我必须将一系列复数更改为它们的傅立叶变换。因此我需要一个高效的 FFT 代码来满足 C89 标准。 我正在使用以下代码,它运行良好: shor
我目前正在尝试了解 numpy 的 fft 函数。为此,我测试了以下假设: 我有两个函数,f(x) = x^2 和 g(x) = f'(x) = 2*x。根据傅立叶变换定律和 wolfram alph
我一直在使用 FFT,目前正在尝试使用 FFT 从文件中获取声音波形(最终对其进行修改),然后将修改后的波形输出回文件。我得到了声波的 FFT,然后对其使用了反 FFT 函数,但输出文件听起来一点也不
我是一名优秀的程序员,十分优秀!