英特尔集成性能基元傅里叶变换幅度
Intel integrated performance primitives Fourier Transform magnitudes
当我使用英特尔 IPP 时 ippsFFTFwd_RToCCS_64f and then ippsMagnitude_64fc 我在幅度数组中的零索引处得到一个巨大的峰值。
我的正弦波很长,我感兴趣的主要成分在 0.15 Hz 和 0.25 Hz 之间。我以 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);
}
Do I really need to address the zero index peak with mean reduction?
对于低频信号分析,小偏差确实会造成干扰(尤其是由于频谱泄漏)。为了便于说明,请考虑以下低频信号 tone
和另一个具有恒定偏置 tone_with_bias
的信号:
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];
}
如果我们绘制这些信号的 100 个样本 window 的频谱,您应该注意到 tone_with_bias
的频谱完全淹没了 tone
的频谱:
所以是的,如果你能消除这种偏见就更好了。但是,应该强调的是,只要您知道偏差的性质,这是可能的。如果您知道偏置确实是一个常数,则将其移除将揭示低频分量。否则,如果偏差只是一个非常低频的分量,从信号中去除均值可能无法达到预期的效果。
Where does this scale of 10 come?
如 this answer 中所述,FFT 的幅度缩放应该是预期的,大约 0.5*N
(其中 N
是 FFT 大小)。如果你正在处理一小块 20 个样本,那么你应该得到 10 的缩放因子。如果将 FFT 的输出缩放 2/N
(或等效缩放 2,同时还使用 IPP_FFT_DIV_FWD_BY_N
标志),您应该得到具有 similar 大小的结果时域信号。
当我使用英特尔 IPP 时 ippsFFTFwd_RToCCS_64f and then ippsMagnitude_64fc 我在幅度数组中的零索引处得到一个巨大的峰值。
我的正弦波很长,我感兴趣的主要成分在 0.15 Hz 和 0.25 Hz 之间。我以 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);
}
Do I really need to address the zero index peak with mean reduction?
对于低频信号分析,小偏差确实会造成干扰(尤其是由于频谱泄漏)。为了便于说明,请考虑以下低频信号 tone
和另一个具有恒定偏置 tone_with_bias
的信号:
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];
}
如果我们绘制这些信号的 100 个样本 window 的频谱,您应该注意到 tone_with_bias
的频谱完全淹没了 tone
的频谱:
所以是的,如果你能消除这种偏见就更好了。但是,应该强调的是,只要您知道偏差的性质,这是可能的。如果您知道偏置确实是一个常数,则将其移除将揭示低频分量。否则,如果偏差只是一个非常低频的分量,从信号中去除均值可能无法达到预期的效果。
Where does this scale of 10 come?
如 this answer 中所述,FFT 的幅度缩放应该是预期的,大约 0.5*N
(其中 N
是 FFT 大小)。如果你正在处理一小块 20 个样本,那么你应该得到 10 的缩放因子。如果将 FFT 的输出缩放 2/N
(或等效缩放 2,同时还使用 IPP_FFT_DIV_FWD_BY_N
标志),您应该得到具有 similar 大小的结果时域信号。