У меня есть двумерный массив данных, сохраненный в формате основных столбцов (в стиле Фортрана), и я хотел бы взять БПФ каждой строки .Я хотел бы избежать транспонирования массива (он не квадратный).Например, мой массив
fftw_complex* data = new fftw_complex[21*256];
содержит записи [r0_val0, r1_val0,..., r20_val0, r0_val1,...,r20_val255]
.
Я могу использовать fftw_plan_many_dft
, чтобы составить план для решения каждого из 21 БПФ на месте в data
массив, если он строка -основный, например [r0_val0, r0_val1,..., r0_val255, r1_val0,...,r20_val255]
:
int main() {
int N = 256;
int howmany = 21;
fftw_complex* data = new fftw_complex[N*howmany];
fftw_plan p;
// this plan is OK
p = fftw_plan_many_dft(1,&N,howmany,data,NULL,1,N,data,NULL,1,N,FFTW_FORWARD,FFTW_MEASURE);
// do stuff...
return 0;
}
Согласно документации ( раздел 4.4.1 руководства FFTW ),подпись для функции
fftw_plan fftw_plan_many_dft(int rank, const int *n, int howmany,
fftw_complex *in, const int *inembed,
int istride, int idist,
fftw_complex *out, const int *onembed,
int ostride, int odist,
int sign, unsigned flags);
, и я должен иметь возможность использовать параметры stride
и dist
для установки индексации.Из того, что я могу понять из документации, записи в массиве для преобразования индексируются как in + j*istride + k*idist
, где j=0..n-1
и k=0..howmany-1
.(Мои массивы 1D и их howmany
).Однако следующий код приводит к сегментированию.ошибка ( редактировать: длина шага неправильно , см. обновление ниже):
int main() {
int N = 256;
int howmany = 21;
fftw_complex* data = new fftw_complex[N*howmany];
fftw_plan p;
// this call results in a seg. fault.
p = fftw_plan_many_dft(1,&N,howmany,data,NULL,N,1,data,NULL,N,1,FFTW_FORWARD,FFTW_MEASURE);
return 0;
}
Обновление:
Я сделал ошибку при выборедлина шага.Правильный вызов (правильная длина шага howmany
, а не N
):
int main() {
int N = 256;
int howmany = 21;
fftw_complex* data = new fftw_complex[N*howmany];
fftw_plan p;
// OK
p = fftw_plan_many_dft(1,&N,howmany,data,NULL,howmany,1,data,NULL,howmany,1,FFTW_FORWARD,FFTW_MEASURE);
// do stuff
return 0;
}