Я пытаюсь сделать FFT по данным, используя библиотеку FFT. Здесь также приведен код.
Проблема в том, что когда я пытаюсь сделать БПФ размером NX> 2048 (например, 4096), он дает мне ошибку 0xC00000FD: переполнение стека. Я видел, как люди публиковали результат, делая БПФ около 2 ^ 12 и 2 ^ 15 пунктов ДПФ. Мой вопрос: как мне вычислить N-точечный FFT с N> 2048.
Сигнал, который я использую, предназначен только для проверки кода. Сигнал в реальной задаче будет получен в реальном времени с аппаратного обеспечения.
Я использую Visual Studio 2010. Системные спецификации (Core i7, RAM: 16 ГБ)
// Raw Data Generation
#define TABLE_SIZE 1000
#define TWO_PI (3.14159 * 2.0)
#define CYCLES 20
#define NUMBER_OF_SAMPLES (TABLE_SIZE*CYCLES)
// FFT Values
#define NX 2048// NX-point DFT
// Sine Generator Function - Real Samples
void sin_func(double *sample_ptr)
{
double phaseIncrement = TWO_PI/TABLE_SIZE;
double currentPhase = 0.0;
int i;
for (i = 0; i < CYCLES*TABLE_SIZE; i ++){
*sample_ptr = sin(currentPhase);
sample_ptr = sample_ptr + 1;
currentPhase += phaseIncrement;}
}
void main()
{
const int ARRAY_SIZE = NUMBER_OF_SAMPLES*sizeof(double);
const int FFT_OUT_SIZE = sizeof(fftw_complex)*(NX/2+1);
// Initialization
double rawdata_in[NUMBER_OF_SAMPLES];
fftw_complex fft_out[FFT_OUT_SIZE]; // Sizeof(fftw_complex) = 16
fftw_complex temp[FFT_OUT_SIZE];
double datacheck_out[NUMBER_OF_SAMPLES];
// Creating fft plan
fftw_plan plan;
plan = fftw_plan_dft_r2c_1d(NX, rawdata_in , fft_out, FFTW_MEASURE);
// Initializing Input Array
sin_func(&rawdata_in[0]);
fftw_execute(plan);
// Doing Inverse Transform
fftw_plan plan2;
plan2 = fftw_plan_dft_c2r_1d(NX, temp, datacheck_out, NULL);
memcpy(temp, fft_out, sizeof(fftw_complex)*FFT_OUT_SIZE);
fftw_execute(plan2);
fftw_destroy_plan(plan2);
fftw_destroy_plan(plan);
}
В случае N == 4096
размер ваших распределений стека выглядит так:
const int FFT_OUT_SIZE = 32784;
double rawdata_in[20000]; // 8 * 20000 = 160 kb
fftw_complex fft_out[32784]; // 32784 * 16 = 525 kb
fftw_complex temp[32784]; // = 525 kb
double datacheck_out[20000]; // = 160 kb
// Total = 1370 kb
По-видимому, размер стека по умолчанию в VS 2010 равен 1 МБ, поэтому это приводит к переполнению стека. Один из способов обойти это - изменить размер стека в параметрах проекта (Свойства → Свойства конфигурации → Линкера → Система → Размер резерва стека, см. Здесь). Другой способ - использовать динамическое распределение памяти, например:
fftw_complex* fft_out = new fftw_complex[FFT_OUT_SIZE];
//...use the pointer
delete[] fft_out;
Одна заметка: я думаю, ваш FFT_OUT_SIZE
должен быть определен как:
const int FFT_OUT_SIZE = NX/2 + 1;
sizeof(fftw_complex)
выглядит странно там... Я бы только ожидал, если вы используете malloc()
для выделения необработанного буфера в C.