C++ 复数。。啊

C++ 复数。。啊,c++,signal-processing,dft,C++,Signal Processing,Dft,我正在做一个项目,需要我输入数据,执行DFT(离散傅立叶变换),然后从这些值中获取过零次数 我已经编写了一个算法,但是,它使用复数,我不知道如何对它们进行操作/计算。代码如下: #include <iostream> #include <complex> #include <vector> using namespace std; const double PI = 3.14159265358979323846; vector< complex&l

我正在做一个项目,需要我输入数据,执行DFT(离散傅立叶变换),然后从这些值中获取过零次数

我已经编写了一个算法,但是,它使用复数,我不知道如何对它们进行操作/计算。代码如下:

#include <iostream>
#include <complex>
#include <vector>

using namespace std;

const double PI = 3.14159265358979323846;

vector< complex<double> > DFT(vector< complex<double> >& theData)
{
    // Define the Size of the read in vector
    const int S = theData.size();

    // Initalise new vector with size of S
    vector< complex<double> > out(S, 0);
    for(unsigned i=0; (i < S); i++)
    {
        out[i] = complex<double>(0.0, 0.0);
        for(unsigned j=0; (j < S); j++)
        {
            out[i] += theData[j] * polar<double>(2, (-2 * PI * i * j / S));
        }
    }

    return out;
}

int main(int argc, char *argv[]) {
    vector< complex<double> > numbers;

    numbers.push_back(128);
    numbers.push_back(127);

    vector< complex<double> > testing = DFT(numbers);

    for(unsigned i=0; (i < testing.size()); i++)
    {
        cout << testing[i] << endl;
    }
}
然后它将返回一个错误。有什么想法或建议吗?不使用复数就可以创建DFT吗?

例如return,这样您就无法真正绕过它们

根据您的应用程序,您可以安全地忽略复数的虚部,并将DFT的输出视为实数序列

有很多操作可以在复数上执行。有些可能与您的应用程序相关,有些可能与您的应用程序无关。花一些时间来更好地理解复数是值得的


最后,,如果不使用复数,就不可能创建DFT。可以将DFT的复数输出转换为实数,但在这个过程中会丢失信息。您需要了解复数以及DFT在应用程序中的使用方式,才能确定是否适合执行任何此类转换。

我也有类似的问题,我放弃了C++复杂双号的向量容器,因为它没有很好地支持FFT LIBS,最后使用了一个普通的老数组。你会发现你尝试做的大部分事情都很好

 std::complex<double>*  in=new std::complex<double> [N];

DFT总是使用复数,至少对其输出是这样。如果输入描述了一段时间内的一些信号,那么输出根据频率描述信号。每个复数都可以写进去,然后分成表示振幅的绝对值和表示相位的角度。也许你感兴趣的是振幅;如果是这样的话,你会想计算一个绝对值,但它们也都是非负的

有一种DFT方法可以处理实数。在这方面,我想到了问题。不确定这在您的应用程序中是否有用


请注意,有些库可能比代码计算DFT的速度更快。即使是自编的也值得考虑,只要您的输入大小是2的幂。但所有这些都有点偏离了你实际问题的重点。

给你指令的人并没有告诉你在DFT/FFT结果上计算零交叉。那将毫无意义。(如果他们要你这么做,他们是无知的。我允许你嘲笑他们给你如此荒谬的指示)。相反,他们告诉你要计算原始数据的过零次数,还要查看数据的FFT

但是,

  • 过零率是语音识别的一个非常糟糕的起点。也许你可以用它去某个地方。只需稍微夸张一下,我就可以说过零是最不可靠的DSP分析。然而,它也很简单,而且语音识别的研究已经进行了很长时间,所以可能有一些关于它的研究。更新/更正:这有点夸张。事实上,我相信很多语音识别技术确实使用过零,但是你应该知道你首先要做的是什么,因为它不是很健壮,对很多种错误都不敏感,比如倍频程错误。当您使用过零时,最好先使用低通(可能是积极的)。一定要考虑其他因素。

  • 理解FFT的输出是这里经常被问到的问题,所以我写了一篇博客。通常人们都在尝试跟踪音调,实际上你也应该这样做,但是你可以从FFT中得到其他东西,比如频率质心,以及不同频率的相对强度,这在语音中很重要。从这里开始:

  • 你也可以考虑简单地过滤重要的语音频率(找出这些是什么),从维基百科条目开始。例如,通过链接到咝咝声,你会知道“[S]在8000赫兹左右具有最大的声学强度。”Neeto!!你可以从FFT或过滤中获得这些信息。每种方法都有优点和缺点。您可能想查看语音识别文献,了解它们的用途


复数大于零意味着什么(除非它是实数)?除了与原点相等和距离之外,复数无法进行比较。您可以将它们视为平面上的点。如果您询问是否可以不使用复数创建DFT,您可能不应该编写DFT。@MvG-谢谢您的回答。基本上,我试图确定是否有人在说“是”或“否”,我被告知:“处理每个块的重要特征,如不同频率范围的强度、过零次数和总能量。”这可以使用FFT、频率滤波器等、z变换等来完成。。但是FFT的编码非常非常复杂。。所以我想我应该使用DFT,然后确定过零点的数量。。对不起,我正在研究这个项目,所以我的知识是缺乏的,但我正在学习:)!噢。我想你误解了说明。这不是数据->FFT->过零。这是数据->过零和数据->FFT。请看我的答案。如果您将
std::complex*
重新解释为
fftw\u complex*
,您可以编写
&v[0]
&v.begin()
来获取指向双数组的指针,该数组包含向量
v
@MvG的值,这有一个问题。我不知道;我记不清到底是什么,但重新解释是FFTW网站建议的,你说“它没有得到很好的支持”是什么意思?一个向量不关心你放入它(只要你可以复制或在- C++)
 std::complex<double>*  in=new std::complex<double> [N];
    p = fftw_plan_dft_c2r_1d(N, reinterpret_cast<fftw_complex*>(in), out,FFTW_ESTIMATE);  

   fftw_execute(p);