我在Visual c++中编写了c语言。
在visual c++中,我在c代码语法(而不是c++ )上使用<complex>操作复数。
a[]是4001数组,所以使用b[4001]存储操作值,最后返回a[]。NXm是从main定义的4001。
当我与matlab的fft结果进行比较时,差异出现在169到4000的值之间。
你能看看是否有什么错误吗?或者是什么原因?
谢谢你阅读这个问题。
double ak = (double)k * (double)n * (2.0 * M_PI / (double)NXm);改成double ak = k * n * (2.0 * M_PI / (double)NXm);void fft(complex<double> a[], int NXm)
{
complex<double> sum = 0.0 + 0.0*I; ;
complex<double> c = 1.0*I;
complex<double> b[4001] = { 0 };
for (int k = 0; k < NXm; k++)
{
sum = 0.0 + 0.0*I;
for (int n = 0; n < NXm; n++)
{
double ak = (double)k * (double)n * (2.0 * M_PI / (double)NXm);
sum = sum + a[n] * exp(-c * ak);
}
b[k] = sum;
}
for (int i = 0; i < NXm; i++)
{
a[i] = b[i];
}
}我期望得到与matlab的fft几乎相同的结果。轻微的epsilon电平误差是可以的
发布于 2019-08-24 08:56:32
复指数是:
exp(x + I*y) = exp(x) ( cos(y) + I*sin(y)) = exp(x) * cis(y)问题可能是由处理器的FPU部分缺陷引起的,如果y相当小的话,内置的sin(y)函数的精度要比|y - sin(y)|差。Euler公式的简单实现可能会错误地使用小参数,草率的实现可能会假设sin(y)为零。
较好的方法是用互补内禀(1/sin(x))代替sin()。
另一个不太常见的问题是,当trig函数由大于2*PI*n的值提供时,n自然大于1。随着n和sin (x) != sin(2*PI*n + x)的增加,精度下降。
第三,根据编译器的不同,可能有优化标志来规范编译器一般如何处理数学函数和浮点数学。他们可能默认为不精确但快速的计算。这可能会取代在C++代码中使用C头。
发布于 2019-08-24 16:09:41
MATLAB采用快速傅里叶变换( FFT )算法计算DFT。它比直接法的O(n^2)快得多(O(n log n)相对于O(n^2)),而且数值上更稳定。因此,不要期望得到与MATLAB相同的结果。
https://stackoverflow.com/questions/57635793
复制相似问题