Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 英特尔集成性能原件傅里叶变换幅值_C++_Fft_Intel Ipp - Fatal编程技术网

C++ 英特尔集成性能原件傅里叶变换幅值

C++ 英特尔集成性能原件傅里叶变换幅值,c++,fft,intel-ipp,C++,Fft,Intel Ipp,当我使用“英特尔IPP”时,我在震级数组的零索引处得到一个巨大的峰值 我的正弦波很长,我感兴趣的主要成分在0.15赫兹和0.25赫兹之间。我以500Hz的采样频率采样。如果我在FFT之前减少信号的平均值,我会得到非常小的零分量,不再是峰值。以下是震级阵头的图片: 此外,幅度缩放似乎是我在信号时间序列中看到的幅度的10倍,例如,如果幅度为29,则为290 我不知道为什么会这样,我的问题是1。我真的需要用平均值减少和2来解决零指数峰值吗。这个10分制是从哪里来的 void CalculateFor

当我使用“英特尔IPP”时,我在震级数组的零索引处得到一个巨大的峰值

我的正弦波很长,我感兴趣的主要成分在0.15赫兹和0.25赫兹之间。我以500Hz的采样频率采样。如果我在FFT之前减少信号的平均值,我会得到非常小的零分量,不再是峰值。以下是震级阵头的图片:

此外,幅度缩放似乎是我在信号时间序列中看到的幅度的10倍,例如,如果幅度为29,则为290

我不知道为什么会这样,我的问题是1。我真的需要用平均值减少和2来解决零指数峰值吗。这个10分制是从哪里来的

void CalculateForwardTransform(array<double> ^signal, array<double> ^transformedSignal, array<double> ^magnitudes)
{ 
    // source signal
    pin_ptr<double> pinnedSignal = &signal[0];
    double *pSignal = pinnedSignal;
    int order = (int)Math::Round(Math::Log(signal->Length, 2));

    // get sizes
    int sizeSpec = 0, sizeInit = 0, sizeBuf = 0;
    int status = ippsFFTGetSize_R_64f(order, IPP_FFT_DIV_INV_BY_N, ippAlgHintNone, &sizeSpec, &sizeInit, &sizeBuf);

    // memory allocation
    IppsFFTSpec_R_64f* pSpec;
    Ipp8u *pSpecMem = (Ipp8u*)ippMalloc(sizeSpec);
    Ipp8u *pMemInit = (Ipp8u*)ippMalloc(sizeInit);
    
    //  FFT specification structure initialized
    status = ippsFFTInit_R_64f(&pSpec, order, IPP_FFT_DIV_INV_BY_N, ippAlgHintNone, pSpecMem, pMemInit);

    // transform
    pin_ptr<double> pinnedTransformedSignal = &transformedSignal[0];
    double *pDst = pinnedTransformedSignal;
    Ipp8u *pBuffer = (Ipp8u*)ippMalloc(sizeBuf);
    status = ippsFFTFwd_RToCCS_64f(pSignal, pDst, pSpec, pBuffer);

    // get magnitudes
    pin_ptr<double> pinnedMagnitudes = &magnitudes[0];
    double *pMagn = pinnedMagnitudes;
    status = ippsMagnitude_64fc((Ipp64fc*)pDst, pMagn, magnitudes->Length); // magnitudes is half of signal len

    // free memory
    ippFree(pSpecMem);
    ippFree(pMemInit);
    ippFree(pBuffer);
}
void CalculateForwardTransform(数组^signal,数组^transformedSignal,数组^magnitudes)
{ 
//源信号
引脚ptr引脚信号=&信号[0];
double*pSignal=钉扎信号;
int order=(int)Math::Round(Math::Log(信号->长度,2));
//获取尺寸
int-sizeSpec=0,sizeInit=0,sizeBuf=0;
int status=ippsFFTGetSize\u R\u 64f(订单、IPP\u FFT\u DIV\u INV\u BY\u N、IPPALGHINTONE、&SIZESPECT、&sizeInit、&sizeBuf);
//内存分配
IPPSFTSPEC_R_64f*pSpec;
Ipp8u*pSpecMem=(Ipp8u*)ippMalloc(sizeSpec);
Ipp8u*pMemInit=(Ipp8u*)ippMalloc(sizeInit);
//FFT规范结构初始化
状态=ippsFFTInit\u R\u 64f(和pSpec、订单、IPP\u FFT\u DIV\u INV\u BY\u N、IPPALGHINTONE、pSpecMem、pMemInit);
//转化
pin_ptr pinnedTransformedSignal=&transformedSignal[0];
双*pDst=针式变压器信号;
Ipp8u*pBuffer=(Ipp8u*)ippMalloc(sizeBuf);
状态=ippsFFTFwd_RTOCSCs_64f(pSignal、pDst、pSpec、pBuffer);
//得到震级
pin_ptr pinnedMagnites=&震级[0];
double*pMagn=羽化磁位;
状态=ippsMagnitude_64fc((Ipp64fc*)pDst,pMagn,震级->长度);//震级是信号长度的一半
//空闲内存
ippFree(pSpecMem);
ippFree(pMemInit);
ippFree(pBuffer);
}
我真的需要用平均值降低来解决零指数峰值吗

对于低频信号分析,小偏差确实会产生干扰(尤其是由于频谱泄漏)。为了说明,考虑下面的低频信号<代码>声调和另一个具有恒定偏差<代码> ToeNeX的偏差:< /P> >:

fs = 1;
f0 = 0.15;
for (int i = 0; i < N; i++)
{
  tone[i] = 0.001*cos(2*M_PI*i*f0/fs);
  tone_with_bias[i] = 1 + tone[i];
}
fs=1;
f0=0.15;
对于(int i=0;i
如果我们绘制这些信号的100个采样窗口的频谱,您应该注意到带有偏差的
音调的频谱完全淹没了
音调的频谱

是的,如果你能消除这种偏见就更好了。然而,应该强调的是,如果你知道偏见的性质,这是可能的。如果你知道偏差确实是一个常数,去除它将显示低频分量。否则,如果偏置只是一个非常低频的分量,则从信号中移除平均值可能无法达到期望的效果

这个10分制是从哪里来的

void CalculateForwardTransform(array<double> ^signal, array<double> ^transformedSignal, array<double> ^magnitudes)
{ 
    // source signal
    pin_ptr<double> pinnedSignal = &signal[0];
    double *pSignal = pinnedSignal;
    int order = (int)Math::Round(Math::Log(signal->Length, 2));

    // get sizes
    int sizeSpec = 0, sizeInit = 0, sizeBuf = 0;
    int status = ippsFFTGetSize_R_64f(order, IPP_FFT_DIV_INV_BY_N, ippAlgHintNone, &sizeSpec, &sizeInit, &sizeBuf);

    // memory allocation
    IppsFFTSpec_R_64f* pSpec;
    Ipp8u *pSpecMem = (Ipp8u*)ippMalloc(sizeSpec);
    Ipp8u *pMemInit = (Ipp8u*)ippMalloc(sizeInit);
    
    //  FFT specification structure initialized
    status = ippsFFTInit_R_64f(&pSpec, order, IPP_FFT_DIV_INV_BY_N, ippAlgHintNone, pSpecMem, pMemInit);

    // transform
    pin_ptr<double> pinnedTransformedSignal = &transformedSignal[0];
    double *pDst = pinnedTransformedSignal;
    Ipp8u *pBuffer = (Ipp8u*)ippMalloc(sizeBuf);
    status = ippsFFTFwd_RToCCS_64f(pSignal, pDst, pSpec, pBuffer);

    // get magnitudes
    pin_ptr<double> pinnedMagnitudes = &magnitudes[0];
    double *pMagn = pinnedMagnitudes;
    status = ippsMagnitude_64fc((Ipp64fc*)pDst, pMagn, magnitudes->Length); // magnitudes is half of signal len

    // free memory
    ippFree(pSpecMem);
    ippFree(pMemInit);
    ippFree(pBuffer);
}

应预期通过FFT对幅度进行缩放,如中所述,大约
0.5*N
(其中
N
是FFT大小)。如果你在处理一小块20个样本,那么你应该得到这样一个10倍的比例。如果按
2/N
缩放FFT的输出(或在使用
IPP\u FFT\u DIV\u FWD\u by\u N
标志的同时等效缩放2),则应得到与时域信号具有类似量级的结果。

对于1:对于低频信号分析,小的恒定偏差确实会产生干扰(尤其是由于频谱泄漏)是的,如果你能消除这种偏见就更好了。对于2:我希望通过FFT(参见示例)对幅度进行缩放。然而,如果你的FFT使用的样本数量明显超过20个,那么只有10个因子的比例看起来很小(但我无法在不知道传递给FFT例程的样本数量的情况下进行确认)。好的,数据有点像半波,现在我有了完整长度的正弦波(0.17Hz)我可以用:magnity[I]*2/N得到正确的幅值,其中N是信号长度,在本例中是2879个数据点。谢谢你的回答,我将继续消除偏见。这毫无意义。减去信号的平均值在数值上与将零频率bin设置为0相同。向信号中添加一个常数只会影响零频率单元。也许你在变换中使用了一个窗口,如果信号的平均值非零,它会增加更高的频率。您所指的“光谱泄漏”只能是加窗造成的伪影。请注意,在转换之前,OP不开窗信号。@克里斯伦戈在估计频谱时,不可避免地必须对信号进行窗口化(并且不加显式窗口等效于使用矩形窗口),因此将不得不考虑某种形式的泄漏。如果你通过在时域中填充(承认类似于加窗)来插值该偏差的频谱,你会注意到一个类似sinc的函数,除了0位之外,它与零相交。当偏差不是很恒定时,这就变得很重要,因为零交叉点与箱子不太一致。还要注意的是,我没有说OP应该减去平均值(正如你所说,这只会影响箱子0),而是尽可能地消除偏差。高通或带通滤波器更适合这种情况。