New Structure is beginning

Changes to be committed:
	deleted:    _release/.gitignore
	deleted:    _release/Makefile
	modified:   _release/dspl.c
	modified:   _release/dspl.h
	deleted:    _release/test.c
	modified:   dspl/Makefile
	modified:   dspl/src/array.c
	new file:   dspl/src/array/array_scale_lin.c
	new file:   dspl/src/array/concat.c
	new file:   dspl/src/array/decimate.c
	new file:   dspl/src/array/decimate_cmplx.c
	new file:   dspl/src/array/find_nearest.c
	new file:   dspl/src/array/flipip.c
	new file:   dspl/src/array/flipip_cmplx.c
	new file:   dspl/src/array/linspace.c
	new file:   dspl/src/array/logspace.c
	new file:   dspl/src/array/ones.c
	new file:   dspl/src/array/sum.c
	new file:   dspl/src/array/sum_sqr.c
	modified:   dspl/src/dft.c
	new file:   dspl/src/dft/dft.c
	new file:   dspl/src/dft/dft_cmplx.c
	new file:   dspl/src/dft/fft.c
	new file:   dspl/src/dft/fft_abs.c
	new file:   dspl/src/dft/fft_abs_cmplx.c
	new file:   dspl/src/dft/fft_cmplx.c
	new file:   dspl/src/dft/fft_create.c
	new file:   dspl/src/dft/fft_free.c
	new file:   dspl/src/dft/fft_krn.c
	new file:   dspl/src/dft/fft_mag.c
	new file:   dspl/src/dft/fft_mag_cmplx.c
	new file:   dspl/src/dft/fft_shift.c
	new file:   dspl/src/dft/fft_shift_cmplx.c
	renamed:    dspl/src/fft_subkernel.c -> dspl/src/dft/fft_subkernel.c
	new file:   dspl/src/dft/fourier_integral_cmplx.c
	new file:   dspl/src/dft/fourier_series_dec.c
	new file:   dspl/src/dft/fourier_series_dec_cmplx.c
	new file:   dspl/src/dft/fourier_series_rec.c
	new file:   dspl/src/dft/goertzel.c
	renamed:    dspl/src/goertzel.c -> dspl/src/dft/goertzel_cmplx.c
	new file:   dspl/src/dft/idft_cmplx.c
	new file:   dspl/src/dft/ifft_cmplx.c
	deleted:    dspl/src/fft.c
	deleted:    dspl/src/fourier_series.c
	new file:   dspl/src/math_poly.c
	new file:   dspl/src/math_poly/cheby_poly1.c
	renamed:    dspl/src/cheby.c -> dspl/src/math_poly/cheby_poly2.c
	new file:   dspl/src/math_poly/poly_z2a_cmplx.c
	renamed:    dspl/src/polyval.c -> dspl/src/math_poly/polyroots.c
	new file:   dspl/src/math_poly/polyval.c
	new file:   dspl/src/math_poly/polyval_cmplx.c
	modified:   make.inc
pull/6/merge
Dsplib 2021-12-29 14:33:52 +03:00
rodzic d509c033f6
commit c76bd63ace
52 zmienionych plików z 6197 dodań i 5354 usunięć

4
_release/.gitignore vendored
Wyświetl plik

@ -1,4 +0,0 @@
*.o
*.so
*.dll
*.exe

Wyświetl plik

@ -1,37 +0,0 @@
CC = gcc
# Define OS
ifeq ($(OS),Windows_NT)
DSPL_LIBNAME = libdspl.dll
DEF_OS = WIN_OS
LFLAGS = -lm
else
UNAME_S := $(shell uname -s)
UNAME_P := $(shell uname -p)
ifeq ($(UNAME_S),Linux)
DSPL_LIBNAME = libdspl.so
DEF_OS = LINUX_OS
LFLAGS = -lm -ldl
else ifeq ($(UNAME_S),Darwin)
DSPL_LIBNAME = libdspl.so
DEF_OS = LINUX_OS
LFLAGS = -lm -ldl
endif
endif
# C-compiler flags
CFLAGS = -c -O3 -D$(DEF_OS)
OBJFILES = test.o dspl.o
all: test.exe clean
test.exe: $(OBJFILES)
$(CC) $(OBJFILES) -o $@ $(LFLAGS)
%.o:%.c
$(CC) $(CFLAGS) $< -o $@ $(LFLAGS)
clean:
rm -f *.o

Wyświetl plik

@ -98,6 +98,7 @@ p_filter_iir filter_iir ;
p_filter_ws1 filter_ws1 ;
p_filter_zp2ab filter_zp2ab ;
p_find_max_abs find_max_abs ;
p_find_nearest find_nearest ;
p_fir_linphase fir_linphase ;
p_flipip flipip ;
p_flipip_cmplx flipip_cmplx ;
@ -179,8 +180,10 @@ p_sin_cmplx sin_cmplx ;
p_sinc sinc ;
p_sine_int sine_int ;
p_sqrt_cmplx sqrt_cmplx ;
p_std std ;
p_std_cmplx std_cmplx ;
p_stat_std stat_std ;
p_stat_std_cmplx stat_std_cmplx ;
p_sum sum ;
p_sum_sqr sum_sqr ;
p_trapint trapint ;
p_trapint_cmplx trapint_cmplx ;
@ -312,6 +315,7 @@ void* dspl_load()
LOAD_FUNC(filter_ws1);
LOAD_FUNC(filter_zp2ab);
LOAD_FUNC(find_max_abs);
LOAD_FUNC(find_nearest);
LOAD_FUNC(fir_linphase);
LOAD_FUNC(flipip);
LOAD_FUNC(flipip_cmplx);
@ -393,8 +397,10 @@ void* dspl_load()
LOAD_FUNC(sinc);
LOAD_FUNC(sine_int);
LOAD_FUNC(sqrt_cmplx);
LOAD_FUNC(std);
LOAD_FUNC(std_cmplx);
LOAD_FUNC(stat_std);
LOAD_FUNC(stat_std_cmplx);
LOAD_FUNC(sum);
LOAD_FUNC(sum_sqr);
LOAD_FUNC(trapint);
LOAD_FUNC(trapint_cmplx);

Wyświetl plik

@ -1068,6 +1068,12 @@ DECLARE_FUNC(int, find_max_abs, double* a
COMMA double* m
COMMA int* ind);
/*----------------------------------------------------------------------------*/
DECLARE_FUNC(int, find_nearest, double* x
COMMA int n
COMMA double val
COMMA int* idx
COMMA double* dist);
/*----------------------------------------------------------------------------*/
DECLARE_FUNC(int, fir_linphase, int ord
COMMA double w0
COMMA double w1
@ -1511,11 +1517,19 @@ DECLARE_FUNC(int, sqrt_cmplx, complex_t*
COMMA int
COMMA complex_t*);
/*----------------------------------------------------------------------------*/
DECLARE_FUNC(int, std, double* x
DECLARE_FUNC(int, stat_std, double* x
COMMA int n
COMMA double* s);
/*----------------------------------------------------------------------------*/
DECLARE_FUNC(int, std_cmplx, complex_t* x
DECLARE_FUNC(int, stat_std_cmplx, complex_t* x
COMMA int n
COMMA double* s);
/*----------------------------------------------------------------------------*/
DECLARE_FUNC(int, sum, double* x
COMMA int n
COMMA double* s);
/*----------------------------------------------------------------------------*/
DECLARE_FUNC(int, sum_sqr, double* x
COMMA int n
COMMA double* s);
/*----------------------------------------------------------------------------*/

Wyświetl plik

@ -1,30 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include "dspl.h"
int main(int argc, char* argv[])
{
/* libdspl handle */
void* hdspl;
/* Load libdspl functions */
hdspl = dspl_load();
/* Check libdspl handle. */
/* If hdspl == NULL means problem with libdspl loading */
if(!hdspl)
{
printf("libdspl loading error!\n");
return -1;
}
/* Print libdspl info */
dspl_info();
/* free dspl handle */
dspl_free(hdspl);
return 0;
}

Wyświetl plik

@ -2,13 +2,12 @@
include ../make.inc
# C-compiler flags
CFLAGS = -c -fPIC -Wall -O3 -I$(INC_DIR) -DBUILD_LIB -D$(DEF_OS)
CFLAGS = -c -fPIC -Wall -O3 -I$(INC_DIR) -Isrc -DBUILD_LIB -D$(DEF_OS)
# DSPL src and obj files list
DSPL_SRC_FILES = $(wildcard $(DSPL_SRC_DIR)/*.c)
DSPL_OBJ_FILES = $(addprefix $(DSPL_OBJ_DIR)/,$(notdir $(DSPL_SRC_FILES:.c=.o)))
all: $(RELEASE_DIR)/$(LIB_NAME)\
$(EXAMPLE_BIN_DIR)/$(LIB_NAME)\
$(PERFORMANCE_BIN_DIR)/$(LIB_NAME)\

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,193 @@
/*
* Copyright (c) 2015-2020 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int array_scale_lin(double* x, int n,
double xmin, double xmax, double dx,
double h, double* y)
\brief Vector `x` linear transformation
Function transforms values \f$x(i)\f$, \f$i = 0,1,\ldots n\f$
to the \f$y(i)\f$, accordint to equation:
\f[
y(i) = k_x x(i) + d_x, \qquad k_x =
\frac{h}{x_{\textrm{max}} - x_{\textrm{min}}}.
\f]
All values of the vector `x` between
\f$x_{\textrm{min}}\f$ and \f$x_{\textrm{max}}\f$, transforms to
the vector `y` between \f$d_x\f$ and \f$h + d_x\f$.
Parameter \f$d_x\f$ sets mean shift of the vector `y`.
This function is convenient for translating values
of different dimensions. For example it can be used
to transfer the values of the vector `x`
to the graph of the height of` h`, where the height can
be set in the number of pixels, in centimeters, etc.
\param[in] x
Pointer to the input vector `x`. \n
Vector size is `[n x 1]`. \n
\n
\param[in] n
Size of vector `x`. \n
\n
\param[in] xmin
Parameter \f$x_{\textrm{min}}\f$. \n
\n
\param[in] xmax
Parameter \f$x_{\textrm{min}}\f$. \n
Value `xmax` must be more than `xmin`. \n
\n
\param[in] dx
Displacement after transformation. \n
This parameter must have output vector `y`
dimensions (pixels, centimeters). \n
\n
\param[in] h
Height of vector `y` after transforming between `dx` and `h+dx`. \n
\n
\param[out] y
Pointer to the output vector `y`. \n
Vector size is `[n x 1]`. \n
Memory must be allocated. \n
\note
Pointer `y` can be equal to `x`.
Velues of vector `x` will be rewritten in this case. \n
\n
\return
`RES_OK` if function returns successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int array_scale_lin(double* x, int n,
double xmin, double xmax, double dx,
double h, double* y)
\brief Линейное растяжение вектора данных `x`
Функция производит преобразование значений \f$x(i)\f$, \f$i = 0,1,\ldots n\f$
в значения \f$y(i)\f$, в соответствии с формулой:
\f[
y(i) = k_x x(i) + d_x, \qquad k_x =
\frac{h}{x_{\textrm{max}} - x_{\textrm{min}}}.
\f]
Таким образом, все значения входного вектора `x` в диапазоне от
\f$x_{\textrm{min}}\f$ до \f$x_{\textrm{max}}\f$, линейно растягиваются в
значения вектора `y` в диапазоне от \f$d_x\f$ до \f$h + d_x\f$.
Заметим, что \f$d_x\f$ задает линейное смещение значений вектора `y`.
Данная функция удобна для перевода величин разных размерностей, в частности,
для переноса значений вектора `x` на график высоты `h`, где высота может
быть задана в количестве пикселей, в сантиметрах и т.д.
\param[in] x
Указатель на вектор входных значений `x`. \n
Размер вектора `[n x 1]`. \n
\n
\param[in] n
Размер вектора `x`. \n
\n
\param[in] xmin
Нижняя граница диапазона трансформации. \n
\n
\param[in] xmax
Верхняя граница диапазона трансформации. \n
Значение `xmax` должно быть строго больше значения `xmin`. \n
\n
\param[in] dx
Смещение после трансформации. \n
Данный параметр должен иметь размерность выходного вектора `y`. \n
\n
\param[in] h
Диапазон значений вектора `y` после трансформации от `dx` до `h+dx`. \n
\n
\param[out] y
Указатель на вектора данных после трансформации. \n
Размер вектора `[n x 1]`. \n
Память должна быть выделена. \n
\note
Указатель `y` может совпадать с `x`, в этом случае,
данные вектора `x` будут перезаписаны линейно измененными в соответствии
с формулой выше. \n
\n
\return
`RES_OK` если функция выполнена успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
\author
Бахурин Сергей
www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API array_scale_lin(double* x, int n,
double xmin, double xmax, double dx,
double h, double* y)
{
double kx;
int k;
if(!x)
return ERROR_PTR;
if(n < 1)
return ERROR_SIZE;
if(h<0.0)
return ERROR_NEGATIVE;
if(xmin >= xmax)
return ERROR_MIN_MAX;
kx = h / (xmax - xmin);
for(k = 0; k < n; k++)
y[k] = (x[k] - xmin) * kx + dx;
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,160 @@
/*
* Copyright (c) 2015-2020 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int concat(void* a, size_t na, void* b, size_t nb, void* c)
\brief
Concatenate arrays `a` and `b`
Let's arrays `a` and `b` are vectors: \n
`a = [a(0), a(1), ... a(na-1)]`, \n
`b = [b(0), b(1), ... b(nb-1)]`, \n
concatenation of these arrays will be array `c` size `na+nb`: \n
`c = [a(0), a(1), ... a(na-1), b(0), b(1), ... b(nb-1)]`.
\param[in] a
Pointer to the first array `a`. \n
Array `a` size is `na` bytes. \n
\n
\param[in] na
Array `a` size (bytes). \n
\n
\param[in] b
Pointer to the second array `b`. \n
Array `b` size is `nb` bytes. \n
\n
\param[in] nb
Array `a` size (bytes). \n
\n
\param[out] c
Pointer to the concatenation result array `c`. \n
Array `c` size is `na + nb` bytes. \n
Memory must be allocated. \n
\n
\return
`RES_OK` if function returns successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
Function uses pointer type `void*` and can be useful for an arrays
concatenation with different types. \n
For example two `double` arrays concatenation:
\code{.cpp}
double a[3] = {1.0, 2.0, 3.0};
double b[2] = {4.0, 5.0};
double c[5];
concat((void*)a, 3*sizeof(double), (void*)b, 2*sizeof(double), (void*)c);
\endcode
Vector `c` keeps follow data:
\verbatim
c = [1.0, 2.0, 3.0, 4.0, 5.0]
\endverbatim
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int concat(void* a, size_t na, void* b, size_t nb, void* c)
\brief Конкатенация двух массивов данных
Функция производит конкатенацию двух массивов. Пусть массивы `a` и `b`
заданы как векторы: \n
`a = [a(0), a(1), ... a(na-1)]`, \n
`b = [b(0), b(1), ... b(nb-1)]`, \n
тогда результатом конкатенации будет вектор размера `na+nb` вида: \n
`c = [a(0), a(1), ... a(na-1), b(0), b(1), ... b(nb-1)]`.
\param[in] a
Указатель на первый вектор `a`. \n
Размер вектора `na` байт. \n \n
\param[in] na
Размер первого вектора `a` в байт. \n \n
\param[in] b
Указатель на второй вектор `b`. \n
Размер памяти вектора `nb` байт. \n \n
\param[in] nb
Размер второго вектора `b` в байт. \n \n
\param[out] c
Указатель на вектор конкатенации `c`. \n
Размер памяти вектора `na + nb` байт. \n
Память должна быть выделена. \n \n
\return
`RES_OK` если функция выполнена успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
\note
Функция использует указатели типа `void*` и может быть использована для
конкатенации данных различного типа. \n
Например конкатенация массивов типа `double`:
\code{.cpp}
double a[3] = {1.0, 2.0, 3.0};
double b[2] = {4.0, 5.0};
double c[5];
concat((void*)a, 3*sizeof(double), (void*)b, 2*sizeof(double), (void*)c);
\endcode
в результате вектор `c` будет хранить массив данных:
\verbatim
c = [1.0, 2.0, 3.0, 4.0, 5.0]
\endverbatim
\author
Бахурин Сергей
www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API concat(void* a, size_t na, void* b, size_t nb, void* c)
{
if(!a || !b || !c || c == b)
return ERROR_PTR;
if(na < 1 || nb < 1)
return ERROR_SIZE;
if(c != a)
memcpy(c, a, na);
memcpy((char*)c+na, b, nb);
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,162 @@
/*
* Copyright (c) 2015-2020 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int decimate(double* x, int n, int d, double* y, int* cnt)
\brief
Real vector decimation
Function `d` times decimates real vector `x`. \n
Output vector `y` keeps values corresponds to:
`y(k) = x(k*d), k = 0...n/d-1` \n
\param[in] x
Pointer to the input real vector `x`. \n
Vector `x` size is `[n x 1]`. \n \n
\param[in] n
Size of input vector `x`. \n \n
\param[in] d
Decimation coefficient. \n
Each d-th vector will be copy from vector `x` to the
output vector `y`. \n \n
\param[out] y
Pointer to the output decimated vector `y`. \n
Output vector size is `[n/d x 1]` will be copy
to the address `cnt`. \n
\param[out] cnt
Address which will keep decimated vector `y` size. \n
Pointer can be `NULL`, vector `y` will not return
in this case. \n \n
\return
`RES_OK` if function calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
Two-times decimation example:
\code{.cpp}
double x[10] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
double y[5];
int d = 2;
int cnt;
decimate(x, 10, d, y, &cnt);
\endcode
As result variable `cnt` will be written value 5 and
vector `y` will keep array:
\verbatim
c = [0.0, 2.0, 4.0, 6.0, 8.0]
\endverbatim
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int decimate(double* x, int n, int d, double* y, int* cnt)
\brief Децимация вещественного вектора данных
Функция производит децимацию вещественного вектора `x` в `d` раз. \n
В результате выходной вектор `y` содержит значения:
`y(k) = x(k*d), k = 0...n/d-1` \n
\param[in] x
Указатель на вектор входных данных `x`. \n
Размер вектора `[n x 1]`. \n \n
\param[in] n
Размер входного вектора `x`. \n \n
\param[in] d
Коэффициент децимации. \n
В результате децимации из вектора `x` будет взять каждый
d-й элемент. \n \n
\param[out] y
Указатель на децимированный вектор `y`. \n
Размер выходного вектора равен `[n/d x 1]`
будет сохранен по адресу `cnt`. \n
Память должна быть выделена. \n \n
\param[out] cnt
Указатель переменную, в которую будет сохранен
размер выходного вектора после децимации. \n
Указатель может быть `NULL`, в этом случае
размер вектора `y` не возвращается. \n \n
\return
`RES_OK` если функция выполнена успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
Пример децимации вещественного массива данных в 2 раза:
\code{.cpp}
double x[10] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
double y[5];
int d = 2;
int cnt;
decimate(x, 10, d, y, &cnt);
\endcode
В результате в переменную `cnt` будет записан размер 5,
а вектор `y` будет хранить массив данных:
\verbatim
c = [0.0, 2.0, 4.0, 6.0, 8.0]
\endverbatim
\author
Бахурин Сергей
www.dsplib.org
**************************************************************************** */
#endif
int DSPL_API decimate(double* x, int n, int d, double* y, int* cnt)
{
int k = 0, i = 0;
if(!x || !y)
return ERROR_PTR;
if(n < 1)
return ERROR_SIZE;
if(d < 1)
return ERROR_NEGATIVE;
k = i = 0;
while(k + d <= n)
{
y[i] = x[k];
k+=d;
i++;
}
if(cnt)
*cnt = i;
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,167 @@
/*
* Copyright (c) 2015-2020 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int decimate_cmplx(complex_t* x, int n, int d, complex_t* y, int* cnt)
\brief
Complex vector decimation
Function `d` times decimates a complex vector `x`. \n
Output vector `y` keeps values corresponds to:
`y(k) = x(k*d), k = 0...n/d-1` \n
\param[in] x
Pointer to the input complex vector `x`. \n
Vector `x` size is `[n x 1]`. \n \n
\param[in] n
Size of input vector `x`. \n \n
\param[in] d
Decimation coefficient. \n
Each d-th vector will be copy from vector `x` to the
output vector `y`. \n \n
\param[out] y
Pointer to the output decimated vector `y`. \n
Output vector size is `[n/d x 1]` will be copy
to the address `cnt`. \n
Memory must be allocated. \n \n
\param[out] cnt
Address which will keep decimated vector `y` size. \n
Pointer can be `NULL`, vector `y` will not return
in this case. \n \n
\return
`RES_OK` if function calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
Two-times complex vector decimation example:
\code{.cpp}
compex_t x[10] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0},
{5.0, 5.0}, {6.0, 6.0}, {7.0, 7.0}, {8.0, 8.0}, {9.0, 9.0}};
compex_t y[5];
int d = 2;
int cnt;
decimate_cmplx(x, 10, d, y, &cnt);
\endcode
As result variable `cnt` will be written value 5 and
vector `y` will keep array:
\verbatim
c = [0.0+0.0j, 2.0+2.0j, 4.0+4.0j, 6.0+6.0j, 8.0+8.0j]
\endverbatim
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int decimate_cmplx(complex_t* x, int n, int d, complex_t* y, int* cnt)
\brief Децимация комплексного вектора данных
Функция производит децимацию комплексного вектора `x` в `d` раз. \n
В результате выходной вектор `y` содержит значения:
`y(k) = x(k*d), k = 0...n/d-1` \n
\param[in] x
Указатель на вектор входных данных `x`. \n
Размер вектора `[n x 1]`. \n \n
\param[in] n
Размер входного вектора `x`. \n \n
\param[in] d
Коэффициент децимации. \n
В результате децимации из вектора `x` будет взять каждый d-й элемент. \n \n
\param[out] y
Указатель на децимированный вектор `y`. \n
Размер выходного вектора равен `[n/d x 1]` будет сохранен по адресу `cnt`. \n
Память должна быть выделена. \n \n
\param[out] cnt
Указатель переменную, в которую будет сохранен
размер выходного вектора после децимации. \n
Указатель может быть `NULL`, в этом случае
размер вектора `y` не возвращается. \n \n
\return
`RES_OK` если функция выполнена успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
Пример децимации комплексного массива данных в 2 раза:
\code{.cpp}
compex_t x[10] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0},
{5.0, 5.0}, {6.0, 6.0}, {7.0, 7.0}, {8.0, 8.0}, {9.0, 9.0}};
compex_t y[5];
int d = 2;
int cnt;
decimate_cmplx(x, 10, d, y, &cnt);
\endcode
В результате в переменную `cnt` будет записан размер 5, а вектор `y` будет
хранить массив данных:
\verbatim
c = [0.0+0.0j, 2.0+2.0j, 4.0+4.0j, 6.0+6.0j, 8.0+8.0j]
\endverbatim
\author
Бахурин Сергей
www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API decimate_cmplx(complex_t* x, int n, int d, complex_t* y, int* cnt)
{
int k = 0, i = 0;
if(!x || !y)
return ERROR_PTR;
if(n < 1)
return ERROR_SIZE;
if(d < 1)
return ERROR_NEGATIVE;
k = i = 0;
while(k + d < n)
{
RE(y[i]) = RE(x[k]);
IM(y[i]) = IM(x[k]);
k+=d;
i++;
}
if(cnt)
*cnt = i;
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,58 @@
/*
* Copyright (c) 2015-2020 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
int DSPL_API find_nearest(double* x, int n, double val, int *idx, double* dist)
{
double mind, dv;
int iv, i;
if(!x)
return ERROR_PTR;
if(n < 1)
return ERROR_SIZE;
mind = fabs(x[0] - val);
iv = 0;
for(i = 1; i < n; i++)
{
dv = fabs(x[i] - val);
if( dv < mind)
{
mind = dv;
iv = i;
}
}
if(idx)
*idx = iv;
if(dist)
*dist = fabs(x[iv] - val);
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,151 @@
/*
* Copyright (c) 2015-2020 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int flipip(double* x, int n)
\brief
Flip real vector `x` in place
Function flips real vector `x` length `n` in the memory. \n
For example real vector `x` length 6:\n
\verbatim
x = [0, 1, 2, 3, 4, 5]
\endverbatim
After flipping it will be as follow:
\verbatim
x = [5, 4, 3, 2, 1, 0]
\endverbatim
\param[in, out] x
Pointer to the real vector `x`. \n
Vector size is `[n x 1]`. \n
Flipped vector will be on the same address. \n
\n
\param[in] n
Length of the vector `x`. \n
\n
\return
`RES_OK` if function returns successfully. \n
Else \ref ERROR_CODE_GROUP "error code".
Example:
\code{.cpp}
double x[5] = {0.0, 1.0, 2.0, 3.0, 4.0};
int i;
for(i = 0; i < 5; i++)
printf("%6.1f ", x[i]);
flipip(x, 5);
printf("\n");
for(i = 0; i < 5; i++)
printf("%6.1f ", x[i]);
\endcode
\n
Program result:
\verbatim
0.0 1.0 2.0 3.0 4.0
4.0 3.0 2.0 1.0 0.0
\endverbatim
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int flipip(double* x, int n)
\brief Функция отражения вещественного вектора `x`
Функция производит отражение вещественного вектора длины `n`
в памяти данных. \n
Например исходный вектор `x` длины 6: \n
\verbatim
x = [0, 1, 2, 3, 4, 5]
\endverbatim
После отражения вектор `x` будет иметь вид:
\verbatim
x = [5, 4, 3, 2, 1, 0]
\endverbatim
\param[in, out] x
Указатель на вещественный вектор `x`. \n
Размер вектора `[n x 1]`. \n
Результат отражения будет помещен по этому же адресу. \n
\param[in] n
Размер вектора `x`. \n \n
\return
`RES_OK` если функция выполнена успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
Пример:
\code{.cpp}
double x[5] = {0.0, 1.0, 2.0, 3.0, 4.0};
int i;
for(i = 0; i < 5; i++)
printf("%6.1f ", x[i]);
flipip(x, 5);
printf("\n");
for(i = 0; i < 5; i++)
printf("%6.1f ", x[i]);
\endcode
\n
Результат выполнения:
\verbatim
0.0 1.0 2.0 3.0 4.0
4.0 3.0 2.0 1.0 0.0
\endverbatim
\author
Бахурин Сергей
www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API flipip(double* x, int n)
{
int k;
double tmp;
if(!x)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
for(k = 0; k < n/2; k++)
{
tmp = x[k];
x[k] = x[n-1-k];
x[n-1-k] = tmp;
}
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,155 @@
/*
* Copyright (c) 2015-2020 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int flipip_cmplx(complex_t* x, int n)
\brief Flip complex vector `x` in place
Function flips complex vector `x` length `n` in the memory
\n
For example complex vector `x` length 6: \n
\verbatim
x = [0+0j, 1+1j, 2+2j, 3+3j, 4+4j, 5+5j]
\endverbatim
After flipping it will be as follow:
\verbatim
x = [5+5j, 4+4j, 3+3j, 2+2j, 1+1j, 0+0j]
\endverbatim
\param[in, out] x
Pointer to the complex vector `x`. \n
Vector size is `[n x 1]`. \n
Flipped vector will be on the same address. \n
\param[in] n
Length of the vector `x`. \n \n
\return
`RES_OK` if function returns successfully. \n
Else \ref ERROR_CODE_GROUP "error code".
Example:
\code{.cpp}
complex_t y[5] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}};
for(i = 0; i < 5; i++)
printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
flipip_cmplx(y, 5);
printf("\n");
for(i = 0; i < 5; i++)
printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
\endcode
\n
Program result:
\verbatim
0.0+0.0j 1.0+1.0j 2.0+2.0j 3.0+3.0j 4.0+4.0j
4.0+4.0j 3.0+3.0j 2.0+2.0j 1.0+1.0j 0.0+0.0j
\endverbatim
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int flipip_cmplx(complex_t* x, int n)
\brief Функция отражения комплексного вектора `x`
Функция производит отражение комплексного вектора длины `n`
в памяти данных. \n
Например исходный вектор `x` длины 6: \n
\verbatim
x = [0+0j, 1+1j, 2+2j, 3+3j, 4+4j, 5+5j]
\endverbatim
После отражения вектор `x` будет иметь вид:
\verbatim
x = [5+5j, 4+4j, 3+3j, 2+2j, 1+1j, 0+0j]
\endverbatim
\param[in, out] x
Указатель на комплексный вектор `x`. \n
Размер вектора `[n x 1]`. \n
Результат отражения будет помещен по этому же адресу. \n
\n
\param[in] n
Размер вектора `x`. \n
\n
\return
`RES_OK` если функция выполнена успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
Пример:
\code{.cpp}
complex_t y[5] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}};
for(i = 0; i < 5; i++)
printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
flipip_cmplx(y, 5);
printf("\n");
for(i = 0; i < 5; i++)
printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
\endcode
\n
Результат выполнения:
\verbatim
0.0+0.0j 1.0+1.0j 2.0+2.0j 3.0+3.0j 4.0+4.0j
4.0+4.0j 3.0+3.0j 2.0+2.0j 1.0+1.0j 0.0+0.0j
\endverbatim
\author
Бахурин Сергей
www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API flipip_cmplx(complex_t* x, int n)
{
int k;
complex_t tmp;
if(!x)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
for(k = 0; k < n/2; k++)
{
RE(tmp) = RE(x[k]);
RE(x[k]) = RE(x[n-1-k]);
RE(x[n-1-k]) = RE(tmp);
IM(tmp) = IM(x[k]);
IM(x[k]) = IM(x[n-1-k]);
IM(x[n-1-k]) = IM(tmp);
}
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,199 @@
/*
* Copyright (c) 2015-2020 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int linspace(double x0, double x1, int n, int type, double* x)
\brief Function fills a vector with `n` linearly spaced elements
between `x0` and `x1`.
Function supports two kinds of filling according to `type` parameter: \n
Symmetric fill (parameter `type=DSPL_SYMMETRIC`): \n
\f$x(k) = x_0 + k \cdot dx\f$,
\f$dx = \frac{x_1 - x_0}{n-1}\f$, \f$k = 0 \ldots n-1.\f$
Periodic fill (parameter `type=DSPL_PERIODIC`): \n
\f$x(k) = x_0 + k \cdot dx\f$,
\f$dx = \frac{x_1 - x_0}{n}\f$, \f$k = 0 \ldots n-1.\f$
\param[in] x0
Start point \f$x_0\f$. \n \n
\param[in] x1
End point \f$x_1\f$. \n \n
\param[in] n
Number of points `x` (size of vector `x`). \n \n
\param[in] type
Fill type: \n
`DSPL_SYMMETRIC` --- symmetric, \n
`DSPL_PERIODIC` --- periodic. \n \n
\param[in,out] x
Pointer to the output linearly spaced vector `x`. \n
Vector size is `[n x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if function returns successfully. \n
Else \ref ERROR_CODE_GROUP "error code".
\note
Difference between symmetric and periodic filling we can
understand from the follow examples. \n
Example 1. Periodic fill.
double x[5];
linspace(0, 5, 5, DSPL_PERIODIC, x);
\endcode
Values in the vector `x` are:
\verbatim
0, 1, 2, 3, 4
\endverbatim
\n \n
Example 2. Symmetric fill.
\code{.cpp}
double x[5];
linspace(0, 5, 5, DSPL_SYMMETRIC, x);
\endcode
Values in the vector `x` are:
\verbatim
0, 1.25, 2.5, 3.75, 5
\endverbatim
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int linspace(double x0, double x1, int n, int type, double* x)
\brief Функция заполняет массив линейно-нарастающими, равноотстоящими
значениями от `x0` до `x1`
Заполняет массив `x` длиной `n` значениями в диапазоне
от \f$x_0\f$ до \f$x_1\f$. Функция поддерживает два типа заполнения
в соответствии с параметром `type`: \n
Симметричное заполнение согласно выражению (параметр `type=DSPL_SYMMETRIC`): \n
\f$x(k) = x_0 + k \cdot dx\f$,
\f$dx = \frac{x_1 - x_0}{n-1}\f$, \f$k = 0 \ldots n-1.\f$
Периодическое заполнение (параметр `type=DSPL_PERIODIC`) согласно выражению: \n
\f$x(k) = x_0 + k \cdot dx\f$,
\f$dx = \frac{x_1 - x_0}{n}\f$, \f$k = 0 \ldots n-1.\f$
\param[in] x0
Начальное показателя \f$x_0\f$. \n \n
\param[in] x1
Конечное значение \f$x_1\f$. \n \n
\param[in] n
Количество точек массива `x`. \n \n
\param[in] type
Тип заполнения: \n
`DSPL_SYMMETRIC` --- симметричное заполнение, \n
`DSPL_PERIODIC` --- периодическое заполнение. \n \n
\param[in,out] x
Указатель на вектор равноотстоящих значений . \n
Размер вектора `[n x 1]`. \n
Память должна быть выделена. \n \n
\return
`RES_OK` --- функция выполнена успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
\note
Отличие периодического и симметричного заполнения можно
понять из следующих примеров. \n
Пример 1. Периодическое заполнение.
\code{.cpp}
double x[5];
linspace(0, 5, 5, DSPL_PERIODIC, x);
\endcode
В массиве `x` будут лежать значения:
\verbatim
0, 1, 2, 3, 4
\endverbatim
\n \n
Пример 2. Симметричное заполнение.
\code{.cpp}
double x[5];
linspace(0, 5, 5, DSPL_SYMMETRIC, x);
\endcode
В массиве `x` будут лежать значения:
\verbatim
0, 1.25, 2.5, 3.75, 5
\endverbatim
\author
Бахурин Сергей
www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API linspace(double x0, double x1, int n, int type, double* x)
{
double dx;
int k;
if(n < 2)
return ERROR_SIZE;
if(!x)
return ERROR_PTR;
switch (type)
{
case DSPL_SYMMETRIC:
dx = (x1 - x0)/(double)(n-1);
x[0] = x0;
for(k = 1; k < n; k++)
x[k] = x[k-1] + dx;
break;
case DSPL_PERIODIC:
dx = (x1 - x0)/(double)n;
x[0] = x0;
for(k = 1; k < n; k++)
x[k] = x[k-1] + dx;
break;
default:
return ERROR_SYM_TYPE;
}
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,211 @@
/*
* Copyright (c) 2015-2020 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int logspace(double x0, double x1, int n, int type, double* x)
\brief Function fills a vector with `n` logarithmically spaced elements
between \f$10^{x_0}\f$ and \f$10^{x_1}\f$.
Function supports two kinds of filling according to `type` parameter: \n
Symmetric fill (parameter `type=DSPL_SYMMETRIC`): \n
\f$x(k) = 10^{x_0} \cdot dx^k\f$, here \f$dx = \sqrt[n-1]{10^{x_1 - x_0}}\f$,
\f$k = 0 \ldots n-1.\f$
Periodic fill (parameter `type=DSPL_PERIODIC`): \n
\f$x(k) = 10^{x_0} \cdot dx^k\f$, here \f$dx = \sqrt[n]{10^{x_1 - x_0}}\f$,
\f$k = 0 \ldots n-1.\f$ \n
\param[in] x0
Start exponent value \f$x_0\f$. \n \n
\param[in] x1
End exponent value \f$x_1\f$. \n \n
\param[in] n
Number of points `x` (size of vector `x`). \n \n
\param[in] type
Fill type: \n
`DSPL_SYMMETRIC` --- symmetric, \n
`DSPL_PERIODIC` --- periodic. \n \n
\param[in,out] x
Pointer to the output logarithmically spaced vector `x` . \n
Vector size is `[n x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if function returns successfully. \n
Else \ref ERROR_CODE_GROUP "error code".
\note
Difference between symmetric and periodic filling we can
understand from the follow examples. \n
Example 1. Periodic fill.
\code{.cpp}
double x[5];
logspace(-2, 3, 5, DSPL_PERIODIC, x);
\endcode
Values in the vector `x` are:
\verbatim
0.01, 0.1, 1, 10, 100
\endverbatim
\n \n
Example 2. Symmetric fill.
\code{.cpp}
double x[5];
logspace(-2, 3, 5, DSPL_SYMMETRIC, x);
\endcode
Values in the vector `x` are:
\verbatim
0.01 0.178 3.162 56.234 1000
\endverbatim
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int logspace(double x0, double x1, int n, int type, double* x)
\brief Функция заполняет массив значениями логарифмической шкале
Заполняет массив `x` длиной `n` значениями в диапазоне
от \f$10^{x_0}\f$ до \f$10^{x_1}\f$. \n
Функция поддерживает два типа заполнения в соответствии с параметром `type`: \n
Симметричное заполнение согласно выражению: \n
\f$x(k) = 10^{x_0} \cdot dx^k\f$, где \f$dx = \sqrt[n-1]{10^{x_1 - x_0}}\f$,
\f$k = 0 \ldots n-1.\f$
Периодическое заполнение согласно выражению:
\f$x(k) = 10^{x_0} \cdot dx^k\f$, где \f$dx = \sqrt[n]{10^{x_1 - x_0}}\f$,
\f$k = 0 \ldots n-1.\f$ \n
\param[in] x0
Начальное значение показателя \f$x_0\f$. \n \n
\param[in] x1
Конечное значение показателя \f$x_1\f$. \n \n
\param[in] n
Количество точек массива `x`. \n \n
\param[in] type
Тип заполнения: \n
`DSPL_SYMMETRIC` --- симметричное заполнение, \n
`DSPL_PERIODIC` --- периодическое заполнение. \n \n
\param[in,out] x
Указатель на вектор значений в логарифмической шкале. \n
Размер вектора `[n x 1]`. \n
Память должна быть выделена. \n \n
\return
`RES_OK` --- функция выполнена успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
\note
Отличие периодического и симметричного заполнения можно
понять из следующих примеров. \n
Пример 1. Периодическое заполнение.
\code{.cpp}
double x[5];
logspace(-2, 3, 5, DSPL_PERIODIC, x);
\endcode
В массиве `x` будут лежать значения:
\verbatim
0.01, 0.1, 1, 10, 100
\endverbatim
\n \n
Пример 2. Симметричное заполнение.
\code{.cpp}
double x[5];
logspace(-2, 3, 5, DSPL_SYMMETRIC, x);
\endcode
В массиве `x` будут лежать значения:
\verbatim
0.01 0.178 3.162 56.234 1000
\endverbatim
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API logspace(double x0, double x1, int n, int type, double* x)
{
double mx, a, b;
int k;
if(n < 2)
return ERROR_SIZE;
if(!x)
return ERROR_PTR;
a = pow(10.0, x0);
b = pow(10.0, x1);
switch (type)
{
case DSPL_SYMMETRIC:
mx = pow(b/a, 1.0/(double)(n-1));
x[0] = a;
for(k = 1; k < n; k++)
x[k] = x[k-1] * mx;
break;
case DSPL_PERIODIC:
mx = pow(b/a, 1.0/(double)n);
x[0] = a;
for(k = 1; k < n; k++)
x[k] = x[k-1] * mx;
break;
default:
return ERROR_SYM_TYPE;
}
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,113 @@
/*
* Copyright (c) 2015-2020 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int ones(double* x, int n)
\brief Function fills all real vector `x` by ones values.
\param[in, out] x
Pointer to the vector `x`. \n
Vector size is `[n x 1]`. \n
All elements on this vector will be set to one. \n
\n
\param[in] n
Size of vector `x`. \n
\n
\return
`RES_OK` if function returns successfully. \n
Else \ref ERROR_CODE_GROUP "error code".
Example:
\code{.cpp}
double y[5] = {0};
int i;
ones(y, 5);
for(i = 0; i < 5; i++)
printf("%6.1f% ", y[i]);
\endcode
\n
Vector `y` values are:
\verbatim
1.0 1.0 1.0 1.0 1.0
\endverbatim
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int ones(double* x, int n)
\brief Функция заполнения вещественного массива единицами
\param[in, out] x
Указатель на вещественный вектор `x`. \n
Размер вектора `[n x 1]`. \n
Значения данного вектора будут установлены в единицу. \n
\n
\param[in] n
Размер вектора `x`. \n
\n
\return
`RES_OK` если функция выполнена успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
Пример:
\code{.cpp}
double y[5] = {0};
int i;
ones(y, 5);
for(i = 0; i < 5; i++)
printf("%6.1f% ", y[i]);
\endcode
\n
Результат выполнения:
\verbatim
1.0 1.0 1.0 1.0 1.0
\endverbatim
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API ones(double* x, int n)
{
int i;
if(!x)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
for(i = 0; i < n; i++)
x[i] = 1.0;
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,56 @@
/*
* Copyright (c) 2015-2020 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int sum(double* x, int n, double* s)
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int sum(double* x, int n, double* s)
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API sum(double* x, int n, double* s)
{
int i;
double z = 0.0;
if(!x || !s)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
for(i = 0; i < n; i++)
z += x[i];
*s = z;
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,55 @@
/*
* Copyright (c) 2015-2020 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int sum(double* x, int n, double* s)
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup ARRAY_GROUP
\fn int sum(double* x, int n, double* s)
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API sum_sqr(double* x, int n, double* s)
{
int i;
double z = 0.0;
if(!x || !s)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
for(i = 0; i < n; i++)
z += x[i]*x[i];
*s = z;
return RES_OK;
}

Wyświetl plik

@ -1,532 +1,53 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
Discrete Fourier Transform Algorithms
*/
#include "dft/dft.c"
#include "dft/dft_cmplx.c"
#include "dft/idft_cmplx.c"
/*
Fast Fourier Transform Algrithms
*/
#include "dft/fft.c"
#include "dft/fft_abs.c"
#include "dft/fft_abs_cmplx.c"
#include "dft/fft_cmplx.c"
#include "dft/fft_create.c"
#include "dft/fft_free.c"
#include "dft/fft_krn.c"
#include "dft/fft_mag.c"
#include "dft/fft_mag_cmplx.c"
#include "dft/fft_shift.c"
#include "dft/fft_shift_cmplx.c"
#include "dft/fft_subkernel.c"
#include "dft/ifft_cmplx.c"
#include <stdlib.h>
#include <math.h>
#include "dspl.h"
/*
Goertzel Algorithm
*/
#include "dft/goertzel.c"
#include "dft/goertzel_cmplx.c"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int dft(double* x, int n, complex_t* y)
\brief Discrete Fourier transform of a real signal.
/*
Fourier Series and Fourier Intergral
*/
#include "dft/fourier_series_dec.c"
#include "dft/fourier_series_dec_cmplx.c"
#include "dft/fourier_integral_cmplx.c"
#include "dft/fourier_series_rec.c"
The function calculates the \f$ n \f$ -point discrete Fourier transform
real signal \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]
where \f$ k = 0 \ldots n-1 \f$.
\param [in] x
Pointer to the vector of the real input signal \f$ x (m) \f$,
\f$ m = 0 \ldots n-1 \f$. \n
The size of the vector is `[n x 1]`. \n \n
\param [in] n
The size of the DFT \f$ n \f$
(the size of the vectors of the input signal and the result of the DFT). \n \n
\param [out] y
Pointer to the complex vector of the DFT result \f$ Y (k) \f$,
\f$ k = 0 \ldots n-1 \f$.
The size of the vector is `[n x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if the DFT is calculated successfully. \n
Otherwise, \ref ERROR_CODE_GROUP "error code".
An example of using the `dft` function:
\include dft_test.c
The result of the program:
\verbatim
y [0] = 120.000 0.000
y [1] = -8.000 40.219
y [2] = -8.000 19.314
y [3] = -8.000 11.973
y [4] = -8.000 8.000
y [5] = -8.000 5.345
y [6] = -8.000 3.314
y [7] = -8.000 1.591
y [8] = -8.000 0.000
y [9] = -8.000 -1.591
y [10] = -8.000 -3.314
y [11] = -8.000 -5.345
y [12] = -8.000 -8.000
y [13] = -8.000 -11.973
y [14] = -8.000 -19.314
y [15] = -8.000 -40.219
\endverbatim
\note
This function performs the DFT calculation using the naive method and
requires \f$ n ^ 2 \f$ complex multiplications. \n
To increase the calculation speed, it is recommended to use
fast Fourier transform algorithms.
\author Bakhurin Sergey www.dsplib.org
**************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int dft(double* x, int n, 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 \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 "код ошибки".
Пример использования функции `dft`:
\include dft_test.c
Результат работы программы:
\verbatim
y[ 0] = 120.000 0.000
y[ 1] = -8.000 40.219
y[ 2] = -8.000 19.314
y[ 3] = -8.000 11.973
y[ 4] = -8.000 8.000
y[ 5] = -8.000 5.345
y[ 6] = -8.000 3.314
y[ 7] = -8.000 1.591
y[ 8] = -8.000 0.000
y[ 9] = -8.000 -1.591
y[10] = -8.000 -3.314
y[11] = -8.000 -5.345
y[12] = -8.000 -8.000
y[13] = -8.000 -11.973
y[14] = -8.000 -19.314
y[15] = -8.000 -40.219
\endverbatim
\note
Данная функция выполняет расчет ДПФ наивным методом и требует \f$ n^2 \f$
комплексных умножений. \n
Для увеличения скорости расчета рекомендуется использовать
алгоритмы быстрого преобразования Фурье.
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API dft(double* x, int n, complex_t* y)
{
int k;
int m;
double divn;
double phi;
if(!x || !y)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
divn = 1.0 / (double)n;
for(k = 0; k < n; k++)
{
RE(y[k]) = IM(y[k]) = 0.0;
for(m = 0; m < n; m++)
{
phi = -M_2PI * divn * (double)k * (double)m;
RE(y[k]) += x[m] * cos(phi);
IM(y[k]) += x[m] * sin(phi);
}
}
return RES_OK;
}
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int dft_cmplx(complex_t* x, int n, complex_t* y)
\brief Discrete Fourier transform of a complex signal.
The function calculates the \f$ n \f$ -point discrete Fourier transform
complex signal \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]
where \f$ k = 0 \ldots n-1 \f$.
\param [in] x
Pointer to a vector of complex
input signal \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
The size of the vector is `[n x 1]`. \n \n
\param [in] n
The size of the DFT \f$ n \f$
(the size of the vectors of the input signal and the result of the DFT). \n \n
\param [out] y
Integrated Vector Pointer
DFT result \f$ Y (k) \f$, \f$ k = 0 \ldots n-1 \f$. \n
The size of the vector is `[n x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if the DFT is calculated successfully. \n
Otherwise, \ref ERROR_CODE_GROUP "error code".
An example of using the `dft_cmplx` function:
\include dft_cmplx_test.c
The result of the program:
\verbatim
y [0] = 120.000 0.000
y [1] = -8.000 40.219
y [2] = -8.000 19.314
y [3] = -8.000 11.973
y [4] = -8.000 8.000
y [5] = -8.000 5.345
y [6] = -8.000 3.314
y [7] = -8.000 1.591
y [8] = -8.000 0.000
y [9] = -8.000 -1.591
y [10] = -8.000 -3.314
y [11] = -8.000 -5.345
y [12] = -8.000 -8.000
y [13] = -8.000 -11.973
y [14] = -8.000 -19.314
y [15] = -8.000 -40.219
\endverbatim
\note
This function performs the calculation of the DFT by the naive method
and requires \f$ n ^ 2 \f$ complex multiplications. \n
To increase the calculation speed, it is recommended
use fast Fourier transform algorithms.
\author Bakhurin Sergey www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int dft_cmplx(complex_t* x, int n, 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 \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 "код ошибки".
Пример использования функции `dft_cmplx`:
\include dft_cmplx_test.c
Результат работы программы:
\verbatim
y[ 0] = 120.000 0.000
y[ 1] = -8.000 40.219
y[ 2] = -8.000 19.314
y[ 3] = -8.000 11.973
y[ 4] = -8.000 8.000
y[ 5] = -8.000 5.345
y[ 6] = -8.000 3.314
y[ 7] = -8.000 1.591
y[ 8] = -8.000 0.000
y[ 9] = -8.000 -1.591
y[10] = -8.000 -3.314
y[11] = -8.000 -5.345
y[12] = -8.000 -8.000
y[13] = -8.000 -11.973
y[14] = -8.000 -19.314
y[15] = -8.000 -40.219
\endverbatim
\note
Данная функция выполняет расчет ДПФ наивным методом
и требует \f$ n^2 \f$ комплексных умножений. \n
Для увеличения скорости расчета рекомендуется
использовать алгоритмы быстрого преобразования Фурье.
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API dft_cmplx(complex_t* x, int n, complex_t* y)
{
int k;
int m;
double divn;
double phi;
complex_t e;
if(!x || !y)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
divn = 1.0 / (double)n;
for(k = 0; k < n; k++)
{
RE(y[k]) = IM(y[k]) = 0.0;
for(m = 0; m < n; m++)
{
phi = -M_2PI * divn * (double)k * (double)m;
RE(e) = cos(phi);
IM(e) = sin(phi);
RE(y[k]) += CMRE(x[m], e);
IM(y[k]) += CMIM(x[m], e);
}
}
return RES_OK;
}
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int idft_cmplx(complex_t* x, int n, complex_t* y)
\brief Inverse discrete Fourier transform of the complex spectrum.
The function calculates the \f$ n \f$ -point inverse discrete transform
Fourier complex spectrum \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]
where \f$ k = 0 \ldots n-1 \f$.
\param [in] x
Pointer to the vector of the input complex signal spectrum \f$ x (m) \f$,
\f$ m = 0 \ldots n-1 \f$. \n
The size of the vector is `[n x 1]`. \n \n
\param [in] n
The size of the ODPF \f$ n \f$
(the size of the vectors of the input spectrum and the result of the ODPF). \n
\n
\param [out] y
Pointer to the complex vector of the ODPF result \f$ y (k) \f$,
\f$ k = 0 \ldots n-1 \f$.
The size of the vector is `[n x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if the ODPF is calculated successfully. \n
Otherwise, \ref ERROR_CODE_GROUP "error code".
An example of using the `dft_cmplx` function:
\include idft_cmplx_test.c
The result of the program:
\verbatim
x [0] = 0.000 + 0.000j, z [0] = 0.000 -0.000
x [1] = 1.000 + 0.000j, z [1] = 1.000 -0.000
x [2] = 2.000 + 0.000j, z [2] = 2.000 -0.000
x [3] = 3.000 + 0.000j, z [3] = 3.000 -0.000
x [4] = 4.000 + 0.000j, z [4] = 4.000 -0.000
x [5] = 5.000 + 0.000j, z [5] = 5.000 -0.000
x [6] = 6.000 + 0.000j, z [6] = 6.000 -0.000
x [7] = 7.000 + 0.000j, z [7] = 7.000 -0.000
x [8] = 8.000 + 0.000j, z [8] = 8.000 -0.000
x [9] = 9.000 + 0.000j, z [9] = 9.000 -0.000
x [10] = 10.000 + 0.000j, z [10] = 10.000 -0.000
x [11] = 11.000 + 0.000j, z [11] = 11.000 +0.000
x [12] = 12.000 + 0.000j, z [12] = 12.000 +0.000
x [13] = 13.000 + 0.000j, z [13] = 13.000 +0.000
x [14] = 14.000 + 0.000j, z [14] = 14.000 +0.000
x [15] = 15.000 + 0.000j, z [15] = 15.000 -0.000
\endverbatim
\note
This function performs the calculation of the DFT using the naive method.
and requires \f$ n ^ 2 \f$ complex multiplications. \n
To increase the calculation speed, it is recommended
use fast Fourier transform algorithms.
\author Bakhurin Sergey www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int idft_cmplx(complex_t* x, int n, 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 \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 "код ошибки".
Пример использования функции `dft_cmplx`:
\include idft_cmplx_test.c
Результат работы программы:
\verbatim
x[ 0] = 0.000 +0.000j, z[ 0] = 0.000 -0.000
x[ 1] = 1.000 +0.000j, z[ 1] = 1.000 -0.000
x[ 2] = 2.000 +0.000j, z[ 2] = 2.000 -0.000
x[ 3] = 3.000 +0.000j, z[ 3] = 3.000 -0.000
x[ 4] = 4.000 +0.000j, z[ 4] = 4.000 -0.000
x[ 5] = 5.000 +0.000j, z[ 5] = 5.000 -0.000
x[ 6] = 6.000 +0.000j, z[ 6] = 6.000 -0.000
x[ 7] = 7.000 +0.000j, z[ 7] = 7.000 -0.000
x[ 8] = 8.000 +0.000j, z[ 8] = 8.000 -0.000
x[ 9] = 9.000 +0.000j, z[ 9] = 9.000 -0.000
x[10] = 10.000 +0.000j, z[10] = 10.000 -0.000
x[11] = 11.000 +0.000j, z[11] = 11.000 +0.000
x[12] = 12.000 +0.000j, z[12] = 12.000 +0.000
x[13] = 13.000 +0.000j, z[13] = 13.000 +0.000
x[14] = 14.000 +0.000j, z[14] = 14.000 +0.000
x[15] = 15.000 +0.000j, z[15] = 15.000 -0.000
\endverbatim
\note
Данная функция выполняет расчет ОДПФ наивным методом
и требует \f$ n^2 \f$ комплексных умножений. \n
Для увеличения скорости расчета рекомендуется
использовать алгоритмы быстрого преобразования Фурье.
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API idft_cmplx(complex_t* x, int n, complex_t* y)
{
int k;
int m;
double divn;
double phi;
complex_t e;
if(!x || !y)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
divn = 1.0 / (double)n;
for(k = 0; k < n; k++)
{
RE(y[k]) = IM(y[k]) = 0.0;
for(m = 0; m < n; m++)
{
phi = M_2PI * divn * (double)k * (double)m;
RE(e) = cos(phi);
IM(e) = sin(phi);
RE(y[k]) += CMRE(x[m], e);
IM(y[k]) += CMIM(x[m], e);
}
RE(y[k]) /= (double)n;
IM(y[k]) /= (double)n;
}
return RES_OK;
}

192
dspl/src/dft/dft.c 100644
Wyświetl plik

@ -0,0 +1,192 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int dft(double* x, int n, complex_t* y)
\brief Discrete Fourier transform of a real signal.
The function calculates the \f$ n \f$ -point discrete Fourier transform
real signal \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]
where \f$ k = 0 \ldots n-1 \f$.
\param [in] x
Pointer to the vector of the real input signal \f$ x (m) \f$,
\f$ m = 0 \ldots n-1 \f$. \n
The size of the vector is `[n x 1]`. \n \n
\param [in] n
The size of the DFT \f$ n \f$
(the size of the vectors of the input signal and the result of the DFT). \n \n
\param [out] y
Pointer to the complex vector of the DFT result \f$ Y (k) \f$,
\f$ k = 0 \ldots n-1 \f$.
The size of the vector is `[n x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if the DFT is calculated successfully. \n
Otherwise, \ref ERROR_CODE_GROUP "error code".
An example of using the `dft` function:
\include dft_test.c
The result of the program:
\verbatim
y [0] = 120.000 0.000
y [1] = -8.000 40.219
y [2] = -8.000 19.314
y [3] = -8.000 11.973
y [4] = -8.000 8.000
y [5] = -8.000 5.345
y [6] = -8.000 3.314
y [7] = -8.000 1.591
y [8] = -8.000 0.000
y [9] = -8.000 -1.591
y [10] = -8.000 -3.314
y [11] = -8.000 -5.345
y [12] = -8.000 -8.000
y [13] = -8.000 -11.973
y [14] = -8.000 -19.314
y [15] = -8.000 -40.219
\endverbatim
\note
This function performs the DFT calculation using the naive method and
requires \f$ n ^ 2 \f$ complex multiplications. \n
To increase the calculation speed, it is recommended to use
fast Fourier transform algorithms.
\author Bakhurin Sergey www.dsplib.org
**************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int dft(double* x, int n, 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 \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 "код ошибки".
Пример использования функции `dft`:
\include dft_test.c
Результат работы программы:
\verbatim
y[ 0] = 120.000 0.000
y[ 1] = -8.000 40.219
y[ 2] = -8.000 19.314
y[ 3] = -8.000 11.973
y[ 4] = -8.000 8.000
y[ 5] = -8.000 5.345
y[ 6] = -8.000 3.314
y[ 7] = -8.000 1.591
y[ 8] = -8.000 0.000
y[ 9] = -8.000 -1.591
y[10] = -8.000 -3.314
y[11] = -8.000 -5.345
y[12] = -8.000 -8.000
y[13] = -8.000 -11.973
y[14] = -8.000 -19.314
y[15] = -8.000 -40.219
\endverbatim
\note
Данная функция выполняет расчет ДПФ наивным методом и требует \f$ n^2 \f$
комплексных умножений. \n
Для увеличения скорости расчета рекомендуется использовать
алгоритмы быстрого преобразования Фурье.
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API dft(double* x, int n, complex_t* y)
{
int k;
int m;
double divn;
double phi;
if(!x || !y)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
divn = 1.0 / (double)n;
for(k = 0; k < n; k++)
{
RE(y[k]) = IM(y[k]) = 0.0;
for(m = 0; m < n; m++)
{
phi = -M_2PI * divn * (double)k * (double)m;
RE(y[k]) += x[m] * cos(phi);
IM(y[k]) += x[m] * sin(phi);
}
}
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,194 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int dft_cmplx(complex_t* x, int n, complex_t* y)
\brief Discrete Fourier transform of a complex signal.
The function calculates the \f$ n \f$ -point discrete Fourier transform
complex signal \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]
where \f$ k = 0 \ldots n-1 \f$.
\param [in] x
Pointer to a vector of complex
input signal \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
The size of the vector is `[n x 1]`. \n \n
\param [in] n
The size of the DFT \f$ n \f$
(the size of the vectors of the input signal and the result of the DFT). \n \n
\param [out] y
Integrated Vector Pointer
DFT result \f$ Y (k) \f$, \f$ k = 0 \ldots n-1 \f$. \n
The size of the vector is `[n x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if the DFT is calculated successfully. \n
Otherwise, \ref ERROR_CODE_GROUP "error code".
An example of using the `dft_cmplx` function:
\include dft_cmplx_test.c
The result of the program:
\verbatim
y [0] = 120.000 0.000
y [1] = -8.000 40.219
y [2] = -8.000 19.314
y [3] = -8.000 11.973
y [4] = -8.000 8.000
y [5] = -8.000 5.345
y [6] = -8.000 3.314
y [7] = -8.000 1.591
y [8] = -8.000 0.000
y [9] = -8.000 -1.591
y [10] = -8.000 -3.314
y [11] = -8.000 -5.345
y [12] = -8.000 -8.000
y [13] = -8.000 -11.973
y [14] = -8.000 -19.314
y [15] = -8.000 -40.219
\endverbatim
\note
This function performs the calculation of the DFT by the naive method
and requires \f$ n ^ 2 \f$ complex multiplications. \n
To increase the calculation speed, it is recommended
use fast Fourier transform algorithms.
\author Bakhurin Sergey www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int dft_cmplx(complex_t* x, int n, 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 \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 "код ошибки".
Пример использования функции `dft_cmplx`:
\include dft_cmplx_test.c
Результат работы программы:
\verbatim
y[ 0] = 120.000 0.000
y[ 1] = -8.000 40.219
y[ 2] = -8.000 19.314
y[ 3] = -8.000 11.973
y[ 4] = -8.000 8.000
y[ 5] = -8.000 5.345
y[ 6] = -8.000 3.314
y[ 7] = -8.000 1.591
y[ 8] = -8.000 0.000
y[ 9] = -8.000 -1.591
y[10] = -8.000 -3.314
y[11] = -8.000 -5.345
y[12] = -8.000 -8.000
y[13] = -8.000 -11.973
y[14] = -8.000 -19.314
y[15] = -8.000 -40.219
\endverbatim
\note
Данная функция выполняет расчет ДПФ наивным методом
и требует \f$ n^2 \f$ комплексных умножений. \n
Для увеличения скорости расчета рекомендуется
использовать алгоритмы быстрого преобразования Фурье.
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API dft_cmplx(complex_t* x, int n, complex_t* y)
{
int k;
int m;
double divn;
double phi;
complex_t e;
if(!x || !y)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
divn = 1.0 / (double)n;
for(k = 0; k < n; k++)
{
RE(y[k]) = IM(y[k]) = 0.0;
for(m = 0; m < n; m++)
{
phi = -M_2PI * divn * (double)k * (double)m;
RE(e) = cos(phi);
IM(e) = sin(phi);
RE(y[k]) += CMRE(x[m], e);
IM(y[k]) += CMIM(x[m], e);
}
}
return RES_OK;
}

192
dspl/src/dft/fft.c 100644
Wyświetl plik

@ -0,0 +1,192 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "dspl.h"
#include "dspl_internal.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fft(double* x, int n, fft_t* pfft, complex_t* y)
\brief Fast Fourier transform for the real vector.
Function calculated \f$ n \f$-points FFT for the real vector
\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]
here \f$ k = 0 \ldots n-1 \f$.
\param[in] x
Pointer to the input real vector \f$x(m)\f$,
\f$ m = 0 \ldots n-1 \f$. \n
Vector size is `[n x 1]`. \n \n
\param[in] n
FFT size \f$n\f$. \n
FFT size can be composite:
\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
simple number less than 46340
(see \ref fft_create function). \n \n
\param[in] pfft
Pointer to the `fft_t` object. \n
This pointer cannot be `NULL`. \n
Structure \ref fft_t should be previously once
filled with the \ref fft_create function, and the memory should be
cleared before exiting by the \ref fft_free function. \n \n
\param[out] y
Pointer to the FFT result complex vector \f$Y(k)\f$,
\f$ k = 0 \ldots n-1 \f$. \n
Vector size is `[n x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if FFT is calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
Example:
\include fft_test.c
Result:
\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 Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\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
***************************************************************************** */
#endif
int DSPL_API fft(double* x, int n, fft_t* pfft, complex_t* y)
{
int err;
if(!x || !pfft || !y)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
err = fft_create(pfft, n);
if(err != RES_OK)
return err;
re2cmplx(x, n, pfft->t1);
return fft_krn(pfft->t1, y, pfft, n, 0);
}

Wyświetl plik

@ -0,0 +1,87 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "dspl.h"
#include "dspl_internal.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API fft_abs(double* x, int n, fft_t* pfft,
double fs, int flag,
double* mag, double* freq)
{
int k, err = RES_OK;
complex_t *X = NULL;
if(!x || !pfft)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
if(mag)
{
X = (complex_t*)malloc(n*sizeof(complex_t));
err = fft(x, n, pfft, X);
if(err!=RES_OK)
goto error_proc;
for(k = 0; k < n; k++)
mag[k] = ABS(X[k]);
if(flag & DSPL_FLAG_FFT_SHIFT)
{
err = fft_shift(mag, n, mag);
if(err!=RES_OK)
goto error_proc;
}
}
if(freq)
{
if(flag & DSPL_FLAG_FFT_SHIFT)
if(n%2)
err = linspace(-fs*0.5 + fs*0.5/(double)n,
fs*0.5 - fs*0.5/(double)n,
n, DSPL_SYMMETRIC, freq);
else
err = linspace(-fs*0.5, fs*0.5, n, DSPL_PERIODIC, freq);
else
err = linspace(0, fs, n, DSPL_PERIODIC, freq);
}
error_proc:
if(X)
free(X);
return err;
}

Wyświetl plik

@ -0,0 +1,85 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "dspl.h"
#include "dspl_internal.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API fft_abs_cmplx(complex_t* x, int n, fft_t* pfft,
double fs, int flag,
double* mag, double* freq)
{
int k, err = RES_OK;
complex_t *X = NULL;
if(!x || !pfft)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
if(mag)
{
X = (complex_t*)malloc(n*sizeof(complex_t));
err = fft_cmplx(x, n, pfft, X);
if(err!=RES_OK)
goto error_proc;
for(k = 0; k < n; k++)
mag[k] = ABS(X[k]);
if(flag & DSPL_FLAG_FFT_SHIFT)
{
err = fft_shift(mag, n, mag);
if(err!=RES_OK)
goto error_proc;
}
}
if(freq)
{
if(flag & DSPL_FLAG_FFT_SHIFT)
if(n%2)
err = linspace(-fs*0.5 + fs*0.5/(double)n,
fs*0.5 - fs*0.5/(double)n,
n, DSPL_SYMMETRIC, freq);
else
err = linspace(-fs*0.5, fs*0.5, n, DSPL_PERIODIC, freq);
else
err = linspace(0, fs, n, DSPL_PERIODIC, freq);
}
error_proc:
if(X)
free(X);
return err;
}

Wyświetl plik

@ -0,0 +1,201 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "dspl.h"
#include "dspl_internal.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
\brief Fast Fourier transform for the complex vector.
Function calculated \f$ n \f$-points FFT for the complex vector
\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]
here \f$ k = 0 \ldots n-1 \f$.
\param[in] x
Pointer to the input complex vector \f$x(m)\f$,
\f$ m = 0 \ldots n-1 \f$. \n
Vector size is `[n x 1]`. \n \n
\param[in] n
FFT size \f$n\f$. \n
FFT size can be composite:
\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
simple number less than 46340
(see \ref fft_create function). \n \n
\param[in] pfft
Pointer to the `fft_t` object. \n
This pointer cannot be `NULL`. \n
Structure \ref fft_t should be previously once
filled with the \ref fft_create function, and the memory should be
cleared before exiting by the \ref fft_free function. \n \n
\param[out] y
Pointer to the FFT result complex vector \f$Y(k)\f$,
\f$ k = 0 \ldots n-1 \f$. \n
Vector size is `[n x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if FFT is calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
Example:
\include fft_cmplx_test.c
Result:
\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 Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\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
***************************************************************************** */
#endif
int DSPL_API fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
{
int err;
if(!x || !pfft || !y)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
err = fft_create(pfft, n);
if(err != RES_OK)
return err;
memcpy(pfft->t1, x, n*sizeof(complex_t));
return fft_krn(pfft->t1, y, pfft, n, 0);
}

Wyświetl plik

@ -0,0 +1,367 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "dspl.h"
#include "dspl_internal.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fft_create(fft_t* pfft, int n)
\brief Function creates and fill `fft_t` structure.
The function allocates memory and calculates twiddle factors
of the `n`-point FFT for the structure` fft_t`.
\param[in,out] pfft
Pointer to the `fft_t` object. \n
Pointer cannot be `NULL`. \n \n
\param[in] n
FFT size \f$n\f$. \n
FFT size can be composite
\f$n = n_0 \times n_1 \times n_2 \ldots \times n_p \times m\f$,
here \f$n_i = 2,3,5,7\f$, and \f$m \f$ --
arbitrary prime factor not exceeding 46340. \n
Thus, the FFT algorithm supports arbitrary integer lengths.
degrees of numbers 2,3,5,7, as well as their various combinations. \n
For example, with \f$ n = 725760 \f$ the structure will be successfully filled,
because
\f$ 725760 = 2 \cdot 3 \cdot 4 \cdot 5 \cdot 6 \cdot 7 \cdot 9 \cdot 16 \f$. \n
If \f$ n = 172804 = 43201 \cdot 4 \f$ then the structure will also be
successfully filled, because the simple factor in \f$ n \f$ does not
exceed 46340. \n
For size \f$ n = 13 \cdot 17 \cdot 23 \cdot 13 = 66079 \f$
the function will return an error since 66079 is greater than 46340 and is
not the result of the product of numbers 2,3,5,7. \n \n
\return
`RES_OK` if FFT structure is created and filled successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
\note
Some compilers do not nullify its contents when creating a structure.
Therefore, it is recommended to reset the structure after its declaration:
\code{.cpp}
fft_t pfft = {0}; // fill and fields of fft_t as zeros
int n = 64; // FFT size
int err;
// Create fft_t object for 64-points FFT
err = fft_create(&pfft, n);
// ...................................
// Clear fft_t structure
fft_free(&pfft);
\endcode
Before exiting the program, the memory allocated in the structure
need to clear by \ref fft_free function. \n \n
\note
The "magic number" 46340 because \f$\sqrt{2^{31}} = 46340.95\f$. \n
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\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 = {0}; // объявляем объект fft_t
int n = 64; // Размер БПФ
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
***************************************************************************** */
#endif
int DSPL_API fft_create(fft_t* pfft, int n)
{
int n1, n2, addr, s, k, m, nw, err;
double phi;
s = n;
nw = addr = 0;
if(pfft->n == n)
return RES_OK;
while(s > 1)
{
n2 = 1;
if(s%4096 == 0) { n2 = 4096; goto label_size; }
if(s%2048 == 0) { n2 = 2048; goto label_size; }
if(s%1024 == 0) { n2 = 1024; goto label_size; }
if(s%512 == 0) { n2 = 512; goto label_size; }
if(s%256 == 0) { n2 = 256; goto label_size; }
if(s%128 == 0) { n2 = 128; goto label_size; }
if(s% 64 == 0) { n2 = 64; goto label_size; }
if(s% 32 == 0) { n2 = 32; goto label_size; }
if(s% 16 == 0) { n2 = 16; goto label_size; }
if(s% 7 == 0) { n2 = 7; goto label_size; }
if(s% 8 == 0) { n2 = 8; goto label_size; }
if(s% 5 == 0) { n2 = 5; goto label_size; }
if(s% 4 == 0) { n2 = 4; goto label_size; }
if(s% 3 == 0) { n2 = 3; goto label_size; }
if(s% 2 == 0) { n2 = 2; goto label_size; }
label_size:
if(n2 == 1)
{
if(s > FFT_COMPOSITE_MAX)
{
err = ERROR_FFT_SIZE;
goto error_proc;
}
nw += s;
pfft->w = pfft->w ?
(complex_t*) realloc(pfft->w, nw*sizeof(complex_t)):
(complex_t*) malloc( nw*sizeof(complex_t));
for(k = 0; k < s; k++)
{
phi = - M_2PI * (double)k / (double)s;
RE(pfft->w[addr]) = cos(phi);
IM(pfft->w[addr]) = sin(phi);
addr++;
}
s = 1;
}
else
{
n1 = s / n2;
nw += s;
pfft->w = pfft->w ?
(complex_t*) realloc(pfft->w, nw*sizeof(complex_t)):
(complex_t*) malloc( nw*sizeof(complex_t));
for(k = 0; k < n1; k++)
{
for(m = 0; m < n2; m++)
{
phi = - M_2PI * (double)(k*m) / (double)s;
RE(pfft->w[addr]) = cos(phi);
IM(pfft->w[addr]) = sin(phi);
addr++;
}
}
}
s /= n2;
}
pfft->t0 = pfft->t0 ? (complex_t*) realloc(pfft->t0, n*sizeof(complex_t)):
(complex_t*) malloc( n*sizeof(complex_t));
pfft->t1 = pfft->t1 ? (complex_t*) realloc(pfft->t1, n*sizeof(complex_t)):
(complex_t*) malloc( n*sizeof(complex_t));
pfft->n = n;
/* w32 fill */
addr = 0;
for(k = 0; k < 4; k++)
{
for(m = 0; m < 8; m++)
{
phi = - M_2PI * (double)(k*m) / 32.0;
RE(pfft->w32[addr]) = cos(phi);
IM(pfft->w32[addr]) = sin(phi);
addr++;
}
}
/* w64 fill */
addr = 0;
for(k = 0; k < 8; k++)
{
for(m = 0; m < 8; m++)
{
phi = - M_2PI * (double)(k*m) / 64.0;
RE(pfft->w64[addr]) = cos(phi);
IM(pfft->w64[addr]) = sin(phi);
addr++;
}
}
/* w128 fill */
addr = 0;
for(k = 0; k < 8; k++)
{
for(m = 0; m < 16; m++)
{
phi = - M_2PI * (double)(k*m) / 128.0;
RE(pfft->w128[addr]) = cos(phi);
IM(pfft->w128[addr]) = sin(phi);
addr++;
}
}
/* w256 fill */
addr = 0;
for(k = 0; k < 16; k++)
{
for(m = 0; m < 16; m++)
{
phi = - M_2PI * (double)(k*m) / 256.0;
RE(pfft->w256[addr]) = cos(phi);
IM(pfft->w256[addr]) = sin(phi);
addr++;
}
}
/* w512 fill */
addr = 0;
for(k = 0; k < 16; k++)
{
for(m = 0; m < 32; m++)
{
phi = - M_2PI * (double)(k*m) / 512.0;
RE(pfft->w512[addr]) = cos(phi);
IM(pfft->w512[addr]) = sin(phi);
addr++;
}
}
/* w1024 fill */
if(pfft->w1024 == NULL)
{
pfft->w1024 = (complex_t*) malloc(1024 * sizeof(complex_t));
addr = 0;
for(k = 0; k < 32; k++)
{
for(m = 0; m < 32; m++)
{
phi = - M_2PI * (double)(k*m) / 1024.0;
RE(pfft->w1024[addr]) = cos(phi);
IM(pfft->w1024[addr]) = sin(phi);
addr++;
}
}
}
/* w2048 fill */
if(pfft->w2048 == NULL)
{
pfft->w2048= (complex_t*) malloc(2048 * sizeof(complex_t));
addr = 0;
for(k = 0; k < 32; k++)
{
for(m = 0; m < 64; m++)
{
phi = - M_2PI * (double)(k*m) / 2048.0;
RE(pfft->w2048[addr]) = cos(phi);
IM(pfft->w2048[addr]) = sin(phi);
addr++;
}
}
}
/* w4096 fill */
if(pfft->w4096 == NULL)
{
pfft->w4096= (complex_t*) malloc(4096 * sizeof(complex_t));
addr = 0;
for(k = 0; k < 16; k++)
{
for(m = 0; m < 256; m++)
{
phi = - M_2PI * (double)(k*m) / 4096.0;
RE(pfft->w4096[addr]) = cos(phi);
IM(pfft->w4096[addr]) = sin(phi);
addr++;
}
}
}
return RES_OK;
error_proc:
if(pfft->t0) free(pfft->t0);
if(pfft->t1) free(pfft->t1);
if(pfft->w) free(pfft->w);
pfft->n = 0;
return err;
}

Wyświetl plik

@ -0,0 +1,85 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "dspl.h"
#include "dspl_internal.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn void fft_free(fft_t *pfft)
\brief Free `fft_t` structure.
The function clears the intermediate data memory
and vectors of FFT twiddle factors of the structure `fft_t`.
\param[in] pfft
Pointer to the `fft_t` object. \n
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\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
***************************************************************************** */
#endif
void DSPL_API fft_free(fft_t *pfft)
{
if(!pfft)
return;
if(pfft->w)
free(pfft->w);
if(pfft->t0)
free(pfft->t0);
if(pfft->t1)
free(pfft->t1);
if(pfft->w1024)
free(pfft->w1024);
if(pfft->w2048)
free(pfft->w2048);
if(pfft->w4096)
free(pfft->w4096);
memset(pfft, 0, sizeof(fft_t));
}

Wyświetl plik

@ -0,0 +1,170 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "dspl.h"
#include "dspl_internal.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int fft_krn(complex_t* t0, complex_t* t1, fft_t* p, int n, int addr)
{
int n1, n2, k, m, i;
complex_t *pw = p->w+addr;
complex_t tmp;
n1 = 1;
if(n % 4096 == 0) { n1 = 4096; goto label_size; }
if(n % 2048 == 0) { n1 = 2048; goto label_size; }
if(n % 1024 == 0) { n1 = 1024; goto label_size; }
if(n % 512 == 0) { n1 = 512; goto label_size; }
if(n % 256 == 0) { n1 = 256; goto label_size; }
if(n % 128 == 0) { n1 = 128; goto label_size; }
if(n % 64 == 0) { n1 = 64; goto label_size; }
if(n % 32 == 0) { n1 = 32; goto label_size; }
if(n % 16 == 0) { n1 = 16; goto label_size; }
if(n % 7 == 0) { n1 = 7; goto label_size; }
if(n % 8 == 0) { n1 = 8; goto label_size; }
if(n % 5 == 0) { n1 = 5; goto label_size; }
if(n % 4 == 0) { n1 = 4; goto label_size; }
if(n % 3 == 0) { n1 = 3; goto label_size; }
if(n % 2 == 0) { n1 = 2; goto label_size; }
label_size:
if(n1 == 1)
{
for(k = 0; k < n; k++)
{
RE(t1[k]) = IM(t1[k]) = 0.0;
for(m = 0; m < n; m++)
{
i = (k*m) % n;
RE(tmp) = CMRE(t0[m], pw[i]);
IM(tmp) = CMIM(t0[m], pw[i]);
RE(t1[k]) += RE(tmp);
IM(t1[k]) += IM(tmp);
}
}
}
else
{
n2 = n / n1;
if(n2>1)
{
memcpy(t1, t0, n*sizeof(complex_t));
matrix_transpose_cmplx(t1, n2, n1, t0);
}
if(n1 == 4096)
for(k = 0; k < n2; k++)
dft4096(t0+4096*k, t1+4096*k, p->w4096, p->w256);
if(n1 == 2048)
for(k = 0; k < n2; k++)
dft2048(t0+2048*k, t1+2048*k, p->w2048, p->w32, p->w64);
if(n1 == 1024)
for(k = 0; k < n2; k++)
dft1024(t0+1024*k, t1+1024*k, p->w1024, p->w32);
if(n1 == 512)
for(k = 0; k < n2; k++)
dft512(t0+512*k, t1+512*k, p->w512, p->w32);
if(n1 == 256)
for(k = 0; k < n2; k++)
dft256(t0+256*k, t1+256*k, p->w256);
if(n1 == 128)
for(k = 0; k < n2; k++)
dft128(t0+128*k, t1+128*k, p->w128);
if(n1 == 64)
for(k = 0; k < n2; k++)
dft64(t0+64*k, t1+64*k, p->w64);
if(n1 == 32)
for(k = 0; k < n2; k++)
dft32(t0+32*k, t1+32*k, p->w32);
if(n1 == 16)
for(k = 0; k < n2; k++)
dft16(t0+16*k, t1+16*k);
if(n1 == 7)
for(k = 0; k < n2; k++)
dft7(t0+7*k, t1+7*k);
if(n1 == 8)
for(k = 0; k < n2; k++)
dft8(t0+8*k, t1+8*k);
if(n1 == 5)
for(k = 0; k < n2; k++)
dft5(t0+5*k, t1+5*k);
if(n1 == 4)
for(k = 0; k < n2; k++)
dft4(t0+4*k, t1+4*k);
if(n1 == 3)
for(k = 0; k < n2; k++)
dft3(t0+3*k, t1+3*k);
if(n1 == 2)
for(k = 0; k < n2; k++)
dft2(t0+2*k, t1+2*k);
if(n2 > 1)
{
for(k =0; k < n; k++)
{
RE(t0[k]) = CMRE(t1[k], pw[k]);
IM(t0[k]) = CMIM(t1[k], pw[k]);
}
matrix_transpose_cmplx(t0, n1, n2, t1);
for(k = 0; k < n1; k++)
{
fft_krn(t1+k*n2, t0+k*n2, p, n2, addr+n);
}
matrix_transpose_cmplx(t0, n2, n1, t1);
}
}
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,68 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "dspl.h"
#include "dspl_internal.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API fft_mag(double* x, int n, fft_t* pfft,
double fs, int flag,
double* mag, double* freq)
{
int k, err;
fft_t *cfft = NULL;
if(pfft)
cfft = pfft;
else
{
cfft = (fft_t*) malloc(sizeof(fft_t));
memset(cfft, 0, sizeof(fft_t));
}
err = fft_abs(x, n, cfft, fs, flag, mag, freq);
if(err != RES_OK)
goto error_proc;
if(mag)
{
if(flag & DSPL_FLAG_LOGMAG)
for(k = 0; k < n; k++)
mag[k] = 20.0 * log10(mag[k] + DBL_EPSILON);
else
for(k = 0; k < n; k++)
mag[k] *= mag[k];
}
error_proc:
if(cfft && cfft != pfft)
free(cfft);
return err;
}

Wyświetl plik

@ -0,0 +1,74 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "dspl.h"
#include "dspl_internal.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API fft_mag_cmplx(complex_t* x, int n, fft_t* pfft,
double fs, int flag,
double* mag, double* freq)
{
int k, err;
fft_t *cfft = NULL;
if(pfft)
cfft = pfft;
else
{
cfft = (fft_t*) malloc(sizeof(fft_t));
memset(cfft, 0, sizeof(fft_t));
}
err = fft_abs_cmplx(x, n, cfft, fs, flag, mag, freq);
if(err != RES_OK)
goto error_proc;
if(mag)
{
if(flag & DSPL_FLAG_LOGMAG)
for(k = 0; k < n; k++)
mag[k] = 20.0 * log10(mag[k] + DBL_EPSILON);
else
for(k = 0; k < n; k++)
mag[k] *= mag[k];
}
error_proc:
if(cfft && cfft != pfft)
free(cfft);
return err;
}

Wyświetl plik

@ -0,0 +1,129 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "dspl.h"
#include "dspl_internal.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fft_shift(double* x, int n, double* y)
\brief Perform a shift of the vector `x`, for use with the `fft` and `ifft`
functions, in order
<a href="http://en.dsplib.org/content/dft_freq/dft_freq.html">
to move the frequency 0 to the center
</a> of the vector `y`.
\param[in] x
Pointer to the input vector (FFT or IFFT result). \n
Vector size is `[n x 1]`. \n \n
\param[in] n
Input and output vector size. \n \n
\param[out] y
Pointer to the output vector with frequency 0 in the center. \n
Vector size is `[n x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if function is calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\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
***************************************************************************** */
#endif
int DSPL_API fft_shift(double* x, int n, double* y)
{
int n2, r;
int k;
double tmp;
double *buf;
if(!x || !y)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
r = n%2;
if(!r)
{
n2 = n>>1;
for(k = 0; k < n2; k++)
{
tmp = x[k];
y[k] = x[k+n2];
y[k+n2] = tmp;
}
}
else
{
n2 = (n+1) >> 1;
buf = (double*) malloc(n2*sizeof(double));
memcpy(buf, x, n2*sizeof(double));
memcpy(y, x+n2, (n2-1)*sizeof(double));
memcpy(y+n2-1, buf, n2*sizeof(double));
free(buf);
}
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,76 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "dspl.h"
#include "dspl_internal.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API fft_shift_cmplx(complex_t* x, int n, complex_t* y)
{
int n2, r;
int k;
complex_t tmp;
complex_t *buf;
if(!x || !y)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
r = n%2;
if(!r)
{
n2 = n>>1;
for(k = 0; k < n2; k++)
{
RE(tmp) = RE(x[k]);
IM(tmp) = IM(x[k]);
RE(y[k]) = RE(x[k+n2]);
IM(y[k]) = IM(x[k+n2]);
RE(y[k+n2]) = RE(tmp);
IM(y[k+n2]) = IM(tmp);
}
}
else
{
n2 = (n+1) >> 1;
buf = (complex_t*) malloc(n2*sizeof(complex_t));
memcpy(buf, x, n2*sizeof(complex_t));
memcpy(y, x+n2, (n2-1)*sizeof(complex_t));
memcpy(y+n2-1, buf, n2*sizeof(complex_t));
free(buf);
}
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,69 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API fourier_integral_cmplx(double* t, complex_t* s, int nt,
int nw, double* w, complex_t* y)
{
int k, m;
complex_t e[2];
if(!t || !s || !w || !y)
return ERROR_PTR;
if(nt<1 || nw < 1)
return ERROR_SIZE;
memset(y, 0 , nw*sizeof(complex_t));
for(k = 0; k < nw; k++)
{
RE(e[1]) = RE(s[0]) * cos(w[k] * t[0]) +
IM(s[0]) * sin(w[k] * t[0]);
IM(e[1]) = -RE(s[0]) * sin(w[k] * t[0]) +
IM(s[0]) * cos(w[k] * t[0]);
for(m = 1; m < nt; m++)
{
RE(e[0]) = RE(e[1]);
IM(e[0]) = IM(e[1]);
RE(e[1]) = RE(s[m]) * cos(w[k] * t[m]) +
IM(s[m]) * sin(w[k] * t[m]);
IM(e[1]) = -RE(s[m]) * sin(w[k] * t[m]) +
IM(s[m]) * cos(w[k] * t[m]);
RE(y[k]) += 0.5 * (RE(e[0]) + RE(e[1]))*(t[m] - t[m-1]);
IM(y[k]) += 0.5 * (IM(e[0]) + IM(e[1]))*(t[m] - t[m-1]);
}
}
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,190 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fourier_series_dec(double* t, double* s, int nt, double period,
int nw, double* w, complex_t* y)
\brief
Fourier series coefficient calculation for periodic signal
\param[in] t
Pointer to the time vector. \n
Vector size is `[nt x 1]`. \n
\n
\param[in] s
Pointer to the signal corresponds to time `t`. \n
Vector size is `[nt x 1]`. \n
\n
\param[in] nt
Size of time and signal vectors. \n
This value must be positive. \n
\n
\param[in] period
Signal time period. \n
\n
\param[in] nw
Number of Fourie series coefficients. \n
\n
\param[out] w
Pointer to the frequency vector (rad/s). \n
Vector size is `[nw x 1]`. \n
Memory must be allocated. \n
\n
\param[out] y
Pointer to the complex Fourier series coefficients vector. \n
Vector size is `[nw x 1]`. \n
Memory must be allocated. \n
\n
\return
`RES_OK` if function is calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
\note
Numerical integration is used for Fourier series coefficients calculation.
This function is not effective.
To increase the speed of calculation of the signal spectrum
it is more expedient to use fast Fourier transform algorithms.
\n
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fourier_series_dec(double* t, double* s, int nt, double period,
int nw, double* w, complex_t* y)
\brief
Расчет коэффициентов разложения в ряд Фурье
Функция рассчитывает спектр периодического сигнала при усечении ряда Фурье \n
\param[in] t
Указатель на массив моментов времени дискретизации исходного сигнала `s`. \n
Размер вектора вектора `[nt x 1]`. \n
Память должна быть выделена. \n
\n
\param[in] s
Указатель на массив значений исходного сигнала`s`. \n
Размер вектора `[nt x 1]`. \n
Память должна быть выделена. \n
\n
\param[in] nt
Размер выборки исходного сигнала. \n
Значение должно быть положительным. \n
\n
\param[in] period
Период повторения сигнала. \n
\n
\param[in] nw
Размер усеченного ряда Фурье. \n
\n
\param[out] w
Указатель на массив частот спектра периодического сигнала. \n
Размер вектора `[nw x 1]`. \n
Память должна быть выделена. \n
\n
\param[out] y
Указатель массив комплексных значений спектра периодического сигнала. \n
Размер вектора `[nw x 1]`. \n
Память должна быть выделена. \n
\n
\return
`RES_OK` --- коэффициенты ряда Фурье рассчитаны успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
\note
Для расчета спектра сигнала используется численное интегрирование
исходного сигнала методом трапеций. Данная функция не является
эффективной. Для увеличения скорости расчета спектра сигнала
целесообразнее использовать алгоритмы дискретного
и быстрого преобразования Фурье.
\n
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API fourier_series_dec(double* t, double* s, int nt, double period,
int nw, double* w, complex_t* y)
{
int k, m;
double dw = M_2PI / period;
complex_t e[2];
if(!t || !s || !w || !y)
return ERROR_PTR;
if(nt<1 || nw < 1)
return ERROR_SIZE;
if(period <= 0.0)
return ERROR_NEGATIVE;
memset(y, 0 , nw*sizeof(complex_t));
for(k = 0; k < nw; k++)
{
w[k] = (k - nw/2) * dw;
RE(e[1]) = s[0] * cos(w[k] * t[0]);
IM(e[1]) = -s[0] * sin(w[k] * t[0]);
for(m = 1; m < nt; m++)
{
RE(e[0]) = RE(e[1]);
IM(e[0]) = IM(e[1]);
RE(e[1]) = s[m] * cos(w[k] * t[m]);
IM(e[1]) = - s[m] * sin(w[k] * t[m]);
RE(y[k]) += 0.5 * (RE(e[0]) + RE(e[1]))*(t[m] - t[m-1]);
IM(y[k]) += 0.5 * (IM(e[0]) + IM(e[1]))*(t[m] - t[m-1]);
}
RE(y[k]) /= period;
IM(y[k]) /= period;
}
if(!(nw%2))
RE(y[0]) = RE(y[1]) = 0.0;
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,76 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API fourier_series_dec_cmplx(double* t, complex_t* s, int nt,
double period, int nw, double* w, complex_t* y)
{
int k, m;
double dw = M_2PI / period;
complex_t e[2];
if(!t || !s || !w || !y)
return ERROR_PTR;
if(nt<1 || nw < 1)
return ERROR_SIZE;
if(period <= 0.0)
return ERROR_NEGATIVE;
memset(y, 0 , nw*sizeof(complex_t));
for(k = 0; k < nw; k++)
{
w[k] = (k - nw/2) * dw;
RE(e[1]) = RE(s[0]) * cos(w[k] * t[0]) +
IM(s[0]) * sin(w[k] * t[0]);
IM(e[1]) = -RE(s[0]) * sin(w[k] * t[0]) +
IM(s[0]) * cos(w[k] * t[0]);
for(m = 1; m < nt; m++)
{
RE(e[0]) = RE(e[1]);
IM(e[0]) = IM(e[1]);
RE(e[1]) = RE(s[m]) * cos(w[k] * t[m]) +
IM(s[m]) * sin(w[k] * t[m]);
IM(e[1]) = -RE(s[m]) * sin(w[k] * t[m]) +
IM(s[m]) * cos(w[k] * t[m]);
RE(y[k]) += 0.5 * (RE(e[0]) + RE(e[1]))*(t[m] - t[m-1]);
IM(y[k]) += 0.5 * (IM(e[0]) + IM(e[1]))*(t[m] - t[m-1]);
}
RE(y[k]) /= period;
IM(y[k]) /= period;
}
if(!(nw%2))
RE(y[0]) = RE(y[1]) = 0.0;
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,185 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fourier_series_rec(double* w, complex_t* s, int nw,
double* t, int nt, complex_t* y)
\brief Time signal reconstruction from Fourier series coefficients.
Function reconstructs the time signal:
\f[
s(t) = \sum\limits_{n = 0}^{n_{\omega}-1} S(\omega_n) \exp(j\omega_n t)
\f]
\param[in] w
Pointer to the Fourier series spectrum frequency vector \f$\omega_n\f$. \n
Vector size is `[nw x 1]`. \n
\n
\param[in] s
Pointer to the Fourier series coefficients vector \f$S(\omega_n)\f$. \n
Vector size is `[nw x 1]`. \n
\n
\param[in] nw
Number of Fourier series coefficients. \n
This value must be positive. \n
\n
\param[in] t
Pointer to the reconstructed signal time vector. \n
Vector size is `[nt x 1]`. \n
\n
\param[in] nt
Size of time vector and reconstructed signal vector . \n
\n
\param[out] y
Pointer to the reconstructed signal vector. \n
Vector size is `[nt x 1]`. \n
Memory must be allocated. \n
\n
\return
`RES_OK` if function is calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
\note
The output reconstructed signal is generally complex.
However, subject to the symmetry properties of the vectors `w` and` s`
with respect to zero frequency we get the imaginary part of the vector `y`
at the EPS level. The negligible imaginary part in this case
can be ignored.
\n
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fourier_series_rec(double* w, complex_t* s, int nw,
double* t, int nt, complex_t* y)
\brief Восстановление сигнала при усечении ряда Фурье
Функция рассчитывает восстановленный сигнал при усечении ряда Фурье:
\f[
s(t) = \sum\limits_{n = 0}^{n_{\omega}-1} S(\omega_n) \exp(j\omega_n t)
\f]
\param[in] w
Указатель на массив частот \f$\omega_n\f$ усеченного ряда Фурье. \n
Размер вектора `[nw x 1]`. \n
Память должна быть выделена и заполнена. \n
\n
\param[in] s
Указатель на массив значений спектра \f$S(\omega_n)\f$. \n
Размер вектора `[nw x 1]`. \n
Память должна быть выделена и заполнена. \n
\n
\param[in] nw
Количество членов усеченного ряда Фурье. \n
Значение должно быть положительным. \n
\n
\param[in] t
Указатель на массив временных отсчетов восстановленного сигнала. \n
Размер вектора `[nt x 1]`. \n
Память должна быть выделена и заполнена. \n
\n
\param[in] nt
Размер вектора времени и восстановленного сигнала. \n
\n
\param[out] y
Указатель на массив восстановленного сигнала. \n
Размер вектора `[nt x 1]`. \n
Память должна быть выделена. \n
\n
\return
`RES_OK` --- восстановление сигнала прошло успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
\note
Выходной восстановленный сигнал в общем случае является комплексным.
Однако при соблюдении свойств симметрии векторов `w` и `s` относительно
нулевой частоты получим мнимую часть элементов вектора `y` на уровне ошибок
округления числа с двойной точностью. Ничтожно малую мнимую часть в этом случае
можно игнорировать.
\n
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API fourier_series_rec(double* w, complex_t* s, int nw,
double* t, int nt, complex_t* y)
{
int k, m;
complex_t e;
if(!t || !s || !w || !y)
return ERROR_PTR;
if(nt<1 || nw < 1)
return ERROR_SIZE;
memset(y, 0, nt*sizeof(complex_t));
for(k = 0; k < nw; k++)
{
for(m = 0; m < nt; m++)
{
RE(e) = cos(w[k] * t[m]);
IM(e) = sin(w[k] * t[m]);
RE(y[m]) += CMRE(s[k], e);
IM(y[m]) += CMIM(s[k], e);
}
}
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,157 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int goertzel(double *x, int n, int *ind, int k, complex_t *y)
\brief <a href = "http://en.dsplib.org/content/goertzel/goertzel.html">
Goertzel algorithm </a> individual DFT samples calculation for the real input vector `x`.
Goertzel algorithm calculates `k` samples of `n`-point DFT, according to
`ind` indexes vector.
\param[in] x
Pointer to the real input vector `x` \n
Vector size is `[n x 1]`. \n \n
\param[in] n
Size of vector `x`. \n \n
\param[in] ind
Pointer to the DFT samples indexes which need
to calculate by Goertzel algorithm. \n
Vector size is `[k x 1]`. \n \n
\param[in] k
Size of vector `ind`. \n \n
\param[out] y
Pointer to the DFT samples vector corresponds to indexes `ind`. \n
Vector size is `[k x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if function is calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
\note
Goertzel's algorithm is effective when it is necessary to calculate
several DFT samples of a signal of long duration. \n
However, the size `k` of the vector of indices` ind` can be arbitrary,
including more than the length of the signal `n`.
In this case, some DFT samples will be repeated, but this will not entail
a runtime error. \n
The values of the indices of the DFT spectral samples `ind`
can also be arbitrary integers, including negative ones.
In this case, the DFT samples will be calculated.
with indices modulo `n`. \n
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int goertzel(double *x, int n, int *ind, int k, complex_t *y)
\brief <a href = "http://ru.dsplib.org/content/goertzel/goertzel.html">
Алгоритм Гёрцеля</a> для расчета отдельных спектральных отсчетов дискретного
преобразования Фурье вещественного сигнала `x`.
Данный алгоритм позволяет рассчитать `k` спектральных отсчетов
`n`-точечного ДПФ, заданных вектором индексов `ind`.
\param[in] x
Указатель на вектор вещественного входного сигнала. \n
Размер вектора `[n x 1]`. \n \n
\param[in] n
Размер вектора входного сигнала. \n \n
\param[in] ind
Указатель на вектор индексов спектральных отсчетов для расчета которых
будет использоваться алгоритм Герцеля. \n
Размер вектора `[k x 1]`. \n \n
\param[in] k
Размер вектора индексов спектральных отсчетов `ind`. \n \n
\param[out] y
Указатель на вектор спектральных отсчетов, соответствующих номерам `ind`. \n
Размер вектора `[k x 1]`. \n
Память должна быть выделена. \n \n
\return
`RES_OK` --- расчёт выполнен успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
\note
Алгоритм Гёрцеля эффективен когда необходимо рассчитать несколько
спектральных отсчетов сигнала большой длительности. \n
Однако, размер `k` вектора индексов `ind` может быть произвольным,
в том числе больше длины сигнала `n`.
В этом случае некоторые спектральные отсчеты будут повторяться, но это
не повлечет за собой ошибки выполнения. \n
Значения индексов спектральных отсчетов `ind` также могут быть
произвольными целыми, в том числе и отрицательными.
В этом случае будут рассчитаны спектральные отсчеты
с индексами по модулю `n`. \n
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API goertzel(double *x, int n, int *ind, int k, complex_t *y)
{
int m, p;
double wR, wI;
double alpha;
double v[3];
if(!x || !y || !ind)
return ERROR_PTR;
if(n < 1 || k < 1)
return ERROR_SIZE;
for(p = 0; p < k; p++)
{
wR = cos(M_2PI * (double)ind[p] / (double)n);
wI = sin(M_2PI * (double)ind[p] / (double)n);
alpha = 2.0 * wR;
v[0] = v[1] = v[2] = 0.0;
for(m = 0; m < n; m++)
{
v[2] = v[1];
v[1] = v[0];
v[0] = x[m]+alpha*v[1] - v[2];
}
RE(y[p]) = wR * v[0] - v[1];
IM(y[p]) = wI * v[0];
}
return RES_OK;
}

Wyświetl plik

@ -23,142 +23,6 @@
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int goertzel(double *x, int n, int *ind, int k, complex_t *y)
\brief <a href = "http://en.dsplib.org/content/goertzel/goertzel.html">
Goertzel algorithm </a> individual DFT samples calculation for the real input vector `x`.
Goertzel algorithm calculates `k` samples of `n`-point DFT, according to
`ind` indexes vector.
\param[in] x
Pointer to the real input vector `x` \n
Vector size is `[n x 1]`. \n \n
\param[in] n
Size of vector `x`. \n \n
\param[in] ind
Pointer to the DFT samples indexes which need
to calculate by Goertzel algorithm. \n
Vector size is `[k x 1]`. \n \n
\param[in] k
Size of vector `ind`. \n \n
\param[out] y
Pointer to the DFT samples vector corresponds to indexes `ind`. \n
Vector size is `[k x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if function is calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
\note
Goertzel's algorithm is effective when it is necessary to calculate
several DFT samples of a signal of long duration. \n
However, the size `k` of the vector of indices` ind` can be arbitrary,
including more than the length of the signal `n`.
In this case, some DFT samples will be repeated, but this will not entail
a runtime error. \n
The values of the indices of the DFT spectral samples `ind`
can also be arbitrary integers, including negative ones.
In this case, the DFT samples will be calculated.
with indices modulo `n`. \n
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int goertzel(double *x, int n, int *ind, int k, complex_t *y)
\brief <a href = "http://ru.dsplib.org/content/goertzel/goertzel.html">
Алгоритм Гёрцеля</a> для расчета отдельных спектральных отсчетов дискретного
преобразования Фурье вещественного сигнала `x`.
Данный алгоритм позволяет рассчитать `k` спектральных отсчетов
`n`-точечного ДПФ, заданных вектором индексов `ind`.
\param[in] x
Указатель на вектор вещественного входного сигнала. \n
Размер вектора `[n x 1]`. \n \n
\param[in] n
Размер вектора входного сигнала. \n \n
\param[in] ind
Указатель на вектор индексов спектральных отсчетов для расчета которых
будет использоваться алгоритм Герцеля. \n
Размер вектора `[k x 1]`. \n \n
\param[in] k
Размер вектора индексов спектральных отсчетов `ind`. \n \n
\param[out] y
Указатель на вектор спектральных отсчетов, соответствующих номерам `ind`. \n
Размер вектора `[k x 1]`. \n
Память должна быть выделена. \n \n
\return
`RES_OK` --- расчёт выполнен успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
\note
Алгоритм Гёрцеля эффективен когда необходимо рассчитать несколько
спектральных отсчетов сигнала большой длительности. \n
Однако, размер `k` вектора индексов `ind` может быть произвольным,
в том числе больше длины сигнала `n`.
В этом случае некоторые спектральные отсчеты будут повторяться, но это
не повлечет за собой ошибки выполнения. \n
Значения индексов спектральных отсчетов `ind` также могут быть
произвольными целыми, в том числе и отрицательными.
В этом случае будут рассчитаны спектральные отсчеты
с индексами по модулю `n`. \n
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API goertzel(double *x, int n, int *ind, int k, complex_t *y)
{
int m, p;
double wR, wI;
double alpha;
double v[3];
if(!x || !y || !ind)
return ERROR_PTR;
if(n < 1 || k < 1)
return ERROR_SIZE;
for(p = 0; p < k; p++)
{
wR = cos(M_2PI * (double)ind[p] / (double)n);
wI = sin(M_2PI * (double)ind[p] / (double)n);
alpha = 2.0 * wR;
v[0] = v[1] = v[2] = 0.0;
for(m = 0; m < n; m++)
{
v[2] = v[1];
v[1] = v[0];
v[0] = x[m]+alpha*v[1] - v[2];
}
RE(y[p]) = wR * v[0] - v[1];
IM(y[p]) = wI * v[0];
}
return RES_OK;
}
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************

Wyświetl plik

@ -0,0 +1,195 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int idft_cmplx(complex_t* x, int n, complex_t* y)
\brief Inverse discrete Fourier transform of the complex spectrum.
The function calculates the \f$ n \f$ -point inverse discrete transform
Fourier complex spectrum \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]
where \f$ k = 0 \ldots n-1 \f$.
\param [in] x
Pointer to the vector of the input complex signal spectrum \f$ x (m) \f$,
\f$ m = 0 \ldots n-1 \f$. \n
The size of the vector is `[n x 1]`. \n \n
\param [in] n
The size of the ODPF \f$ n \f$
(the size of the vectors of the input spectrum and the result of the ODPF). \n
\n
\param [out] y
Pointer to the complex vector of the ODPF result \f$ y (k) \f$,
\f$ k = 0 \ldots n-1 \f$.
The size of the vector is `[n x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if the ODPF is calculated successfully. \n
Otherwise, \ref ERROR_CODE_GROUP "error code".
An example of using the `dft_cmplx` function:
\include idft_cmplx_test.c
The result of the program:
\verbatim
x [0] = 0.000 + 0.000j, z [0] = 0.000 -0.000
x [1] = 1.000 + 0.000j, z [1] = 1.000 -0.000
x [2] = 2.000 + 0.000j, z [2] = 2.000 -0.000
x [3] = 3.000 + 0.000j, z [3] = 3.000 -0.000
x [4] = 4.000 + 0.000j, z [4] = 4.000 -0.000
x [5] = 5.000 + 0.000j, z [5] = 5.000 -0.000
x [6] = 6.000 + 0.000j, z [6] = 6.000 -0.000
x [7] = 7.000 + 0.000j, z [7] = 7.000 -0.000
x [8] = 8.000 + 0.000j, z [8] = 8.000 -0.000
x [9] = 9.000 + 0.000j, z [9] = 9.000 -0.000
x [10] = 10.000 + 0.000j, z [10] = 10.000 -0.000
x [11] = 11.000 + 0.000j, z [11] = 11.000 +0.000
x [12] = 12.000 + 0.000j, z [12] = 12.000 +0.000
x [13] = 13.000 + 0.000j, z [13] = 13.000 +0.000
x [14] = 14.000 + 0.000j, z [14] = 14.000 +0.000
x [15] = 15.000 + 0.000j, z [15] = 15.000 -0.000
\endverbatim
\note
This function performs the calculation of the DFT using the naive method.
and requires \f$ n ^ 2 \f$ complex multiplications. \n
To increase the calculation speed, it is recommended
use fast Fourier transform algorithms.
\author Bakhurin Sergey www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int idft_cmplx(complex_t* x, int n, 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 \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 "код ошибки".
Пример использования функции `dft_cmplx`:
\include idft_cmplx_test.c
Результат работы программы:
\verbatim
x[ 0] = 0.000 +0.000j, z[ 0] = 0.000 -0.000
x[ 1] = 1.000 +0.000j, z[ 1] = 1.000 -0.000
x[ 2] = 2.000 +0.000j, z[ 2] = 2.000 -0.000
x[ 3] = 3.000 +0.000j, z[ 3] = 3.000 -0.000
x[ 4] = 4.000 +0.000j, z[ 4] = 4.000 -0.000
x[ 5] = 5.000 +0.000j, z[ 5] = 5.000 -0.000
x[ 6] = 6.000 +0.000j, z[ 6] = 6.000 -0.000
x[ 7] = 7.000 +0.000j, z[ 7] = 7.000 -0.000
x[ 8] = 8.000 +0.000j, z[ 8] = 8.000 -0.000
x[ 9] = 9.000 +0.000j, z[ 9] = 9.000 -0.000
x[10] = 10.000 +0.000j, z[10] = 10.000 -0.000
x[11] = 11.000 +0.000j, z[11] = 11.000 +0.000
x[12] = 12.000 +0.000j, z[12] = 12.000 +0.000
x[13] = 13.000 +0.000j, z[13] = 13.000 +0.000
x[14] = 14.000 +0.000j, z[14] = 14.000 +0.000
x[15] = 15.000 +0.000j, z[15] = 15.000 -0.000
\endverbatim
\note
Данная функция выполняет расчет ОДПФ наивным методом
и требует \f$ n^2 \f$ комплексных умножений. \n
Для увеличения скорости расчета рекомендуется
использовать алгоритмы быстрого преобразования Фурье.
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API idft_cmplx(complex_t* x, int n, complex_t* y)
{
int k;
int m;
double divn;
double phi;
complex_t e;
if(!x || !y)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
divn = 1.0 / (double)n;
for(k = 0; k < n; k++)
{
RE(y[k]) = IM(y[k]) = 0.0;
for(m = 0; m < n; m++)
{
phi = M_2PI * divn * (double)k * (double)m;
RE(e) = cos(phi);
IM(e) = sin(phi);
RE(y[k]) += CMRE(x[m], e);
IM(y[k]) += CMIM(x[m], e);
}
RE(y[k]) /= (double)n;
IM(y[k]) /= (double)n;
}
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,209 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "dspl.h"
#include "dspl_internal.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int ifft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
\brief Inverse fast Fourier transform
Function calculates \f$ n \f$-point IFFT of complex data
\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]
here \f$ k = 0 \ldots n-1 \f$.
\param[in] x
Pointer to the input vector \f$x(m)\f$,
\f$ m = 0 \ldots n-1 \f$. \n
Vector size is `[n x 1]`. \n \n
\param[in] n
IFFT size \f$n\f$. \n
IFFT size can be composite:
\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
simple number less than 46340
(see \ref fft_create function). \n \n
\param[in] pfft
Pointer to the `fft_t` object. \n
This pointer cannot be `NULL`. \n
Structure \ref fft_t should be previously once
filled with the \ref fft_create function, and the memory should be
cleared before exiting by the \ref fft_free function. \n \n
\param[out] y
Pointer to the IFFT result vector \f$Y(k)\f$,
\f$ k = 0 \ldots n-1 \f$. \n
Vector size is `[n x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if IFFT is calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
IFFT example:
\include ifft_cmplx_test.c
Result:
\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 Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\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
***************************************************************************** */
#endif
int DSPL_API ifft_cmplx(complex_t *x, int n, fft_t* pfft, complex_t* y)
{
int err, k;
double norm;
if(!x || !pfft || !y)
return ERROR_PTR;
if(n<1)
return ERROR_SIZE;
err = fft_create(pfft, n);
if(err != RES_OK)
return err;
memcpy(pfft->t1, x, n*sizeof(complex_t));
for(k = 0; k < n; k++)
IM(pfft->t1[k]) = -IM(pfft->t1[k]);
err = fft_krn(pfft->t1, pfft->t0, pfft, n, 0);
if(err!=RES_OK)
return err;
norm = 1.0 / (double)n;
for(k = 0; k < n; k++)
{
RE(y[k]) = RE(pfft->t0[k])*norm;
IM(y[k]) = -IM(pfft->t0[k])*norm;
}
return RES_OK;
}

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,442 +0,0 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fourier_series_dec(double* t, double* s, int nt, double period,
int nw, double* w, complex_t* y)
\brief
Fourier series coefficient calculation for periodic signal
\param[in] t
Pointer to the time vector. \n
Vector size is `[nt x 1]`. \n
\n
\param[in] s
Pointer to the signal corresponds to time `t`. \n
Vector size is `[nt x 1]`. \n
\n
\param[in] nt
Size of time and signal vectors. \n
This value must be positive. \n
\n
\param[in] period
Signal time period. \n
\n
\param[in] nw
Number of Fourie series coefficients. \n
\n
\param[out] w
Pointer to the frequency vector (rad/s). \n
Vector size is `[nw x 1]`. \n
Memory must be allocated. \n
\n
\param[out] y
Pointer to the complex Fourier series coefficients vector. \n
Vector size is `[nw x 1]`. \n
Memory must be allocated. \n
\n
\return
`RES_OK` if function is calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
\note
Numerical integration is used for Fourier series coefficients calculation.
This function is not effective.
To increase the speed of calculation of the signal spectrum
it is more expedient to use fast Fourier transform algorithms.
\n
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fourier_series_dec(double* t, double* s, int nt, double period,
int nw, double* w, complex_t* y)
\brief
Расчет коэффициентов разложения в ряд Фурье
Функция рассчитывает спектр периодического сигнала при усечении ряда Фурье \n
\param[in] t
Указатель на массив моментов времени дискретизации исходного сигнала `s`. \n
Размер вектора вектора `[nt x 1]`. \n
Память должна быть выделена. \n
\n
\param[in] s
Указатель на массив значений исходного сигнала`s`. \n
Размер вектора `[nt x 1]`. \n
Память должна быть выделена. \n
\n
\param[in] nt
Размер выборки исходного сигнала. \n
Значение должно быть положительным. \n
\n
\param[in] period
Период повторения сигнала. \n
\n
\param[in] nw
Размер усеченного ряда Фурье. \n
\n
\param[out] w
Указатель на массив частот спектра периодического сигнала. \n
Размер вектора `[nw x 1]`. \n
Память должна быть выделена. \n
\n
\param[out] y
Указатель массив комплексных значений спектра периодического сигнала. \n
Размер вектора `[nw x 1]`. \n
Память должна быть выделена. \n
\n
\return
`RES_OK` --- коэффициенты ряда Фурье рассчитаны успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
\note
Для расчета спектра сигнала используется численное интегрирование
исходного сигнала методом трапеций. Данная функция не является
эффективной. Для увеличения скорости расчета спектра сигнала
целесообразнее использовать алгоритмы дискретного
и быстрого преобразования Фурье.
\n
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API fourier_series_dec(double* t, double* s, int nt, double period,
int nw, double* w, complex_t* y)
{
int k, m;
double dw = M_2PI / period;
complex_t e[2];
if(!t || !s || !w || !y)
return ERROR_PTR;
if(nt<1 || nw < 1)
return ERROR_SIZE;
if(period <= 0.0)
return ERROR_NEGATIVE;
memset(y, 0 , nw*sizeof(complex_t));
for(k = 0; k < nw; k++)
{
w[k] = (k - nw/2) * dw;
RE(e[1]) = s[0] * cos(w[k] * t[0]);
IM(e[1]) = -s[0] * sin(w[k] * t[0]);
for(m = 1; m < nt; m++)
{
RE(e[0]) = RE(e[1]);
IM(e[0]) = IM(e[1]);
RE(e[1]) = s[m] * cos(w[k] * t[m]);
IM(e[1]) = - s[m] * sin(w[k] * t[m]);
RE(y[k]) += 0.5 * (RE(e[0]) + RE(e[1]))*(t[m] - t[m-1]);
IM(y[k]) += 0.5 * (IM(e[0]) + IM(e[1]))*(t[m] - t[m-1]);
}
RE(y[k]) /= period;
IM(y[k]) /= period;
}
if(!(nw%2))
RE(y[0]) = RE(y[1]) = 0.0;
return RES_OK;
}
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API fourier_series_dec_cmplx(double* t, complex_t* s, int nt,
double period, int nw, double* w, complex_t* y)
{
int k, m;
double dw = M_2PI / period;
complex_t e[2];
if(!t || !s || !w || !y)
return ERROR_PTR;
if(nt<1 || nw < 1)
return ERROR_SIZE;
if(period <= 0.0)
return ERROR_NEGATIVE;
memset(y, 0 , nw*sizeof(complex_t));
for(k = 0; k < nw; k++)
{
w[k] = (k - nw/2) * dw;
RE(e[1]) = RE(s[0]) * cos(w[k] * t[0]) +
IM(s[0]) * sin(w[k] * t[0]);
IM(e[1]) = -RE(s[0]) * sin(w[k] * t[0]) +
IM(s[0]) * cos(w[k] * t[0]);
for(m = 1; m < nt; m++)
{
RE(e[0]) = RE(e[1]);
IM(e[0]) = IM(e[1]);
RE(e[1]) = RE(s[m]) * cos(w[k] * t[m]) +
IM(s[m]) * sin(w[k] * t[m]);
IM(e[1]) = -RE(s[m]) * sin(w[k] * t[m]) +
IM(s[m]) * cos(w[k] * t[m]);
RE(y[k]) += 0.5 * (RE(e[0]) + RE(e[1]))*(t[m] - t[m-1]);
IM(y[k]) += 0.5 * (IM(e[0]) + IM(e[1]))*(t[m] - t[m-1]);
}
RE(y[k]) /= period;
IM(y[k]) /= period;
}
if(!(nw%2))
RE(y[0]) = RE(y[1]) = 0.0;
return RES_OK;
}
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API fourier_integral_cmplx(double* t, complex_t* s, int nt,
int nw, double* w, complex_t* y)
{
int k, m;
complex_t e[2];
if(!t || !s || !w || !y)
return ERROR_PTR;
if(nt<1 || nw < 1)
return ERROR_SIZE;
memset(y, 0 , nw*sizeof(complex_t));
for(k = 0; k < nw; k++)
{
RE(e[1]) = RE(s[0]) * cos(w[k] * t[0]) +
IM(s[0]) * sin(w[k] * t[0]);
IM(e[1]) = -RE(s[0]) * sin(w[k] * t[0]) +
IM(s[0]) * cos(w[k] * t[0]);
for(m = 1; m < nt; m++)
{
RE(e[0]) = RE(e[1]);
IM(e[0]) = IM(e[1]);
RE(e[1]) = RE(s[m]) * cos(w[k] * t[m]) +
IM(s[m]) * sin(w[k] * t[m]);
IM(e[1]) = -RE(s[m]) * sin(w[k] * t[m]) +
IM(s[m]) * cos(w[k] * t[m]);
RE(y[k]) += 0.5 * (RE(e[0]) + RE(e[1]))*(t[m] - t[m-1]);
IM(y[k]) += 0.5 * (IM(e[0]) + IM(e[1]))*(t[m] - t[m-1]);
}
}
return RES_OK;
}
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fourier_series_rec(double* w, complex_t* s, int nw,
double* t, int nt, complex_t* y)
\brief Time signal reconstruction from Fourier series coefficients.
Function reconstructs the time signal:
\f[
s(t) = \sum\limits_{n = 0}^{n_{\omega}-1} S(\omega_n) \exp(j\omega_n t)
\f]
\param[in] w
Pointer to the Fourier series spectrum frequency vector \f$\omega_n\f$. \n
Vector size is `[nw x 1]`. \n
\n
\param[in] s
Pointer to the Fourier series coefficients vector \f$S(\omega_n)\f$. \n
Vector size is `[nw x 1]`. \n
\n
\param[in] nw
Number of Fourier series coefficients. \n
This value must be positive. \n
\n
\param[in] t
Pointer to the reconstructed signal time vector. \n
Vector size is `[nt x 1]`. \n
\n
\param[in] nt
Size of time vector and reconstructed signal vector . \n
\n
\param[out] y
Pointer to the reconstructed signal vector. \n
Vector size is `[nt x 1]`. \n
Memory must be allocated. \n
\n
\return
`RES_OK` if function is calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error".
\note
The output reconstructed signal is generally complex.
However, subject to the symmetry properties of the vectors `w` and` s`
with respect to zero frequency we get the imaginary part of the vector `y`
at the EPS level. The negligible imaginary part in this case
can be ignored.
\n
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup DFT_GROUP
\fn int fourier_series_rec(double* w, complex_t* s, int nw,
double* t, int nt, complex_t* y)
\brief Восстановление сигнала при усечении ряда Фурье
Функция рассчитывает восстановленный сигнал при усечении ряда Фурье:
\f[
s(t) = \sum\limits_{n = 0}^{n_{\omega}-1} S(\omega_n) \exp(j\omega_n t)
\f]
\param[in] w
Указатель на массив частот \f$\omega_n\f$ усеченного ряда Фурье. \n
Размер вектора `[nw x 1]`. \n
Память должна быть выделена и заполнена. \n
\n
\param[in] s
Указатель на массив значений спектра \f$S(\omega_n)\f$. \n
Размер вектора `[nw x 1]`. \n
Память должна быть выделена и заполнена. \n
\n
\param[in] nw
Количество членов усеченного ряда Фурье. \n
Значение должно быть положительным. \n
\n
\param[in] t
Указатель на массив временных отсчетов восстановленного сигнала. \n
Размер вектора `[nt x 1]`. \n
Память должна быть выделена и заполнена. \n
\n
\param[in] nt
Размер вектора времени и восстановленного сигнала. \n
\n
\param[out] y
Указатель на массив восстановленного сигнала. \n
Размер вектора `[nt x 1]`. \n
Память должна быть выделена. \n
\n
\return
`RES_OK` --- восстановление сигнала прошло успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
\note
Выходной восстановленный сигнал в общем случае является комплексным.
Однако при соблюдении свойств симметрии векторов `w` и `s` относительно
нулевой частоты получим мнимую часть элементов вектора `y` на уровне ошибок
округления числа с двойной точностью. Ничтожно малую мнимую часть в этом случае
можно игнорировать.
\n
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API fourier_series_rec(double* w, complex_t* s, int nw,
double* t, int nt, complex_t* y)
{
int k, m;
complex_t e;
if(!t || !s || !w || !y)
return ERROR_PTR;
if(nt<1 || nw < 1)
return ERROR_SIZE;
memset(y, 0, nt*sizeof(complex_t));
for(k = 0; k < nw; k++)
{
for(m = 0; m < nt; m++)
{
RE(e) = cos(w[k] * t[m]);
IM(e) = sin(w[k] * t[m]);
RE(y[m]) += CMRE(s[k], e);
IM(y[m]) += CMIM(s[k], e);
}
}
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,10 @@
#include "math_poly/poly_z2a_cmplx.c"
#include "math_poly/polyroots.c"
#include "math_poly/polyval.c"
#include "math_poly/polyval_cmplx.c"
#include "math_poly/cheby_poly1.c"
#include "math_poly/cheby_poly2.c"

Wyświetl plik

@ -0,0 +1,177 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup SPEC_MATH_POLY_GROUP
\fn int cheby_poly1(double* x, int n, int ord, double* y)
\brief Chebyshev polynomial of the first kind order `ord`
Function calculates Chebyshev polynomial \f$ C_{ord}(x)\f$ of the first kind
order `ord` for the real vector `x` (length `n`) by recurrent equation:
\f[
C_{ord}(x) = 2 x C_{ord-1}(x) - C_{ord-2}(x),
\f]
where \f$ C_0(x) = 1 \f$, \f$ C_1(x) = x\f$
\param[in] x
Pointer to the real argument vector `x`. \n
Vector size is `[n x 1]`. \n \n
\param[in] n
Size of vectors `x` and `y`. \n \n
\param[in] ord
Chebyshev polynomial order. \n \n
\param[out] y
Pointer to the Chebyshev polynomial values, corresponds to the argument `x`. \n
Vector size is `[n x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if Chebyshev polynomial is calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error". \n
Example:
\include cheby_poly1_test.c
Text files will be created in `dat` directory: \n
\verbatim
cheby_poly1_ord1.txt
cheby_poly1_ord2.txt
cheby_poly1_ord3.txt
cheby_poly1_ord4.txt
\endverbatim
GNUPLOT package will create Chebyshev polynomials plot from saved text-files:
\image html cheby_poly1.png
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup SPEC_MATH_POLY_GROUP
\fn int cheby_poly1(double* x, int n, int ord, double* y)
\brief Многочлен Чебышева первого рода порядка `ord`
Функция производит расчет многочлена Чебышева первого рода \f$ C_{ord}(x)\f$ для
вещественного вектора `x` длины `n`на основе рекуррентной формулы
\f[
C_{ord}(x) = 2 x C_{ord-1}(x) - C_{ord-2}(x),
\f]
где \f$ C_0(x) = 1 \f$, \f$ C_1(x) = x\f$
\param[in] x
Указатель на вектор `x` аргумента полинома Чебышева первого рода. \n
Размер вектора `[n x 1]`. \n \n
\param[in] n
Размер векторов `x` и `y`. \n \n
\param[in] ord
Порядок полинома Чебышева первого рода. \n \n
\param[out] y
Указатель на вектор значений полинома Чебышева,
соответствующих аргументу `x`. \n
Размер вектора `[n x 1]`. \n
Память должна быть выделена. \n \n
\return
`RES_OK` Расчет произведен успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
Пример использования функции:
\include cheby_poly1_test.c
В каталоге `dat` будут созданы текстовые файлы значений
полиномов порядка 1-4: \n
\verbatim
cheby_poly1_ord1.txt
cheby_poly1_ord2.txt
cheby_poly1_ord3.txt
cheby_poly1_ord4.txt
\endverbatim
Кроме того программа GNUPLOT произведет построение следующих графиков
по сохраненным в файлах данным:
\image html cheby_poly1.png
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API cheby_poly1(double* x, int n, int ord, double* y)
{
int k, m;
double t[2];
if(!x || !y)
return ERROR_PTR;
if(n < 1)
return ERROR_SIZE;
if(ord<0)
return ERROR_POLY_ORD;
if(ord==0)
{
for(k = 0; k < n; k++)
{
y[k] = 1.0;
}
return RES_OK;
}
if(ord==1)
{
memcpy(y, x, n*sizeof(double));
return RES_OK;
}
for(k = 0; k < n; k++)
{
m = 2;
t[1] = x[k];
t[0] = 1.0;
while(m <= ord)
{
y[k] = 2.0 * x[k] *t[1] - t[0];
t[0] = t[1];
t[1] = y[k];
m++;
}
}
return RES_OK;
}

Wyświetl plik

@ -24,158 +24,6 @@
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup SPEC_MATH_POLY_GROUP
\fn int cheby_poly1(double* x, int n, int ord, double* y)
\brief Chebyshev polynomial of the first kind order `ord`
Function calculates Chebyshev polynomial \f$ C_{ord}(x)\f$ of the first kind
order `ord` for the real vector `x` (length `n`) by recurrent equation:
\f[
C_{ord}(x) = 2 x C_{ord-1}(x) - C_{ord-2}(x),
\f]
where \f$ C_0(x) = 1 \f$, \f$ C_1(x) = x\f$
\param[in] x
Pointer to the real argument vector `x`. \n
Vector size is `[n x 1]`. \n \n
\param[in] n
Size of vectors `x` and `y`. \n \n
\param[in] ord
Chebyshev polynomial order. \n \n
\param[out] y
Pointer to the Chebyshev polynomial values, corresponds to the argument `x`. \n
Vector size is `[n x 1]`. \n
Memory must be allocated. \n \n
\return
`RES_OK` if Chebyshev polynomial is calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error". \n
Example:
\include cheby_poly1_test.c
Text files will be created in `dat` directory: \n
\verbatim
cheby_poly1_ord1.txt
cheby_poly1_ord2.txt
cheby_poly1_ord3.txt
cheby_poly1_ord4.txt
\endverbatim
GNUPLOT package will create Chebyshev polynomials plot from saved text-files:
\image html cheby_poly1.png
\author Sergey Bakhurin www.dsplib.org
***************************************************************************** */
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup SPEC_MATH_POLY_GROUP
\fn int cheby_poly1(double* x, int n, int ord, double* y)
\brief Многочлен Чебышева первого рода порядка `ord`
Функция производит расчет многочлена Чебышева первого рода \f$ C_{ord}(x)\f$ для
вещественного вектора `x` длины `n`на основе рекуррентной формулы
\f[
C_{ord}(x) = 2 x C_{ord-1}(x) - C_{ord-2}(x),
\f]
где \f$ C_0(x) = 1 \f$, \f$ C_1(x) = x\f$
\param[in] x
Указатель на вектор `x` аргумента полинома Чебышева первого рода. \n
Размер вектора `[n x 1]`. \n \n
\param[in] n
Размер векторов `x` и `y`. \n \n
\param[in] ord
Порядок полинома Чебышева первого рода. \n \n
\param[out] y
Указатель на вектор значений полинома Чебышева,
соответствующих аргументу `x`. \n
Размер вектора `[n x 1]`. \n
Память должна быть выделена. \n \n
\return
`RES_OK` Расчет произведен успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
Пример использования функции:
\include cheby_poly1_test.c
В каталоге `dat` будут созданы текстовые файлы значений
полиномов порядка 1-4: \n
\verbatim
cheby_poly1_ord1.txt
cheby_poly1_ord2.txt
cheby_poly1_ord3.txt
cheby_poly1_ord4.txt
\endverbatim
Кроме того программа GNUPLOT произведет построение следующих графиков
по сохраненным в файлах данным:
\image html cheby_poly1.png
\author Бахурин Сергей www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API cheby_poly1(double* x, int n, int ord, double* y)
{
int k, m;
double t[2];
if(!x || !y)
return ERROR_PTR;
if(n < 1)
return ERROR_SIZE;
if(ord<0)
return ERROR_POLY_ORD;
if(ord==0)
{
for(k = 0; k < n; k++)
{
y[k] = 1.0;
}
return RES_OK;
}
if(ord==1)
{
memcpy(y, x, n*sizeof(double));
return RES_OK;
}
for(k = 0; k < n; k++)
{
m = 2;
t[1] = x[k];
t[0] = 1.0;
while(m <= ord)
{
y[k] = 2.0 * x[k] *t[1] - t[0];
t[0] = t[1];
t[1] = y[k];
m++;
}
}
return RES_OK;
}
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup SPEC_MATH_POLY_GROUP

Wyświetl plik

@ -0,0 +1,65 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API poly_z2a_cmplx(complex_t* z, int nz, int ord, complex_t* a)
{
int k, ind, res;
complex_t x[2];
if(!z || !a)
return ERROR_PTR;
if(nz < 0)
return ERROR_SIZE;
if(nz > ord || ord < 1)
return ERROR_POLY_ORD;
RE(x[1]) = 1.0;
IM(x[1]) = 0.0;
memset(a, 0, (ord+1) * sizeof(complex_t));
RE(a[0]) = 1.0;
ind = 1;
for(k = 0; k < nz; k++)
{
RE(x[0]) = -RE(z[k]);
IM(x[0]) = -IM(z[k]);
res = conv_cmplx(a, ind, x, 2, a);
if(res!=RES_OK)
return res;
ind++;
}
return RES_OK;
}

Wyświetl plik

@ -18,58 +18,16 @@
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API poly_z2a_cmplx(complex_t* z, int nz, int ord, complex_t* a)
{
int k, ind, res;
complex_t x[2];
if(!z || !a)
return ERROR_PTR;
if(nz < 0)
return ERROR_SIZE;
if(nz > ord || ord < 1)
return ERROR_POLY_ORD;
RE(x[1]) = 1.0;
IM(x[1]) = 0.0;
memset(a, 0, (ord+1) * sizeof(complex_t));
RE(a[0]) = 1.0;
ind = 1;
for(k = 0; k < nz; k++)
{
RE(x[0]) = -RE(z[k]);
IM(x[0]) = -IM(z[k]);
res = conv_cmplx(a, ind, x, 2, a);
if(res!=RES_OK)
return res;
ind++;
}
return RES_OK;
}
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup SPEC_MATH_COMMON_GROUP
\ingroup SPEC_MATH_POLY_GROUP
\fn int polyroots(double* a, int ord, complex_t* r, int* info)
\brief Function calculates real polynomial roots.
@ -132,7 +90,7 @@ r[1] = -1.00000-1.00000 j
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup SPEC_MATH_COMMON_GROUP
\ingroup SPEC_MATH_POLY_GROUP
\fn int polyroots(double* a, int ord, complex_t* r, int* info)
\brief Расчет корней вещественного полинома
@ -226,159 +184,3 @@ int DSPL_API polyroots(double* a, int ord, complex_t* r, int* info)
free(t);
return err;
}
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup SPEC_MATH_COMMON_GROUP
\fn int polyval(double* a, int ord, double* x, int n, double* y)
\brief Расчет вещественного полинома
Функция рассчитывает полином \f$P_N(x)\f$ \f$N-\f$ого порядка для вещественного
аргумента, заданного вектором `x`.
\f[
P_N(x) = a_0 + a_1 \cdot x + a_2 \cdot x^2 +
a_3 \cdot x^3 + ... a_N \cdot x^N.
\f]
Для расчета используется формула Горнера:
\f[
P_N(x) = a_0 + x \cdot (a_1 + x \cdot (a_2 + \cdot
( \ldots x \cdot (a_{N-1} + x\cdot a_N) \ldots )))
\f]
\param[in] a
Указатель на вектор вещественных коэффициентов полинома. \n
Размер вектора `[ord+1 x 1]`. \n
Коэффициент `a[0]` соответствует коэффициенту полинома \f$a_0\f$. \n \n
\param[in] ord
Порядок полинома \f$N\f$. \n \n
\param[in] x
Указатель на вектор аргумента полинома. \n
Размер вектора `[n x 1]`. \n
Значения полинома будут расчитаны для всех значений аргумента вектора `x`. \n\n
\param[in] n
Размер вектора агрумента полинома. \n \n
\param[out] y
Указатель на значения полинома для аргумента `x`. \n
Размер вектора `[n x 1]`. \n
Память должна быть выделена. \n\n
\return
`RES_OK` --- полином рассчитан успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
\author Бахурин Сергей. www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API polyval(double* a, int ord, double* x, int n, double* y)
{
int k, m;
if(!a || !x || !y)
return ERROR_PTR;
if(ord<0)
return ERROR_POLY_ORD;
if(n<1)
return ERROR_SIZE;
for(k = 0; k < n; k++)
{
y[k] = a[ord];
for(m = ord-1; m>-1; m--)
y[k] = y[k]*x[k] + a[m];
}
return RES_OK;
}
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup SPEC_MATH_COMMON_GROUP
\fn int polyval_cmplx(complex_t* a, int ord, complex_t* x, int n, complex_t* y)
\brief Расчет комплексного полинома
Функция рассчитывает полином \f$P_N(x)\f$ \f$N\f$-го порядка
комплексного аргумента, заданного вектором `x`. \n
\f[
P_N(x) = a_0 + a_1 \cdot x + a_2 \cdot x^2 + a_3 \cdot x^3 + ... a_N \cdot x^N.
\f]
Для расчета используется формула Горнера: \n
\f[
P_N(x) = a_0 + x \cdot (a_1 + x \cdot (a_2 + \cdot
( \ldots x \cdot (a_{N-1} + x\cdot a_N) \ldots )))
\f]
\param[in] a
Указатель на вектор комплексных коэффициентов полинома. \n
Размер вектора `[ord+1 x 1]`. \n
Коэффициент `a[0]` соответствует коэффициенту полинома \f$a_0\f$. \n \n
\param[in] ord
Порядок полинома \f$N\f$. \n \n
\param[in] x
Указатель на вектор аргумента полинома. \n
Размер вектора `[n x 1]`. \n
Значения полинома будут расчитаны для всех значений аргумента вектора `x`. \n \n
\param[in] n
Размер вектора агрумента полинома. \n\n
\param[out] y
Указатель вектор значения полинома для аргумента `x`. \n
Размер вектора `[n x 1]`. \n
Память должна быть выделена. \n \n
\return
`RES_OK` --- полином расчитан успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
\author Бахурин Сергей. www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API polyval_cmplx(complex_t* a, int ord,
complex_t* x, int n, complex_t* y)
{
int k, m;
complex_t t;
if(!a || !x || !y)
return ERROR_PTR;
if(ord<0)
return ERROR_POLY_ORD;
if(n<1)
return ERROR_SIZE;
for(k = 0; k < n; k++)
{
RE(y[k]) = RE(a[ord]);
IM(y[k]) = IM(a[ord]);
for(m = ord-1; m>-1; m--)
{
RE(t) = CMRE(y[k], x[k]);
IM(t) = CMIM(y[k], x[k]);
RE(y[k]) = RE(t) + RE(a[m]);
IM(y[k]) = IM(t) + IM(a[m]);
}
}
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,96 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup SPEC_MATH_POLY_GROUP
\fn int polyval(double* a, int ord, double* x, int n, double* y)
\brief Расчет вещественного полинома
Функция рассчитывает полином \f$P_N(x)\f$ \f$N-\f$ого порядка для вещественного
аргумента, заданного вектором `x`.
\f[
P_N(x) = a_0 + a_1 \cdot x + a_2 \cdot x^2 +
a_3 \cdot x^3 + ... a_N \cdot x^N.
\f]
Для расчета используется формула Горнера:
\f[
P_N(x) = a_0 + x \cdot (a_1 + x \cdot (a_2 + \cdot
( \ldots x \cdot (a_{N-1} + x\cdot a_N) \ldots )))
\f]
\param[in] a
Указатель на вектор вещественных коэффициентов полинома. \n
Размер вектора `[ord+1 x 1]`. \n
Коэффициент `a[0]` соответствует коэффициенту полинома \f$a_0\f$. \n \n
\param[in] ord
Порядок полинома \f$N\f$. \n \n
\param[in] x
Указатель на вектор аргумента полинома. \n
Размер вектора `[n x 1]`. \n
Значения полинома будут расчитаны для всех значений аргумента вектора `x`. \n\n
\param[in] n
Размер вектора агрумента полинома. \n \n
\param[out] y
Указатель на значения полинома для аргумента `x`. \n
Размер вектора `[n x 1]`. \n
Память должна быть выделена. \n\n
\return
`RES_OK` --- полином рассчитан успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
\author Бахурин Сергей. www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API polyval(double* a, int ord, double* x, int n, double* y)
{
int k, m;
if(!a || !x || !y)
return ERROR_PTR;
if(ord<0)
return ERROR_POLY_ORD;
if(n<1)
return ERROR_SIZE;
for(k = 0; k < n; k++)
{
y[k] = a[ord];
for(m = ord-1; m>-1; m--)
y[k] = y[k]*x[k] + a[m];
}
return RES_OK;
}

Wyświetl plik

@ -0,0 +1,107 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup SPEC_MATH_POLY_GROUP
\fn int polyval_cmplx(complex_t* a, int ord, complex_t* x, int n, complex_t* y)
\brief Расчет комплексного полинома
Функция рассчитывает полином \f$P_N(x)\f$ \f$N\f$-го порядка
комплексного аргумента, заданного вектором `x`. \n
\f[
P_N(x) = a_0 + a_1 \cdot x + a_2 \cdot x^2 + a_3 \cdot x^3 + ... a_N \cdot x^N.
\f]
Для расчета используется формула Горнера: \n
\f[
P_N(x) = a_0 + x \cdot (a_1 + x \cdot (a_2 + \cdot
( \ldots x \cdot (a_{N-1} + x\cdot a_N) \ldots )))
\f]
\param[in] a
Указатель на вектор комплексных коэффициентов полинома. \n
Размер вектора `[ord+1 x 1]`. \n
Коэффициент `a[0]` соответствует коэффициенту полинома \f$a_0\f$. \n \n
\param[in] ord
Порядок полинома \f$N\f$. \n \n
\param[in] x
Указатель на вектор аргумента полинома. \n
Размер вектора `[n x 1]`. \n
Значения полинома будут расчитаны для всех значений аргумента вектора `x`. \n \n
\param[in] n
Размер вектора агрумента полинома. \n\n
\param[out] y
Указатель вектор значения полинома для аргумента `x`. \n
Размер вектора `[n x 1]`. \n
Память должна быть выделена. \n \n
\return
`RES_OK` --- полином расчитан успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
\author Бахурин Сергей. www.dsplib.org
***************************************************************************** */
#endif
int DSPL_API polyval_cmplx(complex_t* a, int ord,
complex_t* x, int n, complex_t* y)
{
int k, m;
complex_t t;
if(!a || !x || !y)
return ERROR_PTR;
if(ord<0)
return ERROR_POLY_ORD;
if(n<1)
return ERROR_SIZE;
for(k = 0; k < n; k++)
{
RE(y[k]) = RE(a[ord]);
IM(y[k]) = IM(a[ord]);
for(m = ord-1; m>-1; m--)
{
RE(t) = CMRE(y[k], x[k]);
IM(t) = CMIM(y[k], x[k]);
RE(y[k]) = RE(t) + RE(a[m]);
IM(y[k]) = IM(t) + IM(a[m]);
}
}
return RES_OK;
}

Wyświetl plik

@ -22,6 +22,8 @@ LAPACK_DOUBLE_LIB_NAME = $(LAPACK_RELEASE_DIR)/liblapack_double.a
LAPACK_COMPLEX_SRC_DIR = $(LAPACK_LIB_DIR)/src
LAPACK_COMPLEX_LIB_NAME = $(LAPACK_RELEASE_DIR)/liblapack_complex.a
INC_DIR = ../include
RELEASE_DIR = ../_release
EXAMPLE_BIN_DIR = ../examples/bin