首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带C++码的离散傅里叶变换

带C++码的离散傅里叶变换
EN

Stack Overflow用户
提问于 2019-08-24 06:56:59
回答 2查看 1.5K关注 0票数 0

我在Visual c++中编写了c语言。

在visual c++中,我在c代码语法(而不是c++ )上使用<complex>操作复数。

a[]是4001数组,所以使用b[4001]存储操作值,最后返回a[]NXm是从main定义的4001。

当我与matlab的fft结果进行比较时,差异出现在169到4000的值之间。

你能看看是否有什么错误吗?或者是什么原因?

谢谢你阅读这个问题。

  1. 我尝试了反向"for",从NXm到0。
  2. 我试过把double ak = (double)k * (double)n * (2.0 * M_PI / (double)NXm);改成double ak = k * n * (2.0 * M_PI / (double)NXm);
  3. 当我尝试操作较短的场时,函数工作得很好。 这是密码。
代码语言:javascript
运行
复制
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电平误差是可以的

EN

回答 2

Stack Overflow用户

发布于 2019-08-24 08:56:32

复指数是:

代码语言:javascript
运行
复制
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。随着nsin (x) != sin(2*PI*n + x)的增加,精度下降。

第三,根据编译器的不同,可能有优化标志来规范编译器一般如何处理数学函数和浮点数学。他们可能默认为不精确但快速的计算。这可能会取代在C++代码中使用C头。

票数 0
EN

Stack Overflow用户

发布于 2019-08-24 16:09:41

MATLAB采用快速傅里叶变换( FFT )算法计算DFT。它比直接法的O(n^2)快得多(O(n log n)相对于O(n^2)),而且数值上更稳定。因此,不要期望得到与MATLAB相同的结果。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57635793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档