pull/6/merge
Sergey Bakhurin 2019-06-09 15:30:11 +03:00
rodzic 5da9d064a1
commit ba715696a5
12 zmienionych plików z 288 dodań i 142 usunięć

Wyświetl plik

@ -59,12 +59,12 @@
\defgroup SPEC_MATH_GROUP Специальные математические функции
\ingroup MAIN_GROUP
\defgroup SPEC_MATH_COMMON_GROUP Базовые математические функции
\defgroup SPEC_MATH_COMMON_GROUP Базовые математические функции и работа с массивами данных
\ingroup SPEC_MATH_GROUP
\defgroup SPEC_MATH_TRIG_GROUP Тригонометрические и гиперболические функции
вещественного и комплексного аргумента.
вещественного и комплексного аргумента
\ingroup SPEC_MATH_GROUP
\defgroup SPEC_MATH_TRANSCEND Высшие трансцендентные функции

Wyświetl plik

@ -0,0 +1,54 @@
/*! ****************************************************************************
\ingroup SPEC_MATH_COMMON_GROUP
\fn int concat(void* a, size_t na, void* b, size_t nb, void* c)
\brief Конкатенация двух массивов данных
Функция производит конкатенацию двух массивов. Пусть массивы `a` и `b`
заданы как векторы:<BR>
`a = [a(0), a(1), ... a(na-1)]`, <BR>
`b = [b(0), b(1), ... b(nb-1)]`, <BR>
тогда результатом конкатенации будет вектор размера `na+nb` вида:<BR>
`c = [a(0), a(1), ... a(na-1), b(0), b(1), ... b(nb-1)]`.
\param[in] a Указатель на первый вектор `a`.<BR>
Размер вектора `na` байт.<BR><BR>
\param[in] na Размер первого вектора `a` в байт.<BR><BR>
\param[in] b Указатель на второй вектор `b`.<BR>
Размер памяти вектора `nb` байт.<BR><BR>
\param[in] nb Размер второго вектора `b` в байт.<BR><BR>
\param[out] c Указатель на вектор конкатенации `c`.<BR>
Размер памяти вектора `na + nb` байт.<BR>
Память должна быть выделена.<BR><BR>
\return
`RES_OK` если функция выполнена успешно.<BR>
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
Функция использует указатели типа `void*` и может быть использована для
конкатенации данных различного типа.<BR>
Например конкатенация массивов типа `double`:
\code
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` будет хранить массив данных:
\code
c = [1.0, 2.0, 3.0, 4.0, 5.0]
\endcode
\author
Бахурин Сергей
www.dsplib.org
**************************************************************************** */

Wyświetl plik

@ -1,35 +1,34 @@
/*! **************************************************************************************************
\ingroup FILTER_CONV_GROUP
\fn int conv(double* a, int na, double* b, int nb, double* c)
\brief Линейная свертка двух вещественных векторов
/*! ****************************************************************************
\ingroup FILTER_CONV_GROUP
\fn int conv(double* a, int na, double* b, int nb, double* c)
\brief Линейная свертка двух вещественных векторов
Функция рассчитывает линейную свертку двух векторов \f$ c = a * b\f$.
Функция рассчитывает линейную свертку двух векторов \f$ c = a * b\f$.
\param[in] a Указатель на первый вектор \f$a\f$.<BR>
Размер вектора `[na x 1]`.<BR><BR>
\param[in] na Размер первого вектора.<BR><BR>
\param[in] b Указатель на второй вектор \f$b\f$.<BR>
Размер вектора `[nb x 1]`.<BR><BR>
\param[in] nb азмер второго вектора.<BR><BR>
\param[out] c Указатель на вектор свертки \f$ c = a * b\f$.<BR>
Размер вектора `[na + nb - 1 x 1]`.<BR>
Память должна быть выделена.<BR><BR>
\return
`RES_OK` если свертка расчитана успешно.<BR>
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
\param[in] a Указатель на первый вектор \f$a\f$.<BR>
Размер вектора `[na x 1]`.<BR><BR>
\author
Бахурин Сергей
www.dsplib.org
\param[in] na Размер первого вектора.<BR><BR>
**************************************************************************************************** */
\param[in] b Указатель на второй вектор \f$b\f$.<BR>
Размер вектора `[nb x 1]`.<BR><BR>
\param[in] nb Размер второго вектора.<BR><BR>
\param[out] c Указатель на вектор свертки \f$ c = a * b\f$.<BR>
Размер вектора `[na + nb - 1 x 1]`.<BR>
Память должна быть выделена.<BR><BR>
\return
`RES_OK` если свертка расчитана успешно.<BR>
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
\author
Бахурин Сергей
www.dsplib.org
**************************************************************************** */
@ -38,37 +37,36 @@
/*! **************************************************************************************************
\ingroup FILTER_CONV_GROUP
\fn int conv_cmplx(complex_t* a, int na, complex_t* b, int nb, complex_t* c)
\brief Линейная свертка двух комплексных векторов
/*! ****************************************************************************
\ingroup FILTER_CONV_GROUP
\fn int conv_cmplx(complex_t* a, int na, complex_t* b, int nb, complex_t* c)
\brief Линейная свертка двух комплексных векторов
Функция рассчитывает линейную свертку двух векторов \f$ c = a * b\f$.
Функция рассчитывает линейную свертку двух векторов \f$ c = a * b\f$.
\param[in] a Указатель на первый вектор \f$a\f$.<BR>
Размер вектора `[na x 1]`.<BR><BR>
\param[in] na Размер первого вектора.<BR><BR>
\param[in] b Указатель на второй вектор \f$b\f$.<BR>
Размер вектора `[nb x 1]`.<BR><BR>
\param[in] nb Размер второго вектора.<BR><BR>
\param[out] c Указатель на вектор свертки \f$ c = a * b\f$.<BR>
Размер вектора `[na + nb - 1 x 1]`.<BR>
Память должна быть выделена.<BR><BR>
\return
`RES_OK` если свертка расчитана успешно.<BR>
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
\param[in] a Указатель на первый вектор \f$a\f$.<BR>
Размер вектора `[na x 1]`.<BR><BR>
\author
Бахурин Сергей
www.dsplib.org
\param[in] na Размер первого вектора.<BR><BR>
*************************************************************************************************** */
\param[in] b Указатель на второй вектор \f$b\f$.<BR>
Размер вектора `[nb x 1]`.<BR><BR>
\param[in] nb Размер второго вектора.<BR><BR>
\param[out] c Указатель на вектор свертки \f$ c = a * b\f$.<BR>
Размер вектора `[na + nb - 1 x 1]`.<BR>
Память должна быть выделена.<BR><BR>
\return
`RES_OK` если свертка расчитана успешно.<BR>
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
\author
Бахурин Сергей
www.dsplib.org
***************************************************************************** */
@ -77,50 +75,49 @@
/*! **************************************************************************************************
\ingroup FILTER_CONV_GROUP
\fn int filter_iir(double* b, double* a, int ord, double* x, int n, double* y)
\brief Фильтрация вещественного сигнала вещественным БИХ-фильтром
/*! ****************************************************************************
\ingroup FILTER_CONV_GROUP
\fn int filter_iir(double* b, double* a, int ord, double* x, int n, double* y)
\brief Фильтрация вещественного сигнала вещественным БИХ-фильтром
Функция рассчитывает выход фильтра заданного выражением
\f[
H(z) = \frac{\sum_{n = 0}^{N} b_n z^{-n}}
{1+{\frac{1}{a_0}}\sum_{m = 1}^{M} a_m z^{-n}},
\f]
где \f$a_0\f$ не может быть 0, \f$N=M=\f$`ord`.
Функция рассчитывает выход фильтра заданного выражением
\f[
H(z) = \frac{\sum_{n = 0}^{N} b_n z^{-n}}
{1+{\frac{1}{a_0}}\sum_{m = 1}^{M} a_m z^{-n}},
\f]
где \f$a_0\f$ не может быть 0, \f$N=M=\f$`ord`.
\param[in] b Указатель на вектор коэффициентов числителя
передаточной функции БИХ-фильтра.<BR>
Размер вектора `[ord + 1 x 1]`.<BR><BR>
\param[in] b Указатель на вектор коэффициентов числителя
передаточной функции БИХ-фильтра.<BR>
Размер вектора `[ord + 1 x 1]`.<BR><BR>
\param[in] a Указатель на вектор коэффициентов знаменателя
передаточной функции БИХ-фильтра.<BR>
Размер вектора `[ord + 1 x 1]`.<BR>
Этот указатель может быть `NULL`,
тогда фильтрация производится без использования
рекурсивной части.<BR><BR>
\param[in] ord Порядок фильтра. Количество коэффициентов числителя
и знаменателя передаточной функции
БИХ-фильтра равно `ord + 1`.<BR><BR>
\param[in] a Указатель на вектор коэффициентов знаменателя
передаточной функции БИХ-фильтра.<BR>
Размер вектора `[ord + 1 x 1]`.<BR>
Этот указатель может быть `NULL`,
тогда фильтрация производится без использования
рекурсивной части.<BR><BR>
\param[in] x Указатель на вектор отсчетов входного сигнала.<BR>
Размер вектора `[n x 1]`.<BR><BR>
\param[in] n Длина входного сигнала.<BR><BR>
\param[out] y Указатель на вектор выходных отсчетов фильтра.<BR>
Размер вектора `[n x 1]`.<BR>
Память должна быть выделена заранее.<BR><BR>
\return
`RES_OK` Если фильтрация произведена успешно.<BR>
В противном случае \ref ERROR_CODE_GROUP "код ошибки":<BR>
\param[in] ord Порядок фильтра. Количество коэффициентов числителя
и знаменателя передаточной функции
БИХ-фильтра равно `ord + 1`.<BR><BR>
\author
Бахурин Сергей
www.dsplib.org
\param[in] x Указатель на вектор отсчетов входного сигнала.<BR>
Размер вектора `[n x 1]`.<BR><BR>
************************************************************************************************** */
\param[in] n Длина входного сигнала.<BR><BR>
\param[out] y Указатель на вектор выходных отсчетов фильтра.<BR>
Размер вектора `[n x 1]`.<BR>
Память должна быть выделена заранее.<BR><BR>
\return
`RES_OK` Если фильтрация произведена успешно.<BR>
В противном случае \ref ERROR_CODE_GROUP "код ошибки":<BR>
\author
Бахурин Сергей
www.dsplib.org
***************************************************************************** */

Wyświetl plik

@ -62,9 +62,9 @@ s \leftarrow \frac{1 - z^{-1}}{1 - z^{-1}}.
\include bilinear_test.c
Данная программа производит расчет передаточной характеристики аналогового фильта
Чебышева первого рода, с частотой среза равной 1 рад/с, и производит билинейное
преобразование в цифровой, с частотой среза равной 0.5.
Данная программа производит расчет передаточной характеристики аналогового
фильтра Чебышева первого рода, с частотой среза равной 1 рад/с, и производит
билинейное преобразование в цифровой, с частотой среза равной 0.5.
Результат работы программы:
@ -78,7 +78,7 @@ err = 0
\endverbatim
Кроме этого производится расчет АЧХ полученного цифрового фильтра и строится
график АЧХ пакетом GNUPLOT^
график АЧХ пакетом GNUPLOT
\image html bilinear.png

Wyświetl plik

@ -26,9 +26,52 @@
/******************************************************************************
Concntenate arrays
\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:<BR>
`a = [a(0), a(1), ... a(na-1)]`, <BR>
`b = [b(0), b(1), ... b(nb-1)]`, <BR>
concatenation of these arrays will be array `c` size `na+nb`:<BR>
`c = [a(0), a(1), ... a(na-1), b(0), b(1), ... b(nb-1)]`.
\param[in] a Pointer to the first array `a`.<BR>
Array `a` size is `na` bytes.<BR><BR>
\param[in] na Array `a` size (bytes).<BR><BR>
\param[in] b Pointer to the second array `b`.<BR>
Array `b` size is `nb` bytes.<BR><BR>
\param[in] nb Array `a` size (bytes).<BR><BR>
\param[out] c Pointer to the concatenation result array `c`.<BR>
Array `c` size is `na + nb` bytes.<BR>
Memory must be allocated.<BR><BR>
\return
`RES_OK` if function returns successfully.<BR>
Else \ref ERROR_CODE_GROUP "code error".
Function uses pointer type `void*` and can be useful for an arrays
concatenation with different types.<BR>
For example two `double` arrays concatenation:
\code
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:
\code
c = [1.0, 2.0, 3.0, 4.0, 5.0]
\endcode
\author Sergey Bakhurin www.dsplib.org
*******************************************************************************/
int DSPL_API concat(void* a, size_t na, void *b, size_t nb, void* c)
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;
@ -79,7 +122,7 @@ int DSPL_API decimate(double* x, int n, int dec, double* y, int* cnt)
decimate complex vector
*******************************************************************************/
int DSPL_API decimate_cmplx(complex_t* x, int n, int dec,
complex_t* y, int* cnt)
complex_t* y, int* cnt)
{
int k = 0, i = 0;
if(!x || !y)
@ -231,8 +274,8 @@ int DSPL_API verif_cmplx(complex_t* x, complex_t* y, size_t n,
{
complex_t d;
double mx, md, maxd;
size_t k;
double mx, md, maxd;
size_t k;
int res;
if(!x || !y)
return ERROR_PTR;
@ -256,7 +299,7 @@ int DSPL_API verif_cmplx(complex_t* x, complex_t* y, size_t n,
maxd = md;
}
}
if(err)
if(err)
*err = maxd;
if(maxd > eps)

Wyświetl plik

@ -392,7 +392,7 @@ void dft16 (complex_t *x, complex_t* y)
}
/*******************************************************************************
16 x 16 matrix transpose
4 x 4 matrix transpose
*******************************************************************************/
void transpose4x4(complex_t *x, complex_t* y)
{

Wyświetl plik

@ -26,8 +26,56 @@
/******************************************************************************
Bilinear transform H(s) -> H(z)
/*******************************************************************************
\ingroup IIR_FILTER_DESIGN_GROUP
\fn int bilinear(double* bs, double* as, int ord, double* bz, double* az)
\brief Analog filter transfer function H(s) bilinear transform to the
digital filter transfer function H(z).
Function calculates digital filter coefficients by rational substitution
\f[
s \leftarrow \frac{1 - z^{-1}}{1 - z^{-1}}.
\f]
Digital filter order still the same as analog prototype order.
Analog prototype frequency \f$\Omega\f$ related with the digital filter
normalized frequency \f$\omega\f$ as:
\f[
\Omega = \tan(\omega / 2).
\f]
\param[in] bs Pointer to the numerator coefficients of an
analog prototype transfer function \f$H(s)\f$. <BR>
Array size is `[ord+1 x 1]`.<BR>
Memory must be allocated.<BR><BR>
\param[in] as Pointer to the denominator coefficients of an
analog prototype transfer function \f$H(s)\f$. <BR>
Array size is `[ord+1 x 1]`.<BR>
Memory must be allocated.<BR><BR>
\param[in] ord Filter order.<BR>
Number of coefficients \f$H(s)\f$ and \f$H(z)\f$
numerator and denominator equals `ord+1`.<BR><BR>
\param[out] bz Pointer to the numerator coefficients of a
digital filter transfer function \f$H(z)\f$. <BR>
Array size is `[ord+1 x 1]`.<BR>
Memory must be allocated.<BR><BR>
\param[out] az Pointer to the numerator coefficients of a
digital filter transfer function \f$H(z)\f$. <BR>
Array size is `[ord+1 x 1]`.<BR>
Memory must be allocated.<BR><BR>
\return
`RES_OK` if filter is calculated successfully.<BR><BR>
Else \ref ERROR_CODE_GROUP "code error".<BR>
\author Sergey Bakhurin www.dsplib.org
*******************************************************************************/
int DSPL_API bilinear(double* bs, double* as, int ord, double* bz, double* az)
{

Wyświetl plik

@ -6,27 +6,28 @@
#define N 16
int main()
{
void* handle; // DSPL handle
handle = dspl_load(); // Load DSPL function
void* handle; // DSPL handle
handle = dspl_load(); // Load DSPL function
complex_t y[N]; // DFT
complex_t x[N]; // complex input signal
complex_t y[N]; // DFT
complex_t x[N]; // complex input signal
int k;
for(int k = 0; k < N; k++)
{
RE(x[k]) = (double)k;
IM(x[k]) = 0.0;
}
for(k = 0; k < N; k++)
{
RE(x[k]) = (double)k;
IM(x[k]) = 0.0;
}
dft_cmplx(x,N,y);
dft_cmplx(x,N,y);
for(int k = 0; k < N; k++)
printf("y[%2d] = %9.3f%9.3f\n", k, RE(y[k]), IM(y[k]));
dspl_free(handle); // remember to free the resource
return 0;
for(k = 0; k < N; k++)
printf("y[%2d] = %9.3f%9.3f\n", k, RE(y[k]), IM(y[k]));
dspl_free(handle); // remember to free the resource
return 0;
}

Wyświetl plik

@ -6,24 +6,24 @@
#define N 16
int main()
{
void* handle; // DSPL handle
handle = dspl_load(); // Load DSPL function
void* handle; // DSPL handle
handle = dspl_load(); // Load DSPL function
double x[N]; // real input signal
complex_t y[N]; // DFT
double x[N]; // real input signal
complex_t y[N]; // DFT
int k;
for(int k = 0; k < N; k++)
x[k] = (double)k;
for(k = 0; k < N; k++)
x[k] = (double)k;
dft(x, N, y);
dft(x, N, y);
for(int k = 0; k < N; k++)
printf("y[%2d] = %9.3f%9.3f\n", k, RE(y[k]), IM(y[k]));
dspl_free(handle); // remember to free the resource
return 0;
for(k = 0; k < N; k++)
printf("y[%2d] = %9.3f%9.3f\n", k, RE(y[k]), IM(y[k]));
dspl_free(handle); // remember to free the resource
return 0;
}

Wyświetl plik

@ -13,13 +13,14 @@ int main()
complex_t x[N]; // массив входного сигнала
complex_t y[N]; // массив результата БПФ
fft_t pfft; // FFT объект
int k;
memset(&pfft, 0, sizeof(fft_t)); // Заполняем FFT структуру нулями
fft_create(&pfft, N); // Создаем FFT структуру для длины N
// заполняем массив входного сигнала
for(int k = 0; k < N; k++)
for(k = 0; k < N; k++)
{
RE(x[k]) = (double)cos((double)k);
IM(x[k]) = (double)sin((double)k);
@ -28,7 +29,7 @@ int main()
fft_cmplx(x, N, &pfft, y); // FFT
// Печать результата
for(int k = 0; k < N; k++)
for(k = 0; k < N; k++)
printf("y[%2d] = %9.3f%9.3f\n", k, RE(y[k]), IM(y[k]));
fft_free(&pfft); // Очищаем структуру fft_t

Wyświetl plik

@ -13,19 +13,20 @@ int main()
double x[N]; // массив входного сигнала
complex_t y[N]; // массив результата БПФ
fft_t pfft; // FFT объект
int k;
memset(&pfft, 0, sizeof(fft_t)); // Заполняем FFT структуру нулями
fft_create(&pfft, N); // Создаем FFT структуру для длины N
// заполняем массив входного сигнала
for(int k = 0; k < N; k++)
for(k = 0; k < N; k++)
x[k] = (double)k;
fft(x, N, &pfft, y); // FFT
// Печать результата
for(int k = 0; k < N; k++)
for(k = 0; k < N; k++)
printf("y[%2d] = %9.3f%9.3f\n", k, RE(y[k]), IM(y[k]));
fft_free(&pfft); // Очищаем структуру fft_t

Wyświetl plik

@ -14,13 +14,14 @@ int main()
complex_t y[N]; // массив результата БПФ
complex_t z[N]; // массив результата ОБПФ
fft_t pfft; // FFT объект
int k;
memset(&pfft, 0, sizeof(fft_t)); // Заполняем FFT структуру нулями
fft_create(&pfft, N); // Создаем FFT структуру для длины N
// заполняем массив входного сигнала
for(int k = 0; k < N; k++)
for(k = 0; k < N; k++)
{
RE(x[k]) = (double)cos((double)k);
IM(x[k]) = (double)sin((double)k);
@ -30,7 +31,7 @@ int main()
ifft_cmplx(y, N, &pfft, z); // IFFT
// Печать результата
for(int k = 0; k < N; k++)
for(k = 0; k < N; k++)
{
printf("| x[%2d] = %9.3f%9.3f ", k, RE(x[k]), IM(x[k]));
printf("| y[%2d] = %9.3f%9.3f ", k, RE(y[k]), IM(y[k]));