FFTW — вычисление реального 2D FFT, особые требования

Я использую FFTW3 для вычисления 2D реального FFT в C ++. Я прочитал руководство, но у меня есть несколько вопросов. Из руководства: http://www.fftw.org/fftw3_doc/One_002dDimensional-DFTs-of-Real-Data.html#One_002dDimensional-DFTs-of-Real-Data

В обмен на эти преимущества скорости и пространства пользователь жертвует
некоторые из простоты сложных преобразований FFTW. Прежде всего,
входные и выходные массивы имеют разные размеры и типы: входные
n действительных чисел, в то время как на выходе получается n / 2 + 1 комплексных чисел (
не избыточные выходы); это также требует небольшого «дополнения»
входной массив для преобразований на месте. Во-вторых, обратное преобразование
(сложный к реальному) имеет побочный эффект перезаписи входного массива,
по умолчанию. Ни одно из этих неудобств не должно вызывать серьезного
проблема для пользователей, но важно знать о них.

  1. Я понимаю, что мне нужно преобразовать входную двумерную матрицу в одномерный вектор порядка строк. Но как выглядит результат? Что означают числа n / 2 + 1? Другими словами, как мне изменить порядок вывода, чтобы получить 2D матрицу?

  2. Что конкретно я должен сделать, чтобы создать этот «отступ»?

5

Решение

  1. Если ваш ввод уже находится в обычном двумерном массиве C ++, все, что вам нужно сделать, это ввести его:

    double twoDarray[10][10];
    double *oneDarrayPointer = (double *)twoDarray;
    

    Если ваш ввод равен 100 (как в приведенном выше примере), ваш выходной массив будет 51 комплексным числом. Формат этих чисел должен быть описан вашей библиотекой, но, вероятно, это массив из 102 doubles — 51 раз записи 2 (реальные / мнимые части).

    Изменить: подтверждено — fftw_complex определяется как:

    typedef double fftw_complex[2];
    

    Так что они просто последовательные пары doubles представляющие действительные и мнимые части комплексного числа.

  2. Если вы не хотите делать это на месте, вам не нужно ничего дополнять — просто выделите выходной массив соответствующего размера. если ты делать необходимо сделать это на месте, ваш буфер ввода должен иметь место для 2 дополнительных двойных по сравнению с размером ввода. Предполагая, что объявления выше, вы хотели бы что-то вроде:

    double *inPlaceFFTPointer = malloc(sizeof twoDarray + 2*sizeof(double));
    memcpy(inPlaceFFTPointer, oneDarrayPointer, sizeof twoDarray);
    

    Я не уверен, нужно ли вам обязательно иметь 0.0 в последних двух записях или нет, но это достаточно легко добавить.

2

Другие решения

Вы можете взглянуть на реальные преобразования в FFTW3, которые делают именно то, что вы просили. Они не требуют заполнения и принимают во внимание, что как волновое число 0, так и значение, представляющее частоту Найквиста, имеют только реальный компонент. Посмотрите здесь:

FFTW3 Преобразование из реального в реальное

и для макета в памяти:

FFTW3 Преобразование реального типа в реальное

2

По вопросам рекламы [email protected]