




/*! ****************************************************************************
\ingroup DFT_GROUP
\struct fft_t
\brief Fast Fourier Transform Object Data Structure

The structure stores pointers to twiddle factors and arrays of intermediate data of the fast Fourier transform algorithm.

The DSPL library uses an FFT algorithm for composite size.


\param  n
The size of the FFT vector for which memory is allocated in the structure arrays.  \n
The parameter `n` must be equal to an integer power of two (radix 2). \n \n


\param  w
Pointer to the vector of twiddle factors. \n
The size of the vector is `[n x 1]`. \n
The memory must be allocated and an array of twiddle factors
must be filled with the \ref fft_create function. \n\n


\param  t0
Pointer to the vector of intermediate results of the FFT algorithm. \n
The size of the vector is `[n x 1]`. \n
Memory must be allocated by \ref fft_create function. \n\n 


\param  t1
Pointer to the vector of intermediate results. \n
The size of the vector is `[n x 1]`. \n
The memory must be allocated with the \ref fft_create function. \n\n
The structure is populated with the \ref fft_create function once
before using the FFT algorithm. \n
A pointer to an object of this structure may be
reused when calling FFT functions. \n
Before exiting the program, dedicated memory for twiddle factors and arrays of intermediate data
must be cleared by the \ref fft_free function. For example:
\code
fft_t pfft = {0};     /* Structure fft_t and clear all fields */
int n = 64;           /* FFT size */

int err;

/* Create and fill FFT structure for 64-points FFT */
err = fft_create(&pfft, n);

/* FFT calculation here            */
/* FFT calculation here one more   */
/* ...  */

/* Clear fft structure */
fft_free(&pfft);
\endcode

\note
It is important to note that if the object `fft_t` was created for the FFT size equal to` n`,
it can only be used for FFT of size `n`. \n \n
It’s also worth noting that the FFT functions independently control the size, and independently allocate the memory of the FFT object, if necessary.
So if you call any function using the `fft_t` structure with filled
data for the FFT length `k` for calculating the FFT of length`n`,
then the structure arrays will be automatically recreated for the length `n`.

\author  Sergey Bakhurin  www.dsplib.org  
***************************************************************************** */










/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int ifft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
\brief Обратное быстрое преобразование Фурье

Функция рассчитывает \f$ n \f$-точечное обратное быстрое преобразование Фурье 
от \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
\f[
  Y(k) = \frac{1}{N} \sum_{m = 0}^{n-1} x(m)   \exp 
   \left( j   \frac{2\pi}{n}    m    k \right),
\f]
где \f$ k = 0 \ldots n-1 \f$.

Для расчета используется алгоритм БПФ составной длины.

\param[in]  x
Указатель на входной комплексный вектор \f$x(m)\f$, 
\f$ m = 0 \ldots n-1 \f$.  \n
Размер вектора `[n x 1]`.  \n \n

\param[in]  n
Размер ОБПФ \f$n\f$. \n
Размер ОБПФ может быть составным вида 
\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
где \f$n_i = 2,3,5,7\f$, а \f$m \f$ -- 
произвольный простой множитель не превосходящий 46340
(см. описание функции \ref fft_create). \n \n

\param[in]  pfft
Указатель на структуру `fft_t`.  \n
Указатель не должен быть `NULL`.  \n
Структура \ref fft_t должна быть предварительно однократно
заполнена функцией  \ref fft_create, и память должна быть 
очищена перед выходом функцией \ref fft_free. \n \n

\param[out] y
Указатель на вектор результата ОБПФ \f$Y(k)\f$, 
\f$ k = 0 \ldots n-1 \f$. Размер вектора `[n x 1]`.  \n
Память должна быть выделена. \n \n

\return
`RES_OK` если расчет произведен успешно.  \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n

Пример использования функции `fft`:

\include ifft_cmplx_test.c

Результат работы программы:

\verbatim
| x[ 0] =  1.000   0.000 | y[ 0] = -0.517   0.686 | z[ 0] =   1.000   0.000 |
| x[ 1] =  0.540   0.841 | y[ 1] = -0.943   0.879 | z[ 1] =   0.540   0.841 |
| x[ 2] = -0.416   0.909 | y[ 2] = -2.299   1.492 | z[ 2] =  -0.416   0.909 |
| x[ 3] = -0.990   0.141 | y[ 3] = 16.078  -6.820 | z[ 3] =  -0.990   0.141 |
| x[ 4] = -0.654  -0.757 | y[ 4] =  2.040  -0.470 | z[ 4] =  -0.654  -0.757 |
| x[ 5] =  0.284  -0.959 | y[ 5] =  1.130  -0.059 | z[ 5] =   0.284  -0.959 |
| x[ 6] =  0.960  -0.279 | y[ 6] =  0.786   0.097 | z[ 6] =   0.960  -0.279 |
| x[ 7] =  0.754   0.657 | y[ 7] =  0.596   0.183 | z[ 7] =   0.754   0.657 |
| x[ 8] = -0.146   0.989 | y[ 8] =  0.470   0.240 | z[ 8] =  -0.146   0.989 |
| x[ 9] = -0.911   0.412 | y[ 9] =  0.375   0.283 | z[ 9] =  -0.911   0.412 |
| x[10] = -0.839  -0.544 | y[10] =  0.297   0.318 | z[10] =  -0.839  -0.544 |
| x[11] =  0.004  -1.000 | y[11] =  0.227   0.350 | z[11] =   0.004  -1.000 |
| x[12] =  0.844  -0.537 | y[12] =  0.161   0.380 | z[12] =   0.844  -0.537 |
| x[13] =  0.907   0.420 | y[13] =  0.094   0.410 | z[13] =   0.907   0.420 |
| x[14] =  0.137   0.991 | y[14] =  0.023   0.442 | z[14] =   0.137   0.991 |
| x[15] = -0.760   0.650 | y[15] = -0.059   0.479 | z[15] =  -0.760   0.650 |
| x[16] = -0.958  -0.288 | y[16] = -0.161   0.525 | z[16] =  -0.958  -0.288 |
| x[17] = -0.275  -0.961 | y[17] = -0.300   0.588 | z[17] =  -0.275  -0.961 |
\endverbatim

\author
Бахурин Сергей
www.dsplib.org 
***************************************************************************** */




/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fft(double* x, int n, fft_t* pfft, complex_t* y)
\brief Быстрое преобразование Фурье вещественного сигнала

Функция рассчитывает \f$ n \f$-точечное  быстрое преобразование Фурье 
вещественного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
\f[
  Y(k) = \sum_{m = 0}^{n-1} x(m)   \exp 
  \left( -j   \frac{2\pi}{n}    m    k \right),
\f]
где \f$ k = 0 \ldots n-1 \f$.

Для расчета используется алгоритм БПФ составной длины.

\param[in]  x
Указатель на вектор вещественного входного сигнала \f$x(m)\f$, 
\f$ m = 0 \ldots n-1 \f$.  \n
Размер вектора `[n x 1]`.  \n \n

\param[in]  n
Размер БПФ \f$n\f$. \n
Размер БПФ может быть составным вида 
\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
где \f$n_i = 2,3,5,7\f$, а \f$m \f$ -- 
произвольный простой множитель не превосходящий 46340
(см. описание функции \ref fft_create). \n \n

\param[in]  pfft
Указатель на структуру `fft_t`. \n
Указатель не должен быть `NULL`. \n
Структура \ref fft_t должна быть предварительно однократно
заполнена функцией  \ref fft_create, и память должна быть 
очищена перед выходом функцией \ref fft_free. \n \n

\param[out] y
Указатель на комплексный вектор результата БПФ \f$Y(k)\f$, 
\f$ k = 0 \ldots n-1 \f$. \n
Размер вектора `[n x 1]`. \n
Память должна быть выделена. \n \n

\return
`RES_OK` если расчет произведен успешно.  \n
 В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n

Пример использования функции `fft`:

\include fft_test.c

Результат работы программы:

\verbatim
y[ 0] =    91.000    0.000
y[ 1] =    -7.000   30.669
y[ 2] =    -7.000   14.536
y[ 3] =    -7.000    8.778
y[ 4] =    -7.000    5.582
y[ 5] =    -7.000    3.371
y[ 6] =    -7.000    1.598
y[ 7] =    -7.000    0.000
y[ 8] =    -7.000   -1.598
y[ 9] =    -7.000   -3.371
y[10] =    -7.000   -5.582
y[11] =    -7.000   -8.778
y[12] =    -7.000  -14.536
y[13] =    -7.000  -30.669
\endverbatim

\author
Бахурин Сергей
www.dsplib.org 
***************************************************************************** */






/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
\brief Быстрое преобразование Фурье комплексного сигнала

Функция рассчитывает \f$ n \f$-точечное  быстрое преобразование Фурье 
комплексного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
\f[
  Y(k) = \sum_{m = 0}^{n-1} x(m)   \exp 
   \left( -j   \frac{2\pi}{n}    m    k \right),
\f]
где \f$ k = 0 \ldots n-1 \f$.

Для расчета используется алгоритм БПФ составной длины.

\param[in]  x
Указатель на вектор комплексного 
входного сигнала \f$x(m)\f$, \f$ m = 0 \ldots n-1 \f$.  \n
Размер вектора `[n x 1]`. \n \n

\param[in]  n
Размер БПФ \f$n\f$. \n
Размер БПФ может быть составным вида 
\f$n = n_0 \times n_1 \times n_2 \times n_3 \times \ldots \times n_p \times m\f$,
где \f$n_i = 2,3,5,7\f$, а \f$m \f$ -- 
произвольный простой множитель не превосходящий 46340
(см. описание функции \ref fft_create). \n \n

\param[in]  pfft
Указатель на структуру `fft_t`. \n
Указатель не должен быть `NULL`.  \n
Структура \ref fft_t должна быть предварительно однократно
заполнена функцией  \ref fft_create, и память должна быть 
очищена перед выходом функцией \ref fft_free. \n \n

\param[out] y
Указатель на комплексный вектор 
результата БПФ \f$Y(k)\f$, 
\f$ k = 0 \ldots n-1 \f$. 
Размер вектора `[n x 1]`.  \n
Память должна быть выделена. \n \n

\return
`RES_OK` если расчет произведен успешно.  \n
 В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n

Пример использования функции `fft`:

\include fft_cmplx_test.c

Результат работы программы:

\verbatim
y[ 0] =    -0.517    0.686
y[ 1] =    -0.943    0.879
y[ 2] =    -2.299    1.492
y[ 3] =    16.078   -6.820
y[ 4] =     2.040   -0.470
y[ 5] =     1.130   -0.059
y[ 6] =     0.786    0.097
y[ 7] =     0.596    0.183
y[ 8] =     0.470    0.240
y[ 9] =     0.375    0.283
y[10] =     0.297    0.318
y[11] =     0.227    0.350
y[12] =     0.161    0.380
y[13] =     0.094    0.410
y[14] =     0.023    0.442
y[15] =    -0.059    0.479
y[16] =    -0.161    0.525
y[17] =    -0.300    0.588
\endverbatim

\author
Бахурин Сергей
www.dsplib.org 
***************************************************************************** */




/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fft_create(fft_t* pfft, int n)
\brief Заполнение структуры `fft_t` для алгоритма БПФ

Функция производит выделение памяти и рассчет векторов 
поворотных коэффициентов `n`-точечного БПФ для структуры `fft_t`.

\param[in,out]  pfft
Указатель на структуру `fft_t`.  \n
Указатель не должен быть `NULL`.  \n \n

\param[in]  n
Размер БПФ \f$n\f$. \n
Размер БПФ может быть составным вида 
\f$n = n_0 \times n_1 \times n_2 \ldots \times n_p \times m\f$,
где \f$n_i = 2,3,5,7\f$, а \f$m \f$ -- 
произвольный простой множитель не превосходящий 46340. \n
Таким образом алгоритм БПФ поддерживает произвольные длины, равные целой 
степени чисел 2,3,5,7, а также различные их комбинации.  \n
Так например, при \f$ n = 725760 \f$ структура будет успешно заполнена, 
потому что 
\f$725760 = 2 \cdot 3 \cdot 4 \cdot 5 \cdot 6 \cdot 7 \cdot 9 \cdot 16 \f$, 
т.е. получается как произведение множителей 2,3,5,7. \n
При \f$ n = 172804 = 43201 \cdot 4 \f$ структура также будет успешно заполнена, 
потому что простой множитель входящий в \f$n\f$ не превосходит 46340. \n
Для размера \f$ n = 13 \cdot 17 \cdot 23 \cdot 13 = 66079 \f$ 
функция вернет ошибку, поскольку 66079 больше 46340 и не является результатом 
произведения чисел 2,3,5,7. \n \n

\return
`RES_OK` если структура заполнена успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n

\note
Некоторые компиляторы при создании структуры не обнуляют ее содержимое. 
Поэтому рекомендуется произвести обнуление структуры после ее объявления:
\code{.cpp}
fft_t pfft;     /* объявляем объект fft_t */
int n = 64;     /* Размер БПФ             */

/*
бнуляем все поля и указатели. 
Данные шаг рекомендуется ввиду того, что некоторые 
компиляторы при создании переменной не инициализируют ее нулем.
*/

memset(&pfft, 0, sizeof(fft_t));

int err;

/* создаем объект для 64-точечного БПФ */

err = fft_create(&pfft, n);

/* ................................... */

/* очистить память объекта БПФ         */

fft_free(&pfft);
\endcode

Перед выходом из программы выделенную в структуре память 
необходимо очистить функцией \ref fft_free . \n \n

\note
Магия числа 46340 заключается в том, что \f$\sqrt{2^{31}} = 46340.95\f$. \n

\author
Бахурин Сергей
www.dsplib.org 
***************************************************************************** */









/*! ****************************************************************************
\ingroup DFT_GROUP
\fn void fft_free(fft_t *pfft)
\brief Очистить структуру `fft_t` алгоритма БПФ

Функция производит очищение памяти промежуточных данных 
и векторов поворотных коэффициентов структуры `fft_t`.

\param[in] pfft
Указатель на структуру `fft_t`. \n

\author
Бахурин Сергей
www.dsplib.org 
***************************************************************************** */








/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fft_shift(double* x, int n, double* y)
\brief Перестановка спектральных отсчетов дискретного преобразования Фурье

Функция производит 
<a href="http://ru.dsplib.org/content/dft_freq/dft_freq.html">
перестановку спектральных отсчетов ДПФ
</a> и переносит нулевую частоту в центр вектора ДПФ.  \n
Данная функция обрабатывает вещественные входные и выходные вектора 
и может применяться для перестановки 
амплитудного или фазового спектра.

\param[in]  x
Указатель на исходный вектор ДПФ.  \n
Размер вектора `[n x 1]`.  \n \n

\param[in]  n
Размер ДПФ \f$n\f$ (размер векторов до и после перестановки). \n \n

\param[out] y
Указатель на вектор результата перестановки. \n
Размер вектора `[n x 1]`.  \n
Память должна быть выделена. \n \n


\return
`RES_OK` если перестановка произведена успешно.  \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n

\author
Бахурин Сергей 
www.dsplib.org 
***************************************************************************** */
