Интегрированные примитивы производительности Intel Величины преобразования Фурье - PullRequest
1 голос
/ 14 июля 2020

Когда я использую Intel IPP ippsFFTFwd_RToCCS_64f , а затем ippsMagnitude_64f c, я получаю массивный пик при нулевом индексе в массиве величин.

Моя синусоида длинный и интересующий меня главный компонент находится где-то между 0,15 Гц и 0,25 Гц. Я беру образец с частотой дискретизации 500 Гц. Если я уменьшу среднее значение сигнала перед БПФ, я получу действительно небольшую нулевую составляющую, а не этот пик. Ниже приведен заголовок массива величин pi c:

введите описание изображения здесь

Также масштабирование амплитуды кажется в 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);
}

1 Ответ

1 голос
/ 23 июля 2020

Действительно ли мне нужно адресовать пик с нулевым индексом с помощью среднего уменьшения?

Для анализа низкочастотного сигнала небольшое смещение действительно может мешать (особенно из-за спектральной утечки). Для иллюстрации рассмотрим следующий низкочастотный сигнал 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 отсчетов этих сигналов, вы должны заметить, что спектр tone_with_bias полностью заглушает спектр tone: Spectrum of tone & tone with bias

So yes it's better if you can remove that bias. However, it should be emphasized that this is possible provided that you know the nature of the bias. If you know that the bias is indeed a constant, removing it will reveal the low-frequency component. Otherwise, removing the mean from the signal may not achieve the desired effect if the bias is just a very low-frequency component.

Where does this scale of 10 come?

Scaling of the magnitude by the FFT should be expected, as described in этот ответ примерно 0.5*N (где N - размер БПФ). Если вы обрабатывали небольшой фрагмент из 20 сэмплов, то вы должны получить такой коэффициент масштабирования 10. Если вы масштабируете выходной сигнал БПФ на 2/N (или, что то же самое, масштабируете на 2, одновременно используя флаг IPP_FFT_DIV_FWD_BY_N), вы должны получить результаты, которые имеют аналогичные величины, как у сигнала временной области.

...