首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法将complex<double>转换为双倍

无法将complex<double>转换为双倍
EN

Stack Overflow用户
提问于 2017-06-09 01:26:53
回答 2查看 5.3K关注 0票数 3

我正在尝试修复一个我找到的程序,所以它需要不同的值,而不是将其作为对自己的测试。程序应该能够接受一组将数学函数重新表示为信号的值,输出应该是对该信号的快速傅里叶变换。下面是我在代码中已经修复的内容:

代码语言:javascript
复制
#include <complex>
#include <iostream>
#include <valarray>

#define fnc(x) (x)

const double PI = 3.141592653589793238460;

typedef std::valarray<double> CArray;

union{
    double d;
    int i;
}num,i;


void fft(CArray& x)
{
    const size_t N = x.size();
    if (N <= 1) return;

    // divide
    CArray even = x[std::slice(0, N/2, 2)];
    CArray  odd = x[std::slice(1, N/2, 2)];

    // conquer
    fft(even);
    fft(odd);

    // combine
    for (size_t k = 0; k < N/2; ++k)
    {
        double t = std::polar(1.0, -2 * PI * k / N) * odd[k];
        x[k    ] = even[k] + t;
        x[k+N/2] = even[k] - t;
    }
}
    //Complex f = 1.0 / sqrt(N);
    //for (unsigned int i = 0; i < N; i++)
    //  x[i] *= f;

int main()
{
    num.d=513;
    double test[num.i];
    for(i.i=1; i.i < num.i;++i.i)
        test[i.i] = (double)fnc(i.i);
    CArray data(test, num.d);

    // forward fft
    fft(data);

    std::cout << "fft" << std::endl;
    for (i.i = 0; i.i < num.i; ++i.i)
    {
        std::cout << data[i.i] << std::endl;
    }
    return 0;
}

当我试图编译它时,ti向我展示了

错误:无法将初始化中的‘std::复合’转换为'double‘

在第34行,在本部标记的线上:

代码语言:javascript
复制
    for (size_t k = 0; k < N/2; ++k)
    {
        double t = std::polar(1.0, -2 * PI * k / N) * odd[k];
        x[k    ] = even[k] + t;
        x[k+N/2] = even[k] - t;
    }

佩西扎利这个:

代码语言:javascript
复制
        double t = std::polar(1.0, -2 * PI * k / N) * odd[k];

如果有人能告诉我怎么修理它,我会非常笨手笨脚的。为了获得更好的参考,这是原始代码,以防任何人告诉我修复它的更好方法,这样它就能满足我的需要。

代码语言:javascript
复制
#include <complex>
#include <iostream>
#include <valarray>
 
const double PI = 3.141592653589793238460;
 
typedef std::complex<double> Complex;
typedef std::valarray<Complex> CArray;
 
// Cooley–Tukey FFT (in-place, divide-and-conquer)
// Higher memory requirements and redundancy although more intuitive
void fft(CArray& x)
{
    const size_t N = x.size();
    if (N <= 1) return;
 
    // divide
    CArray even = x[std::slice(0, N/2, 2)];
    CArray  odd = x[std::slice(1, N/2, 2)];
 
    // conquer
    fft(even);
    fft(odd);
 
    // combine
    for (size_t k = 0; k < N/2; ++k)
    {
        Complex t = std::polar(1.0, -2 * PI * k / N) * odd[k];
        x[k    ] = even[k] + t;
        x[k+N/2] = even[k] - t;
    }
}
 
// Cooley-Tukey FFT (in-place, breadth-first, decimation-in-frequency)
// Better optimized but less intuitive
// !!! Warning : in some cases this code make result different from not     optimased version above (need to fix bug)
// The bug is now fixed @2017/05/30 
void fft(CArray &x)
{
    // DFT
    unsigned int N = x.size(), k = N, n;
    double thetaT = 3.14159265358979323846264338328L / N;
    Complex phiT = Complex(cos(thetaT), -sin(thetaT)), T;
    while (k > 1)
    {
        n = k;
        k >>= 1;
        phiT = phiT * phiT;
        T = 1.0L;
        for (unsigned int l = 0; l < k; l++)
        {
            for (unsigned int a = l; a < N; a += n)
            {
                unsigned int b = a + k;
                Complex t = x[a] - x[b];
                x[a] += x[b];
                x[b] = t * T;
            }
            T *= phiT;
        }
    }
    // Decimate
    unsigned int m = (unsigned int)log2(N);
    for (unsigned int a = 0; a < N; a++)
    {
        unsigned int b = a;
        // Reverse bits
        b = (((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1));
        b = (((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2));
        b = (((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4));
        b = (((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8));
        b = ((b >> 16) | (b << 16)) >> (32 - m);
        if (b > a)
        {
            Complex t = x[a];
            x[a] = x[b];
            x[b] = t;
        }
    }
    //// Normalize (This section make it not working correctly)
    //Complex f = 1.0 / sqrt(N);
    //for (unsigned int i = 0; i < N; i++)
    //  x[i] *= f;
}
 
// inverse fft (in-place)
void ifft(CArray& x)
{
    // conjugate the complex numbers
    x = x.apply(std::conj);
 
    // forward fft
    fft( x );
 
    // conjugate the complex numbers again
    x = x.apply(std::conj);
 
    // scale the numbers
    x /= x.size();
}
 
int main()
{
    const Complex test[] = { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 };
    CArray data(test, 8);
 
    // forward fft
    fft(data);
 
    std::cout << "fft" << std::endl;
    for (int i = 0; i < 8; ++i)
    {
        std::cout << data[i] << std::endl;
    }
 
    // inverse fft
    ifft(data);
 
    std::cout << std::endl << "ifft" << std::endl;
    for (int i = 0; i < 8; ++i)
    {
        std::cout << data[i] << std::endl;
    }
    return 0;
}

Ps。如果有人知道我需要什么更好的代码,我也可以用它。

EN

回答 2

Stack Overflow用户

发布于 2017-06-09 01:31:43

std::complex<double>double是不兼容的类型。

改变这一点:

代码语言:javascript
复制
double t = std::polar(1.0, -2 * PI * k / N) * odd[k];

对此:

代码语言:javascript
复制
std::complex<double> t = std::polar(1.0, -2 * PI * k / N) * odd[k];

因为std::polar返回:

与rho和theta形成的极地格式等价的复笛卡儿。

票数 1
EN

Stack Overflow用户

发布于 2017-06-09 01:31:15

错误消息非常明确:std::polar返回一个std::complex,而不是double。看看其余的代码,也许只需更改t的类型

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

https://stackoverflow.com/questions/44447905

复制
相关文章

相似问题

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