Встроенные примитивы производительности Intel Величины преобразования Фурье

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

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

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

Кроме того, масштабирование величины кажется в 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);
}

person eemilk    schedule 14.07.2020    source источник
comment
Для 1: для анализа низкочастотного сигнала небольшое постоянное смещение может действительно мешать (особенно из-за спектральной утечки), поэтому да, лучше, если вы можете удалить это смещение. Для 2: я ожидаю масштабирования величины с помощью БПФ (см., например, this ответ). Однако только коэффициент 10 кажется странным, очень малым масштабированием, если вы используете значительно больше, чем 20 отсчетов для своего БПФ (но я не могу подтвердить, не зная фактического количества отсчетов, которые вы передаете процедуре БПФ).   -  person SleuthEye    schedule 15.07.2020
comment
Хорошо, данные были своего рода полуволной, теперь, когда у меня есть полная длина синусоиды (0,17 Гц), я могу получить правильную величину с помощью: величина [i] * 2/N, где N — длина сигнала, и в этом случае 2879 точки данных. Спасибо за ответ, я продолжу устранение предвзятости.   -  person eemilk    schedule 16.07.2020


Ответы (1)


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

При анализе низкочастотных сигналов небольшое смещение может действительно мешать (особенно из-за спектральной утечки). Для иллюстрации рассмотрим следующий низкочастотный сигнал 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: Спектр тона и тона со смещением

Так что да, лучше, если вы сможете удалить эту предвзятость. Однако следует подчеркнуть, что это возможно при условии, что вы знаете характер предвзятости. Если вы знаете, что смещение действительно является константой, его удаление обнаружит низкочастотную составляющую. В противном случае удаление среднего значения из сигнала может не дать желаемого эффекта, если смещение представляет собой лишь очень низкочастотный компонент.

Откуда взялась эта шкала 10?

Следует ожидать масштабирования величины с помощью БПФ, как описано в этом ответе примерно 0.5*N (где N — размер БПФ). Если вы обрабатывали небольшой кусок из 20 сэмплов, то вы должны получить такой коэффициент масштабирования 10. Если вы масштабируете выходные данные БПФ на 2/N (или, что то же самое, масштабируете на 2, используя также флаг IPP_FFT_DIV_FWD_BY_N), вы должны получить результаты, имеющие подобные величины, что и сигнал во временной области.

person SleuthEye    schedule 23.07.2020
comment
Это не имеет никакого смысла. Вычитание среднего значения сигнала численно идентично установке бина нулевой частоты в 0. Добавление константы к сигналу влияет только на бин нулевой частоты. Возможно, вы используете окно в своем преобразовании, которое добавляет более высокую частоту, если сигнал имеет ненулевое среднее значение. Эта «спектральная утечка», о которой вы говорите, не может быть ничем иным, как артефактом, вызванным оконным режимом. Обратите внимание, что OP не обрабатывает свой сигнал перед преобразованием. - person Cris Luengo; 23.07.2020
comment
@CrisLuengo при оценке спектра вам неизбежно придется отображать сигнал в окне (и отсутствие явного окна эквивалентно использованию прямоугольного окна), поэтому вам придется учитывать некоторую форму утечки. Если вы интерполируете спектр этого смещения, заполняя временную область (по общему признанию, похожей на работу с окнами), вы заметите функцию, подобную sinc, которая пересекает ноль вообще, кроме 0-го интервала. Это становится актуальным, когда смещение не совсем постоянное, так что пересечения нуля не совсем совпадают с бинами. - person SleuthEye; 23.07.2020
comment
Также обратите внимание, что я не сказал, что ОП должен вычесть среднее значение (которое, как вы сказали, повлияет только на ячейку 0), а скорее, чтобы удалить смещения, если это возможно. Для этого лучше подойдет фильтр верхних частот или полосовой фильтр. - person SleuthEye; 23.07.2020