使用 FFTW 计算波长、幅度和相位

问题描述 投票:0回答:1

我正在尝试使用 C++ 和 FFTW 从一系列数字中获取幅度、波长和相位,但运气不佳,我想知道是否有人可以帮助我?

我已经在互联网上进行了搜索,但由于我是 FFT 新手,所以我无法找到任何我能理解的足够具体的内容

我有 370 个双精度值,正在从文件中读取到 inputRecord 数组中,例如1.11567, 1.11599, 1.11679

这就是我迄今为止在 FFTW 上所做的事情:

double *input;
fftw_complex *output;
fftw_plan p;
int binCount = inputCount/ 2; // inputCount = the number of records in the input file

input = (double*)fftw_malloc(sizeof(double) * inputCount);
output = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * inputCount);

p = fftw_plan_dft_r2c_1d(barCount, input, output, FFTW_ESTIMATE);

// Copy the double numbers into the FFTW input array 
for (int i = 0; i < barCount; i++)
{
    input[i] = inputRecord[i];
}

fftw_execute(p); //performs the fourier transform, fills `output'

然后我循环遍历 FFTW 输出数组,尝试通过此计算获取幅度:

Amplitude = 2 * abs(FFTOutput[i]) / 370

我还想获得波长(不知道如何)和正弦波的相位(也不知道如何做到这一点)

非常感谢任何帮助。

signal-processing fftw phase amplitude
1个回答
0
投票

有同样的问题。我希望能够创建一组样本,然后让 FFTW 返回我用于创建该组样本的参数。

这段代码创建了示例。您可以给它频率、偏置、幅度和相位。

    int const N = 32;
    fftw_complex in[N + 1];

    double const freq = 3; // Hz
    double const bias = 1.5;
    double const magnitude = 1.0;
    // double const phase = 0;
    double const phase = M_PI / 2.0;

    double const omega = (2 * M_PI * freq);
    double const increment = omega / N;
    double sample = 0.0;
    for (int time = 0; time < (N + 1); ++time) {
        in[time][0] = bias + (magnitude * ::cos(sample + phase));
        in[time][1] = 0.0;
        printf("%-10s: %3d %+9.5f\n", "input", time, in[time][0]);
        sample += increment;
    }

该块使用 FFTW 来分析并报告这些相同的值:

#include <fftw3.h>


    /* forward Fourier transform, save the result in 'out' */
    fftw_complex out[N];
    fftw_plan p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
    fftw_execute(p);
    printf("\n");
    printf("Expected phase: %9.5f\n", phase);
    printf("%-10s: %3s %9s %9s %9s %9s\n", "FFT", "Hz", "out[0]", "out[1]", "mag", "phase");
    for (int i = 0; i < (N + 1); i++) {
        double const rpt_real = out[i][0];
        double const rpt_imag = out[i][1];
        if (i == 0) {
            printf("%-10s: %3d %+9.5f %9s %9s %9s\n", "bias", i, rpt_real / N, "n/a", "n/a", "n/a");
        } else {
            // phase - 2 * PI => reported phase
            double const calc_phase = std::atan2(rpt_imag, rpt_real);
            double const calc_magnitude = std::sqrt(std::pow(rpt_real, 2) + std::pow(rpt_imag, 2)) * (2.0 / N);
            printf("%-10s: %3d %+9.5f %+9.5f %9.5f %9.5f\n", "freq.", i, rpt_real, rpt_imag, calc_magnitude, calc_phase);
        }
    }
    fftw_destroy_plan(p);

这是示例输出:

FFT       :  Hz    out[0]    out[1]       mag     phase
bias      :   0  +1.50000       n/a       n/a       n/a
freq.     :   1  -0.00000  -0.00000   0.00000  -2.54329
freq.     :   2  -0.00000  -0.00000   0.00000  -2.16145
freq.     :   3  +0.00000 +16.00000   1.00000   1.57080
freq.     :   4  -0.00000  +0.00000   0.00000   2.27161

在 out[0]: 中找到偏差,并显示 +1.5 与

double const bias = 1.5;

匹配

在 out[3] 中找到与

double const freq = 3;

匹配的频率

震级可在“mag”列下找到。 1.00000 匹配

double const magnitude = 1.0;

该相可在“相”列 1.57080 中找到,它与

double const phase = M_PI / 2.0;

相匹配

我尝试过各种频率、偏差、幅度和相位。据我所知,它每次都给出正确的值。

(使用一组 GTest UT 来自动确认所有这些。)

© www.soinside.com 2019 - 2024. All rights reserved.