diff --git a/dspl/src/conv.c b/dspl/src/conv.c
deleted file mode 100644
index 804672a..0000000
--- a/dspl/src/conv.c
+++ /dev/null
@@ -1,1056 +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 .
-*/
-
-#include
-#include
-#include "dspl.h"
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup FILTER_CONV_GROUP
-\fn int conv(double* a, int na, double* b, int nb, double* c)
-\brief Real vectors linear convolution.
-
-Function convolves two real vectors \f$ c = a * b\f$ length `na` and `nb`.
-The output convolution is a vector `c` with length equal to `na + nb - 1`.
-
-\param[in] a
-Pointer to the first vector `a`. \n
-Vector size is `[na x 1]`. \n \n
-
-\param[in] na
-Size of the first vector `a`. \n \n
-
-\param[in] b
-Pointer to the second vector `b`. \n
-Vector size is `[nb x 1]`. \n \n
-
-\param[in] nb
-Size of the second vector `b`. \n \n
-
-\param[out] c
-Pointer to the convolution output vector \f$ c = a * b\f$. \n
-Vector size is `[na + nb - 1 x 1]`. \n
-Memory must be allocated. \n \n
-
-\return `RES_OK` if convolution is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\note If vectors `a` and `b` are coefficients of two polynomials,
-then convolution of the vectors `a` and `b` returns polynomial product
-coefficients.
-
-Example:
-\code{.cpp}
- double ar[3] = {1.0, 2.0, 3.0};
- double br[4] = {3.0, -1.0, 2.0, 4.0};
- double cr[6];
-
- int n;
-
- conv(ar, 3, br, 4, cr);
-
- for(n = 0; n < 6; n++)
- printf("cr[%d] = %5.1f\n", n, cr[n]);
-
-\endcode
-\n
-
-Output:
-\verbatim
-cr[0] = 3.0
-cr[1] = 5.0
-cr[2] = 9.0
-cr[3] = 5.0
-cr[4] = 14.0
-cr[5] = 12.0
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup FILTER_CONV_GROUP
-\fn int conv(double* a, int na, double* b, int nb, double* c)
-\brief Линейная свертка двух вещественных векторов
-
-Функция рассчитывает линейную свертку двух векторов \f$ c = a * b\f$.
-
-\param[in] a
-Указатель на первый вектор \f$a\f$. \n
-Размер вектора `[na x 1]`. \n \n
-
-\param[in] na
-Размер первого вектора. \n \n
-
-\param[in] b
-Указатель на второй вектор \f$b\f$. \n
-Размер вектора `[nb x 1]`. \n \n
-
-\param[in] nb
-Размер второго вектора. \n \n
-
-\param[out] c
-Указатель на вектор свертки \f$ c = a * b\f$. \n
-Размер вектора `[na + nb - 1 x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если свертка расчитана успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-\note
-Если вектора `a` и `b` представляют собой коэффициенты двух полиномов,
-то результат линейной свертки представляет собой коэффициенты произведения
-исходных полиномов.
-
-Пример использования функции:
-
-\code{.cpp}
- double ar[3] = {1.0, 2.0, 3.0};
- double br[4] = {3.0, -1.0, 2.0, 4.0};
- double cr[6];
-
- int n;
-
- conv(ar, 3, br, 4, cr);
-
- for(n = 0; n < 6; n++)
- printf("cr[%d] = %5.1f \n ", n, cr[n]);
-
-\endcode
-\n
-
-Результат работы:
-\verbatim
-cr[0] = 3.0
-cr[1] = 5.0
-cr[2] = 9.0
-cr[3] = 5.0
-cr[4] = 14.0
-cr[5] = 12.0
-\endverbatim
-
-\author Бахурин Сергей. www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API conv(double* a, int na, double* b, int nb, double* c)
-{
- int k;
- int n;
-
- double *t;
- size_t bufsize;
-
- if(!a || !b || !c)
- return ERROR_PTR;
- if(na < 1 || nb < 1)
- return ERROR_SIZE;
-
-
- bufsize = (na + nb - 1) * sizeof(double);
-
- if((a != c) && (b != c))
- t = c;
- else
- t = (double*)malloc(bufsize);
-
- memset(t, 0, bufsize);
-
- for(k = 0; k < na; k++)
- for(n = 0; n < nb; n++)
- t[k+n] += a[k]*b[n];
-
- if(t!=c)
- {
- memcpy(c, t, bufsize);
- free(t);
- }
- return RES_OK;
-}
-
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup FILTER_CONV_GROUP
-\fn int conv_cmplx(complex_t* a, int na, complex_t* b, int nb, complex_t* c)
-\brief Complex vectors linear convolution.
-
-Function convolves two complex vectors \f$ c = a * b\f$ length `na` and `nb`.
-The output convolution is a vector `c` with length equal to `na + nb - 1`.
-
-\param[in] a
-Pointer to the first vector `a`. \n
-Vector size is `[na x 1]`. \n \n
-
-\param[in] na
-Size of the first vector `a`. \n \n
-
-\param[in] b
-Pointer to the second vector `b`. \n
-Vector size is `[nb x 1]`. \n \n
-
-\param[in] nb
-Size of the second vector `b`. \n \n
-
-\param[out] c
-Pointer to the convolution output vector \f$ c = a * b\f$. \n
-Vector size is `[na + nb - 1 x 1]`. \n
-Memory must be allocated. \n \n
-
-\return `RES_OK` if convolution is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\note If vectors `a` and `b` are coefficients of two polynomials,
-then convolution of the vectors `a` and `b` returns polynomial product
-coefficients.
-
-Example:
-\code{.cpp}
- complex_t ac[3] = {{0.0, 1.0}, {1.0, 1.0}, {2.0, 2.0}};
- complex_t bc[4] = {{3.0, 3.0}, {4.0, 4.0}, {5.0, 5.0}, {6.0, 6.0}};
- complex_t cc[6];
-
- int n;
-
- conv_cmplx(ac, 3, bc, 4, cc);
-
- for(n = 0; n < 6; n++)
- printf("cc[%d] = %5.1f%+5.1fj\n", n, RE(cc[n]),IM(cc[n]));
-
-\endcode
- \n
-
-Output:
-\verbatim
-cc[0] = -3.0 +3.0j
-cc[1] = -4.0+10.0j
-cc[2] = -5.0+25.0j
-cc[3] = -6.0+32.0j
-cc[4] = 0.0+32.0j
-cc[5] = 0.0+24.0j
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\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$.
-
-\param[in] a
-Указатель на первый вектор \f$a\f$. \n
-Размер вектора `[na x 1]`. \n \n
-
-\param[in] na
-Размер первого вектора. \n \n
-
-\param[in] b
-Указатель на второй вектор \f$b\f$. \n
-Размер вектора `[nb x 1]`. \n \n
-
-\param[in] nb
-Размер второго вектора. \n \n
-
-\param[out] c
-Указатель на вектор свертки \f$ c = a * b\f$. \n
-Размер вектора `[na + nb - 1 x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если свертка рассчитана успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-\note
-Если векторы `a` и `b` представляют собой коэффициенты двух полиномов,
-то результат линейной свертки представляет собой коэффициенты произведения
-исходных полиномов.
-
-Пример использования функции:
-
-\code{.cpp}
- complex_t ac[3] = {{0.0, 1.0}, {1.0, 1.0}, {2.0, 2.0}};
- complex_t bc[4] = {{3.0, 3.0}, {4.0, 4.0}, {5.0, 5.0}, {6.0, 6.0}};
- complex_t cc[6];
-
- int n;
-
- conv_cmplx(ac, 3, bc, 4, cc);
-
- for(n = 0; n < 6; n++)
- printf("cc[%d] = %5.1f%+5.1fj \n ", n, RE(cc[n]),IM(cc[n]));
-
-\endcode
-\n
-
-Результат работы:
-\verbatim
-cc[0] = -3.0 +3.0j
-cc[1] = -4.0+10.0j
-cc[2] = -5.0+25.0j
-cc[3] = -6.0+32.0j
-cc[4] = 0.0+32.0j
-cc[5] = 0.0+24.0j
-\endverbatim
-
-\author Бахурин Сергей. www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API conv_cmplx(complex_t* a, int na, complex_t* b,
- int nb, complex_t* c)
-{
- int k;
- int n;
-
- complex_t *t;
- size_t bufsize;
-
- if(!a || !b || !c)
- return ERROR_PTR;
- if(na < 1 || nb < 1)
- return ERROR_SIZE;
-
- bufsize = (na + nb - 1) * sizeof(complex_t);
-
- if((a != c) && (b != c))
- t = c;
- else
- t = (complex_t*)malloc(bufsize);
-
- memset(t, 0, bufsize);
-
- for(k = 0; k < na; k++)
- {
- for(n = 0; n < nb; n++)
- {
- RE(t[k+n]) += CMRE(a[k], b[n]);
- IM(t[k+n]) += CMIM(a[k], b[n]);
- }
- }
-
- if(t!=c)
- {
- memcpy(c, t, bufsize);
- free(t);
- }
-
- return RES_OK;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup FILTER_CONV_GROUP
-\fn int conv_fft(double* a, int na, double* b, int nb,
- fft_t* pfft, int nfft, double* c)
-\brief Real vectors fast linear convolution by using fast Fourier
-transform algorithms
-
-Function convolves two real vectors \f$ c = a * b\f$ length `na` and `nb`
-in the frequency domain by using FFT algorithms. This approach provide
-high-performance convolution which increases with `na` and `nb` increasing.
-The output convolution is a vector `c` with length equal to `na + nb - 1`.
-
-\param[in] a
-Pointer to the first vector `a`. \n
-Vector size is `[na x 1]`. \n \n
-
-\param[in] na
-Size of the first vector `a`. \n \n
-
-\param[in] b
-Pointer to the second vector `b`. \n
-Vector size is `[nb x 1]`. \n \n
-
-\param[in] nb
-Size of the second vector `b`. \n \n
-
-\param[in] pfft
-Pointer to the structure `fft_t`. \n
-Function changes `fft_t` structure fields so `fft_t` must
-be clear before program returns. \n \n
-
-\param[in] nfft
-FFT size. \n
-This parameter set which FFT size will be used
-for overlapped frequency domain convolution. \n
-FFT size must be more of minimal `na` and `nb` value.
-For example if `na = 10`, `nb = 4` then `nfft` parameter must
-be more than 4. \n
-
-\param[out] c
-Pointer to the convolution output vector \f$ c = a * b\f$. \n
-Vector size is `[na + nb - 1 x 1]`. \n
-Memory must be allocated. \n \n
-
-\return `RES_OK` if convolution is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error". \n \n
-
-Example:
-\include conv_fft_test.c
-
-Program output:
-
-\verbatim
-conv_fft error: 0x00000000
-conv error: 0x00000000
-c[ 0] = -0.00 d[ 0] = 0.00
-c[ 1] = -0.00 d[ 1] = 0.00
-c[ 2] = 1.00 d[ 2] = 1.00
-c[ 3] = 4.00 d[ 3] = 4.00
-c[ 4] = 10.00 d[ 4] = 10.00
-c[ 5] = 20.00 d[ 5] = 20.00
-c[ 6] = 35.00 d[ 6] = 35.00
-c[ 7] = 56.00 d[ 7] = 56.00
-c[ 8] = 77.00 d[ 8] = 77.00
-c[ 9] = 98.00 d[ 9] = 98.00
-c[ 10] = 119.00 d[ 10] = 119.00
-c[ 11] = 140.00 d[ 11] = 140.00
-c[ 12] = 161.00 d[ 12] = 161.00
-c[ 13] = 182.00 d[ 13] = 182.00
-c[ 14] = 190.00 d[ 14] = 190.00
-c[ 15] = 184.00 d[ 15] = 184.00
-c[ 16] = 163.00 d[ 16] = 163.00
-c[ 17] = 126.00 d[ 17] = 126.00
-c[ 18] = 72.00 d[ 18] = 72.00
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup FILTER_CONV_GROUP
-\fn int conv_fft(double* a, int na, double* b, int nb,
- fft_t* pfft, double* c)
-\brief Линейная свертка двух вещественных векторов с использованием алгоритмов
-быстрого преобразования Фурье
-
-Функция рассчитывает линейную свертку двух векторов \f$ c = a * b\f$ используя
-секционную обработку с перекрытием в частотной области. Это позволяет сократить
-вычислительные операции при расчете длинных сверток.
-
-\param[in] a
-Указатель на первый вектор \f$a\f$. \n
-Размер вектора `[na x 1]`. \n \n
-
-\param[in] na
-Размер первого вектора. \n \n
-
-\param[in] b
-Указатель на второй вектор \f$b\f$. \n
-Размер вектора `[nb x 1]`. \n \n
-
-\param[in] nb
-Размер второго вектора. \n \n
-
-\param[in] pfft
-Указатель на структуру `fft_t` алгоритма
-быстрого преобразования Фурье. \n
-Функция изменит состояние полей структуры `fft_t`,
-поэтому структура должна быть очищена перед выходом из
-программы для исключения утечек памяти. \n
-
-\param[in] nfft
-Размер алгоритма БПФ который будет использован для расчета
-секционной свертки с перекрытием. \n
-Данный параметр должен быть больше чем минимальное значение
-размеров сворачиваемых векторов. \n
-Например если `na=10`, а `nb=4`, то параметр `nfft` должен быть больше 4. \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).
-Однако, максимальное быстродействие достигается при использовании длин равных
-степени двойки.
-
-\param[out] c
-Указатель на вектор свертки \f$ c = a * b\f$. \n
-Размер вектора `[na + nb - 1 x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если свертка рассчитана успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-\note
-Данная функция наиболее эффективна при вычислении длинных сверток.
-
-Пример использования функции:
-
-\include conv_fft_test.c
-
-Результат работы:
-\verbatim
-
-conv_fft error: 0x00000000
-conv error: 0x00000000
-c[ 0] = -0.00 d[ 0] = 0.00
-c[ 1] = -0.00 d[ 1] = 0.00
-c[ 2] = 1.00 d[ 2] = 1.00
-c[ 3] = 4.00 d[ 3] = 4.00
-c[ 4] = 10.00 d[ 4] = 10.00
-c[ 5] = 20.00 d[ 5] = 20.00
-c[ 6] = 35.00 d[ 6] = 35.00
-c[ 7] = 56.00 d[ 7] = 56.00
-c[ 8] = 77.00 d[ 8] = 77.00
-c[ 9] = 98.00 d[ 9] = 98.00
-c[ 10] = 119.00 d[ 10] = 119.00
-c[ 11] = 140.00 d[ 11] = 140.00
-c[ 12] = 161.00 d[ 12] = 161.00
-c[ 13] = 182.00 d[ 13] = 182.00
-c[ 14] = 190.00 d[ 14] = 190.00
-c[ 15] = 184.00 d[ 15] = 184.00
-c[ 16] = 163.00 d[ 16] = 163.00
-c[ 17] = 126.00 d[ 17] = 126.00
-c[ 18] = 72.00 d[ 18] = 72.00
-\endverbatim
-
-\author Бахурин Сергей. www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API conv_fft(double* a, int na, double* b, int nb,
- fft_t* pfft, int nfft, double* c)
-{
- complex_t *pa = NULL, *pb = NULL, *pc = NULL;
- int err;
-
- if(!a || !b || !c || !pfft)
- return ERROR_PTR;
- if(na<1 || nb < 1)
- return ERROR_SIZE;
- if(nfft<2)
- return ERROR_FFT_SIZE;
-
- pa = (complex_t*) malloc(na*sizeof(complex_t));
- pb = (complex_t*) malloc(nb*sizeof(complex_t));
- pc = (complex_t*) malloc((na+nb-1)*sizeof(complex_t));
-
- re2cmplx(a, na, pa);
- re2cmplx(b, nb, pb);
-
- err = conv_fft_cmplx(pa, na, pb, nb, pfft, nfft, pc);
- if(err != RES_OK)
- goto exit_label;
-
- err = cmplx2re(pc, na+nb-1, c, NULL);
-
-exit_label:
- if(pa) free(pa);
- if(pb) free(pb);
- if(pc) free(pc);
-
- return err;
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup FILTER_CONV_GROUP
-\fn int conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
- fft_t* pfft, int nfft, complex_t* c)
-\brief Complex vectors fast linear convolution by using fast Fourier
-transform algorithms
-
-Function convolves two complex vectors \f$ c = a * b\f$ length `na` and `nb`
-in the frequency domain by using FFT algorithms. This approach provide
-high-performance convolution which increases with `na` and `nb` increasing.
-The output convolution is a vector `c` with length equal to `na + nb - 1`.
-
-\param[in] a
-Pointer to the first vector `a`. \n
-Vector size is `[na x 1]`. \n \n
-
-\param[in] na
-Size of the first vector `a`. \n \n
-
-\param[in] b
-Pointer to the second vector `b`. \n
-Vector size is `[nb x 1]`. \n \n
-
-\param[in] nb
-Size of the second vector `b`. \n \n
-
-\param[in] pfft
-Pointer to the structure `fft_t`. \n
-Function changes `fft_t` structure fields so `fft_t` must
-be clear before program returns. \n \n
-
-\param[in] nfft
-FFT size. \n
-This parameter set which FFT size will be used
-for overlapped frequency domain convolution. \n
-FFT size must be more of minimal `na` and `nb` value.
-For example if `na = 10`, `nb = 4` then `nfft` parameter must
-be more than 4. \n
-
-\param[out] c
-Pointer to the convolution output vector \f$ c = a * b\f$. \n
-Vector size is `[na + nb - 1 x 1]`. \n
-Memory must be allocated. \n \n
-
-\return `RES_OK` if convolution is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error". \n \n
-
-Example:
-\include conv_fft_cmplx_test.c
-
-Program output:
-
-\verbatim
-c[ 0] = -1.00 -0.00j d[ 0] = -1.00 +0.00j
-c[ 1] = -6.00 +4.00j d[ 1] = -6.00 +4.00j
-c[ 2] = -15.00 +20.00j d[ 2] = -15.00 +20.00j
-c[ 3] = -28.00 +56.00j d[ 3] = -28.00 +56.00j
-c[ 4] = -45.00 +120.00j d[ 4] = -45.00 +120.00j
-c[ 5] = -55.00 +210.00j d[ 5] = -55.00 +210.00j
-c[ 6] = -65.00 +300.00j d[ 6] = -65.00 +300.00j
-c[ 7] = -75.00 +390.00j d[ 7] = -75.00 +390.00j
-c[ 8] = -85.00 +480.00j d[ 8] = -85.00 +480.00j
-c[ 9] = -95.00 +570.00j d[ 9] = -95.00 +570.00j
-c[ 10] = -105.00 +660.00j d[ 10] = -105.00 +660.00j
-c[ 11] = -115.00 +750.00j d[ 11] = -115.00 +750.00j
-c[ 12] = -125.00 +840.00j d[ 12] = -125.00 +840.00j
-c[ 13] = -135.00 +930.00j d[ 13] = -135.00 +930.00j
-c[ 14] = -145.00 +1020.00j d[ 14] = -145.00 +1020.00j
-c[ 15] = -124.00 +1080.00j d[ 15] = -124.00 +1080.00j
-c[ 16] = -99.00 +1016.00j d[ 16] = -99.00 +1016.00j
-c[ 17] = -70.00 +820.00j d[ 17] = -70.00 +820.00j
-c[ 18] = -37.00 +484.00j d[ 18] = -37.00 +484.00j
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup FILTER_CONV_GROUP
-\fn int conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
- fft_t* pfft, complex_t* c)
-\brief Линейная свертка двух комплексных векторов с использованием алгоритмов
-быстрого преобразования Фурье
-
-Функция рассчитывает линейную свертку двух векторов \f$ c = a * b\f$ используя
-секционную обработку с перекрытием в частотной области. Это позволяет сократить
-вычислительные операции при расчете длинных сверток.
-
-\param[in] a
-Указатель на первый вектор \f$a\f$. \n
-Размер вектора `[na x 1]`. \n \n
-
-\param[in] na
-Размер первого вектора. \n \n
-
-\param[in] b
-Указатель на второй вектор \f$b\f$. \n
-Размер вектора `[nb x 1]`. \n \n
-
-\param[in] nb
-Размер второго вектора. \n \n
-
-\param[in] pfft
-Указатель на структуру `fft_t` алгоритма
-быстрого преобразования Фурье. \n
-Функция изменит состояние полей структуры `fft_t`,
-поэтому структура должна быть очищена перед выходом из
-программы для исключения утечек памяти. \n
-
-\param[in] nfft
-Размер алгоритма БПФ который будет использован для расчета
-секционной свертки с перекрытием. \n
-Данный параметр должен быть больше чем минимальное значение
-размеров сворачиваемых векторов. \n
-Например если `na=10`, а `nb=4`, то параметр `nfft` должен быть больше 4. \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).
-Однако, максимальное быстродействие достигается при использовании длин равных
-степени двойки.
-
-\param[out] c
-Указатель на вектор свертки \f$ c = a * b\f$. \n
-Размер вектора `[na + nb - 1 x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если свертка рассчитана успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-\note
-Данная функция наиболее эффективна при вычислении длинных сверток.
-
-Пример использования функции:
-
-\include conv_fft_cmplx_test.c
-
-Результат работы:
-\verbatim
-c[ 0] = -1.00 -0.00j d[ 0] = -1.00 +0.00j
-c[ 1] = -6.00 +4.00j d[ 1] = -6.00 +4.00j
-c[ 2] = -15.00 +20.00j d[ 2] = -15.00 +20.00j
-c[ 3] = -28.00 +56.00j d[ 3] = -28.00 +56.00j
-c[ 4] = -45.00 +120.00j d[ 4] = -45.00 +120.00j
-c[ 5] = -55.00 +210.00j d[ 5] = -55.00 +210.00j
-c[ 6] = -65.00 +300.00j d[ 6] = -65.00 +300.00j
-c[ 7] = -75.00 +390.00j d[ 7] = -75.00 +390.00j
-c[ 8] = -85.00 +480.00j d[ 8] = -85.00 +480.00j
-c[ 9] = -95.00 +570.00j d[ 9] = -95.00 +570.00j
-c[ 10] = -105.00 +660.00j d[ 10] = -105.00 +660.00j
-c[ 11] = -115.00 +750.00j d[ 11] = -115.00 +750.00j
-c[ 12] = -125.00 +840.00j d[ 12] = -125.00 +840.00j
-c[ 13] = -135.00 +930.00j d[ 13] = -135.00 +930.00j
-c[ 14] = -145.00 +1020.00j d[ 14] = -145.00 +1020.00j
-c[ 15] = -124.00 +1080.00j d[ 15] = -124.00 +1080.00j
-c[ 16] = -99.00 +1016.00j d[ 16] = -99.00 +1016.00j
-c[ 17] = -70.00 +820.00j d[ 17] = -70.00 +820.00j
-c[ 18] = -37.00 +484.00j d[ 18] = -37.00 +484.00j
-\endverbatim
-
-\author Бахурин Сергей. www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
- fft_t* pfft, int nfft, complex_t* c)
-{
-
- int La, Lb, Lc, Nz, n, p0, p1, ind, err;
- complex_t *pa, *pb;
- complex_t *pt, *pA, *pB, *pC;
-
- if(!a || !b || !c)
- return ERROR_PTR;
- if(na < 1 || nb < 1)
- return ERROR_SIZE;
-
- if(na >= nb)
- {
- La = na;
- Lb = nb;
- pa = a;
- pb = b;
- }
- else
- {
- La = nb;
- pa = b;
- Lb = na;
- pb = a;
- }
-
- Lc = La + Lb - 1;
- Nz = nfft - Lb;
-
- if(Nz <= 0)
- return ERROR_FFT_SIZE;
-
- pt = (complex_t*)malloc(nfft*sizeof(complex_t));
- pB = (complex_t*)malloc(nfft*sizeof(complex_t));
- pA = (complex_t*)malloc(nfft*sizeof(complex_t));
- pC = (complex_t*)malloc(nfft*sizeof(complex_t));
-
- memset(pt, 0, nfft*sizeof(complex_t));
- memcpy(pt+Nz, pb, Lb*sizeof(complex_t));
-
- err = fft_cmplx(pt, nfft, pfft, pB);
- if(err != RES_OK)
- goto exit_label;
-
- p0 = -Lb;
- p1 = p0 + nfft;
- ind = 0;
- while(ind < Lc)
- {
- if(p0 >=0)
- {
- if(p1 < La)
- err = fft_cmplx(pa + p0, nfft, pfft, pA);
- else
- {
- memset(pt, 0, nfft*sizeof(complex_t));
- memcpy(pt, pa+p0, (nfft+La-p1)*sizeof(complex_t));
- err = fft_cmplx(pt, nfft, pfft, pA);
- }
- }
- else
- {
- memset(pt, 0, nfft*sizeof(complex_t));
- if(p1 < La)
- memcpy(pt - p0, pa, (nfft+p0)*sizeof(complex_t));
- else
- memcpy(pt - p0, pa, La * sizeof(complex_t));
- err = fft_cmplx(pt, nfft, pfft, pA);
- }
-
- if(err != RES_OK)
- goto exit_label;
-
- for(n = 0; n < nfft; n++)
- {
- RE(pC[n]) = CMRE(pA[n], pB[n]);
- IM(pC[n]) = CMIM(pA[n], pB[n]);
- }
-
-
- if(ind+nfft < Lc)
- err = ifft_cmplx(pC, nfft, pfft, c+ind);
- else
- {
- err = ifft_cmplx(pC, nfft, pfft, pt);
- memcpy(c+ind, pt, (Lc-ind)*sizeof(complex_t));
- }
- if(err != RES_OK)
- goto exit_label;
-
- p0 += Nz;
- p1 += Nz;
- ind += Nz;
- }
-
-exit_label:
- if(pt) free(pt);
- if(pB) free(pB);
- if(pA) free(pA);
- if(pC) free(pC);
-
- return err;
-}
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup FILTER_CONV_GROUP
-\fn int filter_iir(double* b, double* a, int ord, double* x, int n, double* y)
-\brief Real IIR filtration
-
-Function calculates real IIR filter output for real signal. The real filter
-contains real coefficients of the transfer function \f$H(z)\f$
- numerator and denominator:
-\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]
-here \f$a_0\f$ cannot be equals zeros, \f$N=M=\f$`ord`.
-
-\param[in] b
-Pointer to the vector \f$b\f$ of IIR filter
-transfer function numerator coefficients. \n
-Vector size is `[ord + 1 x 1]`. \n \n
-
-\param[in] a
-Pointer to the vector \f$a\f$ of IIR filter
-transfer function denominator coefficients. \n
-Vector size is `[ord + 1 x 1]`. \n
-This pointer can be `NULL` if filter is FIR. \n \n
-
-\param[in] ord
-Filter order. Number of the transfer function
-numerator and denominator coefficients
-(length of vectors `b` and `a`) is `ord + 1`. \n \n
-
-\param[in] x
-Pointer to the input signal vector. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of the input signal vector `x`. \n \n
-
-\param[out] y
-Pointer to the IIR filter output vector. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if filter output is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error". \n
-
-Example:
-
-\include filter_iir_test.c
-
-Input signal is
-\f$s(t) = \sin(2\pi \cdot 0.05 t) + n(t)\f$, here \f$n(t)\f$ white Gaussian
-noise with zero mean value and unit standard deviation. \n
-
-Input signal is filtered by elliptic LPF order 6 and output signal and data
-saves in the txt-files
-
-\verbatim
-dat/s.txt - input signal + noise
-dat/sf.txt - filter output.
-\endverbatim
-
-Plots:
-
-\image html filter_iir_test.png
-
-GNUPLOT script for make plots is:
-\include filter_iir.plt
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\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^{-m}},
-\f]
-где \f$a_0\f$ не может быть 0, \f$N=M=\f$`ord`.
-
-\param[in] b
-Указатель на вектор коэффициентов числителя
-передаточной функции \f$H(z)\f$ БИХ-фильтра. \n
-Размер вектора `[ord + 1 x 1]`. \n \n
-
-\param[in] a
-Указатель на вектор коэффициентов знаменателя
-передаточной функции \f$H(z)\f$ БИХ-фильтра. \n
-Размер вектора `[ord + 1 x 1]`. \n
-Этот указатель может быть `NULL`, тогда фильтрация производится
-без использования рекурсивной части
-(вектор коэффициентов `b` задает КИХ-фильтр). \n \n
-
-\param[in] ord
-Порядок фильтра. Количество коэффициентов числителя и знаменателя
-передаточной функции \f$H(z)\f$ БИХ-фильтра равно `ord + 1`. \n \n
-
-\param[in] x
-Указатель на вектор отсчетов входного сигнала. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Длина входного сигнала. \n \n
-
-\param[out] y
-Указатель на вектор выходных отсчетов фильтра. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена заранее. \n \n
-
-\return
-`RES_OK` Если фильтрация произведена успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-Пример использования функции `filter_iir`:
-
-\include filter_iir_test.c
-
-На входе цифрового фильтра задан сигнал
-\f$s(t) = \sin(2\pi \cdot 0.05 t) + n(t)\f$, где \f$n(t)\f$ белый гауссовский
-шум, с нулевым средним и единичной дисперсией. \n
-Фильтр представляет собой эллиптический ФНЧ 6 порядка.
-Входной сигнал фильтруется данным фильтром, и результат сохраняется в файлы:
-
-\verbatim
-dat/s.txt - исходный зашумленный сигнал
-dat/sf.txt - сигнал на выходе фильтра.
-\endverbatim
-
-По полученным данным производится построение графиков:
-
-\image html filter_iir_test.png
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API filter_iir(double* b, double* a, int ord,
- double* x, int n, double* y)
-{
- double *buf = NULL;
- double *an = NULL;
- double *bn = NULL;
- double u;
- int k;
- int m;
- int count;
-
- if(!b || !x || !y)
- return ERROR_PTR;
-
- if(ord < 1 || n < 1)
- return ERROR_SIZE;
-
- if(a && a[0]==0.0)
- return ERROR_FILTER_A0;
-
- count = ord + 1;
- buf = (double*) malloc(count*sizeof(double));
- an = (double*) malloc(count*sizeof(double));
-
- memset(buf, 0, count*sizeof(double));
-
- if(!a)
- {
- memset(an, 0, count*sizeof(double));
- bn = b;
- }
- else
- {
- bn = (double*) malloc(count*sizeof(double));
- for(k = 0; k < count; k++)
- {
- an[k] = a[k] / a[0];
- bn[k] = b[k] / a[0];
- }
- }
-
- for(k = 0; k < n; k++)
- {
- for(m = ord; m > 0; m--)
- buf[m] = buf[m-1];
- u = 0.0;
- for(m = ord; m > 0; m--)
- u += buf[m]*an[m];
-
- buf[0] = x[k] - u;
- y[k] = 0.0;
- for(m = 0; m < count; m++)
- y[k] += buf[m] * bn[m];
- }
-
- if(buf)
- free(buf);
- if(an)
- free(an);
- if(bn && (bn != b))
- free(bn);
- return RES_OK;
-}
-
diff --git a/dspl/src/convolution.c b/dspl/src/convolution.c
new file mode 100644
index 0000000..29996d7
--- /dev/null
+++ b/dspl/src/convolution.c
@@ -0,0 +1,5 @@
+#include "convolution/conv.c"
+#include "convolution/conv_cmplx.c"
+#include "convolution/conv_fft.c"
+#include "convolution/conv_fft_cmplx.c"
+#include "convolution/filter_iir.c"
\ No newline at end of file
diff --git a/dspl/src/convolution/conv.c b/dspl/src/convolution/conv.c
new file mode 100644
index 0000000..e552e56
--- /dev/null
+++ b/dspl/src/convolution/conv.c
@@ -0,0 +1,193 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup FILTER_CONV_GROUP
+\fn int conv(double* a, int na, double* b, int nb, double* c)
+\brief Real vectors linear convolution.
+
+Function convolves two real vectors \f$ c = a * b\f$ length `na` and `nb`.
+The output convolution is a vector `c` with length equal to `na + nb - 1`.
+
+\param[in] a
+Pointer to the first vector `a`. \n
+Vector size is `[na x 1]`. \n \n
+
+\param[in] na
+Size of the first vector `a`. \n \n
+
+\param[in] b
+Pointer to the second vector `b`. \n
+Vector size is `[nb x 1]`. \n \n
+
+\param[in] nb
+Size of the second vector `b`. \n \n
+
+\param[out] c
+Pointer to the convolution output vector \f$ c = a * b\f$. \n
+Vector size is `[na + nb - 1 x 1]`. \n
+Memory must be allocated. \n \n
+
+\return `RES_OK` if convolution is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\note If vectors `a` and `b` are coefficients of two polynomials,
+then convolution of the vectors `a` and `b` returns polynomial product
+coefficients.
+
+Example:
+\code{.cpp}
+ double ar[3] = {1.0, 2.0, 3.0};
+ double br[4] = {3.0, -1.0, 2.0, 4.0};
+ double cr[6];
+
+ int n;
+
+ conv(ar, 3, br, 4, cr);
+
+ for(n = 0; n < 6; n++)
+ printf("cr[%d] = %5.1f\n", n, cr[n]);
+
+\endcode
+\n
+
+Output:
+\verbatim
+cr[0] = 3.0
+cr[1] = 5.0
+cr[2] = 9.0
+cr[3] = 5.0
+cr[4] = 14.0
+cr[5] = 12.0
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup FILTER_CONV_GROUP
+\fn int conv(double* a, int na, double* b, int nb, double* c)
+\brief Линейная свертка двух вещественных векторов
+
+Функция рассчитывает линейную свертку двух векторов \f$ c = a * b\f$.
+
+\param[in] a
+Указатель на первый вектор \f$a\f$. \n
+Размер вектора `[na x 1]`. \n \n
+
+\param[in] na
+Размер первого вектора. \n \n
+
+\param[in] b
+Указатель на второй вектор \f$b\f$. \n
+Размер вектора `[nb x 1]`. \n \n
+
+\param[in] nb
+Размер второго вектора. \n \n
+
+\param[out] c
+Указатель на вектор свертки \f$ c = a * b\f$. \n
+Размер вектора `[na + nb - 1 x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если свертка расчитана успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+\note
+Если вектора `a` и `b` представляют собой коэффициенты двух полиномов,
+то результат линейной свертки представляет собой коэффициенты произведения
+исходных полиномов.
+
+Пример использования функции:
+
+\code{.cpp}
+ double ar[3] = {1.0, 2.0, 3.0};
+ double br[4] = {3.0, -1.0, 2.0, 4.0};
+ double cr[6];
+
+ int n;
+
+ conv(ar, 3, br, 4, cr);
+
+ for(n = 0; n < 6; n++)
+ printf("cr[%d] = %5.1f \n ", n, cr[n]);
+
+\endcode
+\n
+
+Результат работы:
+\verbatim
+cr[0] = 3.0
+cr[1] = 5.0
+cr[2] = 9.0
+cr[3] = 5.0
+cr[4] = 14.0
+cr[5] = 12.0
+\endverbatim
+
+\author Бахурин Сергей. www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API conv(double* a, int na, double* b, int nb, double* c)
+{
+ int k;
+ int n;
+
+ double *t;
+ size_t bufsize;
+
+ if(!a || !b || !c)
+ return ERROR_PTR;
+ if(na < 1 || nb < 1)
+ return ERROR_SIZE;
+
+
+ bufsize = (na + nb - 1) * sizeof(double);
+
+ if((a != c) && (b != c))
+ t = c;
+ else
+ t = (double*)malloc(bufsize);
+
+ memset(t, 0, bufsize);
+
+ for(k = 0; k < na; k++)
+ for(n = 0; n < nb; n++)
+ t[k+n] += a[k]*b[n];
+
+ if(t!=c)
+ {
+ memcpy(c, t, bufsize);
+ free(t);
+ }
+ return RES_OK;
+}
+
diff --git a/dspl/src/convolution/conv_cmplx.c b/dspl/src/convolution/conv_cmplx.c
new file mode 100644
index 0000000..a5a80ad
--- /dev/null
+++ b/dspl/src/convolution/conv_cmplx.c
@@ -0,0 +1,200 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup FILTER_CONV_GROUP
+\fn int conv_cmplx(complex_t* a, int na, complex_t* b, int nb, complex_t* c)
+\brief Complex vectors linear convolution.
+
+Function convolves two complex vectors \f$ c = a * b\f$ length `na` and `nb`.
+The output convolution is a vector `c` with length equal to `na + nb - 1`.
+
+\param[in] a
+Pointer to the first vector `a`. \n
+Vector size is `[na x 1]`. \n \n
+
+\param[in] na
+Size of the first vector `a`. \n \n
+
+\param[in] b
+Pointer to the second vector `b`. \n
+Vector size is `[nb x 1]`. \n \n
+
+\param[in] nb
+Size of the second vector `b`. \n \n
+
+\param[out] c
+Pointer to the convolution output vector \f$ c = a * b\f$. \n
+Vector size is `[na + nb - 1 x 1]`. \n
+Memory must be allocated. \n \n
+
+\return `RES_OK` if convolution is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\note If vectors `a` and `b` are coefficients of two polynomials,
+then convolution of the vectors `a` and `b` returns polynomial product
+coefficients.
+
+Example:
+\code{.cpp}
+ complex_t ac[3] = {{0.0, 1.0}, {1.0, 1.0}, {2.0, 2.0}};
+ complex_t bc[4] = {{3.0, 3.0}, {4.0, 4.0}, {5.0, 5.0}, {6.0, 6.0}};
+ complex_t cc[6];
+
+ int n;
+
+ conv_cmplx(ac, 3, bc, 4, cc);
+
+ for(n = 0; n < 6; n++)
+ printf("cc[%d] = %5.1f%+5.1fj\n", n, RE(cc[n]),IM(cc[n]));
+
+\endcode
+ \n
+
+Output:
+\verbatim
+cc[0] = -3.0 +3.0j
+cc[1] = -4.0+10.0j
+cc[2] = -5.0+25.0j
+cc[3] = -6.0+32.0j
+cc[4] = 0.0+32.0j
+cc[5] = 0.0+24.0j
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\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$.
+
+\param[in] a
+Указатель на первый вектор \f$a\f$. \n
+Размер вектора `[na x 1]`. \n \n
+
+\param[in] na
+Размер первого вектора. \n \n
+
+\param[in] b
+Указатель на второй вектор \f$b\f$. \n
+Размер вектора `[nb x 1]`. \n \n
+
+\param[in] nb
+Размер второго вектора. \n \n
+
+\param[out] c
+Указатель на вектор свертки \f$ c = a * b\f$. \n
+Размер вектора `[na + nb - 1 x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если свертка рассчитана успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+\note
+Если векторы `a` и `b` представляют собой коэффициенты двух полиномов,
+то результат линейной свертки представляет собой коэффициенты произведения
+исходных полиномов.
+
+Пример использования функции:
+
+\code{.cpp}
+ complex_t ac[3] = {{0.0, 1.0}, {1.0, 1.0}, {2.0, 2.0}};
+ complex_t bc[4] = {{3.0, 3.0}, {4.0, 4.0}, {5.0, 5.0}, {6.0, 6.0}};
+ complex_t cc[6];
+
+ int n;
+
+ conv_cmplx(ac, 3, bc, 4, cc);
+
+ for(n = 0; n < 6; n++)
+ printf("cc[%d] = %5.1f%+5.1fj \n ", n, RE(cc[n]),IM(cc[n]));
+
+\endcode
+\n
+
+Результат работы:
+\verbatim
+cc[0] = -3.0 +3.0j
+cc[1] = -4.0+10.0j
+cc[2] = -5.0+25.0j
+cc[3] = -6.0+32.0j
+cc[4] = 0.0+32.0j
+cc[5] = 0.0+24.0j
+\endverbatim
+
+\author Бахурин Сергей. www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API conv_cmplx(complex_t* a, int na, complex_t* b,
+ int nb, complex_t* c)
+{
+ int k;
+ int n;
+
+ complex_t *t;
+ size_t bufsize;
+
+ if(!a || !b || !c)
+ return ERROR_PTR;
+ if(na < 1 || nb < 1)
+ return ERROR_SIZE;
+
+ bufsize = (na + nb - 1) * sizeof(complex_t);
+
+ if((a != c) && (b != c))
+ t = c;
+ else
+ t = (complex_t*)malloc(bufsize);
+
+ memset(t, 0, bufsize);
+
+ for(k = 0; k < na; k++)
+ {
+ for(n = 0; n < nb; n++)
+ {
+ RE(t[k+n]) += CMRE(a[k], b[n]);
+ IM(t[k+n]) += CMIM(a[k], b[n]);
+ }
+ }
+
+ if(t!=c)
+ {
+ memcpy(c, t, bufsize);
+ free(t);
+ }
+
+ return RES_OK;
+}
+
diff --git a/dspl/src/convolution/conv_fft.c b/dspl/src/convolution/conv_fft.c
new file mode 100644
index 0000000..7def560
--- /dev/null
+++ b/dspl/src/convolution/conv_fft.c
@@ -0,0 +1,235 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup FILTER_CONV_GROUP
+\fn int conv_fft(double* a, int na, double* b, int nb,
+ fft_t* pfft, int nfft, double* c)
+\brief Real vectors fast linear convolution by using fast Fourier
+transform algorithms
+
+Function convolves two real vectors \f$ c = a * b\f$ length `na` and `nb`
+in the frequency domain by using FFT algorithms. This approach provide
+high-performance convolution which increases with `na` and `nb` increasing.
+The output convolution is a vector `c` with length equal to `na + nb - 1`.
+
+\param[in] a
+Pointer to the first vector `a`. \n
+Vector size is `[na x 1]`. \n \n
+
+\param[in] na
+Size of the first vector `a`. \n \n
+
+\param[in] b
+Pointer to the second vector `b`. \n
+Vector size is `[nb x 1]`. \n \n
+
+\param[in] nb
+Size of the second vector `b`. \n \n
+
+\param[in] pfft
+Pointer to the structure `fft_t`. \n
+Function changes `fft_t` structure fields so `fft_t` must
+be clear before program returns. \n \n
+
+\param[in] nfft
+FFT size. \n
+This parameter set which FFT size will be used
+for overlapped frequency domain convolution. \n
+FFT size must be more of minimal `na` and `nb` value.
+For example if `na = 10`, `nb = 4` then `nfft` parameter must
+be more than 4. \n
+
+\param[out] c
+Pointer to the convolution output vector \f$ c = a * b\f$. \n
+Vector size is `[na + nb - 1 x 1]`. \n
+Memory must be allocated. \n \n
+
+\return `RES_OK` if convolution is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n \n
+
+Example:
+\include conv_fft_test.c
+
+Program output:
+
+\verbatim
+conv_fft error: 0x00000000
+conv error: 0x00000000
+c[ 0] = -0.00 d[ 0] = 0.00
+c[ 1] = -0.00 d[ 1] = 0.00
+c[ 2] = 1.00 d[ 2] = 1.00
+c[ 3] = 4.00 d[ 3] = 4.00
+c[ 4] = 10.00 d[ 4] = 10.00
+c[ 5] = 20.00 d[ 5] = 20.00
+c[ 6] = 35.00 d[ 6] = 35.00
+c[ 7] = 56.00 d[ 7] = 56.00
+c[ 8] = 77.00 d[ 8] = 77.00
+c[ 9] = 98.00 d[ 9] = 98.00
+c[ 10] = 119.00 d[ 10] = 119.00
+c[ 11] = 140.00 d[ 11] = 140.00
+c[ 12] = 161.00 d[ 12] = 161.00
+c[ 13] = 182.00 d[ 13] = 182.00
+c[ 14] = 190.00 d[ 14] = 190.00
+c[ 15] = 184.00 d[ 15] = 184.00
+c[ 16] = 163.00 d[ 16] = 163.00
+c[ 17] = 126.00 d[ 17] = 126.00
+c[ 18] = 72.00 d[ 18] = 72.00
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup FILTER_CONV_GROUP
+\fn int conv_fft(double* a, int na, double* b, int nb,
+ fft_t* pfft, double* c)
+\brief Линейная свертка двух вещественных векторов с использованием алгоритмов
+быстрого преобразования Фурье
+
+Функция рассчитывает линейную свертку двух векторов \f$ c = a * b\f$ используя
+секционную обработку с перекрытием в частотной области. Это позволяет сократить
+вычислительные операции при расчете длинных сверток.
+
+\param[in] a
+Указатель на первый вектор \f$a\f$. \n
+Размер вектора `[na x 1]`. \n \n
+
+\param[in] na
+Размер первого вектора. \n \n
+
+\param[in] b
+Указатель на второй вектор \f$b\f$. \n
+Размер вектора `[nb x 1]`. \n \n
+
+\param[in] nb
+Размер второго вектора. \n \n
+
+\param[in] pfft
+Указатель на структуру `fft_t` алгоритма
+быстрого преобразования Фурье. \n
+Функция изменит состояние полей структуры `fft_t`,
+поэтому структура должна быть очищена перед выходом из
+программы для исключения утечек памяти. \n
+
+\param[in] nfft
+Размер алгоритма БПФ который будет использован для расчета
+секционной свертки с перекрытием. \n
+Данный параметр должен быть больше чем минимальное значение
+размеров сворачиваемых векторов. \n
+Например если `na=10`, а `nb=4`, то параметр `nfft` должен быть больше 4. \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).
+Однако, максимальное быстродействие достигается при использовании длин равных
+степени двойки.
+
+\param[out] c
+Указатель на вектор свертки \f$ c = a * b\f$. \n
+Размер вектора `[na + nb - 1 x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если свертка рассчитана успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+\note
+Данная функция наиболее эффективна при вычислении длинных сверток.
+
+Пример использования функции:
+
+\include conv_fft_test.c
+
+Результат работы:
+\verbatim
+
+conv_fft error: 0x00000000
+conv error: 0x00000000
+c[ 0] = -0.00 d[ 0] = 0.00
+c[ 1] = -0.00 d[ 1] = 0.00
+c[ 2] = 1.00 d[ 2] = 1.00
+c[ 3] = 4.00 d[ 3] = 4.00
+c[ 4] = 10.00 d[ 4] = 10.00
+c[ 5] = 20.00 d[ 5] = 20.00
+c[ 6] = 35.00 d[ 6] = 35.00
+c[ 7] = 56.00 d[ 7] = 56.00
+c[ 8] = 77.00 d[ 8] = 77.00
+c[ 9] = 98.00 d[ 9] = 98.00
+c[ 10] = 119.00 d[ 10] = 119.00
+c[ 11] = 140.00 d[ 11] = 140.00
+c[ 12] = 161.00 d[ 12] = 161.00
+c[ 13] = 182.00 d[ 13] = 182.00
+c[ 14] = 190.00 d[ 14] = 190.00
+c[ 15] = 184.00 d[ 15] = 184.00
+c[ 16] = 163.00 d[ 16] = 163.00
+c[ 17] = 126.00 d[ 17] = 126.00
+c[ 18] = 72.00 d[ 18] = 72.00
+\endverbatim
+
+\author Бахурин Сергей. www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API conv_fft(double* a, int na, double* b, int nb,
+ fft_t* pfft, int nfft, double* c)
+{
+ complex_t *pa = NULL, *pb = NULL, *pc = NULL;
+ int err;
+
+ if(!a || !b || !c || !pfft)
+ return ERROR_PTR;
+ if(na<1 || nb < 1)
+ return ERROR_SIZE;
+ if(nfft<2)
+ return ERROR_FFT_SIZE;
+
+ pa = (complex_t*) malloc(na*sizeof(complex_t));
+ pb = (complex_t*) malloc(nb*sizeof(complex_t));
+ pc = (complex_t*) malloc((na+nb-1)*sizeof(complex_t));
+
+ re2cmplx(a, na, pa);
+ re2cmplx(b, nb, pb);
+
+ err = conv_fft_cmplx(pa, na, pb, nb, pfft, nfft, pc);
+ if(err != RES_OK)
+ goto exit_label;
+
+ err = cmplx2re(pc, na+nb-1, c, NULL);
+
+exit_label:
+ if(pa) free(pa);
+ if(pb) free(pb);
+ if(pc) free(pc);
+
+ return err;
+}
+
diff --git a/dspl/src/convolution/conv_fft_cmplx.c b/dspl/src/convolution/conv_fft_cmplx.c
new file mode 100644
index 0000000..feba86d
--- /dev/null
+++ b/dspl/src/convolution/conv_fft_cmplx.c
@@ -0,0 +1,296 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup FILTER_CONV_GROUP
+\fn int conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
+ fft_t* pfft, int nfft, complex_t* c)
+\brief Complex vectors fast linear convolution by using fast Fourier
+transform algorithms
+
+Function convolves two complex vectors \f$ c = a * b\f$ length `na` and `nb`
+in the frequency domain by using FFT algorithms. This approach provide
+high-performance convolution which increases with `na` and `nb` increasing.
+The output convolution is a vector `c` with length equal to `na + nb - 1`.
+
+\param[in] a
+Pointer to the first vector `a`. \n
+Vector size is `[na x 1]`. \n \n
+
+\param[in] na
+Size of the first vector `a`. \n \n
+
+\param[in] b
+Pointer to the second vector `b`. \n
+Vector size is `[nb x 1]`. \n \n
+
+\param[in] nb
+Size of the second vector `b`. \n \n
+
+\param[in] pfft
+Pointer to the structure `fft_t`. \n
+Function changes `fft_t` structure fields so `fft_t` must
+be clear before program returns. \n \n
+
+\param[in] nfft
+FFT size. \n
+This parameter set which FFT size will be used
+for overlapped frequency domain convolution. \n
+FFT size must be more of minimal `na` and `nb` value.
+For example if `na = 10`, `nb = 4` then `nfft` parameter must
+be more than 4. \n
+
+\param[out] c
+Pointer to the convolution output vector \f$ c = a * b\f$. \n
+Vector size is `[na + nb - 1 x 1]`. \n
+Memory must be allocated. \n \n
+
+\return `RES_OK` if convolution is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n \n
+
+Example:
+\include conv_fft_cmplx_test.c
+
+Program output:
+
+\verbatim
+c[ 0] = -1.00 -0.00j d[ 0] = -1.00 +0.00j
+c[ 1] = -6.00 +4.00j d[ 1] = -6.00 +4.00j
+c[ 2] = -15.00 +20.00j d[ 2] = -15.00 +20.00j
+c[ 3] = -28.00 +56.00j d[ 3] = -28.00 +56.00j
+c[ 4] = -45.00 +120.00j d[ 4] = -45.00 +120.00j
+c[ 5] = -55.00 +210.00j d[ 5] = -55.00 +210.00j
+c[ 6] = -65.00 +300.00j d[ 6] = -65.00 +300.00j
+c[ 7] = -75.00 +390.00j d[ 7] = -75.00 +390.00j
+c[ 8] = -85.00 +480.00j d[ 8] = -85.00 +480.00j
+c[ 9] = -95.00 +570.00j d[ 9] = -95.00 +570.00j
+c[ 10] = -105.00 +660.00j d[ 10] = -105.00 +660.00j
+c[ 11] = -115.00 +750.00j d[ 11] = -115.00 +750.00j
+c[ 12] = -125.00 +840.00j d[ 12] = -125.00 +840.00j
+c[ 13] = -135.00 +930.00j d[ 13] = -135.00 +930.00j
+c[ 14] = -145.00 +1020.00j d[ 14] = -145.00 +1020.00j
+c[ 15] = -124.00 +1080.00j d[ 15] = -124.00 +1080.00j
+c[ 16] = -99.00 +1016.00j d[ 16] = -99.00 +1016.00j
+c[ 17] = -70.00 +820.00j d[ 17] = -70.00 +820.00j
+c[ 18] = -37.00 +484.00j d[ 18] = -37.00 +484.00j
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup FILTER_CONV_GROUP
+\fn int conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
+ fft_t* pfft, complex_t* c)
+\brief Линейная свертка двух комплексных векторов с использованием алгоритмов
+быстрого преобразования Фурье
+
+Функция рассчитывает линейную свертку двух векторов \f$ c = a * b\f$ используя
+секционную обработку с перекрытием в частотной области. Это позволяет сократить
+вычислительные операции при расчете длинных сверток.
+
+\param[in] a
+Указатель на первый вектор \f$a\f$. \n
+Размер вектора `[na x 1]`. \n \n
+
+\param[in] na
+Размер первого вектора. \n \n
+
+\param[in] b
+Указатель на второй вектор \f$b\f$. \n
+Размер вектора `[nb x 1]`. \n \n
+
+\param[in] nb
+Размер второго вектора. \n \n
+
+\param[in] pfft
+Указатель на структуру `fft_t` алгоритма
+быстрого преобразования Фурье. \n
+Функция изменит состояние полей структуры `fft_t`,
+поэтому структура должна быть очищена перед выходом из
+программы для исключения утечек памяти. \n
+
+\param[in] nfft
+Размер алгоритма БПФ который будет использован для расчета
+секционной свертки с перекрытием. \n
+Данный параметр должен быть больше чем минимальное значение
+размеров сворачиваемых векторов. \n
+Например если `na=10`, а `nb=4`, то параметр `nfft` должен быть больше 4. \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).
+Однако, максимальное быстродействие достигается при использовании длин равных
+степени двойки.
+
+\param[out] c
+Указатель на вектор свертки \f$ c = a * b\f$. \n
+Размер вектора `[na + nb - 1 x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если свертка рассчитана успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+\note
+Данная функция наиболее эффективна при вычислении длинных сверток.
+
+Пример использования функции:
+
+\include conv_fft_cmplx_test.c
+
+Результат работы:
+\verbatim
+c[ 0] = -1.00 -0.00j d[ 0] = -1.00 +0.00j
+c[ 1] = -6.00 +4.00j d[ 1] = -6.00 +4.00j
+c[ 2] = -15.00 +20.00j d[ 2] = -15.00 +20.00j
+c[ 3] = -28.00 +56.00j d[ 3] = -28.00 +56.00j
+c[ 4] = -45.00 +120.00j d[ 4] = -45.00 +120.00j
+c[ 5] = -55.00 +210.00j d[ 5] = -55.00 +210.00j
+c[ 6] = -65.00 +300.00j d[ 6] = -65.00 +300.00j
+c[ 7] = -75.00 +390.00j d[ 7] = -75.00 +390.00j
+c[ 8] = -85.00 +480.00j d[ 8] = -85.00 +480.00j
+c[ 9] = -95.00 +570.00j d[ 9] = -95.00 +570.00j
+c[ 10] = -105.00 +660.00j d[ 10] = -105.00 +660.00j
+c[ 11] = -115.00 +750.00j d[ 11] = -115.00 +750.00j
+c[ 12] = -125.00 +840.00j d[ 12] = -125.00 +840.00j
+c[ 13] = -135.00 +930.00j d[ 13] = -135.00 +930.00j
+c[ 14] = -145.00 +1020.00j d[ 14] = -145.00 +1020.00j
+c[ 15] = -124.00 +1080.00j d[ 15] = -124.00 +1080.00j
+c[ 16] = -99.00 +1016.00j d[ 16] = -99.00 +1016.00j
+c[ 17] = -70.00 +820.00j d[ 17] = -70.00 +820.00j
+c[ 18] = -37.00 +484.00j d[ 18] = -37.00 +484.00j
+\endverbatim
+
+\author Бахурин Сергей. www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API conv_fft_cmplx(complex_t* a, int na, complex_t* b, int nb,
+ fft_t* pfft, int nfft, complex_t* c)
+{
+
+ int La, Lb, Lc, Nz, n, p0, p1, ind, err;
+ complex_t *pa, *pb;
+ complex_t *pt, *pA, *pB, *pC;
+
+ if(!a || !b || !c)
+ return ERROR_PTR;
+ if(na < 1 || nb < 1)
+ return ERROR_SIZE;
+
+ if(na >= nb)
+ {
+ La = na;
+ Lb = nb;
+ pa = a;
+ pb = b;
+ }
+ else
+ {
+ La = nb;
+ pa = b;
+ Lb = na;
+ pb = a;
+ }
+
+ Lc = La + Lb - 1;
+ Nz = nfft - Lb;
+
+ if(Nz <= 0)
+ return ERROR_FFT_SIZE;
+
+ pt = (complex_t*)malloc(nfft*sizeof(complex_t));
+ pB = (complex_t*)malloc(nfft*sizeof(complex_t));
+ pA = (complex_t*)malloc(nfft*sizeof(complex_t));
+ pC = (complex_t*)malloc(nfft*sizeof(complex_t));
+
+ memset(pt, 0, nfft*sizeof(complex_t));
+ memcpy(pt+Nz, pb, Lb*sizeof(complex_t));
+
+ err = fft_cmplx(pt, nfft, pfft, pB);
+ if(err != RES_OK)
+ goto exit_label;
+
+ p0 = -Lb;
+ p1 = p0 + nfft;
+ ind = 0;
+ while(ind < Lc)
+ {
+ if(p0 >=0)
+ {
+ if(p1 < La)
+ err = fft_cmplx(pa + p0, nfft, pfft, pA);
+ else
+ {
+ memset(pt, 0, nfft*sizeof(complex_t));
+ memcpy(pt, pa+p0, (nfft+La-p1)*sizeof(complex_t));
+ err = fft_cmplx(pt, nfft, pfft, pA);
+ }
+ }
+ else
+ {
+ memset(pt, 0, nfft*sizeof(complex_t));
+ if(p1 < La)
+ memcpy(pt - p0, pa, (nfft+p0)*sizeof(complex_t));
+ else
+ memcpy(pt - p0, pa, La * sizeof(complex_t));
+ err = fft_cmplx(pt, nfft, pfft, pA);
+ }
+
+ if(err != RES_OK)
+ goto exit_label;
+
+ for(n = 0; n < nfft; n++)
+ {
+ RE(pC[n]) = CMRE(pA[n], pB[n]);
+ IM(pC[n]) = CMIM(pA[n], pB[n]);
+ }
+
+
+ if(ind+nfft < Lc)
+ err = ifft_cmplx(pC, nfft, pfft, c+ind);
+ else
+ {
+ err = ifft_cmplx(pC, nfft, pfft, pt);
+ memcpy(c+ind, pt, (Lc-ind)*sizeof(complex_t));
+ }
+ if(err != RES_OK)
+ goto exit_label;
+
+ p0 += Nz;
+ p1 += Nz;
+ ind += Nz;
+ }
+
+exit_label:
+ if(pt) free(pt);
+ if(pB) free(pB);
+ if(pA) free(pA);
+ if(pC) free(pC);
+
+ return err;
+}
diff --git a/dspl/src/convolution/filter_iir.c b/dspl/src/convolution/filter_iir.c
new file mode 100644
index 0000000..cdab6f4
--- /dev/null
+++ b/dspl/src/convolution/filter_iir.c
@@ -0,0 +1,230 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup FILTER_CONV_GROUP
+\fn int filter_iir(double* b, double* a, int ord, double* x, int n, double* y)
+\brief Real IIR filtration
+
+Function calculates real IIR filter output for real signal. The real filter
+contains real coefficients of the transfer function \f$H(z)\f$
+ numerator and denominator:
+\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]
+here \f$a_0\f$ cannot be equals zeros, \f$N=M=\f$`ord`.
+
+\param[in] b
+Pointer to the vector \f$b\f$ of IIR filter
+transfer function numerator coefficients. \n
+Vector size is `[ord + 1 x 1]`. \n \n
+
+\param[in] a
+Pointer to the vector \f$a\f$ of IIR filter
+transfer function denominator coefficients. \n
+Vector size is `[ord + 1 x 1]`. \n
+This pointer can be `NULL` if filter is FIR. \n \n
+
+\param[in] ord
+Filter order. Number of the transfer function
+numerator and denominator coefficients
+(length of vectors `b` and `a`) is `ord + 1`. \n \n
+
+\param[in] x
+Pointer to the input signal vector. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of the input signal vector `x`. \n \n
+
+\param[out] y
+Pointer to the IIR filter output vector. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if filter output is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
+
+Example:
+
+\include filter_iir_test.c
+
+Input signal is
+\f$s(t) = \sin(2\pi \cdot 0.05 t) + n(t)\f$, here \f$n(t)\f$ white Gaussian
+noise with zero mean value and unit standard deviation. \n
+
+Input signal is filtered by elliptic LPF order 6 and output signal and data
+saves in the txt-files
+
+\verbatim
+dat/s.txt - input signal + noise
+dat/sf.txt - filter output.
+\endverbatim
+
+Plots:
+
+\image html filter_iir_test.png
+
+GNUPLOT script for make plots is:
+\include filter_iir.plt
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\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^{-m}},
+\f]
+где \f$a_0\f$ не может быть 0, \f$N=M=\f$`ord`.
+
+\param[in] b
+Указатель на вектор коэффициентов числителя
+передаточной функции \f$H(z)\f$ БИХ-фильтра. \n
+Размер вектора `[ord + 1 x 1]`. \n \n
+
+\param[in] a
+Указатель на вектор коэффициентов знаменателя
+передаточной функции \f$H(z)\f$ БИХ-фильтра. \n
+Размер вектора `[ord + 1 x 1]`. \n
+Этот указатель может быть `NULL`, тогда фильтрация производится
+без использования рекурсивной части
+(вектор коэффициентов `b` задает КИХ-фильтр). \n \n
+
+\param[in] ord
+Порядок фильтра. Количество коэффициентов числителя и знаменателя
+передаточной функции \f$H(z)\f$ БИХ-фильтра равно `ord + 1`. \n \n
+
+\param[in] x
+Указатель на вектор отсчетов входного сигнала. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Длина входного сигнала. \n \n
+
+\param[out] y
+Указатель на вектор выходных отсчетов фильтра. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена заранее. \n \n
+
+\return
+`RES_OK` Если фильтрация произведена успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+Пример использования функции `filter_iir`:
+
+\include filter_iir_test.c
+
+На входе цифрового фильтра задан сигнал
+\f$s(t) = \sin(2\pi \cdot 0.05 t) + n(t)\f$, где \f$n(t)\f$ белый гауссовский
+шум, с нулевым средним и единичной дисперсией. \n
+Фильтр представляет собой эллиптический ФНЧ 6 порядка.
+Входной сигнал фильтруется данным фильтром, и результат сохраняется в файлы:
+
+\verbatim
+dat/s.txt - исходный зашумленный сигнал
+dat/sf.txt - сигнал на выходе фильтра.
+\endverbatim
+
+По полученным данным производится построение графиков:
+
+\image html filter_iir_test.png
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API filter_iir(double* b, double* a, int ord,
+ double* x, int n, double* y)
+{
+ double *buf = NULL;
+ double *an = NULL;
+ double *bn = NULL;
+ double u;
+ int k;
+ int m;
+ int count;
+
+ if(!b || !x || !y)
+ return ERROR_PTR;
+
+ if(ord < 1 || n < 1)
+ return ERROR_SIZE;
+
+ if(a && a[0]==0.0)
+ return ERROR_FILTER_A0;
+
+ count = ord + 1;
+ buf = (double*) malloc(count*sizeof(double));
+ an = (double*) malloc(count*sizeof(double));
+
+ memset(buf, 0, count*sizeof(double));
+
+ if(!a)
+ {
+ memset(an, 0, count*sizeof(double));
+ bn = b;
+ }
+ else
+ {
+ bn = (double*) malloc(count*sizeof(double));
+ for(k = 0; k < count; k++)
+ {
+ an[k] = a[k] / a[0];
+ bn[k] = b[k] / a[0];
+ }
+ }
+
+ for(k = 0; k < n; k++)
+ {
+ for(m = ord; m > 0; m--)
+ buf[m] = buf[m-1];
+ u = 0.0;
+ for(m = ord; m > 0; m--)
+ u += buf[m]*an[m];
+
+ buf[0] = x[k] - u;
+ y[k] = 0.0;
+ for(m = 0; m < count; m++)
+ y[k] += buf[m] * bn[m];
+ }
+
+ if(buf)
+ free(buf);
+ if(an)
+ free(an);
+ if(bn && (bn != b))
+ free(bn);
+ return RES_OK;
+}
+
diff --git a/dspl/src/ellipj.c b/dspl/src/ellipj.c
deleted file mode 100644
index bd8ecf1..0000000
--- a/dspl/src/ellipj.c
+++ /dev/null
@@ -1,1255 +0,0 @@
-/*
-* Copyright (c) 2015-2019 Sergey Bakhurin
-* Digital Signal Processing Library [http://dsplib.org]
-*
-* This file is part of DSPL.
-*
-* is free software: you can redistribute it and/or modify
-* it under the terms of the GNU 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 General Public License
-* along with Foobar. If not, see .
-*/
-
-
-#include
-#include
-#include
-#include
-#include "dspl.h"
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_acd(double* w, int n, double k, double* u)
-\brief Inverse Jacobi elliptic function \f$ u = \textrm{cd}^{-1}(w, k)\f$
-of the real vector argument
-
-Function calculates inverse Jacobi elliptic function
-\f$ u = \textrm{cd}^{-1}(w, k)\f$ of the real vector `w`. \n
-
-\param[in] w
-Pointer to the argument vector \f$ w \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\param[in] n
-Size of vector `w`. \n
-
-\param[in] k
-Elliptical modulus \f$ k \f$. \n
-Elliptical modulus is real parameter,
-which values can be from 0 to 1. \n \n
-
-\param[out] u
-Pointer to the vector of inverse Jacobi elliptic function
-\f$ u = \textrm{cd}^{-1}(w, k)\f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_acd(double* w, int n, double k, double* u)
-\brief Обратная эллиптическая функция Якоби
- \f$ u = \textrm{cd}^{-1}(w, k)\f$ вещественного аргумента
-
-Функция рассчитывает значения обратной эллиптической функции
-\f$ u = \textrm{cd}^{-1}(w, k)\f$ для вещественного вектора `w`. \n
-
-Для расчета используется итерационный алгоритм на основе преобразования
-Ландена. \n
-
-\param[in] w
-Указатель на массив вектора переменной \f$ w \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\param[in] n
-Размер вектора `w`. \n
-
-\param[in] k Значение эллиптического модуля \f$ k \f$.
-Эллиптический модуль -- вещественный параметр,
-принимающий значения от 0 до 1. \n \n
-
-\param[out] u
-Указатель на вектор значений обратной эллиптической
-функции \f$ u = \textrm{cd}^{-1}(w, k)\f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` Расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API ellip_acd(double* w, int n, double k, double* u)
-{
- double lnd[ELLIP_ITER], t;
- int i, m;
-
- if(!u || !w)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
- if(k < 0.0 || k>= 1.0)
- return ERROR_ELLIP_MODULE;
-
- ellip_landen(k,ELLIP_ITER, lnd);
-
- for(m = 0; m < n; m++)
- {
- u[m] = w[m];
- for(i = 1; i < ELLIP_ITER; i++)
- {
- t = lnd[i-1]*u[m];
- t *= t;
- t = 1.0 + sqrt(1.0 - t);
- u[m] = 2.0 * u[m] / (t+t*lnd[i]);
- }
- u[m] = 2.0 * acos(u[m]) / M_PI;
- }
- return RES_OK;
-}
-
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_acd_cmplx(complex_t* w, int n, double k, complex_t* u)
-\brief Inverse Jacobi elliptic function \f$ u = \textrm{cd}^{-1}(w, k)\f$
-of complex vector argument
-
-Function calculates inverse Jacobi elliptic function
-\f$ u = \textrm{cd}^{-1}(w, k)\f$ of complex vector `w`. \n
-
-\param[in] w
-Pointer to the argument vector \f$ w \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\param[in] n
-Size of vector `w`. \n \n
-
-\param[in] k
-Elliptical modulus \f$ k \f$. \n
-Elliptical modulus is real parameter,
-which values can be from 0 to 1. \n \n
-
-\param[out] u
-Pointer to the vector of inverse Jacobi elliptic function
-\f$ u = \textrm{cd}^{-1}(w, k)\f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_acd_cmplx(complex_t* w, int n, double k, complex_t* u)
-\brief Обратная эллиптическая функция Якоби
- \f$ u = \textrm{cd}^{-1}(w, k)\f$ комплексного аргумента
-
-Функция рассчитывает значения значения обратной эллиптической функции
-\f$ u = \textrm{cd}^{-1}(w, k)\f$ для комплексного вектора `w`. \n
-
-Для расчета используется итерационный алгоритм на основе преобразования
-Ландена. \n
-
-\param[in] w
-Указатель на массив вектора переменной \f$ w \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\param[in] n
-Размер вектора `w`. \n \n
-
-\param[in] k
-Значение эллиптического модуля \f$ k \f$. \n
-Эллиптический модуль -- вещественный параметр,
-принимающий значения от 0 до 1. \n \n
-
-\param[out] u
-Указатель на вектор значений обратной эллиптической
-функции \f$ u = \textrm{cd}^{-1}(w, k)\f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` Расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API ellip_acd_cmplx(complex_t* w, int n, double k, complex_t* u)
-{
- double lnd[ELLIP_ITER], t;
- complex_t tmp0, tmp1;
- int i, m;
-
- if(!u || !w)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
- if(k < 0.0 || k>= 1.0)
- return ERROR_ELLIP_MODULE;
-
- ellip_landen(k,ELLIP_ITER, lnd);
-
- for(m = 0; m < n; m++)
- {
- RE(u[m]) = RE(w[m]);
- IM(u[m]) = IM(w[m]);
- for(i = 1; i < ELLIP_ITER; i++)
- {
- RE(tmp0) = lnd[i-1]*RE(u[m]);
- IM(tmp0) = lnd[i-1]*IM(u[m]);
- RE(tmp1) = 1.0 - CMRE(tmp0, tmp0);
- IM(tmp1) = - CMIM(tmp0, tmp0);
-
- sqrt_cmplx(&tmp1, 1, &tmp0);
- RE(tmp0) += 1.0;
-
- RE(tmp1) = RE(tmp0) * (1.0 + lnd[i]);
- IM(tmp1) = IM(tmp0) * (1.0 + lnd[i]);
-
- t = 2.0 / ABSSQR(tmp1);
-
- RE(tmp0) = t * CMCONJRE(u[m], tmp1);
- IM(tmp0) = t * CMCONJIM(u[m], tmp1);
-
- RE(u[m]) = RE(tmp0);
- IM(u[m]) = IM(tmp0);
- }
- acos_cmplx(&tmp0, 1, u+m);
- t = 2.0 / M_PI;
- RE(u[m]) *= t;
- IM(u[m]) *= t;
- }
- return RES_OK;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_asn(double* w, int n, double k, double* u)
-\brief Inverse Jacobi elliptic function \f$ u = \textrm{sn}^{-1}(w, k)\f$
-of real vector argument
-
-Function calculates inverse Jacobi elliptic function
-\f$ u = \textrm{sn}^{-1}(w, k)\f$ of real vector `w`. \n
-
-\param[in] w
-Pointer to the argument vector \f$ w \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\param[in] n
-Size of vector `w`. \n
-
-\param[in] k
-Elliptical modulus \f$ k \f$. \n
-Elliptical modulus is real parameter,
-which values can be from 0 to 1. \n \n
-
-\param[out] u
-Pointer to the vector of inverse Jacobi elliptic function
-\f$ u = \textrm{sn}^{-1}(w, k)\f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_asn(double* w, int n, double k, double* u)
-\brief Обратная эллиптическая функция Якоби
- \f$ u = \textrm{sn}^{-1}(w, k)\f$ вещественного аргумента
-
-Функция рассчитывает значения значения обратной эллиптической функции
-\f$ u = \textrm{sn}^{-1}(w, k)\f$ для вещественного вектора `w`. \n
-
-Для расчета используется итерационный алгоритм на основе преобразования
-Ландена. \n
-
-\param[in] w
-Указатель на массив вектора переменной \f$ w \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\param[in] n
-Размер вектора `w`. \n \n
-
-\param[in] k
-Значение эллиптического модуля \f$ k \f$. \n
-Эллиптический модуль -- вещественный параметр,
-принимающий значения от 0 до 1. \n \n
-
-\param[out] u
-Указатель на вектор значений обратной эллиптической
-функции \f$ u = \textrm{sn}^{-1}(w, k)\f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` Расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API ellip_asn(double* w, int n, double k, double* u)
-{
- double lnd[ELLIP_ITER], t;
- int i, m;
-
- if(!u || !w)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
- if(k < 0.0 || k>= 1.0)
- return ERROR_ELLIP_MODULE;
-
- ellip_landen(k,ELLIP_ITER, lnd);
-
- for(m = 0; m < n; m++)
- {
- u[m] = w[m];
- for(i = 1; i < ELLIP_ITER; i++)
- {
- t = lnd[i-1]*u[m];
- t *= t;
- t = 1.0 + sqrt(1.0 - t);
- u[m] = 2.0 * u[m] / (t+t*lnd[i]);
- }
- u[m] = 2.0 * asin(u[m]) / M_PI;
- }
- return RES_OK;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_asn_cmplx(complex_t* w, int n, double k, complex_t* u)
-\brief Inverse Jacobi elliptic function \f$ u = \textrm{sn}^{-1}(w, k)\f$
-of complex vector argument
-
-Function calculates inverse Jacobi elliptic function
-\f$ u = \textrm{sn}^{-1}(w, k)\f$ of complex vector `w`. \n
-
-\param[in] w
-Pointer to the argument vector \f$ w \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\param[in] n
-Size of vector `w`. \n
-
-\param[in] k
-Elliptical modulus \f$ k \f$. \n
-Elliptical modulus is real parameter,
-which values can be from 0 to 1. \n \n
-
-\param[out] u
-Pointer to the vector of inverse Jacobi elliptic function
-\f$ u = \textrm{sn}^{-1}(w, k)\f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_asn_cmplx(complex_t* w, int n, double k, complex_t* u)
-\brief Обратная эллиптическая функция Якоби
- \f$ u = \textrm{sn}^{-1}(w, k)\f$ комплексного аргумента
-
-Функция рассчитывает значения значения обратной эллиптической функции
-\f$ u = \textrm{sn}^{-1}(w, k)\f$ для комплексного вектора `w`. \n
-
-Для расчета используется итерационный алгоритм на основе преобразования
-Ландена. \n
-
-
-\param[in] w
-Указатель на массив вектора переменной \f$ w \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\param[in] n
-Размер вектора `w`. \n \n
-
-\param[in] k
-Значение эллиптического модуля \f$ k \f$. \n
-Эллиптический модуль -- вещественный параметр,
-принимающий значения от 0 до 1. \n \n
-
-\param[out] u
-Указатель на вектор значений обратной эллиптической
-функции \f$ u = \textrm{sn}^{-1}(w, k)\f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK`Расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API ellip_asn_cmplx(complex_t* w, int n, double k, complex_t* u)
-{
- double lnd[ELLIP_ITER], t;
- complex_t tmp0, tmp1;
- int i, m;
-
- if(!u || !w)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
- if(k < 0.0 || k>= 1.0)
- return ERROR_ELLIP_MODULE;
-
- ellip_landen(k,ELLIP_ITER, lnd);
-
- for(m = 0; m < n; m++)
- {
- RE(u[m]) = RE(w[m]);
- IM(u[m]) = IM(w[m]);
- for(i = 1; i < ELLIP_ITER; i++)
- {
- RE(tmp0) = lnd[i-1]*RE(u[m]);
- IM(tmp0) = lnd[i-1]*IM(u[m]);
- RE(tmp1) = 1.0 - CMRE(tmp0, tmp0);
- IM(tmp1) = - CMIM(tmp0, tmp0);
-
- sqrt_cmplx(&tmp1, 1, &tmp0);
- RE(tmp0) += 1.0;
-
- RE(tmp1) = RE(tmp0) * (1.0 + lnd[i]);
- IM(tmp1) = IM(tmp0) * (1.0 + lnd[i]);
-
- t = 2.0 / ABSSQR(tmp1);
-
- RE(tmp0) = t * CMCONJRE(u[m], tmp1);
- IM(tmp0) = t * CMCONJIM(u[m], tmp1);
-
- RE(u[m]) = RE(tmp0);
- IM(u[m]) = IM(tmp0);
- }
-
- asin_cmplx(&tmp0, 1, u+m);
- t = 2.0 / M_PI;
- RE(u[m]) *= t;
- IM(u[m]) *= t;
- }
- return RES_OK;
-}
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_cd(double* u, int n, double k, double* y)
-\brief Jacobi elliptic function \f$ y = \textrm{cd}(u K(k), k)\f$
-of real vector argument
-
-Function calculates Jacobi elliptic function
-\f$ y = \textrm{cd}(u K(k), k)\f$ of real vector `u` and
-elliptical modulus `k`. \n
-
-\param[in] u
-Pointer to the argument vector \f$ u \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\param[in] n
-Size of vector `u`. \n
-
-\param[in] k
-Elliptical modulus \f$ k \f$. \n
-Elliptical modulus is real parameter,
-which values can be from 0 to 1. \n \n
-
-\param[out] y
-Pointer to the vector of Jacobi elliptic function
-\f$ y = \textrm{cd}(u K(k), k)\f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
-
-Example
-\include ellip_cd_test.c
-
-The program calculates two periods of the \f$ y = \textrm{cd}(u K(k), k)\f$
-function for different modulus values `k = 0`, `k= 0.9` и `k = 0.99`.
-Also program draws the plot of calculated elliptic functions.
-
-\image html ellip_cd.png
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_cd(double* u, int n, double k, double* y)
-\brief Эллиптическая функция Якоби
-\f$ y = \textrm{cd}(u K(k), k)\f$ вещественного аргумента
-
-Функция рассчитывает значения значения эллиптической функции
-\f$ y = \textrm{cd}(u K(k), k)\f$ для вещественного вектора `u` и
-эллиптического модуля `k`. \n
-
-Для расчета используется итерационный алгоритм на основе преобразования
-Ландена. \n
-
-\param[in] u
-Указатель на массив вектора переменной \f$ u \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\param[in] n
-Размер вектора `u`. \n \n
-
-\param[in] k
-Значение эллиптического модуля \f$ k \f$. \n
-Эллиптический модуль -- вещественный параметр,
-принимающий значения от 0 до 1. \n \n
-
-\param[out] y
-Указатель на вектор значений эллиптической
-функции \f$ y = \textrm{cd}(u K(k), k)\f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` Расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-Пример представлен в следующем листинге:
-
-\include ellip_cd_test.c
-
-Программа рассчитывает два периода эллиптической функции
-\f$ y = \textrm{cd}(u K(k), k)\f$ для `k = 0`, `k= 0.9` и `k = 0.99`,
-а также выводит графики данных функций
-
-\image html ellip_cd.png
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API ellip_cd(double* u, int n, double k, double* y)
-{
- double lnd[ELLIP_ITER];
- int i, m;
-
- if(!u || !y)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
- if(k < 0.0 || k>= 1.0)
- return ERROR_ELLIP_MODULE;
-
- ellip_landen(k,ELLIP_ITER, lnd);
-
- for(m = 0; m < n; m++)
- {
- y[m] = cos(u[m] * M_PI * 0.5);
- for(i = ELLIP_ITER-1; i>0; i--)
- {
- y[m] = (1.0 + lnd[i]) / (1.0 / y[m] + lnd[i]*y[m]);
- }
- }
- return RES_OK;
-}
-
-
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_cd_cmplx(complex_t* u, int n, double k, complex_t* y)
-\brief Jacobi elliptic function \f$ y = \textrm{cd}(u K(k), k)\f$
-of complex vector argument
-
-Function calculates Jacobi elliptic function
-\f$ y = \textrm{cd}(u K(k), k)\f$ of complex vector `u` and
-elliptical modulus `k`. \n
-
-\param[in] u
-Pointer to the argument vector \f$ u \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\param[in] n
-Size of vector `u`. \n
-
-\param[in] k
-Elliptical modulus \f$ k \f$. \n
-Elliptical modulus is real parameter,
-which values can be from 0 to 1. \n \n
-
-\param[out] y
-Pointer to the vector of Jacobi elliptic function
-\f$ y = \textrm{cd}(u K(k), k)\f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_cd_cmplx(complex_t* u, int n, double k, complex_t* y)
-\brief Эллиптическая функция Якоби
- \f$ y = \textrm{cd}(u K(k), k)\f$ комплексного аргумента
-
-Функция рассчитывает значения значения эллиптической функции
-\f$ y = \textrm{cd}(u K(k), k)\f$ для комплексного вектора `u` и
-эллиптического модуля `k`. \n
-
-Для расчета используется итерационный алгоритм на основе преобразования
-Ландена. \n
-
-\param[in] u
-Указатель на массив вектора переменной \f$ u \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\param[in] n
-Размер вектора `u`. \n \n
-
-\param[in] k
-Значение эллиптического модуля \f$ k \f$. \n
-Эллиптический модуль -- вещественный параметр,
-принимающий значения от 0 до 1. \n \n
-
-\param[out] y
-Указатель на вектор значений эллиптической
-функции \f$ y = \textrm{cd}(u K(k), k)\f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` Расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API ellip_cd_cmplx(complex_t* u, int n, double k, complex_t* y)
-{
- double lnd[ELLIP_ITER], t;
- int i, m;
- complex_t tmp;
-
- if(!u || !y)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
- if(k < 0.0 || k>= 1.0)
- return ERROR_ELLIP_MODULE;
-
- ellip_landen(k,ELLIP_ITER, lnd);
-
- for(m = 0; m < n; m++)
- {
- RE(tmp) = RE(u[m]) * M_PI * 0.5;
- IM(tmp) = IM(u[m]) * M_PI * 0.5;
-
- cos_cmplx(&tmp, 1, y+m);
-
- for(i = ELLIP_ITER-1; i>0; i--)
- {
- t = 1.0 / ABSSQR(y[m]);
-
- RE(tmp) = RE(y[m]) * t + RE(y[m]) * lnd[i];
- IM(tmp) = -IM(y[m]) * t + IM(y[m]) * lnd[i];
-
- t = (1.0 + lnd[i]) / ABSSQR(tmp);
-
- RE(y[m]) = RE(tmp) * t;
- IM(y[m]) = -IM(tmp) * t;
- }
- }
- return RES_OK;
-}
-
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_landen(double k, int n, double* y)
-\brief Function calculates complete elliptical integral
-coefficients \f$ k_i \f$
-
-Complete elliptical integral \f$ K(k) \f$ can be described as:
-
-\f[
- K(k) = \frac{\pi}{2} \prod_{i = 1}^{\infty}(1+k_i),
-\f]
-
-here \f$ k_i \f$ -- coefficients which calculated
-iterative from \f$ k_0 = k\f$:
-
-\f[
- k_i = \left( \frac{k_{i-1}}{1+\sqrt{1-k_{i-1}^2}}\right)^2
-\f]
-
-This function calculates `n` fist coefficients \f$ k_i \f$, which can
-be used for Complete elliptical integral.
-
-\param[in] k
-Elliptical modulus \f$ k \f$. \n
-Elliptical modulus is real parameter, which values can be from 0 to 1. \n \n
-
-\param[in] n
-Number of \f$ k_i \f$ which need to calculate. \n
-Parameter `n` is size of output vector `y`. \n
-
-\param[out] y
-pointer to the real vector which keep \f$ k_i \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
- `RES_OK` -- successful exit, else \ref ERROR_CODE_GROUP "error code". \n
-
-Example:
-
-\include ellip_landen_test.c
-
-Result:
-
-\verbatim
- i k[i]
-
- 1 4.625e-01
- 2 6.009e-02
- 3 9.042e-04
- 4 2.044e-07
- 5 1.044e-14
- 6 2.727e-29
- 7 1.859e-58
- 8 8.640e-117
- 9 1.866e-233
-10 0.000e+00
-11 0.000e+00
-12 0.000e+00
-13 0.000e+00
-\endverbatim
-
-\note Complete elliptical integral converges enough fast
- if modulus \f$ k<1 \f$. There are 10 to 20 coefficients \f$ k_i \f$
- are sufficient for practical applications
- to ensure complete elliptic integral precision within EPS.
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_landen(double k, int n, double* y)
-\brief Расчет коэффициентов \f$ k_i \f$ ряда полного эллиптического интеграла.
-
-Полный эллиптический интеграл \f$ K(k) \f$ может быть представлен рядом:
-
-\f[
-K(k) = \frac{\pi}{2} \prod_{i = 1}^{\infty}(1+k_i),
-\f]
-
-где \f$ k_i \f$ вычисляется итерационно при начальных условиях \f$ k_0 = k\f$:
-
-\f[
- k_i = \left( \frac{k_{i-1}}{1+\sqrt{1-k_{i-1}^2}}\right)^2
-\f]
-
-Данная функция рассчитывает ряд первых `n` значений \f$ k_i \f$, которые в
-дальнейшем могут быть использованы для расчета эллиптического интеграла и
-эллиптических функций.
-
-\param[in] k
-Эллиптический модуль \f$ k \f$. \n
-
-\param[in] n
-Размер вектора `y` соответствующих коэффициентам \f$ k_i \f$. \n \n
-
-\param[out] y
-Указатель на вектор значений коэффициентов \f$ k_i \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-
-\return
-`RES_OK` Расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-Пример использования функции `ellip_landen`:
-
-\include ellip_landen_test.c
-
-Результат работы программы:
-
-\verbatim
- i k[i]
-
- 1 4.625e-01
- 2 6.009e-02
- 3 9.042e-04
- 4 2.044e-07
- 5 1.044e-14
- 6 2.727e-29
- 7 1.859e-58
- 8 8.640e-117
- 9 1.866e-233
-10 0.000e+00
-11 0.000e+00
-12 0.000e+00
-13 0.000e+00
-\endverbatim
-
-\note
-Ряд полного эллиптического интеграла сходится при значениях
-эллиптического модуля \f$ k<1 \f$. При этом сходимость ряда достаточно
-быстрая и для практический приложений достаточно от 10 до 20 значений
-\f$ k_i \f$ для обеспечения погрешности при расчете полного
-эллиптического интеграла в пределах машинной точности.
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API ellip_landen(double k, int n, double* y)
-{
- int i;
- y[0] = k;
-
- if(!y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
- if(k < 0.0 || k>= 1.0)
- return ERROR_ELLIP_MODULE;
-
- for(i = 1; i < n; i++)
- {
- y[i] = y[i-1] / (1.0 + sqrt(1.0 - y[i-1] * y[i-1]));
- y[i] *= y[i];
- }
-
- return RES_OK;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API ellip_modulareq(double rp, double rs, int ord, double *k)
-{
- double ep, es, ke, kp, t, sn = 0.0;
- int i, L, r;
-
- if(rp < 0 || rp == 0)
- return ERROR_FILTER_RP;
- if(rs < 0 || rs == 0)
- return ERROR_FILTER_RS;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(!k)
- return ERROR_PTR;
-
-
- ep = sqrt(pow(10.0, rp*0.1)-1.0);
- es = sqrt(pow(10.0, rs*0.1)-1.0);
-
- ke = ep/es;
-
- ke = sqrt(1.0 - ke*ke);
-
- r = ord % 2;
- L = (ord-r)/2;
-
- kp = 1.0;
- for(i = 0; i < L; i++)
- {
- t = (double)(2*i+1) / (double)ord;
- ellip_sn(&t, 1, ke, &sn);
- sn*=sn;
- kp *= sn*sn;
- }
-
- kp *= pow(ke, (double)ord);
- *k = sqrt(1.0 - kp*kp);
-
- return RES_OK;
-
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API ellip_rat(double* w, int n, int ord, double k, double* u)
-{
- double t, xi, w2, xi2, k2;
- int i, m, r, L;
-
- if(!u || !w)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
- if(k < 0.0 || k>= 1.0)
- return ERROR_ELLIP_MODULE;
-
- r = ord%2;
- L = (ord-r)/2;
-
- if(r)
- memcpy(u, w, n*sizeof(double));
- else
- {
- for(m = 0; m < n; m++)
- {
- u[m] = 1.0;
- }
- }
-
- k2 = k*k;
- for(i = 0; i < L; i++)
- {
- t = (double)(2*i+1) / (double)ord;
- ellip_cd(&t, 1, k, &xi);
- xi2 = xi*xi;
- for(m = 0; m < n; m++)
- {
- w2 = w[m]*w[m];
- u[m] *= (w2 - xi2) / (1.0 - w2 * k2 * xi2);
- u[m] *= (1.0 - k2*xi2) / (1.0 - xi2);
- }
- }
- return RES_OK;
-}
-
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_sn(double* u, int n, double k, double* y)
-\brief Jacobi elliptic function \f$ y = \textrm{sn}(u K(k), k)\f$
-of real vector argument
-
-Function calculates Jacobi elliptic function
-\f$ y = \textrm{sn}(u K(k), k)\f$ of real vector `u` and
-elliptical modulus `k`. \n
-
-\param[in] u
-Pointer to the argument vector \f$ u \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\param[in] n
-Size of vector `u`. \n \n
-
-\param[in] k
-Elliptical modulus \f$ k \f$. \n
-Elliptical modulus is real parameter,
-which values can be from 0 to 1. \n \n
-
-\param[out] y
-Pointer to the vector of Jacobi elliptic function
-\f$ y = \textrm{sn}(u K(k), k)\f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
-
-Example
-\include ellip_sn_test.c
-
-The program calculates two periods of the \f$ y = \textrm{sn}(u K(k), k)\f$
-function for different modulus values `k = 0`, `k= 0.9` и `k = 0.99`.
-Also program draws the plot of calculated elliptic functions.
-
-\image html ellip_sn.png
-
-\author Sergey Bakhurin www.dsplib.org
- **************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_sn(double* u, int n, double k, double* y)
-\brief Эллиптическая функция Якоби
-\f$ y = \textrm{sn}(u K(k), k)\f$ вещественного аргумента
-
-Функция рассчитывает значения значения эллиптической функции
-\f$ y = \textrm{sn}(u K(k), k)\f$ для вещественного вектора `u` и
-эллиптического модуля `k`. \n
-
-Для расчета используется итерационный алгоритм на основе преобразования
-Ландена. \n
-
-\param[in] u
-Указатель на массив вектора переменной \f$ u \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\param[in] n
-Размер вектора `u`. \n \n
-
-\param[in] k
-Значение эллиптического модуля \f$ k \f$. \n
-Эллиптический модуль -- вещественный параметр,
-принимающий значения от 0 до 1. \n \n
-
-\param[out] y
-Указатель на вектор значений эллиптической
-функции \f$ y = \textrm{sn}(u K(k), k)\f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` Расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-
-Пример представлен в следующем листинге:
-
-\include ellip_sn_test.c
-
-Программа рассчитывает два периода эллиптической функции
-\f$ y = \textrm{sn}(u K(k), k)\f$ для `k = 0`, `k= 0.9` и `k = 0.99`,
-а также выводит графики данных функций
-
-\image html ellip_sn.png
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API ellip_sn(double* u, int n, double k, double* y)
-{
- double lnd[ELLIP_ITER];
- int i, m;
-
- if(!u || !y)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
- if(k < 0.0 || k>= 1.0)
- return ERROR_ELLIP_MODULE;
-
- ellip_landen(k,ELLIP_ITER, lnd);
-
-
- for(m = 0; m < n; m++)
- {
- y[m] = sin(u[m] * M_PI * 0.5);
- for(i = ELLIP_ITER-1; i>0; i--)
- {
- y[m] = (1.0 + lnd[i]) / (1.0 / y[m] + lnd[i]*y[m]);
- }
- }
- return RES_OK;
-}
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_sn_cmplx(complex_t* u, int n, double k, complex_t* y)
-\brief Jacobi elliptic function \f$ y = \textrm{sn}(u K(k), k)\f$ of
-complex vector argument
-
-Function calculates Jacobi elliptic function
-\f$ y = \textrm{sn}(u K(k), k)\f$ of complex vector `u` and
-elliptical modulus `k`. \n
-
-\param[in] u
-Pointer to the argument vector \f$ u \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\param[in] n
-Size of vector `u`. \n
-
-\param[in] k
-Elliptical modulus \f$ k \f$. \n
-Elliptical modulus is real parameter,
-which values can be from 0 to 1. \n \n
-
-\param[out] y
-Pointer to the vector of Jacobi elliptic function
-\f$ y = \textrm{sn}(u K(k), k)\f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup SPEC_MATH_ELLIP_GROUP
-\fn int ellip_sn_cmplx(complex_t* u, int n, double k, complex_t* y)
-\brief Эллиптическая функция Якоби
-\f$ y = \textrm{sn}(u K(k), k)\f$ комплексного аргумента
-
-Функция рассчитывает значения значения эллиптической функции
-\f$ y = \textrm{sn}(u K(k), k)\f$ для комплексного вектора `u` и
-эллиптического модуля `k`. \n
-
-Для расчета используется итерационный алгоритм на основе преобразования
-Ландена. \n
-
-\param[in] u
-Указатель на массив вектора переменной \f$ u \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\param[in] n
-Размер вектора `u`. \n \n
-
-\param[in] k
-Значение эллиптического модуля \f$ k \f$. \n
-Эллиптический модуль -- вещественный параметр,
-принимающий значения от 0 до 1. \n \n
-
-\param[out] y
-Указатель на вектор значений эллиптической
-функции \f$ y = \textrm{sn}(u K(k), k)\f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` Расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API ellip_sn_cmplx(complex_t* u, int n, double k, complex_t* y)
-{
- double lnd[ELLIP_ITER], t;
- int i, m;
- complex_t tmp;
-
- if(!u || !y)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
- if(k < 0.0 || k>= 1.0)
- return ERROR_ELLIP_MODULE;
-
- ellip_landen(k,ELLIP_ITER, lnd);
-
-
- for(m = 0; m < n; m++)
- {
- RE(tmp) = RE(u[m]) * M_PI * 0.5;
- IM(tmp) = IM(u[m]) * M_PI * 0.5;
-
- sin_cmplx(&tmp, 1, y+m);
-
- for(i = ELLIP_ITER-1; i>0; i--)
- {
- t = 1.0 / ABSSQR(y[m]);
-
- RE(tmp) = RE(y[m]) * t + RE(y[m]) * lnd[i];
- IM(tmp) = -IM(y[m]) * t + IM(y[m]) * lnd[i];
-
- t = (1.0 + lnd[i]) / ABSSQR(tmp);
-
- RE(y[m]) = RE(tmp) * t;
- IM(y[m]) = -IM(tmp) * t;
-
- }
- }
- return RES_OK;
-}
-
diff --git a/dspl/src/filter_an.c b/dspl/src/filter_an.c
deleted file mode 100644
index 762443b..0000000
--- a/dspl/src/filter_an.c
+++ /dev/null
@@ -1,1266 +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 .
-*/
-
-
-#include
-#include
-#include
-#include "dspl.h"
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup FILTER_ANALYSIS_GROUP
-\fn int DSPL_API group_delay(double* b, double* a, int ord, int flag,
- double* w, int n, double* tau)
-
-\brief
-Group delay calculation for digital or analog filter corresponds to
-\f$H(s)\f$, or \f$H(z)\f$ transfer function.
-
-Group delay is describes as:
-\f[
-\tau_g(\omega) = - \frac{d\Phi(\omega)}{d\omega},
-\f]
-here \f$\Phi(\omega)\f$ -- filter phase response, \f$\omega\f$ is angular
-frequency for analog filter, or normalized frequency for digital filter.
-
-\param[in] b
-Pointer to the \f$ H(s) \f$ or \f$H(z)\f$ transfer function
-numerator coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n \n
-
-\param[in] a
-Pointer to the \f$ H(s) \f$ or \f$H(z)\f$ transfer function
-denominator coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n \n
-
-\param[in] ord
-Filter order. \n
-Transfer function \f$ H(s) \f$ or \f$H(z)\f$ numerator
-and denominator coefficients number equals `ord+1`. \n \n
-
-\param[in] flag
-Binary flags to set calculation rules: \n
-\verbatim
-DSPL_FLAG_ANALOG Coefficients corresponds to analog filter
-DSPL_FLAG_DIGITAL Coefficients corresponds to digital filter
-\endverbatim
-\n \n
-
-\param[in] w
-Pointer to the angular frequency \f$ \omega \f$ (rad/s),
-which used for analog filter characteristics calculation
-(flag sets as `DSPL_FLAG_ANALOG`). \n
-For digital filter (flag sets as `DSPL_FLAG_DIGITAL`),
- parameter `w` describes normalized frequency of
-frequency response \f$ H \left(\mathrm{e}^{j\omega} \right) \f$.
-Digital filter frequency response is \f$ 2\pi \f$-periodic function,
-and vector `w` advisable to set from 0 to \f$ \pi \f$,
-or from 0 to \f$ 2\pi \f$, or from \f$ -\pi \f$ to \f$ \pi \f$.
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of frequency vector `w`. \n \n
-
-\param[out] tau
-Pointer to the group delay vector. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-\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 FILTER_ANALYSIS_GROUP
-\fn int DSPL_API group_delay(double* b, double* a, int ord, int flag,
- double* w, int n, double* tau)
-\brief
-Расчет группового времени запаздывания цифрового или аналогового фильтра.
-
-Групповое время запаздывания определяется как:
-\f[
-\tau_g(\omega) = - \frac{d\Phi(\omega)}{d\omega},
-\f]
-где \f$\Phi(\omega)\f$ -- ФЧХ фильтра, \f$\omega\f$ циктическая частот в случае
-аналогового фильтра, или нормированная частота цифрового фильтра.
-
-\param[in] b
-Указатель на вектор коэффициентов числителя передаточной функции
-аналогового фильтра \f$ H(s) \f$ или цифрового фильтра \f$ H(z) \f$. \n
-Размер вектора `[ord+1 x 1]`. \n \n
-
-\param[in] a
-Указатель на вектор коэффициентов числителя передаточной функции
-аналогового фильтра \f$ H(s) \f$ или цифрового фильтра \f$ H(z) \f$. \n
-Размер вектора `[ord+1 x 1]`. \n
-Параметр может быть `NULL`. В этом случае расчет производится для цифрового
-КИХ-фильтра с коэффициентами, заданными вектором `b`. \n\n
-
-\param[in] ord
-Порядок фильтра. Количество коэффициентов
-числителя и знаменателя передаточной
-функции \f$ H(s) \f$ или \f$ H(z) \f$ равно `ord+1`. \n \n
-
-\param[in] flag
-Флаг который задает тип фильтра: \n
-\verbatim
-DSPL_FLAG_ANALOG Коэффициенты относятся к аналоговому фильтру
-DSPL_FLAG_DIGITAL Коэффициенты относятся к цифровому фильтру
-\endverbatim
-
-\param[in] w
-Указатель на вектор значений циклической частоты \f$ \omega \f$ (рад/с),
-для которого будет рассчитаны АЧХ, ФЧХ и ГВЗ аналогового фильтра,
-если установлен флаг `DSPL_FLAG_ANALOG`. \n
-В случае если флаг `DSPL_FLAG_ANALOG` не установлен, то вектор частоты `w`
-используется как нормированная частота комплексного коэффициента передачи
-\f$ H \left(\mathrm{e}^{j\omega} \right) \f$ цифрового фильтра. \n
-В этом случае характеристика цифрового фильтра является
-\f$ 2\pi \f$-периодической, и вектор частоты может содержать
-произвольные значения, однако целесообразно задавать
-его от 0 до \f$ \pi \f$, а такжет от 0 до \f$ 2\pi \f$, или
-от \f$ -\pi \f$ до \f$ \pi \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер вектора циклической частоты `w`. \n \n
-
-\param[out] tau
-Указатель на вектор групповой задержки. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n
-
-\return
-`RES_OK` групповая задержка фильтра рассчитана успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API group_delay(double* pb, double* pa, int ord, int flag,
- double* w, int n, double* tau)
-{
- double a, b, c, d, da, db, dc, dd, f, e;
- int t, m;
-
- double *qa = NULL;
-
- if(!pb || !w || !tau || (!pa && (flag & DSPL_FLAG_ANALOG)))
- return ERROR_PTR;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(n < 1)
- return ERROR_SIZE;
-
-
- if(pa)
- qa = pa;
- else
- {
- qa = (double*)malloc((ord+1) * sizeof(double));
- memset(qa, 0, (ord+1) * sizeof(double));
- qa[0] = 1.0;
- }
-
- for(t = 0; t < n; t++)
- {
- a = b = c = d = da = db = dc = dd = 0.0;
- if(flag & DSPL_FLAG_ANALOG)
- {
- for(m = 0; m < ord+1; m+=4)
- {
- a += pb[m] * pow(w[t], (double)m);
- c += qa[m] * pow(w[t], (double)m);
- da += pb[m] * (double) m * pow(w[t], (double)(m-1));
- dc += qa[m] * (double) m * pow(w[t], (double)(m-1));
- }
- for(m = 2; m < ord+1; m+=4)
- {
- a -= pb[m] * pow(w[t], (double)m);
- c -= qa[m] * pow(w[t], (double)m);
- da -= pb[m] * (double) m * pow(w[t], (double)(m-1));
- dc -= qa[m] * (double) m * pow(w[t], (double)(m-1));
- }
-
- for(m = 1; m < ord+1; m+=4)
- {
- b += pb[m] * pow(w[t], (double)m) ;
- d += qa[m] * pow(w[t], (double)m) ;
- db += pb[m] * (double) m * pow(w[t], (double)(m-1)) ;
- dd += qa[m] * (double) m * pow(w[t], (double)(m-1)) ;
- }
-
- for(m = 3; m < ord+1; m+=4)
- {
- b -= pb[m] * pow(w[t], (double)m) ;
- d -= qa[m] * pow(w[t], (double)m) ;
- db -= pb[m] * (double) m * pow(w[t], (double)(m-1)) ;
- dd -= qa[m] * (double) m * pow(w[t], (double)(m-1)) ;
- }
-
- }
- else
- {
- for(m = 0; m < ord+1; m++)
- {
- a += pb[m] * cos(w[t]*(double)m);
- b -= pb[m] * sin(w[t]*(double)m);
- c += qa[m] * cos(w[t]*(double)m);
- d -= qa[m] * sin(w[t]*(double)m);
-
- da -= pb[m] *(double)m * sin(w[t]*(double)m);
- db -= pb[m] *(double)m * cos(w[t]*(double)m);
- dc -= qa[m] *(double)m * sin(w[t]*(double)m);
- dd -= qa[m] *(double)m * cos(w[t]*(double)m);
- }
- }
-
- f = da * c + a * dc + db * d + b * dd;
- e = db * c + b * dc - da * d - a * dd;
- tau[t] = (f * (b * c - a * d) - e * (a * c + b * d)) /
- ((a * a + b * b) * (c * c + d * d));
- }
-
- if(qa != pa)
- free(qa);
-
- return RES_OK;
-}
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup FILTER_ANALYSIS_GROUP
-\fn int filter_freq_resp(double* b, double* a, int ord, double* w, int n,
- int flag, double* mag, double* phi, double* tau)
-
-\brief
-Magnitude, phase response and group delay vectors calculation
-for digital or analog filter corresponds to \f$H(s)\f$, or \f$H(z)\f$
-transfer function.
-
-
-\param[in] b
-Pointer to the \f$ H(s) \f$ or \f$H(z)\f$ transfer function
-numerator coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n \n
-
-\param[in] a
-Pointer to the \f$ H(s) \f$ or \f$H(z)\f$ transfer function
-denominator coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n \n
-
-\param[in] ord
-Filter order. \n
-Transfer function \f$ H(s) \f$ or \f$H(z)\f$ numerator
-and denominator coefficients number equals `ord+1`. \n \n
-
-\param[in] w
-Pointer to the angular frequency \f$ \omega \f$ (rad/s),
-which used for analog filter characteristics calculation
-(flag sets as `DSPL_FLAG_ANALOG`). \n
-For digital filter (flag sets as `DSPL_FLAG_DIGITAL`),
- parameter `w` describes normalized frequency of
-frequency response \f$ H \left(\mathrm{e}^{j\omega} \right) \f$.
-Digital filter frequency response is \f$ 2\pi \f$-periodic function,
-and vector `w` advisable to set from 0 to \f$ \pi \f$,
-or from 0 to \f$ 2\pi \f$, or from \f$ -\pi \f$ to \f$ \pi \f$.
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of frequency vector `w`. \n \n
-
-\param[in] flag
-Binary flags to set calculation rules: \n
-\verbatim
-DSPL_FLAG_ANALOG Coefficients corresponds to analog filter
-DSPL_FLAG_DIGITAL Coefficients corresponds to digital filter
-DSPL_FLAG_LOGMAG Calculate magnitude in logarithmic scale (in dB)
-DSPL_FLAG_UNWRAP Unwrap radian phases by adding multiples of 2*pi
-\endverbatim
-
-\param[out] mag
-Pointer to the filter magnitude vector. \n
-Vector size is `[n x 1]`. \n
-If pointer is `NULL`, then magnitude will not calculted. \n \n
-
-\param[out] phi
-Pointer to the phase response vector. \n
-Vector size is `[n x 1]`. \n
-If pointer is `NULL`, then phase response will not calculted. \n \n
-
-\param[out] tau
-Pointer to the group delay vector. \n
-Vector size is `[n x 1]`. \n
-If pointer is `NULL`, then group delay will not calculted. \n \n
-
-\return
-\return `RES_OK` if function is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-Example:
-
-\include butter_ap_test.c
-
-Result:
-
-\verbatim
-b[ 0] = 1.002 a[ 0] = 1.002
-b[ 1] = 0.000 a[ 1] = 2.618
-b[ 2] = 0.000 a[ 2] = 3.418
-b[ 3] = 0.000 a[ 3] = 2.615
-b[ 4] = 0.000 a[ 4] = 1.000
-\endverbatim
-\n
-
-In `dat` folder will be created 3 files: \n
-
-\verbatim
-butter_ap_test_mag.txt magnitude
-butter_ap_test_phi.txt phase response
-butter_ap_test_tau.txt group delay
-\endverbatim
-
-In addition, GNUPLOT will build the following graphs from data stored in files:
-
-\image html butter_ap_test.png
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup FILTER_ANALYSIS_GROUP
-\fn int filter_freq_resp(double* b, double* a, int ord, double* w, int n,
- int flag, double* mag, double* phi, double* tau)
-
-\brief
-Расчет амплитудно-частотной (АЧХ), фазочастотной характеристик (ФЧХ), а также
-группового времени запаздывания (ГВЗ) цифрового или аналогового или фильтра.
-
-Функция рассчитывает АЧХ, ФЧХ и ГВЗ аналогового или цифрового фильтра, заданного
-передаточной характеристикой \f$H(s)\f$, или \f$H(z)\f$ соответственно
-
-\param[in] b
-Указатель на вектор коэффициентов числителя
-передаточной функции \f$ H(s) \f$. \n
-Размер вектора `[ord+1 x 1]`. \n \n
-
-\param[in] a
-Указатель на вектор коэффициентов знаменателя
-передаточной функции \f$ H(s) \f$. \n
-Размер вектора `[ord+1 x 1]`. \n \n
-
-\param[in] ord
-Порядок фильтра. Количество коэффициентов
-числителя и знаменателя передаточной
-функции \f$ H(s) \f$ равно `ord+1`. \n \n
-
-\param[in] w
-Указатель на вектор значений циклической частоты \f$ \omega \f$ (рад/с),
-для которого будет рассчитаны АЧХ, ФЧХ и ГВЗ аналогового фильтра,
-если установлен флаг `DSPL_FLAG_ANALOG`. \n
-В случае если флаг `DSPL_FLAG_ANALOG` не установлен, то вектор частоты `w`
-используется как нормированная частота комплексного коэффициента передачи
-\f$ H \left(\mathrm{e}^{j\omega} \right) \f$ цифрового фильтра. \n
-В этом случае характеристика цифрового фильтра является
-\f$ 2\pi \f$-периодической, и вектор частоты может содержать
-произвольные значения, однако целесообразно задавать
-его от 0 до \f$ \pi \f$, а такжет от 0 до \f$ 2\pi \f$, или
-от \f$ -\pi \f$ до \f$ \pi \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер вектора циклической частоты `w`. \n \n
-
-\param[in] flag
-Комбинация флагов, которые задают расчет параметров: \n
-\verbatim
-DSPL_FLAG_ANALOG Коэффициенты относятся к аналоговому фильтру
-DSPL_FLAG_LOGMAG АЧХ рассчитывать в логарифмическом масштабе
-DSPL_FLAG_UNWRAP раскрывать периодичность ФЧХ
-\endverbatim
-
-\param[out] mag
-Указатель на вектор АЧХ. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n
-Если указатель `NULL`, то расчет АЧХ не производится. \n \n
-
-\param[out] phi
-Указатель на вектор ФЧХ. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n
-Если указатель `NULL`, то расчет ФЧХ не производится. \n \n
-
-\param[out] tau
-Указатель на вектор ГВЗ. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n
-Если указатель `NULL`, то расчет ГВЗ не производится. \n \n
-
-\return
-`RES_OK` Параметры фильтра рассчитаны успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-Пример использования функции `filter_freq_resp`:
-
-\include butter_ap_test.c
-
-Результат работы программы:
-
-\verbatim
-b[ 0] = 1.002 a[ 0] = 1.002
-b[ 1] = 0.000 a[ 1] = 2.618
-b[ 2] = 0.000 a[ 2] = 3.418
-b[ 3] = 0.000 a[ 3] = 2.615
-b[ 4] = 0.000 a[ 4] = 1.000
-\endverbatim
-\n
-
-В каталоге `dat` будут созданы три файла: \n
-
-\verbatim
-butter_ap_test_mag.txt АЧХ фильтра
-butter_ap_test_phi.txt ФЧХ фильтра
-butter_ap_test_tau.txt ГВЗ фильтра
-\endverbatim
-
-Кроме того программа GNUPLOT произведет построение следующих графиков
-по сохраненным в файлах данным:
-
-\image html butter_ap_test.png
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API filter_freq_resp(double* b, double* a, int ord,
- double* w, int n, int flag,
- double* mag, double* phi, double* tau)
-{
- int res, k, flag_analog;
-
- complex_t *hc = NULL;
- double *phi0 = NULL;
- double *phi1 = NULL;
- double *w0 = NULL;
- double *w1 = NULL;
-
- if(!b || !w)
- return ERROR_PTR;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(n < 1)
- return ERROR_SIZE;
-
- flag_analog = flag & DSPL_FLAG_ANALOG;
-
- hc = (complex_t*) malloc (n*sizeof(complex_t));
-
- res = flag_analog ?
- freqs(b, a, ord, w, n, hc) :
- freqz(b, a, ord, w, n, hc);
-
- if(res != RES_OK)
- goto exit_label;
-
-
- if(mag)
- {
- if(flag & DSPL_FLAG_LOGMAG)
- {
- for(k = 0; k < n; k++)
- mag[k] = 10.0 * log10(ABSSQR(hc[k]));
- }
- else
- {
- for(k = 0; k < n; k++)
- mag[k] = sqrt(ABSSQR(hc[k]));
- }
- }
-
-
- if(phi)
- {
- for(k = 0; k < n; k++)
- phi[k] = atan2(IM(hc[k]), RE(hc[k]));
-
- if(flag & DSPL_FLAG_UNWRAP)
- {
- res = unwrap(phi, n, M_2PI, 0.8);
- if(res != RES_OK)
- goto exit_label;
- }
- }
-
-
- if(tau)
- res = group_delay(b, a, ord, flag, w, n, tau);
-
-
-
-exit_label:
- if(hc)
- free(hc);
- if(phi0)
- free(phi0);
- if(phi1)
- free(phi1);
- if(w0)
- free(w0);
- if(w1)
- free(w1);
- return res;
-}
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup FILTER_ANALYSIS_GROUP
-\fn int freqs(double* b, double* a, int ord, double* w, int n, complex_t *h)
-\brief Analog filter frequency response \f$ H(j \omega) \f$ calculation
-
-Function calculates analog filter frequency response \f$ H(j \omega)\f$
-corresponds to transfer function \f$ H(s) \f$:
-
-\f[
- H(s) = \frac {\sum_{k = 0}^{N} b_k s^k}
- {\sum_{m = 0}^{N} a_m s^m},
-\f]
-here \f$ N \f$ - filter order (equals to `ord`).
-
-\param[in] b
-Pointer to the transfer function \f$ H(s) \f$
-numerator coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n \n
-
-\param[in] a
-Pointer to the transfer function \f$ H(s) \f$
-denominator coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n \n
-
-\param[in] ord
-Filter order. \n
-Transfer function \f$ H(s) \f$ numerator and denominator
-coefficients number equals `ord+1`. \n \n
-
-\param[in] w
-Pointer to the angular frequency \f$ \omega \f$ (rad/s),
-which used for frequency response \f$ H(j \omega) \f$ calculation. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-The size of the angular frequency vector `w`. \n \n
-
-\param[out] h
-Pointer to the frequency response vector \f$ H(j \omega) \f$,
-corresponds to angular frequency `w`. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return `RES_OK` if frequency response vector is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup FILTER_ANALYSIS_GROUP
-\fn int freqs(double* b, double* a, int ord, double* w, int n, complex_t *h)
-
-\brief Расчет комплексного коэффициента передачи
-\f$ H(j \omega) \f$ аналогового фильтра.
-
-Функция рассчитывает значения комплексного коэффициента передачи
-\f$ H(j \omega)\f$ аналогового фильтра, заданного коэффициентами
-передаточной функции \f$ H(s) \f$:
-
-\f[
- H(s) = \frac {\sum_{k = 0}^{N} b_k s^k}
- {\sum_{m = 0}^{N} a_m s^m},
-\f]
-где \f$ N \f$ - порядок фильтра (параметр `ord`).
-
-Комплексный коэффициент передачи рассчитывается путем
-подстановки \f$ s = j \omega \f$.
-
-\param[in] b
-Указатель на вектор коэффициентов числителя
-передаточной функции \f$ H(s) \f$. \n
-Размер вектора `[ord+1 x 1]`. \n \n
-
-
-\param[in] a
-Указатель на вектор коэффициентов знаменателя
-передаточной функции \f$ H(s) \f$. \n
-Размер вектора `[ord+1 x 1]`. \n \n
-
-
-\param[in] ord
-Порядок фильтра. Количество коэффициентов числителя и
-знаменателя передаточной функции \f$ H(s) \f$
-равно `ord+1`. \n \n
-
-
-\param[in] w
-Указатель на вектор значений циклической частоты \f$ \omega \f$ (рад/с),
-для которого будет рассчитан комплексный
-коэффициент передачи \f$ H(j \omega) \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-
-\param[in] n
-Размер вектора циклической частоты `w`. \n \n
-
-
-\param[out] h
-Указатель на вектор комплексного коэффициента передачи \f$ H(j \omega) \f$,
-рассчитанного для циклической частоты `w`. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` Комплексный коэффициент передачи рассчитан успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API freqs(double* b, double* a, int ord,
- double* w, int n, complex_t *h)
-{
- complex_t jw;
- complex_t *bc = NULL;
- complex_t *ac = NULL;
- complex_t num, den;
- double mag;
- int k;
- int res;
-
- if(!b || !a || !w || !h)
- return ERROR_PTR;
- if(ord<0)
- return ERROR_FILTER_ORD;
- if(n<1)
- return ERROR_SIZE;
-
- RE(jw) = 0.0;
-
- bc = (complex_t*) malloc((ord+1) * sizeof(complex_t));
- res = re2cmplx(b, ord+1, bc);
-
- if( res!=RES_OK )
- goto exit_label;
-
- ac = (complex_t*) malloc((ord+1) * sizeof(complex_t));
- res = re2cmplx(a, ord+1, ac);
- if( res!=RES_OK )
- goto exit_label;
-
- for(k = 0; k < n; k++)
- {
- IM(jw) = w[k];
- res = polyval_cmplx(bc, ord, &jw, 1, &num);
- if(res != RES_OK)
- goto exit_label;
- res = polyval_cmplx(ac, ord, &jw, 1, &den);
- if(res != RES_OK)
- goto exit_label;
- mag = ABSSQR(den);
- if(mag == 0.0)
- {
- res = ERROR_DIV_ZERO;
- goto exit_label;
- }
- mag = 1.0 / mag;
- RE(h[k]) = CMCONJRE(num, den) * mag;
- IM(h[k]) = CMCONJIM(num, den) * mag;
- }
- res = RES_OK;
-exit_label:
- if(bc)
- free(bc);
- if(ac)
- free(ac);
- return res;
-}
-
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API freqs_cmplx(double* b, double* a, int ord,
- complex_t* s, int n, complex_t *h)
-{
- complex_t *bc = NULL;
- complex_t *ac = NULL;
- complex_t num, den;
- double mag;
- int k;
- int res;
-
- if(!b || !a || !s || !h)
- return ERROR_PTR;
- if(ord<0)
- return ERROR_FILTER_ORD;
- if(n<1)
- return ERROR_SIZE;
-
-
- bc = (complex_t*) malloc((ord+1) * sizeof(complex_t));
- res = re2cmplx(b, ord+1, bc);
-
- if( res!=RES_OK )
- goto exit_label;
-
- ac = (complex_t*) malloc((ord+1) * sizeof(complex_t));
- res = re2cmplx(a, ord+1, ac);
- if( res!=RES_OK )
- goto exit_label;
-
- for(k = 0; k < n; k++)
- {
- res = polyval_cmplx(bc, ord, s+k, 1, &num);
- if(res != RES_OK)
- goto exit_label;
- res = polyval_cmplx(ac, ord, s+k, 1, &den);
- if(res != RES_OK)
- goto exit_label;
- mag = ABSSQR(den);
- if(mag == 0.0)
- {
- res = ERROR_DIV_ZERO;
- goto exit_label;
- }
- mag = 1.0 / mag;
- RE(h[k]) = CMCONJRE(num, den) * mag;
- IM(h[k]) = CMCONJIM(num, den) * mag;
-
- }
- res = RES_OK;
- exit_label:
- if(bc)
- free(bc);
- if(ac)
- free(ac);
- return res;
-}
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API freqs2time(double* b, double* a, int ord, double fs,
- int n, fft_t* pfft, double *t, double *h)
-{
- double *w = NULL;
- complex_t *hs = NULL;
- complex_t *ht = NULL;
- int err, k;
-
- if(!b || !a || !t || !h)
- return ERROR_PTR;
- if(ord<1)
- return ERROR_FILTER_ORD;
- if(n<1)
- return ERROR_SIZE;
-
- w = (double*)malloc(n*sizeof(double));
- hs = (complex_t*)malloc(n*sizeof(complex_t));
-
-
- err = linspace(-fs*0.5, fs*0.5, n, DSPL_PERIODIC, w);
- if(err != RES_OK)
- goto exit_label;
-
- err = freqs(b, a, ord, w, n, hs);
- if(err != RES_OK)
- goto exit_label;
-
- err = fft_shift_cmplx(hs, n, hs);
- if(err != RES_OK)
- goto exit_label;
-
- ht = (complex_t*)malloc(n*sizeof(complex_t));
-
- err = ifft_cmplx(hs, n, pfft, ht);
- if(err != RES_OK)
- {
- err = idft_cmplx(hs, n, ht);
- if(err != RES_OK)
- goto exit_label;
- }
-
- for(k = 0; k < n; k++)
- {
- t[k] = (double)k/fs;
- h[k] = RE(ht[k]) * fs;
- }
-
-exit_label:
- if(w)
- free(w);
- if(hs)
- free(hs);
- if(ht)
- free(ht);
- return err;
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup FILTER_ANALYSIS_GROUP
-\fn int freqz(double* b, double* a, int ord, double* w, int n, complex_t *h)
-
-\brief Function calculates the digital filter frequency response
-\f$ H \left(e^{j \omega} \right)\f$ corresponds to transfer function \f$H(z)\f$.
-
-Digital filter transfer function:
-\f[
-H(z) = \frac{\sum\limits_{k = 0}^{N} b_k z^{-k}}
- {\sum\limits_{m = 0}^{N} a_m z^{-m}},
-\f]
-here \f$N\f$ --- filter order (parameter `ord`). \n
-
-Frequency response \f$ H \left(e^{j \omega} \right)\f$ we can get
-if substitute \f$z = e^{j \omega} \f$. \n
-
-\param[in] b
-Pointer to the \f$ H(z) \f$ transfer function
-numerator coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n \n
-
-\param[in] a
-Pointer to the \f$H(z)\f$ transfer function
-denominator coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n \n
-
-\param[in] ord
-Filter order. \n
-Transfer function \f$H(z)\f$ numerator
-and denominator coefficients number equals `ord+1`. \n \n
-
-\param[in] w
-Pointer to the normalized frequency of digital filter
-frequency response \f$ H \left(\mathrm{e}^{j\omega} \right) \f$. \n
-Digital filter frequency response is \f$ 2\pi \f$-periodic function,
-and vector `w` advisable to set from 0 to \f$ \pi \f$,
-or from 0 to \f$ 2\pi \f$, or from \f$ -\pi \f$ to \f$ \pi \f$.
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of frequency vector `w`. \n \n
-
-\param[out] h
-Pointer to the frequency response vector
-\f$ H \left(\mathrm{e}^{j\omega} \right) \f$,
-corresponds to normalized frequency `w`. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return `RES_OK` if frequency response vector is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup FILTER_ANALYSIS_GROUP
-\fn int freqz(double* b, double* a, int ord, double* w, int n, complex_t *h)
-
-\brief Расчет комплексного коэффициента передачи
- \f$ H \left(e^{j \omega} \right)\f$ цифрового фильтра.
-
-Функция рассчитывает значения комплексного коэффициента передачи
-\f$ H \left(e^{j \omega} \right)\f$ цифрового фильтра, заданного
-коэффициентами передаточной функции \f$H(z)\f$:
-
-\f[
-H(z) = \frac {\sum_{k = 0}^{N} b_k z^{-k}}
- {\sum_{m = 0}^{N} a_m z^{-m}},
-\f]
-
-где \f$N\f$ --- порядок фильтра (параметр `ord`). \n
-
-Комплексный коэффициент передачи рассчитывается путем
-подстановки \f$z = e^{j \omega} \f$. \n
-
-\param[in] b
-Указатель на вектор коэффициентов числителя
-передаточной функции \f$H(z)\f$. \n
-Размер вектора `[ord+1 x 1]`. \n \n
-
-\param[in] a
-Указатель на вектор коэффициентов знаменателя
-передаточной функции \f$H(z)\f$. \n
-Размер вектора `[ord+1 x 1]`. \n \n
-
-\param[in] ord
-Порядок фильтра. Количество коэффициентов числителя и знаменателя
-передаточной функции \f$H(z)\f$ равно `ord+1`. \n \n
-
-\param[in] w
-Указатель на вектор значений нормированной циклической частоты \f$\omega\f$,
-для которого будет рассчитан комплексный коэффициент передачи
-\f$ H \left(e^{j \omega} \right)\f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер вектора нормированной циклической частоты `w`. \n \n
-
-\param[out] h
-Указатель на вектор комплексного коэффициента передачи
-\f$ H \left(e^{j \omega} \right)\f$, рассчитанного для
-циклической частоты `w`. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` Комплексный коэффициент передачи рассчитан успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\note
-Комплексный коэффициент передачи \f$ H \left(e^{j \omega} \right)\f$
-цифрового фильтра представляет собой \f$ 2 \pi-\f$периодическую функцию
-нормированной циклической частоты \f$\omega\f$.
-Поэтому анализ цифровых фильтров целесообразно вести на одном периоде
-повторения \f$ H \left(e^{j \omega} \right)\f$, т.е. в интервале
-\f$\omega\f$ от 0 до \f$2 \pi\f$, или от \f$-\pi\f$ до \f$ \pi\f$. \n
-Кроме того известно, что для фильтра с вещественными коэффициентами
-\f$ H \left(e^{j \omega} \right) = H^* \left(e^{-j \omega} \right)\f$,
-а значит, анализ цифрового фильтра с вещественными коэффициентами
-достаточно вести для нормированной частоты \f$\omega\f$ от 0 до \f$\pi\f$.
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API freqz(double* b, double* a, int ord, double* w,
- int n, complex_t *h)
-{
- complex_t jw;
- complex_t *bc = NULL;
- complex_t *ac = NULL;
- complex_t num, den;
- double mag;
- int k;
- int res;
-
- if(!b || !w || !h)
- return ERROR_PTR;
- if(ord<0)
- return ERROR_FILTER_ORD;
- if(n<1)
- return ERROR_SIZE;
-
-
- bc = (complex_t*) malloc((ord+1) * sizeof(complex_t));
- res = re2cmplx(b, ord+1, bc);
- if( res!=RES_OK )
- goto exit_label;
-
- if(a)
- {
- /* IIR filter if a != NULL */
- ac = (complex_t*) malloc((ord+1) * sizeof(complex_t));
- res = re2cmplx(a, ord+1, ac);
- if( res!=RES_OK )
- goto exit_label;
- for(k = 0; k < n; k++)
- {
- RE(jw) = cos(w[k]);
- IM(jw) = -sin(w[k]);
- res = polyval_cmplx(bc, ord, &jw, 1, &num);
- if(res != RES_OK)
- goto exit_label;
- res = polyval_cmplx(ac, ord, &jw, 1, &den);
- if(res != RES_OK)
- goto exit_label;
- mag = ABSSQR(den);
- if(mag == 0.0)
- {
- res = ERROR_DIV_ZERO;
- goto exit_label;
- }
- mag = 1.0 / mag;
- RE(h[k]) = CMCONJRE(num, den) * mag;
- IM(h[k]) = CMCONJIM(num, den) * mag;
- }
- }
- else
- {
- /* FIR filter if a == NULL */
- for(k = 0; k < n; k++)
- {
- RE(jw) = cos(w[k]);
- IM(jw) = -sin(w[k]);
- res = polyval_cmplx(bc, ord, &jw, 1, h+k);
- if(res != RES_OK)
- goto exit_label;
- }
- }
- res = RES_OK;
-exit_label:
- if(bc)
- free(bc);
- if(ac)
- free(ac);
- return res;
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup FILTER_ANALYSIS_GROUP
-\fn int DSPL_API phase_delay(double* b, double* a, int ord, int flag,
- double* w, int n, double* tau)
-
-\brief
-Phase delay calculation for digital or analog filter corresponds to
-\f$H(s)\f$, or \f$H(z)\f$ transfer function.
-
-Group delay is describes as:
-\f[
-\tau_{\varphi}(\omega) = - \frac{\Phi(\omega)}{\omega},
-\f]
-here \f$\Phi(\omega)\f$ -- filter phase response, \f$\omega\f$ is angular
-frequency for analog filter, or normalized frequency for digital filter.
-
-\param[in] b
-Pointer to the \f$ H(s) \f$ or \f$H(z)\f$ transfer function
-numerator coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n \n
-
-\param[in] a
-Pointer to the \f$ H(s) \f$ or \f$H(z)\f$ transfer function
-denominator coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n \n
-
-\param[in] ord
-Filter order. \n
-Transfer function \f$ H(s) \f$ or \f$H(z)\f$ numerator
-and denominator coefficients number equals `ord+1`. \n \n
-
-\param[in] flag
-Binary flags to set calculation rules: \n
-\verbatim
-DSPL_FLAG_ANALOG Coefficients corresponds to analog filter
-DSPL_FLAG_DIGITAL Coefficients corresponds to digital filter
-\endverbatim
-\n \n
-
-\param[in] w
-Pointer to the angular frequency \f$ \omega \f$ (rad/s),
-which used for analog filter characteristics calculation
-(flag sets as `DSPL_FLAG_ANALOG`). \n
-For digital filter (flag sets as `DSPL_FLAG_DIGITAL`),
- parameter `w` describes normalized frequency of
-frequency response \f$ H \left(\mathrm{e}^{j\omega} \right) \f$.
-Digital filter frequency response is \f$ 2\pi \f$-periodic function,
-and vector `w` advisable to set from 0 to \f$ \pi \f$,
-or from 0 to \f$ 2\pi \f$, or from \f$ -\pi \f$ to \f$ \pi \f$.
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of frequency vector `w`. \n \n
-
-\param[out] tau
-Pointer to the phase delay vector. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-\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 FILTER_ANALYSIS_GROUP
-\fn int DSPL_API phase_delay(double* b, double* a, int ord, int flag,
- double* w, int n, double* tau)
-\brief
-Расчет фазовой задержки цифрового или аналогового фильтра.
-
-Фазовая задержка определяется как:
-\f[
-\tau_{\varphi}(\omega) = - \frac{\Phi(\omega)}{\omega},
-\f]
-где \f$\Phi(\omega)\f$ -- ФЧХ фильтра, \f$\omega\f$ циктическая частот в случае
-аналогового фильтра, или нормированная частота цифрового фильтра.
-
-\param[in] b
-Указатель на вектор коэффициентов числителя передаточной функции
-аналогового фильтра \f$ H(s) \f$ или цифрового фильтра \f$ H(z) \f$. \n
-Размер вектора `[ord+1 x 1]`. \n \n
-
-\param[in] a
-Указатель на вектор коэффициентов числителя передаточной функции
-аналогового фильтра \f$ H(s) \f$ или цифрового фильтра \f$ H(z) \f$. \n
-Размер вектора `[ord+1 x 1]`. \n
-Параметр может быть `NULL`. В этом случае расчет производится для цифрового
-КИХ-фильтра с коэффициентами, заданными вектором `b`. \n\n
-
-\param[in] ord
-Порядок фильтра. Количество коэффициентов
-числителя и знаменателя передаточной
-функции \f$ H(s) \f$ или \f$ H(z) \f$ равно `ord+1`. \n \n
-
-\param[in] flag
-Флаг который задает тип фильтра: \n
-\verbatim
-DSPL_FLAG_ANALOG Коэффициенты относятся к аналоговому фильтру
-DSPL_FLAG_DIGITAL Коэффициенты относятся к цифровому фильтру
-\endverbatim
-
-\param[in] w
-Указатель на вектор значений циклической частоты \f$ \omega \f$ (рад/с),
-для которого будет рассчитаны АЧХ, ФЧХ и ГВЗ аналогового фильтра,
-если установлен флаг `DSPL_FLAG_ANALOG`. \n
-В случае если флаг `DSPL_FLAG_ANALOG` не установлен, то вектор частоты `w`
-используется как нормированная частота комплексного коэффициента передачи
-\f$ H \left(\mathrm{e}^{j\omega} \right) \f$ цифрового фильтра. \n
-В этом случае характеристика цифрового фильтра является
-\f$ 2\pi \f$-периодической, и вектор частоты может содержать
-произвольные значения, однако целесообразно задавать
-его от 0 до \f$ \pi \f$, а такжет от 0 до \f$ 2\pi \f$, или
-от \f$ -\pi \f$ до \f$ \pi \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер вектора циклической частоты `w`. \n \n
-
-\param[out] tau
-Указатель на вектор фазовой задержки. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n
-
-\return
-`RES_OK` фазовая задержка фильтра рассчитана успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API phase_delay(double* b, double* a, int ord, int flag,
- double* w, int n, double* tau)
-{
- int err, i;
- double *phi = NULL;
-
- if(n > 0)
- phi = (double*)malloc(n*sizeof(double));
- else
- return ERROR_SIZE;
-
- err = filter_freq_resp(b, a, ord, w, n, flag | DSPL_FLAG_UNWRAP, NULL, phi, NULL);
- if(err!=RES_OK)
- goto exit_label;
- for(i = 0; i < n; i++)
- {
- tau[i] = w[i] ? ( - phi[i] / w[i]) : ( - phi[i] / (w[i] + 1E-9) );
- }
-exit_label:
- if(phi)
- free(phi);
- return err;
-}
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API unwrap(double* phi, int n, double lev, double mar)
-{
- double a[2] = {0.0, 0.0};
- double d;
- double th;
- int k;
- int flag = 1;
-
- if(!phi)
- return ERROR_PTR;
-
- if(n<1)
- return ERROR_SIZE;
-
- if(lev<=0 || mar <=0)
- return ERROR_UNWRAP;
-
- th = mar*lev;
- while(flag)
- {
- flag = 0;
- a[0] = a[1] = 0.0;
- for(k = 0; k th)
- {
- a[0] -= lev;
- flag = 1;
- }
- if( d < -th)
- {
- a[0] += lev;
- flag = 1;
- }
- phi[k]+=a[1];
- a[1] = a[0];
- }
- phi[n-1]+=a[1];
- }
-
- return RES_OK;
-}
-
diff --git a/dspl/src/filter_ap.c b/dspl/src/filter_ap.c
deleted file mode 100644
index ba6ed1a..0000000
--- a/dspl/src/filter_ap.c
+++ /dev/null
@@ -1,2046 +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 .
-*/
-
-#include
-#include
-#include
-#include "dspl.h"
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int butter_ap(double Rp, int ord, double* b, double* a)
-
-\brief
-Function calculates the transfer function \f$ H(s) \f$ coefficients of
-analog normalized lowpass Butterworth filter.
-
-Analog normalized lowpass filter magnitude ripple equals \f$ -R_p \f$ dB
-for angular frequency \f$ \omega \f$ from 0 to 1 rad/s.
-
-\param[in] Rp
-Magnitude ripple in passband (dB). \n
-This parameter sets maximum filter distortion from 0 to 1 rad/s frequency. \n
-Parameter must be positive. \n
-\n
-
-\param[in] ord
-Filter order. \n
-Filter coefficients number equals `ord+1` for numerator and denominator
-of transfer function \f$ H(s) \f$ \n
-\n
-
-\param[out] b
-Pointer to the vector of transfer function \f$H(s)\f$
-numerator coefficient. \n
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\param[out] a
-Pointer to the vector of transfer function \f$H(s)\f$
-denominator coefficient. \n
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\return
-`RES_OK` if filter coefficients is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-\n
-
-Example:
-
-\include butter_ap_test.c
-
-Result:
-
-\verbatim
-b[ 0] = 1.965 a[ 0] = 1.965
-b[ 1] = 0.000 a[ 1] = 3.138
-b[ 2] = 0.000 a[ 2] = 2.505
-b[ 3] = 0.000 a[ 3] = 1.000
-\endverbatim
-\n
-
-In `dat` folder will be created 3 files: \n
-
-\verbatim
-butter_ap_test_mag.txt magnitude
-butter_ap_test_phi.txt phase response
-butter_ap_test_tau.txt group delay
-\endverbatim
-
-In addition, GNUPLOT will build the following graphs from data stored in files:
-
-\image html butter_ap_test.png
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int butter_ap(double Rp, int ord, double* b, double* a)
-
-\brief
-Расчет передаточной характеристики \f$ H(s) \f$ аналогового
-нормированного ФНЧ Баттерворта.
-
-Функция рассчитывает коэффициенты передаточной характеристики \f$H(s)\f$
-аналогового нормированного ФНЧ Баттерворта порядка `ord` с частотой среза
-1 рад/с по уровню \f$ -R_p \f$ дБ.
-
-\param[in] Rp
-Неравномерность АЧХ в полосе пропускания (дБ). \n
-Параметр задает уровень искажений в полосе от 0 до 1 рад/с. \n
-Значение должно быть положительным. \n
-\n
-
-\param[in] ord
-Порядок фильтра. \n
-Количество коэффициентов числителя и знаменателя
-передаточной функции \f$H(s)\f$ равно `ord+1`. \n
-\n
-
-\param[out] b
-Указатель на вектор коэффициентов числителя
-передаточной функции \f$H(s)\f$. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] a
-Указатель на вектор коэффициентов знаменателя
-передаточной функции \f$H(s)\f$. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\return
-`RES_OK` --- фильтр рассчитан успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-\n
-
-Пример использования функции `butter_ap`:
-
-\include butter_ap_test.c
-
-Результат работы программы:
-
-\verbatim
-b[ 0] = 1.965 a[ 0] = 1.965
-b[ 1] = 0.000 a[ 1] = 3.138
-b[ 2] = 0.000 a[ 2] = 2.505
-b[ 3] = 0.000 a[ 3] = 1.000
-\endverbatim
-\n
-
-В каталоге `dat` будут созданы три файла: \n
-
-\verbatim
-butter_ap_test_mag.txt АЧХ фильтра
-butter_ap_test_phi.txt ФЧХ фильтра
-butter_ap_test_tau.txt ГВЗ фильтра
-\endverbatim
-
-Кроме того программа GNUPLOT произведет построение следующих графиков
-по сохраненным в файлах данным:
-
-\image html butter_ap_test.png
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API butter_ap(double rp, int ord, double* b, double* a)
-{
- int res;
- complex_t *z = NULL;
- complex_t *p = NULL;
- int nz, np;
-
- if(rp < 0.0)
- return ERROR_FILTER_RP;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(!a || !b)
- return ERROR_PTR;
-
- z = (complex_t*) malloc(ord*sizeof(complex_t));
- p = (complex_t*) malloc(ord*sizeof(complex_t));
-
-
- res = butter_ap_zp(ord, rp, z, &nz, p, &np);
- if(res != RES_OK)
- goto exit_label;
-
- res = filter_zp2ab(z, nz, p, np, ord, b, a);
- if(res != RES_OK)
- goto exit_label;
-
- b[0] = a[0];
-
-
-exit_label:
- if(z)
- free(z);
- if(p)
- free(p);
- return res;
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int butter_ap_zp(int ord, double rp, complex_t* z, int* nz,
- complex_t* p, int* np)
-
-\brief
-Function calculates arrays of zeros and poles for analog normlized lowpass
-Batterworth filter transfer function \f$ H(s) \f$ order `ord` .
-
-Analog normalized lowpass filter magnitude ripple equals \f$ -R_p \f$ dB
-for angular frequency \f$ \omega \f$ from 0 to 1 rad/s.
-
-
-\param[in] ord
-Filter order. \n
-Number of zeros and poles of filter can be less or equal `ord`. \n
-\n
-
-\param[in] rp
-Magnitude ripple in passband (dB). \n
-This parameter sets maximum filter distortion from 0 to 1 rad/s frequency. \n
-Parameter must be positive. \n
-\n
-
-\param[out] z
-Pointer to the \f$ H(s) \f$ zeros array. \n
-Maximum vector size is `[ord x 1]`. \n
-Memory must be allocated for maximum vector size. \n
-\n
-
-\param[out] nz
-Pointer to the variable which keep number of finite zeros \f$ H(s) \f$. \n
-Number of finite zeros which was calculated and saved in vector `z`. \n
-Pointer cannot be `NULL`. \n
-\n
-
-\param[out] p
-Pointer to the \f$ H(s) \f$ poles array. \n
-Maximum vector size is `[ord x 1]`. \n
-Memory must be allocated for maximum vector size. \n
-\n
-
-\param[out] np
-Pointer to the variable which keep number of
-calculated poles of \f$ H(s) \f$. \n
-Pointer cannot be `NULL`. \n
-\n
-
-\return
-`RES_OK` if zeros and poles is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-\n
-
-\note
-Normalized Butterworth lowpass filter has no finite zeros.
-So `z` vector will not changed and in pointer `nz` will write 0 value. \n
-
-
-Example of normalized Butterworth lowpass filter zeros and poles calculation:
-\include butter_ap_zp_test.c
-
-Result:
-
-\verbatim
-Butterworth filter zeros: 0
-Butterworth filter poles: 7
-p[ 0] = -1.101 +0.000 j
-p[ 1] = -0.245 +1.074 j
-p[ 2] = -0.245 -1.074 j
-p[ 3] = -0.687 +0.861 j
-p[ 4] = -0.687 -0.861 j
-p[ 5] = -0.992 +0.478 j
-p[ 6] = -0.992 -0.478 j
-\endverbatim
-\n
-
-In `dat` folder will be created `butter_ap_zp.txt` file. \n
-
-In addition, GNUPLOT will build the following graphs
-from data stored in `dat/butter_ap_zp.txt` file:
-
-\image html butter_ap_zp_test.png
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int butter_ap_zp(int ord, double rp, complex_t* z, int* nz,
- complex_t* p, int* np)
-
-\brief
-Расчет массивов нулей и полюсов передаточной функции
-\f$ H(s) \f$ аналогового нормированного ФНЧ Баттерворта.
-
-Функция рассчитывает значения нулей и полюсов передаточной функции
-\f$ H(s)\f$ аналогового нормированного ФНЧ Баттерворта порядка `ord`
-с частотой среза 1 рад/с по уровню \f$-R_p\f$ дБ. \n
-
-
-\param[in] ord
-Порядок фильтра. \n
-\n
-
-\param[in] rp
-Неравномерность АЧХ в полосе пропускания (дБ). \n
-Параметр задает уровень искажений в полосе от 0 до 1 рад/с. \n
-Значение должно быть положительным. \n
-\n
-
-\param[out] z
-Указатель на массив комплексных нулей
-передаточной характеристики \f$ H(s)\f$. \n
-Максимальный размер вектора вектора `[ord x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] nz
-Указатель на переменную количества нулей
-передаточной характеристики \f$ H(s)\f$. \n
-По данному указателю будет записано количество
-нулей фильтра, которые были рассчитаны и
-помещены в вектор `z`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] p
-Указатель на массив комплексных полюсов
-передаточной характеристики \f$ H(s)\f$. \n
-Максимальный размер вектора вектора `[ord x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] np
-Указатель на переменную количества полюсов
-передаточной характеристики \f$ H(s)\f$. \n
-По данному укащзателю будет записано количество нулей фильтра, которые
-были рассчитны и помещены в вектор `p`. \n
-Память должна быть выделена. \n
-\n
-
-\return
-`RES_OK` --- массивы нулей и полюсов рассчитаны успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-\n
-
-\note
-Нормированный ФНЧ Баттерворта не имеет нулей, поэтому массив нулей `z`
-не будет изменен, а по указателю `nz` будет записан 0. \n
-
-
-Пример программы рассчета нулей и полюсов нормированного ФНЧ Баттерворта:
-\include butter_ap_zp_test.c
-
-Результат выполнения программы:
-
-\verbatim
-Butterworth filter zeros: 0
-Butterworth filter poles: 7
-p[ 0] = -1.101 +0.000 j
-p[ 1] = -0.245 +1.074 j
-p[ 2] = -0.245 -1.074 j
-p[ 3] = -0.687 +0.861 j
-p[ 4] = -0.687 -0.861 j
-p[ 5] = -0.992 +0.478 j
-p[ 6] = -0.992 -0.478 j
-\endverbatim
-\n
-
-В каталоге `dat` будет создан файл `butter_ap_zp.txt`. \n
-
-Пакет GNUPLOT произведет построение карты полюсов по
-сохранненным в `dat/butter_ap_zp.txt` данным:
-
-\image html butter_ap_zp_test.png
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API butter_ap_zp(int ord, double rp, complex_t* z, int* nz,
- complex_t *p, int* np)
-{
- double alpha;
- double theta;
- double ep;
- int r;
- int L;
- int ind = 0, k;
-
- if(rp < 0 || rp == 0)
- return ERROR_FILTER_RP;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(!z || !p || !nz || !np)
- return ERROR_PTR;
-
- ep = sqrt(pow(10.0, rp*0.1) - 1.0);
- r = ord % 2;
- L = (int)((ord-r)/2);
-
- alpha = pow(ep, -1.0/(double)ord);
- if(r)
- {
- RE(p[ind]) = -alpha;
- IM(p[ind]) = 0.0;
- ind++;
- }
- for(k = 0; k < L; k++)
- {
- theta = M_PI*(double)(2*k + 1)/(double)(2*ord);
- RE(p[ind]) = RE(p[ind+1]) = -alpha * sin(theta);
- IM(p[ind]) = alpha * cos(theta);
- IM(p[ind+1]) = -alpha * cos(theta);
- ind+=2;
- }
- *np = ord;
- *nz = 0;
- return RES_OK;
-}
-
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int cheby1_ap(double Rp, int ord, double* b, double* a)
-
-\brief
-Function calculates the transfer function \f$ H(s) \f$ coefficients of
-analog normalized lowpass Chebyshev type 1 filter.
-
-Analog normalized lowpass filter magnitude ripple equals \f$ -R_p \f$ dB
-for angular frequency \f$ \omega \f$ from 0 to 1 rad/s.
-
-\param[in] Rp
-Magnitude ripple in passband (dB). \n
-This parameter sets maximum filter distortion from 0 to 1 rad/s frequency. \n
-Parameter must be positive. \n
-\n
-
-\param[in] ord
-Filter order. \n
-Filter coefficients number equals `ord+1` for numerator and denominator
-of transfer function \f$ H(s) \f$ \n
-\n
-
-\param[out] b
-Pointer to the vector of transfer function \f$H(s)\f$
-numerator coefficient. \n
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\param[out] a
-Pointer to the vector of transfer function \f$H(s)\f$
-denominator coefficient. \n
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\return
-`RES_OK` if filter coefficients is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-\n
-
-Example:
-
-\include cheby1_ap_test.c
-
-Result:
-
-\verbatim
-b[ 0] = 0.125 a[ 0] = 0.177
-b[ 1] = 0.000 a[ 1] = 0.405
-b[ 2] = 0.000 a[ 2] = 1.169
-b[ 3] = 0.000 a[ 3] = 0.582
-b[ 4] = 0.000 a[ 4] = 1.000
-\endverbatim
-\n
-
-In `dat` folder will be created 3 files: \n
-
-\verbatim
-cheby1_ap_test_mag.txt magnitude
-cheby1_ap_test_phi.txt phase response
-cheby1_ap_test_tau.txt group delay
-\endverbatim
-
-In addition, GNUPLOT will build the following graphs from data stored in files:
-
-\image html cheby1_ap_test.png
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int cheby1_ap(double Rp, int ord, double* b, double* a)
-
-\brief
-Расчет передаточной характеристики \f$ H(s) \f$ аналогового
-нормированного ФНЧ Чебышёва первого рода.
-
-Функция рассчитывает коэффициенты передаточной характеристики
-\f$ H(s)\f$ аналогового нормированного ФНЧ Чебышёва первого рода
-порядка `ord` с частотой среза 1 рад/с по уровню \f$-R_p\f$ дБ. \n
-
-Особенностью фильтра Чебышёва первого рода являются
-равноволновые пульсации АЧХ в полосе пропускания.
-
-\param[in] Rp
-Неравномерность АЧХ в полосе пропускания (дБ). \n
-Параметр задает уровень искажений в полосе от 0 до 1 рад/с. \n
-Значение должно быть положительным. \n
-\n
-
-\param[in] ord
-Порядок фильтра. \n
-Количество коэффициентов числителя и знаменателя
-передаточной функции \f$ H(s)\f$ равно `ord+1`. \n
-\n
-
-\param[out] b
-Указатель на вектор коэффициентов числителя передаточной функции \f$H(s)\f$. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] a
-Указатель на вектор коэффициентов знаменателя
-передаточной функции \f$H(s)\f$. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\return
-`RES_OK` --- фильтр рассчитан успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-\n
-
-Пример использования функции `cheby1_ap`:
-
-\include cheby1_ap_test.c
-
-Результат работы программы:
-
-\verbatim
-b[ 0] = 0.125 a[ 0] = 0.177
-b[ 1] = 0.000 a[ 1] = 0.405
-b[ 2] = 0.000 a[ 2] = 1.169
-b[ 3] = 0.000 a[ 3] = 0.582
-b[ 4] = 0.000 a[ 4] = 1.000
-\endverbatim
-\n
-
-В каталоге `dat` будут созданы три файла: \n
-
-\verbatim
-cheby1_ap_test_mag.txt АЧХ фильтра
-cheby1_ap_test_phi.txt ФЧХ фильтра
-cheby1_ap_test_tau.txt ГВЗ фильтра
-\endverbatim
-\n
-
-Кроме того программа GNUPLOT произведет построение следующих графиков
-по сохраненным в файлах данным:
-
-\image html cheby1_ap_test.png
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API cheby1_ap(double rp, int ord, double* b, double* a)
-{
- int res;
- complex_t *z = NULL;
- complex_t *p = NULL;
- int nz, np, k;
- complex_t h0 = {1.0, 0.0};
- double tmp;
-
-
- if(rp < 0.0)
- return ERROR_FILTER_RP;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(!a || !b)
- return ERROR_PTR;
-
- z = (complex_t*) malloc(ord*sizeof(complex_t));
- p = (complex_t*) malloc(ord*sizeof(complex_t));
-
-
- res = cheby1_ap_zp(ord, rp, z, &nz, p, &np);
- if(res != RES_OK)
- goto exit_label;
-
- res = filter_zp2ab(z, nz, p, np, ord, b, a);
- if(res != RES_OK)
- goto exit_label;
-
-
- if(!(ord % 2))
- RE(h0) = 1.0 / pow(10.0, rp*0.05);
-
- for(k = 0; k < np; k++)
- {
- tmp = CMRE(h0, p[k]);
- IM(h0) = CMIM(h0, p[k]);
- RE(h0) = tmp;
- }
-
- b[0] = fabs(RE(h0));
-
-exit_label:
- if(z)
- free(z);
- if(p)
- free(p);
- return res;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int cheby1_ap_zp( int ord, double rp, complex_t* z, int* nz,
- complex_t* p, int* np)
-\brief
-Function calculates arrays of zeros and poles for analog normlized lowpass
-Chebyshev type 1 filter transfer function \f$ H(s) \f$ order `ord` .
-
-Analog normalized lowpass filter magnitude ripple equals \f$ -R_p \f$ dB
-for angular frequency \f$ \omega \f$ from 0 to 1 rad/s.
-
-
-\param[in] ord
-Filter order. \n
-Number of zeros and poles of filter can be less or equal `ord`. \n
-\n
-
-\param[in] rp
-Magnitude ripple in passband (dB). \n
-This parameter sets maximum filter distortion from 0 to 1 rad/s frequency. \n
-Parameter must be positive. \n
-\n
-
-\param[out] z
-Pointer to the \f$ H(s) \f$ zeros array. \n
-Maximum vector size is `[ord x 1]`. \n
-Memory must be allocated for maximum vector size. \n
-\n
-
-\param[out] nz
-Pointer to the variable which keep number of finite zeros \f$ H(s) \f$. \n
-Number of finite zeros which was calculated and saved in vector `z`. \n
-Pointer cannot be `NULL`. \n
-\n
-
-\param[out] p
-Pointer to the \f$ H(s) \f$ poles array. \n
-Maximum vector size is `[ord x 1]`. \n
-Memory must be allocated for maximum vector size. \n
-\n
-
-\param[out] np
-Pointer to the variable which keep number of
-calculated poles of \f$ H(s) \f$. \n
-Pointer cannot be `NULL`. \n
-\n
-
-\return
-`RES_OK` if zeros and poles is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-\n
-
-\note
-Normalized Chebyshev type 1 lowpass filter has no finite zeros.
-So `z` vector will not changed and in pointer `nz` will write 0 value. \n
-
-Example of normalized Chebyshev type 1 lowpass filter
- zeros and poles calculation:
-\include cheby1_ap_zp_test.c
-
-Result:
-
-\verbatim
-Chebyshev type 1 filter zeros: 0
-Chebyshev type 1 filter poles: 7
-p[ 0] = -0.256 +0.000 j
-p[ 1] = -0.057 +1.006 j
-p[ 2] = -0.057 -1.006 j
-p[ 3] = -0.160 +0.807 j
-p[ 4] = -0.160 -0.807 j
-p[ 5] = -0.231 +0.448 j
-p[ 6] = -0.231 -0.448 j
-\endverbatim
-\n
-
-In `dat` folder will be created `cheby1_ap_zp.txt` file. \n
-
-In addition, GNUPLOT will build the following graphs
-from data stored in `dat/cheby1_ap_zp.txt` file:
-
-\image html cheby1_ap_zp_test.png
-
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int cheby1_ap_zp(int ord, double rp, complex_t* z, int* nz, complex_t* p, int* np)
-\brief
-Расчет массивов нулей и полюсов передаточной функции \f$ H(s) \f$
-аналогового нормированного ФНЧ Чебышёва первого рода.
-
-Функция рассчитывает значения нулей и полюсов передаточной функции
-\f$ H(s)\f$ аналогового нормированного ФНЧ Чебышёва первого рода
-порядка `ord` с частотой среза 1 рад/с по уровню \f$-R_p\f$ дБ, с
-неравномерностью в полосе пропускания \f$ R_p \f$ дБ. \n
-
-\param[in] ord
-Порядок фильтра. \n
-\n
-
-\param[in] rp
-Неравномерность АЧХ в полосе пропускания (дБ). \n
-Параметр задает уровень искажений в полосе от 0 до 1 рад/с. \n
-Значение должно быть положительным. \n
-\n
-
-\param[out] z
-Указатель на массив комплексных нулей
-передаточной характеристики \f$ H(s)\f$. \n
-Максимальный размер вектора `[ord x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] nz
-Указатель на переменную количества нулей
-передаточной функции \f$H(s)\f$. \n
-По данному указателю будет записано количество нулей фильтра,
-которые были рассчитаны и помещены в вектор `z`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] p
-Указатель на массив комплексных полюсов
-передаточной характеристики \f$H(s)\f$. \n
-Максимальный размер вектора вектора `[ord x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] np
-Указатель на переменную количества полюсов передаточной функции \f$ H(s)\f$. \n
-По данному указателю будет записано количество нулей фильтра, которые были
-рассчитаны и помещены в вектор `p`. \n
-Память должна быть выделена. \n
-\n
-
-\return
-`RES_OK` --- массивы нулей и полюсов рассчитаны успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\note
-Нормированный ФНЧ Чебышёва первого рода не имеет нулей, поэтому массив
-нулей `z` не будет изменен, а по указателю `nz` будет записан 0. \n
-
-
-Пример программы рассчета нулей и полюсов нормированного
-ФНЧ Чебышева первого рода:
-\include cheby1_ap_zp_test.c
-
-Результат выполнения программы:
-
-\verbatim
-Chebyshev type 1 filter zeros: 0
-Chebyshev type 1 filter poles: 7
-p[ 0] = -0.256 +0.000 j
-p[ 1] = -0.057 +1.006 j
-p[ 2] = -0.057 -1.006 j
-p[ 3] = -0.160 +0.807 j
-p[ 4] = -0.160 -0.807 j
-p[ 5] = -0.231 +0.448 j
-p[ 6] = -0.231 -0.448 j
-\endverbatim
-\n
-
-В каталоге `dat` будет создан файл `cheby1_ap_zp.txt`. \n
-
-Пакет GNUPLOT произведет построение карты полюсов по
-сохранненным в `dat/cheby1_ap_zp.txt` данным:
-
-\image html cheby1_ap_zp_test.png
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API cheby1_ap_zp(int ord, double rp, complex_t* z, int* nz,
- complex_t* p, int* np)
-{
- double theta;
- double ep;
- double beta;
- double shbeta;
- double chbeta;
- int r;
- int L;
- int ind = 0, k;
-
- if(rp < 0 || rp == 0)
- return ERROR_FILTER_RP;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(!z || !p || !nz || !np)
- return ERROR_PTR;
-
- ep = sqrt(pow(10.0, rp*0.1) - 1.0);
- r = ord % 2;
- L = (int)((ord-r)/2);
-
-
- beta = asinh(1.0/ep)/(double)ord;
- chbeta = cosh(beta);
- shbeta = sinh(beta);
-
- if(r)
- {
- RE(p[ind]) = -shbeta;
- IM(p[ind]) = 0.0;
- ind++;
- }
- for(k = 0; k < L; k++)
- {
- theta = M_PI*(double)(2*k + 1)/(double)(2*ord);
- RE(p[ind]) = RE(p[ind+1]) = -shbeta * sin(theta);
- IM(p[ind]) = chbeta * cos(theta);
- IM(p[ind+1]) = -IM(p[ind]);
- ind+=2;
- }
- *np = ord;
- *nz = 0;
- return RES_OK;
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int cheby2_ap(double Rs, int ord, double *b, double *a)
-
-\brief
-Function calculates the transfer function \f$ H(s) \f$ coefficients of
-analog normalized lowpass Chebyshev type 2 filter.
-
-Analog normalized Chebyshev type 2 filter lowpass filter has \f$Rs\f$ dB
-suppression in stopband.
-Also analog normalized Chebyshev type 2 filter magnitude equals \f$-Rs\f$ dB
-for angular frequency \f$\omega = 1\f$ rad/s.
-
-\param[in] Rs
-Suppression level in stopband (dB). \n
-This parameter sets filter supression for \f$\omega \geq 1\f$ rad/s frequency. \n
-Parameter must be positive. \n
-\n
-
-\param[in] ord
-Filter order. \n
-Filter coefficients number equals `ord+1` for numerator and denominator
-of transfer function \f$ H(s) \f$ \n
-\n
-
-\param[out] b
-Pointer to the vector of transfer function \f$H(s)\f$
-numerator coefficient. \n
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\param[out] a
-Pointer to the vector of transfer function \f$H(s)\f$
-denominator coefficient. \n
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\return
-`RES_OK` if filter coefficients is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-\n
-
-Example:
-
-\include cheby2_ap_test.c
-
-Result:
-
-\verbatim
-b[ 0] = 0.008 a[ 0] = 0.008
-b[ 1] = 0.000 a[ 1] = 0.068
-b[ 2] = 0.008 a[ 2] = 0.300
-b[ 3] = 0.000 a[ 3] = 0.774
-b[ 4] = 0.001 a[ 4] = 1.000
-\endverbatim
-\n
-
-In `dat` folder will be created 3 files: \n
-
-\verbatim
-cheby2_ap_test_mag.txt magnitude
-cheby2_ap_test_phi.txt phase response
-cheby2_ap_test_tau.txt group delay
-\endverbatim
-
-In addition, GNUPLOT will build the following graphs from data stored in files:
-
-\image html cheby2_ap_test.png
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int cheby2_ap(double Rs, int ord, double *b, double *a)
-
-\brief
-Расчет передаточной характеристики \f$ H(s) \f$ аналогового
-нормированного ФНЧ Чебышёва второго рода.
-
-Функция рассчитывает коэффициенты передаточной характеристики \f$H(s)\f$
-аналогового нормированного ФНЧ Чебышёва второго рода порядка `ord`
-с частотой заграждения 1 рад/с по уровню \f$-R_s\f$ дБ. \n
-
-Особенностью фильтра Чебышёва второго рода являются: \n
-1) равноволновые пульсации АЧХ в полосе заграждения. \n
-2) уровень АЧХ \f$H(j\cdot 1) = -R_s\f$ дБ. \n
-
-\param[in] Rs
-Уровень подавления в полосе пропускания (дБ). \n
-Значение должно быть положительным. \n
-\n
-
-\param[in] ord
-Порядок фильтра. \n
-Количество коэффициентов числителя и знаменателя
-передаточной функции \f$H(s)\f$ равно `ord+1`. \n
-\n
-
-\param[out] b
-Указатель на вектор коэффициентов числителя
-передаточной функции \f$H(s)\f$. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] a
-Указатель на вектор коэффициентов знаменателя
-передаточной функции \f$H(s)\f$. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-Пример использования функции `cheby1_ap`:
-
-\include cheby2_ap_test.c
-
-Результат работы программы:
-
-\verbatim
-b[ 0] = 0.008 a[ 0] = 0.008
-b[ 1] = 0.000 a[ 1] = 0.068
-b[ 2] = 0.008 a[ 2] = 0.300
-b[ 3] = 0.000 a[ 3] = 0.774
-b[ 4] = 0.001 a[ 4] = 1.000
-\endverbatim
-\n
-
-В каталоге `dat` будут созданы три файла: \n
-
-\verbatim
-cheby2_ap_test_mag.txt АЧХ фильтра
-cheby2_ap_test_phi.txt ФЧХ фильтра
-cheby2_ap_test_tau.txt ГВЗ фильтра
-\endverbatim
-\n
-
-Кроме того программа GNUPLOT произведет построение следующих графиков
-по сохраненным в файлах данным:
-
-\image html cheby2_ap_test.png
-
-
-\return
-`RES_OK` --- фильтр рассчитан успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API cheby2_ap(double rs, int ord, double* b, double* a)
-{
- int res;
- complex_t *z = NULL;
- complex_t *p = NULL;
- int nz, np;
- double norm;
-
-
- if(rs < 0.0)
- return ERROR_FILTER_RP;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(!a || !b)
- return ERROR_PTR;
-
- z = (complex_t*) malloc(ord*sizeof(complex_t));
- p = (complex_t*) malloc(ord*sizeof(complex_t));
-
-
- res = cheby2_ap_zp(ord, rs, z, &nz, p, &np);
- if(res != RES_OK)
- goto exit_label;
-
- res = filter_zp2ab(z, nz, p, np, ord, b, a);
- if(res != RES_OK)
- goto exit_label;
-
- norm = a[0] / b[0];
-
- for(nz = 0; nz < ord+1; nz++)
- b[nz]*=norm;
-
-exit_label:
- if(z)
- free(z);
- if(p)
- free(p);
- return res;
-}
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API cheby2_ap_wp1(double rp, double rs, int ord, double* b, double* a)
-{
- int err;
- double es, gp, alpha, beta, y, wp;
-
- if(rp <= 0)
- return ERROR_FILTER_RP;
-
- err = cheby2_ap(rs, ord, b, a);
- if(err!=RES_OK)
- goto exit_label;
-
- es = sqrt(pow(10.0, rs*0.1) - 1.0);
- gp = pow(10.0, -rp*0.05);
- alpha = gp * es / sqrt(1.0 - gp*gp);
- beta = alpha + sqrt(alpha * alpha - 1.0);
- y = log(beta)/ (double)ord;
- wp = 2.0 / (exp(y) + exp(-y));
-
- err = low2low(b, a, ord, wp, 1.0, b, a);
-
-exit_label:
- return err;
-}
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int cheby2_ap_zp(int ord, double rs, complex_t* z, int* nz,
- complex_t* p, int* np)
-
-\brief
-Function calculates arrays of zeros and poles for analog normlized lowpass
-Chebyshev type 2 filter transfer function \f$ H(s) \f$ order `ord` .
-
-Analog normalized Chebyshev type 2 filter lowpass filter has \f$Rs\f$ dB
-suppression in stopband.
-Also analog normalized Chebyshev type 2 filter magnitude equals \f$-Rs\f$ dB
-for angular frequency \f$\omega = 1\f$ rad/s.
-
-
-\param[in] ord
-Filter order. \n
-Number of zeros and poles of filter can be less or equal `ord`. \n
-\n
-
-\param[in] rs
-Suppression level in stopband (dB). \n
-This parameter sets filter supression for \f$\omega \geq 1\f$ rad/s frequency. \n
-Parameter must be positive. \n
-\n
-
-\param[out] z
-Pointer to the \f$ H(s) \f$ zeros array. \n
-Maximum vector size is `[ord x 1]`. \n
-Memory must be allocated for maximum vector size. \n
-\n
-
-\param[out] nz
-Pointer to the variable which keep number of finite zeros \f$ H(s) \f$. \n
-Number of finite zeros which was calculated and saved in vector `z`. \n
-Pointer cannot be `NULL`. \n
-\n
-
-\param[out] p
-Pointer to the \f$ H(s) \f$ poles array. \n
-Maximum vector size is `[ord x 1]`. \n
-Memory must be allocated for maximum vector size. \n
-\n
-
-\param[out] np
-Pointer to the variable which keep number of
-calculated poles of \f$ H(s) \f$. \n
-Pointer cannot be `NULL`. \n
-\n
-
-\return
-`RES_OK` if zeros and poles is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-\n
-
-Example of normalized Chebyshev type 2 lowpass filter
- zeros and poles calculation:
-\include cheby2_ap_zp_test.c
-
-Result:
-
-\verbatim
-Chebyshev type 2 filter zeros: 6
-z[ 0] = 0.000 +1.026 j
-z[ 1] = 0.000 -1.026 j
-z[ 2] = 0.000 +1.279 j
-z[ 3] = 0.000 -1.279 j
-z[ 4] = 0.000 +2.305 j
-z[ 5] = 0.000 -2.305 j
-Chebyshev type 2 filter poles: 7
-p[ 0] = -1.203 +0.000 j
-p[ 1] = -0.113 +0.772 j
-p[ 2] = -0.113 -0.772 j
-p[ 3] = -0.398 +0.781 j
-p[ 4] = -0.398 -0.781 j
-p[ 5] = -0.852 +0.642 j
-p[ 6] = -0.852 -0.642 j
-\endverbatim
-\n
-
-In `dat` folder will be created `cheby2_ap_z.txt` and
-`cheby2_ap_z.txt` files which keeps zeros and poles vectors. \n
-
-In addition, GNUPLOT will build the following graphs
-from data stored in the files:
-
-\image html cheby2_ap_zp_test.png
-
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int cheby2_ap_zp(int ord, double rs, complex_t* z, int* nz,
- complex_t* p, int* np)
-
-\brief
-Расчет массивов нулей и полюсов передаточной функции \f$ H(s) \f$
-аналогового нормированного ФНЧ Чебышёва второго рода.
-
-Функция рассчитывает значения нулей и полюсов передаточной функции
-\f$H(s)\f$ аналогового нормированного ФНЧ Чебышёва второго рода порядка `ord` с
-частотой заграждения 1 рад/с по уровню \f$-R_s\f$ дБ. \n
-
-
-\param[in] ord
-Порядок фильтра. \n
-\n
-
-\param[in] rs
-Уровень подавления АЧХ в полосе загражения (дБ). \n
-Параметр задает уровень подавления сигнала в полосе частот от 1 рад/с и выше. \n
-Значение должно быть положительным. \n
-\n
-
-\param[out] z
-Указатель на массив комплексных нулей передаточной функции \f$H(s)\f$. \n
-Максимальный размер вектора вектора `[ord x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] nz
-Указатель на переменную количества нулей передаточной функции \f$H(s)\f$. \n
-По данному указателю будет записано количество нулей фильтра, которые были
-рассчитаны и помещены в вектор `z`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] p
-Указатель на массив комплексных полюсов передаточной функции \f$H(s)\f$. \n
-Максимальный размер вектора вектора `[ord x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] np
-Указатель на переменную количества полюсов передаточной функции \f$H(s)\f$. \n
-По данному указателю будет записано количество нулей
-фильтра, которые были
-рассчитаны и помещены в вектор `p`. \n
-Память должна быть выделена. \n
-\n
-
-\return
-`RES_OK` --- массивы нулей и полюсов рассчитаны успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-Пример использования функции `cheby2_ap_zp`:
-
-Пример программы рассчета нулей и полюсов нормированного
-ФНЧ Чебышева первого рода:
-\include cheby2_ap_zp_test.c
-
-Результат выполнения программы:
-
-\verbatim
-Chebyshev type 2 filter zeros: 6
-z[ 0] = 0.000 +1.026 j
-z[ 1] = 0.000 -1.026 j
-z[ 2] = 0.000 +1.279 j
-z[ 3] = 0.000 -1.279 j
-z[ 4] = 0.000 +2.305 j
-z[ 5] = 0.000 -2.305 j
-Chebyshev type 2 filter poles: 7
-p[ 0] = -1.203 +0.000 j
-p[ 1] = -0.113 +0.772 j
-p[ 2] = -0.113 -0.772 j
-p[ 3] = -0.398 +0.781 j
-p[ 4] = -0.398 -0.781 j
-p[ 5] = -0.852 +0.642 j
-p[ 6] = -0.852 -0.642 j
-\endverbatim
-\n
-
-В каталоге `dat` будет создан файлы `cheby2_ap_z.txt` и `cheby2_ap_z.txt`,
-хранящие наборы нулей и полюсов на комплексной плоскости. \n
-
-Пакет GNUPLOT произведет построение карты полюсов по
-сохранненным в `dat/cheby2_ap_z.txt` и `dat/cheby2_ap_p.txt` данным:
-
-\image html cheby2_ap_zp_test.png
-
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API cheby2_ap_zp(int ord, double rs, complex_t* z, int* nz,
- complex_t *p, int* np)
-{
- double es;
- int L, r, k;
- double beta;
- int iz, ip;
-
- double alpha;
- double chb, shb, sa, ca;
- double ssh2, cch2;
-
- if(rs < 0 || rs == 0)
- return ERROR_FILTER_RS;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(!z || !p || !nz || !np)
- return ERROR_PTR;
-
- es = sqrt(pow(10.0, rs*0.1) - 1.0);
- r = ord % 2;
- L = (int)((ord-r)/2);
-
- beta = asinh(es)/(double)ord;
-
- chb = cosh(beta);
- shb = sinh(beta);
-
- iz = ip = 0;
-
- if(r)
- {
- RE(p[0]) = -1.0 / sinh(beta);
- IM(p[0]) = 0.0;
- ip = 1;
- }
-
- for(k = 0; k < L; k++)
- {
- alpha = M_PI*(double)(2*k + 1)/(double)(2*ord);
- sa = sin(alpha);
- ca = cos(alpha);
- ssh2 = sa*shb;
- ssh2 *= ssh2;
-
- cch2 = ca*chb;
- cch2 *= cch2;
-
- RE(z[iz]) = RE(z[iz+1]) = 0.0;
- IM(z[iz]) = 1.0 / ca;
- IM(z[iz+1]) = -IM(z[iz]);
- iz+=2;
-
- RE(p[ip]) = RE(p[ip+1]) = -sa*shb / (ssh2 + cch2);
- IM(p[ip]) = ca*chb / (ssh2 + cch2);
- IM(p[ip+1]) = -IM(p[ip]);
- ip+=2;
- }
- *nz = iz;
- *np = ip;
-
- return RES_OK;
-}
-
-
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int ellip_ap(double rp, double rs, int ord, double* b, double* a)
-
-\brief
-Function calculates the transfer function \f$ H(s) \f$ coefficients of
-analog normalized lowpass elliptic filter order `ord` with passband ripple
-`rp` dB and stopband suppression equals `rs` dB.
-
-\param[in] rp
-Magnitude ripple in passband (dB). \n
-This parameter sets maximum filter distortion from 0 to 1 rad/s frequency. \n
-Parameter must be positive. \n
-\n
-
-
-\param[in] rs
-Suppression level in stopband (dB). \n
-This parameter sets filter supression for \f$\omega \geq 1\f$ rad/s frequency. \n
-Parameter must be positive. \n
-\n
-
-\param[in] ord
-Filter order. \n
-Filter coefficients number equals `ord+1` for numerator and denominator
-of transfer function \f$ H(s) \f$ \n
-\n
-
-\param[out] b
-Pointer to the vector of transfer function \f$H(s)\f$
-numerator coefficient. \n
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\param[out] a
-Pointer to the vector of transfer function \f$H(s)\f$
-denominator coefficient. \n
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\return
-`RES_OK` if filter coefficients is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-\n
-
-Example:
-
-\include ellip_ap_test.c
-
-Result:
-
-\verbatim
-b[ 0] = 0.268 a[ 0] = 0.301
-b[ 1] = 0.000 a[ 1] = 0.764
-b[ 2] = 0.045 a[ 2] = 1.472
-b[ 3] = 0.000 a[ 3] = 0.948
-b[ 4] = 0.001 a[ 4] = 1.000
-\endverbatim
-\n
-
-In `dat` folder will be created 3 files: \n
-
-\verbatim
-ellip_ap_test_mag.txt magnitude
-ellip_ap_test_phi.txt phase response
-ellip_ap_test_tau.txt group delay
-\endverbatim
-
-In addition, GNUPLOT will build the following graphs from data stored in files:
-
-\image html ellip_ap_test.png
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int ellip_ap(double rp, double rs, int ord, double* b, double* a)
-
-\brief
-Расчет передаточной характеристики \f$ H(s) \f$ аналогового
-нормированного эллиптического ФНЧ.
-
-Функция рассчитывает коэффициенты передаточной характеристики \f$H(s)\f$
-аналогового нормированного эллиптического ФНЧ порядка `ord`
-с частотой среза 1 рад/с по уровню \f$-R_p\f$ дБ. \n
-
-Особенностью эллиптического фильтра являются равноволновые пульсации
-АЧХ как в полосе пропускания, так и в полосе заграждения, в результате
-чего обеспечиваеся минимальная переходная полоса фильтра. \n
-
-\param[in] rp
-Уровень пульсаций в полосе пропускания (дБ). \n
-Значение должно быть положительным. \n
-\n
-
-\param[in] rs
-Уровень подавления в полосе заграждения (дБ). \n
-Значение должно быть положительным. \n
-\n
-
-\param[in] ord
-Порядок фильтра. \n
-Количество коэффициентов числителя и знаменателя
-передаточной функции \f$H(s)\f$ равно `ord+1`. \n
-\n
-
-\param[out] b
-Указатель на вектор коэффициентов числителя
-передаточной функции \f$H(s)\f$. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] a
-Указатель на вектор коэффициентов знаменателя
-передаточной функции \f$H(s)\f$. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-Пример использования функции `ellip_ap`:
-
-\include ellip_ap_test.c
-
-Результат работы программы:
-
-\verbatim
-b[ 0] = 0.268 a[ 0] = 0.301
-b[ 1] = 0.000 a[ 1] = 0.764
-b[ 2] = 0.045 a[ 2] = 1.472
-b[ 3] = 0.000 a[ 3] = 0.948
-b[ 4] = 0.001 a[ 4] = 1.000
-\endverbatim
-\n
-
-В каталоге `dat` будут созданы три файла: \n
-
-\verbatim
-ellip_ap_test_mag.txt АЧХ фильтра
-ellip_ap_test_phi.txt ФЧХ фильтра
-ellip_ap_test_tau.txt ГВЗ фильтра
-\endverbatim
-\n
-
-Кроме того программа GNUPLOT произведет построение следующих графиков
-по сохраненным в файлах данным:
-
-\image html ellip_ap_test.png
-
-
-\return
-`RES_OK` --- фильтр рассчитан успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API ellip_ap(double rp, double rs, int ord, double* b, double* a)
-{
- int res;
- complex_t *z = NULL;
- complex_t *p = NULL;
- int nz, np;
- double norm, g0;
-
-
- if(rp < 0.0)
- return ERROR_FILTER_RP;
- if(rs < 0.0)
- return ERROR_FILTER_RS;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(!a || !b)
- return ERROR_PTR;
-
- z = (complex_t*) malloc(ord*sizeof(complex_t));
- p = (complex_t*) malloc(ord*sizeof(complex_t));
-
-
- res = ellip_ap_zp(ord, rp, rs, z, &nz, p, &np);
- if(res != RES_OK)
- goto exit_label;
-
- res = filter_zp2ab(z, nz, p, np, ord, b, a);
- if(res != RES_OK)
- goto exit_label;
-
-
- g0 = 1.0;
- if(!(ord % 2))
- {
- g0 = 1.0 / pow(10.0, rp*0.05);
- }
-
-
- norm = g0 * a[0] / b[0];
-
- for(nz = 0; nz < ord+1; nz++)
- b[nz]*=norm;
-
- exit_label:
- if(z)
- free(z);
- if(p)
- free(p);
- return res;
-}
-
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int ellip_ap_zp(int ord, double rp, double rs, complex_t* z, int* nz,
- complex_t* p, int* np)
-
-\brief
-Function calculates arrays of zeros and poles for analog normlized lowpass
-elliptic filter transfer function \f$ H(s) \f$ order `ord` .
-
-\param[in] ord
-Filter order. \n
-Number of zeros and poles of filter can be less or equal `ord`. \n
-\n
-
-\param[in] rp
-Magnitude ripple in passband (dB). \n
-This parameter sets maximum filter distortion from 0 to 1 rad/s frequency. \n
-Parameter must be positive. \n
-\n
-
-\param[in] rs
-Suppression level in stopband (dB). \n
-This parameter sets filter suppression
-for \f$\omega \geq 1\f$ rad/s frequency. \n
-Parameter must be positive. \n
-\n
-
-\param[out] z
-Pointer to the \f$ H(s) \f$ zeros array. \n
-Maximum vector size is `[ord x 1]`. \n
-Memory must be allocated for maximum vector size. \n
-\n
-
-\param[out] nz
-Pointer to the variable which keep number of finite zeros \f$ H(s) \f$. \n
-Number of finite zeros which was calculated and saved in vector `z`. \n
-Pointer cannot be `NULL`. \n
-\n
-
-\param[out] p
-Pointer to the \f$ H(s) \f$ poles array. \n
-Maximum vector size is `[ord x 1]`. \n
-Memory must be allocated for maximum vector size. \n
-\n
-
-\param[out] np
-Pointer to the variable which keep number of
-calculated poles of \f$ H(s) \f$. \n
-Pointer cannot be `NULL`. \n
-\n
-
-\return
-`RES_OK` if zeros and poles is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-\n
-
-Example of normalized elliptic lowpass filter zeros and poles calculation:
-\include ellip_ap_zp_test.c
-
-Result:
-
-\verbatim
-Elliptic filter zeros: 6
-z[ 0] = 0.000 +1.053 j
-z[ 1] = 0.000 -1.053 j
-z[ 2] = 0.000 +1.136 j
-z[ 3] = 0.000 -1.136 j
-z[ 4] = 0.000 +1.626 j
-z[ 5] = 0.000 -1.626 j
-Elliptic filter poles: 7
-p[ 0] = -0.358 +0.000 j
-p[ 1] = -0.011 +1.000 j
-p[ 2] = -0.011 -1.000 j
-p[ 3] = -0.060 +0.940 j
-p[ 4] = -0.060 -0.940 j
-p[ 5] = -0.206 +0.689 j
-p[ 6] = -0.206 -0.689 j
-\endverbatim
-\n
-
-In `dat` folder will be created `ellip_ap_z.txt` and
-`ellip_ap_z.txt` files which keeps zeros and poles vectors. \n
-
-In addition, GNUPLOT will build the following graphs
-from data stored in the files:
-
-\image html ellip_ap_zp_test.png
-
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int ellip_ap_zp(int ord, double rp, double rs, complex_t* z, int* nz,
- complex_t* p, int* np)
-
-\brief
-Расчет массивов нулей и полюсов передаточной функции \f$ H(s) \f$
-аналогового нормированного эллиптического ФНЧ.
-
-\param[in] ord
-Порядок фильтра. \n
-\n
-
-
-\param[in] rp
-Неравномерность АЧХ в полосе пропускания (дБ). \n
-Параметр задает уровень искажений в полосе от 0 до 1 рад/с. \n
-Значение должно быть положительным. \n
-\n
-
-\param[in] rs
-Уровень подавления АЧХ в полосе загражения (дБ). \n
-Параметр задает уровень подавления сигнала в полосе частот от 1 рад/с и выше. \n
-Значение должно быть положительным. \n
-\n
-
-\param[out] z
-Указатель на массив комплексных нулей передаточной функции \f$H(s)\f$. \n
-Максимальный размер вектора вектора `[ord x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] nz
-Указатель на переменную количества нулей передаточной функции \f$H(s)\f$. \n
-По данному указателю будет записано количество нулей фильтра, которые были
-рассчитаны и помещены в вектор `z`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] p
-Указатель на массив комплексных полюсов передаточной функции \f$H(s)\f$. \n
-Максимальный размер вектора вектора `[ord x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] np
-Указатель на переменную количества полюсов передаточной функции \f$H(s)\f$. \n
-По данному указателю будет записано количество нулей
-фильтра, которые были
-рассчитаны и помещены в вектор `p`. \n
-Память должна быть выделена. \n
-\n
-
-\return
-`RES_OK` --- массивы нулей и полюсов рассчитаны успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-Пример использования функции `cheby2_ap_zp`:
-
-Пример программы рассчета нулей и полюсов нормированного
-эллиптического ФНЧ :
-\include ellip_ap_zp_test.c
-
-Результат выполнения программы:
-
-\verbatim
-Elliptic filter zeros: 6
-z[ 0] = 0.000 +1.053 j
-z[ 1] = 0.000 -1.053 j
-z[ 2] = 0.000 +1.136 j
-z[ 3] = 0.000 -1.136 j
-z[ 4] = 0.000 +1.626 j
-z[ 5] = 0.000 -1.626 j
-Elliptic filter poles: 7
-p[ 0] = -0.358 +0.000 j
-p[ 1] = -0.011 +1.000 j
-p[ 2] = -0.011 -1.000 j
-p[ 3] = -0.060 +0.940 j
-p[ 4] = -0.060 -0.940 j
-p[ 5] = -0.206 +0.689 j
-p[ 6] = -0.206 -0.689 j
-\endverbatim
-\n
-
-В каталоге `dat` будет создан файлы `ellip_ap_z.txt` и `ellip_ap_z.txt`,
-хранящие наборы нулей и полюсов на комплексной плоскости. \n
-
-Пакет GNUPLOT произведет построение карты полюсов по
-сохранненным в `dat/ellip_ap_z.txt` и `dat/ellip_ap_p.txt` данным:
-
-\image html ellip_ap_zp_test.png
-
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API ellip_ap_zp(int ord, double rp, double rs,
- complex_t* z, int* nz, complex_t* p, int* np)
-{
- double es, ep;
- int L, r, n, res;
- int iz, ip;
- double ke, k, u, t;
- complex_t tc, v0, jv0;
-
-
- if(rp < 0 || rp == 0)
- return ERROR_FILTER_RP;
- if(rs < 0 || rs == 0)
- return ERROR_FILTER_RS;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(!z || !p || !nz || !np)
- return ERROR_PTR;
-
- es = sqrt(pow(10.0, rs*0.1) - 1.0);
- ep = sqrt(pow(10.0, rp*0.1) - 1.0);
- ke = ep / es;
-
- r = ord % 2;
- L = (int)((ord-r)/2);
-
- res = ellip_modulareq(rp, rs, ord, &k);
- if(res != RES_OK)
- return res;
- // v0
- RE(tc) = 0.0;
- IM(tc) = 1.0 / ep;
-
- ellip_asn_cmplx(&tc, 1, ke, &v0);
-
- t = RE(v0);
- RE(v0) = IM(v0) / (double)ord;
- IM(v0) = -t / (double)ord;
-
- RE(jv0) = -IM(v0);
- IM(jv0) = RE(v0);
-
- iz = ip = 0;
-
- if(r)
- {
- res = ellip_sn_cmplx(&jv0, 1, k, &tc);
- if(res != RES_OK)
- return res;
- RE(p[0]) = -IM(tc);
- IM(p[0]) = RE(tc);
- ip = 1;
- }
-
- for(n = 0; n < L; n++)
- {
- u = (double)(2 * n + 1)/(double)ord;
-
- res = ellip_cd(& u, 1, k, &t);
- if(res != RES_OK)
- return res;
-
- RE(z[iz]) = RE(z[iz+1]) = 0.0;
- IM(z[iz]) = 1.0/(k*t);
- IM(z[iz+1]) = -1.0/(k*t);
- iz+=2;
-
- RE(tc) = u - RE(jv0);
- IM(tc) = - IM(jv0);
-
- res = ellip_cd_cmplx(&tc, 1, k, p+ip+1);
- if(res != RES_OK)
- return res;
-
- RE(p[ip]) = -IM(p[ip+1]);
- IM(p[ip]) = RE(p[ip+1]);
-
- RE(p[ip+1]) = RE(p[ip]);
- IM(p[ip+1]) = -IM(p[ip]);
-
- ip+=2;
- }
- *nz = iz;
- *np = ip;
-
- return RES_OK;
-}
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int filter_zp2ab(complex_t *z, int nz, complex_t *p, int np, int ord,
- double* b, double* a)
-\brief
-Function recalculates complex zeros and poles of transfer function \f$ H(s) \f$
-to the coefficients of \f$ H(s) \f$ numerator and denominator polynomials.
-
-Transfer function can we described as:
-\f[
-H(s) =
-\frac{\sum\limits_{n = 0}^{N_z} b_n s^n}{\sum\limits_{m = 0}^{N_p} a_m s^m} =
-\frac{\prod\limits_{n = 0}^{N_z}(s-z_n)}{\prod\limits_{m = 0}^{N_p} (s-p_m)}
-\f]
-
-\param[in] z
-Pointer to the vector of transfer function zeros. \n
-Vector size is `[nz x 1]`. \n
-Pointer can be `NULL` if filter has no finite zeros (`nz=0`). \n
-\n
-
-\param[in] nz
-Number of fitite zeros (can be zero). \n
-\n
-
-\param[in] p
-Pointer to the vector of transfer function poles. \n
-Vector size is `[np x 1]`. \n
-This pointer cannot be `NULL`. \n
-\n
-
-\param[in] np
-Size of vector of transfer function poles (`p` vector size). \n
-\n
-
-\param[in] ord
-Filter order. \n
-Number of \f$H(s)\f$ numerator and denominator coefficients equals `ord+1`. \n
-\n
-
-\param[out] b
-Pointer to the vector of transfer function \f$H(s)\f$
-numerator coefficient. \n
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\param[out] a
-Pointer to the vector of transfer function \f$H(s)\f$
-denominator coefficient. \n
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\return
-`RES_OK` if filter coefficients is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-\n
-
-\note
-Function calculates real `b` and `a` coefficients of \f$H(s)\f$.
-It means that zeros and poles vectors must have real values or conjugate pairs
-to get zeros image part of `b` and `a` coefficients. This function ignores
-image part of `b` and `a` coeeffitients if the requirements for zeros
-and poles are not fulfilled.
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int filter_zp2ab(complex_t *z, int nz, complex_t *p, int np, int ord,
- double* b, double* a)
-\brief Функция пересчета нулей и полюсов аналогового фильтра в коэффициенты
- передаточной характеристики \f$ H(s) \f$
-
-\f[
-H(s) =
-\frac{\sum_{n = 0}^{N_z} b_n \cdot s^n}{\sum_{m = 0}^{N_p} a_m \cdot s^m} =
-\frac{\prod_{n = 0}^{N_z}(s-z_n)}{\prod_{m = 0}^{N_p} (s-p_m)}
-\f]
-
-\param[in] z
-Указатель на массив нулей передаточной характеристики. \n
-Размер вектора `[nz x 1]`. \n
-Указатель может быть `NULL` если фильтр не имеет конечных нулей (`nz=0`). \n
-\n
-
-\param[in] nz
-Размер вектора нулей передаточной характеристики (может быть равен 0). \n
-\n
-
-\param[in] p
-Указатель на массив полюсов передаточной характеристики. \n
-Размер вектора `[np x 1]`. \n
-Указатель не может быть `NULL`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in] np
-Размер вектора полюсов передаточной характеристики (не может быть равен 0). \n
-\n
-
-\param[in] ord
-Порядок фильтра для которого рассчитаны нули и полюса. \n
-Количество коэффициентов числителя и знаменателя
-передаточной функции \f$H(s)\f$ равно `ord+1`. \n \n
-
-\param[out] b
-Указатель на вектор коэффициентов числителя передаточной функции \f$H(s)\f$. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] a
-Указатель на вектор коэффициентов знаменателя
-передаточной функции \f$H(s)\f$. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\return
-`RES_OK` --- пересчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\note
-Функция возвращает вещественные значения коэффициентов `b` и `a`
-передаточной функции. Это означает, что вектора нулей и полюсов
-должны хранить вещественные значения или комплексно-сопряженные пары
-нулей и полюсов, потому что мнимая часть коэффициентов `b` и `a`
-игнорируется и не сохраняется.
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API filter_zp2ab(complex_t* z, int nz, complex_t* p, int np,
- int ord, double* b, double* a)
-{
- complex_t *acc = NULL;
- int res;
-
- if(!z || !p || !b || !a)
- return ERROR_PTR;
- if(nz < 0 || np < 0)
- return ERROR_SIZE;
- if(nz > ord || np > ord)
- return ERROR_POLY_ORD;
-
- acc = (complex_t*) malloc((ord+1) * sizeof(complex_t));
- res = poly_z2a_cmplx(z, nz, ord, acc);
- if(res != RES_OK)
- goto exit_label;
-
- res = cmplx2re(acc, ord+1, b, NULL);
- if(res != RES_OK)
- goto exit_label;
-
- res = poly_z2a_cmplx(p, np, ord, acc);
- if(res != RES_OK)
- goto exit_label;
-
- res = cmplx2re(acc, ord+1, a, NULL);
- if(res != RES_OK)
- goto exit_label;
-
-exit_label:
- if(acc)
- free(acc);
- return res;
-
-}
-
diff --git a/dspl/src/filter_design.c b/dspl/src/filter_design.c
new file mode 100644
index 0000000..aebf6d7
--- /dev/null
+++ b/dspl/src/filter_design.c
@@ -0,0 +1,55 @@
+
+
+/*
+FILTER_ANALYSIS_GROUP
+*/
+#include "filter_design/group_delay.c"
+#include "filter_design/filter_freq_resp.c"
+#include "filter_design/freqs.c"
+#include "filter_design/freqs_cmplx.c"
+#include "filter_design/freqs2time.c"
+#include "filter_design/freqz.c"
+#include "filter_design/phase_delay.c"
+
+
+
+/*
+Analog Normilized Prototypes
+*/
+#include "filter_design/butter_ap.c"
+#include "filter_design/butter_ap_zp.c"
+#include "filter_design/cheby1_ap.c"
+#include "filter_design/cheby1_ap_zp.c"
+#include "filter_design/cheby2_ap.c"
+#include "filter_design/cheby2_ap_wp1.c"
+#include "filter_design/cheby2_ap_zp.c"
+#include "filter_design/ellip_ap.c"
+#include "filter_design/ellip_ap_zp.c"
+#include "filter_design/filter_zp2ab.c"
+
+
+
+/*
+Filters Frequency Transformation
+*/
+#include "filter_design/filter_ws1.c"
+#include "filter_design/low2bp.c"
+#include "filter_design/low2bs.c"
+#include "filter_design/low2high.c"
+#include "filter_design/low2low.c"
+#include "filter_design/ratcompos.c"
+
+
+/*
+FIR design
+*/
+#include "filter_design/fir_linphase_lpf.c"
+#include "filter_design/fir_linphase.c"
+
+
+/*
+IIR design
+*/
+#include "filter_design/bilinear.c"
+#include "filter_design/iir.c"
+#include "filter_design/iir_ap.c"
diff --git a/dspl/src/filter_design/bilinear.c b/dspl/src/filter_design/bilinear.c
new file mode 100644
index 0000000..c21617a
--- /dev/null
+++ b/dspl/src/filter_design/bilinear.c
@@ -0,0 +1,217 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int bilinear(double* bs, double* as, int ord, double* bz, double* az)
+
+\brief
+Transform a s-plane analog filter transfer function \f$H(s)\f$ to the
+digital filter transfer function \f$H(z)\f$.
+
+Bilinear transform is rational composition:
+
+\f[
+s \leftarrow \frac{1 - z^{-1}}{1 - z^{-1}}.
+\f]
+
+Digital filter order, passband magnitude ripple and stopband suppression
+still the same after bilinear transform as analog filter.
+
+Frequency \f$\Omega\f$ of analog filter and frequency
+\f$\omega\f$ of digital filter relations:
+
+\f[
+\Omega = \tan(\omega / 2).
+\f]
+
+
+\param[in] bs
+Pointer to the vector of analog filter \f$H(s)\f$
+numerator coefficients.
+Vector size is `[ord+1 x 1]`. \n
+\n
+
+\param[in] as
+Pointer to the vector of analog filter \f$H(s)\f$
+denominator coefficients vector.
+Vector size is `[ord+1 x 1]`. \n
+\n
+
+\param[in] ord
+Analog and digital filters order. \n
+\n
+
+\param[out] bz
+Pointer to the vector of digital filter \f$H(z)\f$
+numerator coefficients after bilinear transform.
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\param[out] az
+Pointer to the vector of digital filter \f$H(z)\f$
+denominator coefficients after bilinear transform.
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\return
+`RES_OK` if bilinear transform is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+
+Example:
+
+\include bilinear_test.c
+
+This program calculates the transfer function \f$H(s)\f$ of analog
+Chebyshev filter of the first kind, with a cutoff frequency of 1 rad/s,
+and produces bilinear trandform to digital filter,
+with a normilized cutoff frequency equals 0.5.
+
+Result:
+
+\verbatim
+bz[0] = 0.246 az[0] = 4.425
+bz[1] = 0.983 az[1] = -3.318
+bz[2] = 1.474 az[2] = 4.746
+bz[3] = 0.983 az[3] = -2.477
+bz[4] = 0.246 az[4] = 1.034
+err = 0
+\endverbatim
+
+In addition, the frequency response of the resulting digital filter
+is calculated and plotted by GNUPLOT package.
+
+\image html bilinear.png
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int bilinear(double* bs, double* as, int ord, double* bz, double* az)
+
+\brief
+Билинейное преобразование передаточной характеристики аналогового
+фильтра \f$H(s)\f$, в передаточную характеристику цифрового фильтра \f$H(z)\f$.
+
+Функция рассчитывает коэффициенты передаточной характеристики \f$H(z)\f$
+цифрового фильтра путем дробно-рациональной подстановки вида
+
+\f[
+s \leftarrow \frac{1 - z^{-1}}{1 - z^{-1}}.
+\f]
+
+Порядок цифрового фильтра при этом остается равным порядку аналогового фильтра,
+а ось частот \f$\Omega\f$ аналогового фильтра связана c осью частот
+\f$\omega\f$ цифрового фильтра соотношением:
+
+\f[
+\Omega = \tan(\omega / 2).
+\f]
+
+
+
+\param[in] bs
+Указатель на вектор коэффициентов числителя передаточной функции \f$H(s)\f$
+исходного аналогового фильтра. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in] as
+Указатель на вектор коэффициентов знаменателя передаточной функции \f$H(s)\f$
+исходного аналогового фильтра. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in] ord
+Порядок фильтра. \n
+Количество коэффициентов числителя и знаменателя передаточных функций
+\f$H(s)\f$ и \f$H(z)\f$ аналогового и цифрового фильтров равно `ord+1`. \n
+\n
+
+\param[out] bz
+Указатель на вектор коэффициентов числителя передаточной функции \f$H(z)\f$
+полученного цифрового фильтра. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] az
+Указатель на вектор коэффициентов знаменателя передаточной функции \f$H(z)\f$
+полученного цифрового фильтра. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\return
+`RES_OK` --- фильтр рассчитан успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+
+Пример использования функции `bilinear`:
+
+\include bilinear_test.c
+
+Данная программа производит расчет передаточной характеристики аналогового
+фильтра Чебышева первого рода, с частотой среза равной 1 рад/с, и производит
+билинейное преобразование в цифровой, с частотой среза равной 0.5.
+
+Результат работы программы:
+
+\verbatim
+bz[0] = 0.246 az[0] = 4.425
+bz[1] = 0.983 az[1] = -3.318
+bz[2] = 1.474 az[2] = 4.746
+bz[3] = 0.983 az[3] = -2.477
+bz[4] = 0.246 az[4] = 1.034
+err = 0
+\endverbatim
+
+Кроме этого производится расчет АЧХ полученного цифрового фильтра и строится
+график АЧХ пакетом GNUPLOT
+
+\image html bilinear.png
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API bilinear(double* bs, double* as, int ord, double* bz, double* az)
+{
+ double c[2] = {1.0, -1.0};
+ double d[2] = {1.0, 1.0};
+ return ratcompos(bs, as, ord, c, d, 1, bz, az);
+}
+
+
diff --git a/dspl/src/filter_design/butter_ap.c b/dspl/src/filter_design/butter_ap.c
new file mode 100644
index 0000000..61f01cd
--- /dev/null
+++ b/dspl/src/filter_design/butter_ap.c
@@ -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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int butter_ap(double Rp, int ord, double* b, double* a)
+
+\brief
+Function calculates the transfer function \f$ H(s) \f$ coefficients of
+analog normalized lowpass Butterworth filter.
+
+Analog normalized lowpass filter magnitude ripple equals \f$ -R_p \f$ dB
+for angular frequency \f$ \omega \f$ from 0 to 1 rad/s.
+
+\param[in] Rp
+Magnitude ripple in passband (dB). \n
+This parameter sets maximum filter distortion from 0 to 1 rad/s frequency. \n
+Parameter must be positive. \n
+\n
+
+\param[in] ord
+Filter order. \n
+Filter coefficients number equals `ord+1` for numerator and denominator
+of transfer function \f$ H(s) \f$ \n
+\n
+
+\param[out] b
+Pointer to the vector of transfer function \f$H(s)\f$
+numerator coefficient. \n
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\param[out] a
+Pointer to the vector of transfer function \f$H(s)\f$
+denominator coefficient. \n
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\return
+`RES_OK` if filter coefficients is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+\n
+
+Example:
+
+\include butter_ap_test.c
+
+Result:
+
+\verbatim
+b[ 0] = 1.965 a[ 0] = 1.965
+b[ 1] = 0.000 a[ 1] = 3.138
+b[ 2] = 0.000 a[ 2] = 2.505
+b[ 3] = 0.000 a[ 3] = 1.000
+\endverbatim
+\n
+
+In `dat` folder will be created 3 files: \n
+
+\verbatim
+butter_ap_test_mag.txt magnitude
+butter_ap_test_phi.txt phase response
+butter_ap_test_tau.txt group delay
+\endverbatim
+
+In addition, GNUPLOT will build the following graphs from data stored in files:
+
+\image html butter_ap_test.png
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int butter_ap(double Rp, int ord, double* b, double* a)
+
+\brief
+Расчет передаточной характеристики \f$ H(s) \f$ аналогового
+нормированного ФНЧ Баттерворта.
+
+Функция рассчитывает коэффициенты передаточной характеристики \f$H(s)\f$
+аналогового нормированного ФНЧ Баттерворта порядка `ord` с частотой среза
+1 рад/с по уровню \f$ -R_p \f$ дБ.
+
+\param[in] Rp
+Неравномерность АЧХ в полосе пропускания (дБ). \n
+Параметр задает уровень искажений в полосе от 0 до 1 рад/с. \n
+Значение должно быть положительным. \n
+\n
+
+\param[in] ord
+Порядок фильтра. \n
+Количество коэффициентов числителя и знаменателя
+передаточной функции \f$H(s)\f$ равно `ord+1`. \n
+\n
+
+\param[out] b
+Указатель на вектор коэффициентов числителя
+передаточной функции \f$H(s)\f$. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] a
+Указатель на вектор коэффициентов знаменателя
+передаточной функции \f$H(s)\f$. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\return
+`RES_OK` --- фильтр рассчитан успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+\n
+
+Пример использования функции `butter_ap`:
+
+\include butter_ap_test.c
+
+Результат работы программы:
+
+\verbatim
+b[ 0] = 1.965 a[ 0] = 1.965
+b[ 1] = 0.000 a[ 1] = 3.138
+b[ 2] = 0.000 a[ 2] = 2.505
+b[ 3] = 0.000 a[ 3] = 1.000
+\endverbatim
+\n
+
+В каталоге `dat` будут созданы три файла: \n
+
+\verbatim
+butter_ap_test_mag.txt АЧХ фильтра
+butter_ap_test_phi.txt ФЧХ фильтра
+butter_ap_test_tau.txt ГВЗ фильтра
+\endverbatim
+
+Кроме того программа GNUPLOT произведет построение следующих графиков
+по сохраненным в файлах данным:
+
+\image html butter_ap_test.png
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API butter_ap(double rp, int ord, double* b, double* a)
+{
+ int res;
+ complex_t *z = NULL;
+ complex_t *p = NULL;
+ int nz, np;
+
+ if(rp < 0.0)
+ return ERROR_FILTER_RP;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(!a || !b)
+ return ERROR_PTR;
+
+ z = (complex_t*) malloc(ord*sizeof(complex_t));
+ p = (complex_t*) malloc(ord*sizeof(complex_t));
+
+
+ res = butter_ap_zp(ord, rp, z, &nz, p, &np);
+ if(res != RES_OK)
+ goto exit_label;
+
+ res = filter_zp2ab(z, nz, p, np, ord, b, a);
+ if(res != RES_OK)
+ goto exit_label;
+
+ b[0] = a[0];
+
+
+exit_label:
+ if(z)
+ free(z);
+ if(p)
+ free(p);
+ return res;
+}
+
diff --git a/dspl/src/filter_design/butter_ap_zp.c b/dspl/src/filter_design/butter_ap_zp.c
new file mode 100644
index 0000000..dc4d8b1
--- /dev/null
+++ b/dspl/src/filter_design/butter_ap_zp.c
@@ -0,0 +1,252 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int butter_ap_zp(int ord, double rp, complex_t* z, int* nz,
+ complex_t* p, int* np)
+
+\brief
+Function calculates arrays of zeros and poles for analog normlized lowpass
+Batterworth filter transfer function \f$ H(s) \f$ order `ord` .
+
+Analog normalized lowpass filter magnitude ripple equals \f$ -R_p \f$ dB
+for angular frequency \f$ \omega \f$ from 0 to 1 rad/s.
+
+
+\param[in] ord
+Filter order. \n
+Number of zeros and poles of filter can be less or equal `ord`. \n
+\n
+
+\param[in] rp
+Magnitude ripple in passband (dB). \n
+This parameter sets maximum filter distortion from 0 to 1 rad/s frequency. \n
+Parameter must be positive. \n
+\n
+
+\param[out] z
+Pointer to the \f$ H(s) \f$ zeros array. \n
+Maximum vector size is `[ord x 1]`. \n
+Memory must be allocated for maximum vector size. \n
+\n
+
+\param[out] nz
+Pointer to the variable which keep number of finite zeros \f$ H(s) \f$. \n
+Number of finite zeros which was calculated and saved in vector `z`. \n
+Pointer cannot be `NULL`. \n
+\n
+
+\param[out] p
+Pointer to the \f$ H(s) \f$ poles array. \n
+Maximum vector size is `[ord x 1]`. \n
+Memory must be allocated for maximum vector size. \n
+\n
+
+\param[out] np
+Pointer to the variable which keep number of
+calculated poles of \f$ H(s) \f$. \n
+Pointer cannot be `NULL`. \n
+\n
+
+\return
+`RES_OK` if zeros and poles is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+\n
+
+\note
+Normalized Butterworth lowpass filter has no finite zeros.
+So `z` vector will not changed and in pointer `nz` will write 0 value. \n
+
+
+Example of normalized Butterworth lowpass filter zeros and poles calculation:
+\include butter_ap_zp_test.c
+
+Result:
+
+\verbatim
+Butterworth filter zeros: 0
+Butterworth filter poles: 7
+p[ 0] = -1.101 +0.000 j
+p[ 1] = -0.245 +1.074 j
+p[ 2] = -0.245 -1.074 j
+p[ 3] = -0.687 +0.861 j
+p[ 4] = -0.687 -0.861 j
+p[ 5] = -0.992 +0.478 j
+p[ 6] = -0.992 -0.478 j
+\endverbatim
+\n
+
+In `dat` folder will be created `butter_ap_zp.txt` file. \n
+
+In addition, GNUPLOT will build the following graphs
+from data stored in `dat/butter_ap_zp.txt` file:
+
+\image html butter_ap_zp_test.png
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int butter_ap_zp(int ord, double rp, complex_t* z, int* nz,
+ complex_t* p, int* np)
+
+\brief
+Расчет массивов нулей и полюсов передаточной функции
+\f$ H(s) \f$ аналогового нормированного ФНЧ Баттерворта.
+
+Функция рассчитывает значения нулей и полюсов передаточной функции
+\f$ H(s)\f$ аналогового нормированного ФНЧ Баттерворта порядка `ord`
+с частотой среза 1 рад/с по уровню \f$-R_p\f$ дБ. \n
+
+
+\param[in] ord
+Порядок фильтра. \n
+\n
+
+\param[in] rp
+Неравномерность АЧХ в полосе пропускания (дБ). \n
+Параметр задает уровень искажений в полосе от 0 до 1 рад/с. \n
+Значение должно быть положительным. \n
+\n
+
+\param[out] z
+Указатель на массив комплексных нулей
+передаточной характеристики \f$ H(s)\f$. \n
+Максимальный размер вектора вектора `[ord x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] nz
+Указатель на переменную количества нулей
+передаточной характеристики \f$ H(s)\f$. \n
+По данному указателю будет записано количество
+нулей фильтра, которые были рассчитаны и
+помещены в вектор `z`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] p
+Указатель на массив комплексных полюсов
+передаточной характеристики \f$ H(s)\f$. \n
+Максимальный размер вектора вектора `[ord x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] np
+Указатель на переменную количества полюсов
+передаточной характеристики \f$ H(s)\f$. \n
+По данному укащзателю будет записано количество нулей фильтра, которые
+были рассчитны и помещены в вектор `p`. \n
+Память должна быть выделена. \n
+\n
+
+\return
+`RES_OK` --- массивы нулей и полюсов рассчитаны успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+\n
+
+\note
+Нормированный ФНЧ Баттерворта не имеет нулей, поэтому массив нулей `z`
+не будет изменен, а по указателю `nz` будет записан 0. \n
+
+
+Пример программы рассчета нулей и полюсов нормированного ФНЧ Баттерворта:
+\include butter_ap_zp_test.c
+
+Результат выполнения программы:
+
+\verbatim
+Butterworth filter zeros: 0
+Butterworth filter poles: 7
+p[ 0] = -1.101 +0.000 j
+p[ 1] = -0.245 +1.074 j
+p[ 2] = -0.245 -1.074 j
+p[ 3] = -0.687 +0.861 j
+p[ 4] = -0.687 -0.861 j
+p[ 5] = -0.992 +0.478 j
+p[ 6] = -0.992 -0.478 j
+\endverbatim
+\n
+
+В каталоге `dat` будет создан файл `butter_ap_zp.txt`. \n
+
+Пакет GNUPLOT произведет построение карты полюсов по
+сохранненным в `dat/butter_ap_zp.txt` данным:
+
+\image html butter_ap_zp_test.png
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API butter_ap_zp(int ord, double rp, complex_t* z, int* nz,
+ complex_t *p, int* np)
+{
+ double alpha;
+ double theta;
+ double ep;
+ int r;
+ int L;
+ int ind = 0, k;
+
+ if(rp < 0 || rp == 0)
+ return ERROR_FILTER_RP;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(!z || !p || !nz || !np)
+ return ERROR_PTR;
+
+ ep = sqrt(pow(10.0, rp*0.1) - 1.0);
+ r = ord % 2;
+ L = (int)((ord-r)/2);
+
+ alpha = pow(ep, -1.0/(double)ord);
+ if(r)
+ {
+ RE(p[ind]) = -alpha;
+ IM(p[ind]) = 0.0;
+ ind++;
+ }
+ for(k = 0; k < L; k++)
+ {
+ theta = M_PI*(double)(2*k + 1)/(double)(2*ord);
+ RE(p[ind]) = RE(p[ind+1]) = -alpha * sin(theta);
+ IM(p[ind]) = alpha * cos(theta);
+ IM(p[ind+1]) = -alpha * cos(theta);
+ ind+=2;
+ }
+ *np = ord;
+ *nz = 0;
+ return RES_OK;
+}
+
+
diff --git a/dspl/src/filter_design/cheby1_ap.c b/dspl/src/filter_design/cheby1_ap.c
new file mode 100644
index 0000000..f97d073
--- /dev/null
+++ b/dspl/src/filter_design/cheby1_ap.c
@@ -0,0 +1,230 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int cheby1_ap(double Rp, int ord, double* b, double* a)
+
+\brief
+Function calculates the transfer function \f$ H(s) \f$ coefficients of
+analog normalized lowpass Chebyshev type 1 filter.
+
+Analog normalized lowpass filter magnitude ripple equals \f$ -R_p \f$ dB
+for angular frequency \f$ \omega \f$ from 0 to 1 rad/s.
+
+\param[in] Rp
+Magnitude ripple in passband (dB). \n
+This parameter sets maximum filter distortion from 0 to 1 rad/s frequency. \n
+Parameter must be positive. \n
+\n
+
+\param[in] ord
+Filter order. \n
+Filter coefficients number equals `ord+1` for numerator and denominator
+of transfer function \f$ H(s) \f$ \n
+\n
+
+\param[out] b
+Pointer to the vector of transfer function \f$H(s)\f$
+numerator coefficient. \n
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\param[out] a
+Pointer to the vector of transfer function \f$H(s)\f$
+denominator coefficient. \n
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\return
+`RES_OK` if filter coefficients is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+\n
+
+Example:
+
+\include cheby1_ap_test.c
+
+Result:
+
+\verbatim
+b[ 0] = 0.125 a[ 0] = 0.177
+b[ 1] = 0.000 a[ 1] = 0.405
+b[ 2] = 0.000 a[ 2] = 1.169
+b[ 3] = 0.000 a[ 3] = 0.582
+b[ 4] = 0.000 a[ 4] = 1.000
+\endverbatim
+\n
+
+In `dat` folder will be created 3 files: \n
+
+\verbatim
+cheby1_ap_test_mag.txt magnitude
+cheby1_ap_test_phi.txt phase response
+cheby1_ap_test_tau.txt group delay
+\endverbatim
+
+In addition, GNUPLOT will build the following graphs from data stored in files:
+
+\image html cheby1_ap_test.png
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int cheby1_ap(double Rp, int ord, double* b, double* a)
+
+\brief
+Расчет передаточной характеристики \f$ H(s) \f$ аналогового
+нормированного ФНЧ Чебышёва первого рода.
+
+Функция рассчитывает коэффициенты передаточной характеристики
+\f$ H(s)\f$ аналогового нормированного ФНЧ Чебышёва первого рода
+порядка `ord` с частотой среза 1 рад/с по уровню \f$-R_p\f$ дБ. \n
+
+Особенностью фильтра Чебышёва первого рода являются
+равноволновые пульсации АЧХ в полосе пропускания.
+
+\param[in] Rp
+Неравномерность АЧХ в полосе пропускания (дБ). \n
+Параметр задает уровень искажений в полосе от 0 до 1 рад/с. \n
+Значение должно быть положительным. \n
+\n
+
+\param[in] ord
+Порядок фильтра. \n
+Количество коэффициентов числителя и знаменателя
+передаточной функции \f$ H(s)\f$ равно `ord+1`. \n
+\n
+
+\param[out] b
+Указатель на вектор коэффициентов числителя передаточной функции \f$H(s)\f$. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] a
+Указатель на вектор коэффициентов знаменателя
+передаточной функции \f$H(s)\f$. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\return
+`RES_OK` --- фильтр рассчитан успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+\n
+
+Пример использования функции `cheby1_ap`:
+
+\include cheby1_ap_test.c
+
+Результат работы программы:
+
+\verbatim
+b[ 0] = 0.125 a[ 0] = 0.177
+b[ 1] = 0.000 a[ 1] = 0.405
+b[ 2] = 0.000 a[ 2] = 1.169
+b[ 3] = 0.000 a[ 3] = 0.582
+b[ 4] = 0.000 a[ 4] = 1.000
+\endverbatim
+\n
+
+В каталоге `dat` будут созданы три файла: \n
+
+\verbatim
+cheby1_ap_test_mag.txt АЧХ фильтра
+cheby1_ap_test_phi.txt ФЧХ фильтра
+cheby1_ap_test_tau.txt ГВЗ фильтра
+\endverbatim
+\n
+
+Кроме того программа GNUPLOT произведет построение следующих графиков
+по сохраненным в файлах данным:
+
+\image html cheby1_ap_test.png
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API cheby1_ap(double rp, int ord, double* b, double* a)
+{
+ int res;
+ complex_t *z = NULL;
+ complex_t *p = NULL;
+ int nz, np, k;
+ complex_t h0 = {1.0, 0.0};
+ double tmp;
+
+
+ if(rp < 0.0)
+ return ERROR_FILTER_RP;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(!a || !b)
+ return ERROR_PTR;
+
+ z = (complex_t*) malloc(ord*sizeof(complex_t));
+ p = (complex_t*) malloc(ord*sizeof(complex_t));
+
+
+ res = cheby1_ap_zp(ord, rp, z, &nz, p, &np);
+ if(res != RES_OK)
+ goto exit_label;
+
+ res = filter_zp2ab(z, nz, p, np, ord, b, a);
+ if(res != RES_OK)
+ goto exit_label;
+
+
+ if(!(ord % 2))
+ RE(h0) = 1.0 / pow(10.0, rp*0.05);
+
+ for(k = 0; k < np; k++)
+ {
+ tmp = CMRE(h0, p[k]);
+ IM(h0) = CMIM(h0, p[k]);
+ RE(h0) = tmp;
+ }
+
+ b[0] = fabs(RE(h0));
+
+exit_label:
+ if(z)
+ free(z);
+ if(p)
+ free(p);
+ return res;
+}
+
diff --git a/dspl/src/filter_design/cheby1_ap_zp.c b/dspl/src/filter_design/cheby1_ap_zp.c
new file mode 100644
index 0000000..1325f82
--- /dev/null
+++ b/dspl/src/filter_design/cheby1_ap_zp.c
@@ -0,0 +1,251 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int cheby1_ap_zp( int ord, double rp, complex_t* z, int* nz,
+ complex_t* p, int* np)
+\brief
+Function calculates arrays of zeros and poles for analog normlized lowpass
+Chebyshev type 1 filter transfer function \f$ H(s) \f$ order `ord` .
+
+Analog normalized lowpass filter magnitude ripple equals \f$ -R_p \f$ dB
+for angular frequency \f$ \omega \f$ from 0 to 1 rad/s.
+
+
+\param[in] ord
+Filter order. \n
+Number of zeros and poles of filter can be less or equal `ord`. \n
+\n
+
+\param[in] rp
+Magnitude ripple in passband (dB). \n
+This parameter sets maximum filter distortion from 0 to 1 rad/s frequency. \n
+Parameter must be positive. \n
+\n
+
+\param[out] z
+Pointer to the \f$ H(s) \f$ zeros array. \n
+Maximum vector size is `[ord x 1]`. \n
+Memory must be allocated for maximum vector size. \n
+\n
+
+\param[out] nz
+Pointer to the variable which keep number of finite zeros \f$ H(s) \f$. \n
+Number of finite zeros which was calculated and saved in vector `z`. \n
+Pointer cannot be `NULL`. \n
+\n
+
+\param[out] p
+Pointer to the \f$ H(s) \f$ poles array. \n
+Maximum vector size is `[ord x 1]`. \n
+Memory must be allocated for maximum vector size. \n
+\n
+
+\param[out] np
+Pointer to the variable which keep number of
+calculated poles of \f$ H(s) \f$. \n
+Pointer cannot be `NULL`. \n
+\n
+
+\return
+`RES_OK` if zeros and poles is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+\n
+
+\note
+Normalized Chebyshev type 1 lowpass filter has no finite zeros.
+So `z` vector will not changed and in pointer `nz` will write 0 value. \n
+
+Example of normalized Chebyshev type 1 lowpass filter
+ zeros and poles calculation:
+\include cheby1_ap_zp_test.c
+
+Result:
+
+\verbatim
+Chebyshev type 1 filter zeros: 0
+Chebyshev type 1 filter poles: 7
+p[ 0] = -0.256 +0.000 j
+p[ 1] = -0.057 +1.006 j
+p[ 2] = -0.057 -1.006 j
+p[ 3] = -0.160 +0.807 j
+p[ 4] = -0.160 -0.807 j
+p[ 5] = -0.231 +0.448 j
+p[ 6] = -0.231 -0.448 j
+\endverbatim
+\n
+
+In `dat` folder will be created `cheby1_ap_zp.txt` file. \n
+
+In addition, GNUPLOT will build the following graphs
+from data stored in `dat/cheby1_ap_zp.txt` file:
+
+\image html cheby1_ap_zp_test.png
+
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int cheby1_ap_zp(int ord, double rp, complex_t* z, int* nz, complex_t* p, int* np)
+\brief
+Расчет массивов нулей и полюсов передаточной функции \f$ H(s) \f$
+аналогового нормированного ФНЧ Чебышёва первого рода.
+
+Функция рассчитывает значения нулей и полюсов передаточной функции
+\f$ H(s)\f$ аналогового нормированного ФНЧ Чебышёва первого рода
+порядка `ord` с частотой среза 1 рад/с по уровню \f$-R_p\f$ дБ, с
+неравномерностью в полосе пропускания \f$ R_p \f$ дБ. \n
+
+\param[in] ord
+Порядок фильтра. \n
+\n
+
+\param[in] rp
+Неравномерность АЧХ в полосе пропускания (дБ). \n
+Параметр задает уровень искажений в полосе от 0 до 1 рад/с. \n
+Значение должно быть положительным. \n
+\n
+
+\param[out] z
+Указатель на массив комплексных нулей
+передаточной характеристики \f$ H(s)\f$. \n
+Максимальный размер вектора `[ord x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] nz
+Указатель на переменную количества нулей
+передаточной функции \f$H(s)\f$. \n
+По данному указателю будет записано количество нулей фильтра,
+которые были рассчитаны и помещены в вектор `z`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] p
+Указатель на массив комплексных полюсов
+передаточной характеристики \f$H(s)\f$. \n
+Максимальный размер вектора вектора `[ord x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] np
+Указатель на переменную количества полюсов передаточной функции \f$ H(s)\f$. \n
+По данному указателю будет записано количество нулей фильтра, которые были
+рассчитаны и помещены в вектор `p`. \n
+Память должна быть выделена. \n
+\n
+
+\return
+`RES_OK` --- массивы нулей и полюсов рассчитаны успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\note
+Нормированный ФНЧ Чебышёва первого рода не имеет нулей, поэтому массив
+нулей `z` не будет изменен, а по указателю `nz` будет записан 0. \n
+
+
+Пример программы рассчета нулей и полюсов нормированного
+ФНЧ Чебышева первого рода:
+\include cheby1_ap_zp_test.c
+
+Результат выполнения программы:
+
+\verbatim
+Chebyshev type 1 filter zeros: 0
+Chebyshev type 1 filter poles: 7
+p[ 0] = -0.256 +0.000 j
+p[ 1] = -0.057 +1.006 j
+p[ 2] = -0.057 -1.006 j
+p[ 3] = -0.160 +0.807 j
+p[ 4] = -0.160 -0.807 j
+p[ 5] = -0.231 +0.448 j
+p[ 6] = -0.231 -0.448 j
+\endverbatim
+\n
+
+В каталоге `dat` будет создан файл `cheby1_ap_zp.txt`. \n
+
+Пакет GNUPLOT произведет построение карты полюсов по
+сохранненным в `dat/cheby1_ap_zp.txt` данным:
+
+\image html cheby1_ap_zp_test.png
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API cheby1_ap_zp(int ord, double rp, complex_t* z, int* nz,
+ complex_t* p, int* np)
+{
+ double theta;
+ double ep;
+ double beta;
+ double shbeta;
+ double chbeta;
+ int r;
+ int L;
+ int ind = 0, k;
+
+ if(rp < 0 || rp == 0)
+ return ERROR_FILTER_RP;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(!z || !p || !nz || !np)
+ return ERROR_PTR;
+
+ ep = sqrt(pow(10.0, rp*0.1) - 1.0);
+ r = ord % 2;
+ L = (int)((ord-r)/2);
+
+
+ beta = asinh(1.0/ep)/(double)ord;
+ chbeta = cosh(beta);
+ shbeta = sinh(beta);
+
+ if(r)
+ {
+ RE(p[ind]) = -shbeta;
+ IM(p[ind]) = 0.0;
+ ind++;
+ }
+ for(k = 0; k < L; k++)
+ {
+ theta = M_PI*(double)(2*k + 1)/(double)(2*ord);
+ RE(p[ind]) = RE(p[ind+1]) = -shbeta * sin(theta);
+ IM(p[ind]) = chbeta * cos(theta);
+ IM(p[ind+1]) = -IM(p[ind]);
+ ind+=2;
+ }
+ *np = ord;
+ *nz = 0;
+ return RES_OK;
+}
+
diff --git a/dspl/src/filter_design/cheby2_ap.c b/dspl/src/filter_design/cheby2_ap.c
new file mode 100644
index 0000000..8086524
--- /dev/null
+++ b/dspl/src/filter_design/cheby2_ap.c
@@ -0,0 +1,224 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int cheby2_ap(double Rs, int ord, double *b, double *a)
+
+\brief
+Function calculates the transfer function \f$ H(s) \f$ coefficients of
+analog normalized lowpass Chebyshev type 2 filter.
+
+Analog normalized Chebyshev type 2 filter lowpass filter has \f$Rs\f$ dB
+suppression in stopband.
+Also analog normalized Chebyshev type 2 filter magnitude equals \f$-Rs\f$ dB
+for angular frequency \f$\omega = 1\f$ rad/s.
+
+\param[in] Rs
+Suppression level in stopband (dB). \n
+This parameter sets filter supression for \f$\omega \geq 1\f$ rad/s frequency. \n
+Parameter must be positive. \n
+\n
+
+\param[in] ord
+Filter order. \n
+Filter coefficients number equals `ord+1` for numerator and denominator
+of transfer function \f$ H(s) \f$ \n
+\n
+
+\param[out] b
+Pointer to the vector of transfer function \f$H(s)\f$
+numerator coefficient. \n
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\param[out] a
+Pointer to the vector of transfer function \f$H(s)\f$
+denominator coefficient. \n
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\return
+`RES_OK` if filter coefficients is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+\n
+
+Example:
+
+\include cheby2_ap_test.c
+
+Result:
+
+\verbatim
+b[ 0] = 0.008 a[ 0] = 0.008
+b[ 1] = 0.000 a[ 1] = 0.068
+b[ 2] = 0.008 a[ 2] = 0.300
+b[ 3] = 0.000 a[ 3] = 0.774
+b[ 4] = 0.001 a[ 4] = 1.000
+\endverbatim
+\n
+
+In `dat` folder will be created 3 files: \n
+
+\verbatim
+cheby2_ap_test_mag.txt magnitude
+cheby2_ap_test_phi.txt phase response
+cheby2_ap_test_tau.txt group delay
+\endverbatim
+
+In addition, GNUPLOT will build the following graphs from data stored in files:
+
+\image html cheby2_ap_test.png
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int cheby2_ap(double Rs, int ord, double *b, double *a)
+
+\brief
+Расчет передаточной характеристики \f$ H(s) \f$ аналогового
+нормированного ФНЧ Чебышёва второго рода.
+
+Функция рассчитывает коэффициенты передаточной характеристики \f$H(s)\f$
+аналогового нормированного ФНЧ Чебышёва второго рода порядка `ord`
+с частотой заграждения 1 рад/с по уровню \f$-R_s\f$ дБ. \n
+
+Особенностью фильтра Чебышёва второго рода являются: \n
+1) равноволновые пульсации АЧХ в полосе заграждения. \n
+2) уровень АЧХ \f$H(j\cdot 1) = -R_s\f$ дБ. \n
+
+\param[in] Rs
+Уровень подавления в полосе пропускания (дБ). \n
+Значение должно быть положительным. \n
+\n
+
+\param[in] ord
+Порядок фильтра. \n
+Количество коэффициентов числителя и знаменателя
+передаточной функции \f$H(s)\f$ равно `ord+1`. \n
+\n
+
+\param[out] b
+Указатель на вектор коэффициентов числителя
+передаточной функции \f$H(s)\f$. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] a
+Указатель на вектор коэффициентов знаменателя
+передаточной функции \f$H(s)\f$. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+Пример использования функции `cheby1_ap`:
+
+\include cheby2_ap_test.c
+
+Результат работы программы:
+
+\verbatim
+b[ 0] = 0.008 a[ 0] = 0.008
+b[ 1] = 0.000 a[ 1] = 0.068
+b[ 2] = 0.008 a[ 2] = 0.300
+b[ 3] = 0.000 a[ 3] = 0.774
+b[ 4] = 0.001 a[ 4] = 1.000
+\endverbatim
+\n
+
+В каталоге `dat` будут созданы три файла: \n
+
+\verbatim
+cheby2_ap_test_mag.txt АЧХ фильтра
+cheby2_ap_test_phi.txt ФЧХ фильтра
+cheby2_ap_test_tau.txt ГВЗ фильтра
+\endverbatim
+\n
+
+Кроме того программа GNUPLOT произведет построение следующих графиков
+по сохраненным в файлах данным:
+
+\image html cheby2_ap_test.png
+
+
+\return
+`RES_OK` --- фильтр рассчитан успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API cheby2_ap(double rs, int ord, double* b, double* a)
+{
+ int res;
+ complex_t *z = NULL;
+ complex_t *p = NULL;
+ int nz, np;
+ double norm;
+
+
+ if(rs < 0.0)
+ return ERROR_FILTER_RP;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(!a || !b)
+ return ERROR_PTR;
+
+ z = (complex_t*) malloc(ord*sizeof(complex_t));
+ p = (complex_t*) malloc(ord*sizeof(complex_t));
+
+
+ res = cheby2_ap_zp(ord, rs, z, &nz, p, &np);
+ if(res != RES_OK)
+ goto exit_label;
+
+ res = filter_zp2ab(z, nz, p, np, ord, b, a);
+ if(res != RES_OK)
+ goto exit_label;
+
+ norm = a[0] / b[0];
+
+ for(nz = 0; nz < ord+1; nz++)
+ b[nz]*=norm;
+
+exit_label:
+ if(z)
+ free(z);
+ if(p)
+ free(p);
+ return res;
+}
+
diff --git a/dspl/src/filter_design/cheby2_ap_wp1.c b/dspl/src/filter_design/cheby2_ap_wp1.c
new file mode 100644
index 0000000..a60d4dd
--- /dev/null
+++ b/dspl/src/filter_design/cheby2_ap_wp1.c
@@ -0,0 +1,58 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API cheby2_ap_wp1(double rp, double rs, int ord, double* b, double* a)
+{
+ int err;
+ double es, gp, alpha, beta, y, wp;
+
+ if(rp <= 0)
+ return ERROR_FILTER_RP;
+
+ err = cheby2_ap(rs, ord, b, a);
+ if(err!=RES_OK)
+ goto exit_label;
+
+ es = sqrt(pow(10.0, rs*0.1) - 1.0);
+ gp = pow(10.0, -rp*0.05);
+ alpha = gp * es / sqrt(1.0 - gp*gp);
+ beta = alpha + sqrt(alpha * alpha - 1.0);
+ y = log(beta)/ (double)ord;
+ wp = 2.0 / (exp(y) + exp(-y));
+
+ err = low2low(b, a, ord, wp, 1.0, b, a);
+
+exit_label:
+ return err;
+}
+
diff --git a/dspl/src/filter_design/cheby2_ap_zp.c b/dspl/src/filter_design/cheby2_ap_zp.c
new file mode 100644
index 0000000..291355f
--- /dev/null
+++ b/dspl/src/filter_design/cheby2_ap_zp.c
@@ -0,0 +1,283 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int cheby2_ap_zp(int ord, double rs, complex_t* z, int* nz,
+ complex_t* p, int* np)
+
+\brief
+Function calculates arrays of zeros and poles for analog normlized lowpass
+Chebyshev type 2 filter transfer function \f$ H(s) \f$ order `ord` .
+
+Analog normalized Chebyshev type 2 filter lowpass filter has \f$Rs\f$ dB
+suppression in stopband.
+Also analog normalized Chebyshev type 2 filter magnitude equals \f$-Rs\f$ dB
+for angular frequency \f$\omega = 1\f$ rad/s.
+
+
+\param[in] ord
+Filter order. \n
+Number of zeros and poles of filter can be less or equal `ord`. \n
+\n
+
+\param[in] rs
+Suppression level in stopband (dB). \n
+This parameter sets filter supression for \f$\omega \geq 1\f$ rad/s frequency. \n
+Parameter must be positive. \n
+\n
+
+\param[out] z
+Pointer to the \f$ H(s) \f$ zeros array. \n
+Maximum vector size is `[ord x 1]`. \n
+Memory must be allocated for maximum vector size. \n
+\n
+
+\param[out] nz
+Pointer to the variable which keep number of finite zeros \f$ H(s) \f$. \n
+Number of finite zeros which was calculated and saved in vector `z`. \n
+Pointer cannot be `NULL`. \n
+\n
+
+\param[out] p
+Pointer to the \f$ H(s) \f$ poles array. \n
+Maximum vector size is `[ord x 1]`. \n
+Memory must be allocated for maximum vector size. \n
+\n
+
+\param[out] np
+Pointer to the variable which keep number of
+calculated poles of \f$ H(s) \f$. \n
+Pointer cannot be `NULL`. \n
+\n
+
+\return
+`RES_OK` if zeros and poles is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+\n
+
+Example of normalized Chebyshev type 2 lowpass filter
+ zeros and poles calculation:
+\include cheby2_ap_zp_test.c
+
+Result:
+
+\verbatim
+Chebyshev type 2 filter zeros: 6
+z[ 0] = 0.000 +1.026 j
+z[ 1] = 0.000 -1.026 j
+z[ 2] = 0.000 +1.279 j
+z[ 3] = 0.000 -1.279 j
+z[ 4] = 0.000 +2.305 j
+z[ 5] = 0.000 -2.305 j
+Chebyshev type 2 filter poles: 7
+p[ 0] = -1.203 +0.000 j
+p[ 1] = -0.113 +0.772 j
+p[ 2] = -0.113 -0.772 j
+p[ 3] = -0.398 +0.781 j
+p[ 4] = -0.398 -0.781 j
+p[ 5] = -0.852 +0.642 j
+p[ 6] = -0.852 -0.642 j
+\endverbatim
+\n
+
+In `dat` folder will be created `cheby2_ap_z.txt` and
+`cheby2_ap_z.txt` files which keeps zeros and poles vectors. \n
+
+In addition, GNUPLOT will build the following graphs
+from data stored in the files:
+
+\image html cheby2_ap_zp_test.png
+
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int cheby2_ap_zp(int ord, double rs, complex_t* z, int* nz,
+ complex_t* p, int* np)
+
+\brief
+Расчет массивов нулей и полюсов передаточной функции \f$ H(s) \f$
+аналогового нормированного ФНЧ Чебышёва второго рода.
+
+Функция рассчитывает значения нулей и полюсов передаточной функции
+\f$H(s)\f$ аналогового нормированного ФНЧ Чебышёва второго рода порядка `ord` с
+частотой заграждения 1 рад/с по уровню \f$-R_s\f$ дБ. \n
+
+
+\param[in] ord
+Порядок фильтра. \n
+\n
+
+\param[in] rs
+Уровень подавления АЧХ в полосе загражения (дБ). \n
+Параметр задает уровень подавления сигнала в полосе частот от 1 рад/с и выше. \n
+Значение должно быть положительным. \n
+\n
+
+\param[out] z
+Указатель на массив комплексных нулей передаточной функции \f$H(s)\f$. \n
+Максимальный размер вектора вектора `[ord x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] nz
+Указатель на переменную количества нулей передаточной функции \f$H(s)\f$. \n
+По данному указателю будет записано количество нулей фильтра, которые были
+рассчитаны и помещены в вектор `z`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] p
+Указатель на массив комплексных полюсов передаточной функции \f$H(s)\f$. \n
+Максимальный размер вектора вектора `[ord x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] np
+Указатель на переменную количества полюсов передаточной функции \f$H(s)\f$. \n
+По данному указателю будет записано количество нулей
+фильтра, которые были
+рассчитаны и помещены в вектор `p`. \n
+Память должна быть выделена. \n
+\n
+
+\return
+`RES_OK` --- массивы нулей и полюсов рассчитаны успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+Пример использования функции `cheby2_ap_zp`:
+
+Пример программы рассчета нулей и полюсов нормированного
+ФНЧ Чебышева первого рода:
+\include cheby2_ap_zp_test.c
+
+Результат выполнения программы:
+
+\verbatim
+Chebyshev type 2 filter zeros: 6
+z[ 0] = 0.000 +1.026 j
+z[ 1] = 0.000 -1.026 j
+z[ 2] = 0.000 +1.279 j
+z[ 3] = 0.000 -1.279 j
+z[ 4] = 0.000 +2.305 j
+z[ 5] = 0.000 -2.305 j
+Chebyshev type 2 filter poles: 7
+p[ 0] = -1.203 +0.000 j
+p[ 1] = -0.113 +0.772 j
+p[ 2] = -0.113 -0.772 j
+p[ 3] = -0.398 +0.781 j
+p[ 4] = -0.398 -0.781 j
+p[ 5] = -0.852 +0.642 j
+p[ 6] = -0.852 -0.642 j
+\endverbatim
+\n
+
+В каталоге `dat` будет создан файлы `cheby2_ap_z.txt` и `cheby2_ap_z.txt`,
+хранящие наборы нулей и полюсов на комплексной плоскости. \n
+
+Пакет GNUPLOT произведет построение карты полюсов по
+сохранненным в `dat/cheby2_ap_z.txt` и `dat/cheby2_ap_p.txt` данным:
+
+\image html cheby2_ap_zp_test.png
+
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API cheby2_ap_zp(int ord, double rs, complex_t* z, int* nz,
+ complex_t *p, int* np)
+{
+ double es;
+ int L, r, k;
+ double beta;
+ int iz, ip;
+
+ double alpha;
+ double chb, shb, sa, ca;
+ double ssh2, cch2;
+
+ if(rs < 0 || rs == 0)
+ return ERROR_FILTER_RS;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(!z || !p || !nz || !np)
+ return ERROR_PTR;
+
+ es = sqrt(pow(10.0, rs*0.1) - 1.0);
+ r = ord % 2;
+ L = (int)((ord-r)/2);
+
+ beta = asinh(es)/(double)ord;
+
+ chb = cosh(beta);
+ shb = sinh(beta);
+
+ iz = ip = 0;
+
+ if(r)
+ {
+ RE(p[0]) = -1.0 / sinh(beta);
+ IM(p[0]) = 0.0;
+ ip = 1;
+ }
+
+ for(k = 0; k < L; k++)
+ {
+ alpha = M_PI*(double)(2*k + 1)/(double)(2*ord);
+ sa = sin(alpha);
+ ca = cos(alpha);
+ ssh2 = sa*shb;
+ ssh2 *= ssh2;
+
+ cch2 = ca*chb;
+ cch2 *= cch2;
+
+ RE(z[iz]) = RE(z[iz+1]) = 0.0;
+ IM(z[iz]) = 1.0 / ca;
+ IM(z[iz+1]) = -IM(z[iz]);
+ iz+=2;
+
+ RE(p[ip]) = RE(p[ip+1]) = -sa*shb / (ssh2 + cch2);
+ IM(p[ip]) = ca*chb / (ssh2 + cch2);
+ IM(p[ip+1]) = -IM(p[ip]);
+ ip+=2;
+ }
+ *nz = iz;
+ *np = ip;
+
+ return RES_OK;
+}
+
diff --git a/dspl/src/filter_design/ellip_ap.c b/dspl/src/filter_design/ellip_ap.c
new file mode 100644
index 0000000..21cc39d
--- /dev/null
+++ b/dspl/src/filter_design/ellip_ap.c
@@ -0,0 +1,244 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int ellip_ap(double rp, double rs, int ord, double* b, double* a)
+
+\brief
+Function calculates the transfer function \f$ H(s) \f$ coefficients of
+analog normalized lowpass elliptic filter order `ord` with passband ripple
+`rp` dB and stopband suppression equals `rs` dB.
+
+\param[in] rp
+Magnitude ripple in passband (dB). \n
+This parameter sets maximum filter distortion from 0 to 1 rad/s frequency. \n
+Parameter must be positive. \n
+\n
+
+
+\param[in] rs
+Suppression level in stopband (dB). \n
+This parameter sets filter supression for \f$\omega \geq 1\f$ rad/s frequency. \n
+Parameter must be positive. \n
+\n
+
+\param[in] ord
+Filter order. \n
+Filter coefficients number equals `ord+1` for numerator and denominator
+of transfer function \f$ H(s) \f$ \n
+\n
+
+\param[out] b
+Pointer to the vector of transfer function \f$H(s)\f$
+numerator coefficient. \n
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\param[out] a
+Pointer to the vector of transfer function \f$H(s)\f$
+denominator coefficient. \n
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\return
+`RES_OK` if filter coefficients is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+\n
+
+Example:
+
+\include ellip_ap_test.c
+
+Result:
+
+\verbatim
+b[ 0] = 0.268 a[ 0] = 0.301
+b[ 1] = 0.000 a[ 1] = 0.764
+b[ 2] = 0.045 a[ 2] = 1.472
+b[ 3] = 0.000 a[ 3] = 0.948
+b[ 4] = 0.001 a[ 4] = 1.000
+\endverbatim
+\n
+
+In `dat` folder will be created 3 files: \n
+
+\verbatim
+ellip_ap_test_mag.txt magnitude
+ellip_ap_test_phi.txt phase response
+ellip_ap_test_tau.txt group delay
+\endverbatim
+
+In addition, GNUPLOT will build the following graphs from data stored in files:
+
+\image html ellip_ap_test.png
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int ellip_ap(double rp, double rs, int ord, double* b, double* a)
+
+\brief
+Расчет передаточной характеристики \f$ H(s) \f$ аналогового
+нормированного эллиптического ФНЧ.
+
+Функция рассчитывает коэффициенты передаточной характеристики \f$H(s)\f$
+аналогового нормированного эллиптического ФНЧ порядка `ord`
+с частотой среза 1 рад/с по уровню \f$-R_p\f$ дБ. \n
+
+Особенностью эллиптического фильтра являются равноволновые пульсации
+АЧХ как в полосе пропускания, так и в полосе заграждения, в результате
+чего обеспечиваеся минимальная переходная полоса фильтра. \n
+
+\param[in] rp
+Уровень пульсаций в полосе пропускания (дБ). \n
+Значение должно быть положительным. \n
+\n
+
+\param[in] rs
+Уровень подавления в полосе заграждения (дБ). \n
+Значение должно быть положительным. \n
+\n
+
+\param[in] ord
+Порядок фильтра. \n
+Количество коэффициентов числителя и знаменателя
+передаточной функции \f$H(s)\f$ равно `ord+1`. \n
+\n
+
+\param[out] b
+Указатель на вектор коэффициентов числителя
+передаточной функции \f$H(s)\f$. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] a
+Указатель на вектор коэффициентов знаменателя
+передаточной функции \f$H(s)\f$. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+Пример использования функции `ellip_ap`:
+
+\include ellip_ap_test.c
+
+Результат работы программы:
+
+\verbatim
+b[ 0] = 0.268 a[ 0] = 0.301
+b[ 1] = 0.000 a[ 1] = 0.764
+b[ 2] = 0.045 a[ 2] = 1.472
+b[ 3] = 0.000 a[ 3] = 0.948
+b[ 4] = 0.001 a[ 4] = 1.000
+\endverbatim
+\n
+
+В каталоге `dat` будут созданы три файла: \n
+
+\verbatim
+ellip_ap_test_mag.txt АЧХ фильтра
+ellip_ap_test_phi.txt ФЧХ фильтра
+ellip_ap_test_tau.txt ГВЗ фильтра
+\endverbatim
+\n
+
+Кроме того программа GNUPLOT произведет построение следующих графиков
+по сохраненным в файлах данным:
+
+\image html ellip_ap_test.png
+
+
+\return
+`RES_OK` --- фильтр рассчитан успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API ellip_ap(double rp, double rs, int ord, double* b, double* a)
+{
+ int res;
+ complex_t *z = NULL;
+ complex_t *p = NULL;
+ int nz, np;
+ double norm, g0;
+
+
+ if(rp < 0.0)
+ return ERROR_FILTER_RP;
+ if(rs < 0.0)
+ return ERROR_FILTER_RS;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(!a || !b)
+ return ERROR_PTR;
+
+ z = (complex_t*) malloc(ord*sizeof(complex_t));
+ p = (complex_t*) malloc(ord*sizeof(complex_t));
+
+
+ res = ellip_ap_zp(ord, rp, rs, z, &nz, p, &np);
+ if(res != RES_OK)
+ goto exit_label;
+
+ res = filter_zp2ab(z, nz, p, np, ord, b, a);
+ if(res != RES_OK)
+ goto exit_label;
+
+
+ g0 = 1.0;
+ if(!(ord % 2))
+ {
+ g0 = 1.0 / pow(10.0, rp*0.05);
+ }
+
+
+ norm = g0 * a[0] / b[0];
+
+ for(nz = 0; nz < ord+1; nz++)
+ b[nz]*=norm;
+
+ exit_label:
+ if(z)
+ free(z);
+ if(p)
+ free(p);
+ return res;
+}
+
+
diff --git a/dspl/src/filter_design/ellip_ap_zp.c b/dspl/src/filter_design/ellip_ap_zp.c
new file mode 100644
index 0000000..f573f3a
--- /dev/null
+++ b/dspl/src/filter_design/ellip_ap_zp.c
@@ -0,0 +1,307 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int ellip_ap_zp(int ord, double rp, double rs, complex_t* z, int* nz,
+ complex_t* p, int* np)
+
+\brief
+Function calculates arrays of zeros and poles for analog normlized lowpass
+elliptic filter transfer function \f$ H(s) \f$ order `ord` .
+
+\param[in] ord
+Filter order. \n
+Number of zeros and poles of filter can be less or equal `ord`. \n
+\n
+
+\param[in] rp
+Magnitude ripple in passband (dB). \n
+This parameter sets maximum filter distortion from 0 to 1 rad/s frequency. \n
+Parameter must be positive. \n
+\n
+
+\param[in] rs
+Suppression level in stopband (dB). \n
+This parameter sets filter suppression
+for \f$\omega \geq 1\f$ rad/s frequency. \n
+Parameter must be positive. \n
+\n
+
+\param[out] z
+Pointer to the \f$ H(s) \f$ zeros array. \n
+Maximum vector size is `[ord x 1]`. \n
+Memory must be allocated for maximum vector size. \n
+\n
+
+\param[out] nz
+Pointer to the variable which keep number of finite zeros \f$ H(s) \f$. \n
+Number of finite zeros which was calculated and saved in vector `z`. \n
+Pointer cannot be `NULL`. \n
+\n
+
+\param[out] p
+Pointer to the \f$ H(s) \f$ poles array. \n
+Maximum vector size is `[ord x 1]`. \n
+Memory must be allocated for maximum vector size. \n
+\n
+
+\param[out] np
+Pointer to the variable which keep number of
+calculated poles of \f$ H(s) \f$. \n
+Pointer cannot be `NULL`. \n
+\n
+
+\return
+`RES_OK` if zeros and poles is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+\n
+
+Example of normalized elliptic lowpass filter zeros and poles calculation:
+\include ellip_ap_zp_test.c
+
+Result:
+
+\verbatim
+Elliptic filter zeros: 6
+z[ 0] = 0.000 +1.053 j
+z[ 1] = 0.000 -1.053 j
+z[ 2] = 0.000 +1.136 j
+z[ 3] = 0.000 -1.136 j
+z[ 4] = 0.000 +1.626 j
+z[ 5] = 0.000 -1.626 j
+Elliptic filter poles: 7
+p[ 0] = -0.358 +0.000 j
+p[ 1] = -0.011 +1.000 j
+p[ 2] = -0.011 -1.000 j
+p[ 3] = -0.060 +0.940 j
+p[ 4] = -0.060 -0.940 j
+p[ 5] = -0.206 +0.689 j
+p[ 6] = -0.206 -0.689 j
+\endverbatim
+\n
+
+In `dat` folder will be created `ellip_ap_z.txt` and
+`ellip_ap_z.txt` files which keeps zeros and poles vectors. \n
+
+In addition, GNUPLOT will build the following graphs
+from data stored in the files:
+
+\image html ellip_ap_zp_test.png
+
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int ellip_ap_zp(int ord, double rp, double rs, complex_t* z, int* nz,
+ complex_t* p, int* np)
+
+\brief
+Расчет массивов нулей и полюсов передаточной функции \f$ H(s) \f$
+аналогового нормированного эллиптического ФНЧ.
+
+\param[in] ord
+Порядок фильтра. \n
+\n
+
+
+\param[in] rp
+Неравномерность АЧХ в полосе пропускания (дБ). \n
+Параметр задает уровень искажений в полосе от 0 до 1 рад/с. \n
+Значение должно быть положительным. \n
+\n
+
+\param[in] rs
+Уровень подавления АЧХ в полосе загражения (дБ). \n
+Параметр задает уровень подавления сигнала в полосе частот от 1 рад/с и выше. \n
+Значение должно быть положительным. \n
+\n
+
+\param[out] z
+Указатель на массив комплексных нулей передаточной функции \f$H(s)\f$. \n
+Максимальный размер вектора вектора `[ord x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] nz
+Указатель на переменную количества нулей передаточной функции \f$H(s)\f$. \n
+По данному указателю будет записано количество нулей фильтра, которые были
+рассчитаны и помещены в вектор `z`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] p
+Указатель на массив комплексных полюсов передаточной функции \f$H(s)\f$. \n
+Максимальный размер вектора вектора `[ord x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] np
+Указатель на переменную количества полюсов передаточной функции \f$H(s)\f$. \n
+По данному указателю будет записано количество нулей
+фильтра, которые были
+рассчитаны и помещены в вектор `p`. \n
+Память должна быть выделена. \n
+\n
+
+\return
+`RES_OK` --- массивы нулей и полюсов рассчитаны успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+Пример использования функции `cheby2_ap_zp`:
+
+Пример программы рассчета нулей и полюсов нормированного
+эллиптического ФНЧ :
+\include ellip_ap_zp_test.c
+
+Результат выполнения программы:
+
+\verbatim
+Elliptic filter zeros: 6
+z[ 0] = 0.000 +1.053 j
+z[ 1] = 0.000 -1.053 j
+z[ 2] = 0.000 +1.136 j
+z[ 3] = 0.000 -1.136 j
+z[ 4] = 0.000 +1.626 j
+z[ 5] = 0.000 -1.626 j
+Elliptic filter poles: 7
+p[ 0] = -0.358 +0.000 j
+p[ 1] = -0.011 +1.000 j
+p[ 2] = -0.011 -1.000 j
+p[ 3] = -0.060 +0.940 j
+p[ 4] = -0.060 -0.940 j
+p[ 5] = -0.206 +0.689 j
+p[ 6] = -0.206 -0.689 j
+\endverbatim
+\n
+
+В каталоге `dat` будет создан файлы `ellip_ap_z.txt` и `ellip_ap_z.txt`,
+хранящие наборы нулей и полюсов на комплексной плоскости. \n
+
+Пакет GNUPLOT произведет построение карты полюсов по
+сохранненным в `dat/ellip_ap_z.txt` и `dat/ellip_ap_p.txt` данным:
+
+\image html ellip_ap_zp_test.png
+
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API ellip_ap_zp(int ord, double rp, double rs,
+ complex_t* z, int* nz, complex_t* p, int* np)
+{
+ double es, ep;
+ int L, r, n, res;
+ int iz, ip;
+ double ke, k, u, t;
+ complex_t tc, v0, jv0;
+
+
+ if(rp < 0 || rp == 0)
+ return ERROR_FILTER_RP;
+ if(rs < 0 || rs == 0)
+ return ERROR_FILTER_RS;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(!z || !p || !nz || !np)
+ return ERROR_PTR;
+
+ es = sqrt(pow(10.0, rs*0.1) - 1.0);
+ ep = sqrt(pow(10.0, rp*0.1) - 1.0);
+ ke = ep / es;
+
+ r = ord % 2;
+ L = (int)((ord-r)/2);
+
+ res = ellip_modulareq(rp, rs, ord, &k);
+ if(res != RES_OK)
+ return res;
+ // v0
+ RE(tc) = 0.0;
+ IM(tc) = 1.0 / ep;
+
+ ellip_asn_cmplx(&tc, 1, ke, &v0);
+
+ t = RE(v0);
+ RE(v0) = IM(v0) / (double)ord;
+ IM(v0) = -t / (double)ord;
+
+ RE(jv0) = -IM(v0);
+ IM(jv0) = RE(v0);
+
+ iz = ip = 0;
+
+ if(r)
+ {
+ res = ellip_sn_cmplx(&jv0, 1, k, &tc);
+ if(res != RES_OK)
+ return res;
+ RE(p[0]) = -IM(tc);
+ IM(p[0]) = RE(tc);
+ ip = 1;
+ }
+
+ for(n = 0; n < L; n++)
+ {
+ u = (double)(2 * n + 1)/(double)ord;
+
+ res = ellip_cd(& u, 1, k, &t);
+ if(res != RES_OK)
+ return res;
+
+ RE(z[iz]) = RE(z[iz+1]) = 0.0;
+ IM(z[iz]) = 1.0/(k*t);
+ IM(z[iz+1]) = -1.0/(k*t);
+ iz+=2;
+
+ RE(tc) = u - RE(jv0);
+ IM(tc) = - IM(jv0);
+
+ res = ellip_cd_cmplx(&tc, 1, k, p+ip+1);
+ if(res != RES_OK)
+ return res;
+
+ RE(p[ip]) = -IM(p[ip+1]);
+ IM(p[ip]) = RE(p[ip+1]);
+
+ RE(p[ip+1]) = RE(p[ip]);
+ IM(p[ip+1]) = -IM(p[ip]);
+
+ ip+=2;
+ }
+ *nz = iz;
+ *np = ip;
+
+ return RES_OK;
+}
+
diff --git a/dspl/src/filter_design/filter_freq_resp.c b/dspl/src/filter_design/filter_freq_resp.c
new file mode 100644
index 0000000..7457b5a
--- /dev/null
+++ b/dspl/src/filter_design/filter_freq_resp.c
@@ -0,0 +1,314 @@
+/*
+* 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 .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup FILTER_ANALYSIS_GROUP
+\fn int filter_freq_resp(double* b, double* a, int ord, double* w, int n,
+ int flag, double* mag, double* phi, double* tau)
+
+\brief
+Magnitude, phase response and group delay vectors calculation
+for digital or analog filter corresponds to \f$H(s)\f$, or \f$H(z)\f$
+transfer function.
+
+
+\param[in] b
+Pointer to the \f$ H(s) \f$ or \f$H(z)\f$ transfer function
+numerator coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n \n
+
+\param[in] a
+Pointer to the \f$ H(s) \f$ or \f$H(z)\f$ transfer function
+denominator coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n \n
+
+\param[in] ord
+Filter order. \n
+Transfer function \f$ H(s) \f$ or \f$H(z)\f$ numerator
+and denominator coefficients number equals `ord+1`. \n \n
+
+\param[in] w
+Pointer to the angular frequency \f$ \omega \f$ (rad/s),
+which used for analog filter characteristics calculation
+(flag sets as `DSPL_FLAG_ANALOG`). \n
+For digital filter (flag sets as `DSPL_FLAG_DIGITAL`),
+ parameter `w` describes normalized frequency of
+frequency response \f$ H \left(\mathrm{e}^{j\omega} \right) \f$.
+Digital filter frequency response is \f$ 2\pi \f$-periodic function,
+and vector `w` advisable to set from 0 to \f$ \pi \f$,
+or from 0 to \f$ 2\pi \f$, or from \f$ -\pi \f$ to \f$ \pi \f$.
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of frequency vector `w`. \n \n
+
+\param[in] flag
+Binary flags to set calculation rules: \n
+\verbatim
+DSPL_FLAG_ANALOG Coefficients corresponds to analog filter
+DSPL_FLAG_DIGITAL Coefficients corresponds to digital filter
+DSPL_FLAG_LOGMAG Calculate magnitude in logarithmic scale (in dB)
+DSPL_FLAG_UNWRAP Unwrap radian phases by adding multiples of 2*pi
+\endverbatim
+
+\param[out] mag
+Pointer to the filter magnitude vector. \n
+Vector size is `[n x 1]`. \n
+If pointer is `NULL`, then magnitude will not calculted. \n \n
+
+\param[out] phi
+Pointer to the phase response vector. \n
+Vector size is `[n x 1]`. \n
+If pointer is `NULL`, then phase response will not calculted. \n \n
+
+\param[out] tau
+Pointer to the group delay vector. \n
+Vector size is `[n x 1]`. \n
+If pointer is `NULL`, then group delay will not calculted. \n \n
+
+\return
+\return `RES_OK` if function is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+Example:
+
+\include butter_ap_test.c
+
+Result:
+
+\verbatim
+b[ 0] = 1.002 a[ 0] = 1.002
+b[ 1] = 0.000 a[ 1] = 2.618
+b[ 2] = 0.000 a[ 2] = 3.418
+b[ 3] = 0.000 a[ 3] = 2.615
+b[ 4] = 0.000 a[ 4] = 1.000
+\endverbatim
+\n
+
+In `dat` folder will be created 3 files: \n
+
+\verbatim
+butter_ap_test_mag.txt magnitude
+butter_ap_test_phi.txt phase response
+butter_ap_test_tau.txt group delay
+\endverbatim
+
+In addition, GNUPLOT will build the following graphs from data stored in files:
+
+\image html butter_ap_test.png
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup FILTER_ANALYSIS_GROUP
+\fn int filter_freq_resp(double* b, double* a, int ord, double* w, int n,
+ int flag, double* mag, double* phi, double* tau)
+
+\brief
+Расчет амплитудно-частотной (АЧХ), фазочастотной характеристик (ФЧХ), а также
+группового времени запаздывания (ГВЗ) цифрового или аналогового или фильтра.
+
+Функция рассчитывает АЧХ, ФЧХ и ГВЗ аналогового или цифрового фильтра, заданного
+передаточной характеристикой \f$H(s)\f$, или \f$H(z)\f$ соответственно
+
+\param[in] b
+Указатель на вектор коэффициентов числителя
+передаточной функции \f$ H(s) \f$. \n
+Размер вектора `[ord+1 x 1]`. \n \n
+
+\param[in] a
+Указатель на вектор коэффициентов знаменателя
+передаточной функции \f$ H(s) \f$. \n
+Размер вектора `[ord+1 x 1]`. \n \n
+
+\param[in] ord
+Порядок фильтра. Количество коэффициентов
+числителя и знаменателя передаточной
+функции \f$ H(s) \f$ равно `ord+1`. \n \n
+
+\param[in] w
+Указатель на вектор значений циклической частоты \f$ \omega \f$ (рад/с),
+для которого будет рассчитаны АЧХ, ФЧХ и ГВЗ аналогового фильтра,
+если установлен флаг `DSPL_FLAG_ANALOG`. \n
+В случае если флаг `DSPL_FLAG_ANALOG` не установлен, то вектор частоты `w`
+используется как нормированная частота комплексного коэффициента передачи
+\f$ H \left(\mathrm{e}^{j\omega} \right) \f$ цифрового фильтра. \n
+В этом случае характеристика цифрового фильтра является
+\f$ 2\pi \f$-периодической, и вектор частоты может содержать
+произвольные значения, однако целесообразно задавать
+его от 0 до \f$ \pi \f$, а такжет от 0 до \f$ 2\pi \f$, или
+от \f$ -\pi \f$ до \f$ \pi \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер вектора циклической частоты `w`. \n \n
+
+\param[in] flag
+Комбинация флагов, которые задают расчет параметров: \n
+\verbatim
+DSPL_FLAG_ANALOG Коэффициенты относятся к аналоговому фильтру
+DSPL_FLAG_LOGMAG АЧХ рассчитывать в логарифмическом масштабе
+DSPL_FLAG_UNWRAP раскрывать периодичность ФЧХ
+\endverbatim
+
+\param[out] mag
+Указатель на вектор АЧХ. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n
+Если указатель `NULL`, то расчет АЧХ не производится. \n \n
+
+\param[out] phi
+Указатель на вектор ФЧХ. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n
+Если указатель `NULL`, то расчет ФЧХ не производится. \n \n
+
+\param[out] tau
+Указатель на вектор ГВЗ. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n
+Если указатель `NULL`, то расчет ГВЗ не производится. \n \n
+
+\return
+`RES_OK` Параметры фильтра рассчитаны успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+Пример использования функции `filter_freq_resp`:
+
+\include butter_ap_test.c
+
+Результат работы программы:
+
+\verbatim
+b[ 0] = 1.002 a[ 0] = 1.002
+b[ 1] = 0.000 a[ 1] = 2.618
+b[ 2] = 0.000 a[ 2] = 3.418
+b[ 3] = 0.000 a[ 3] = 2.615
+b[ 4] = 0.000 a[ 4] = 1.000
+\endverbatim
+\n
+
+В каталоге `dat` будут созданы три файла: \n
+
+\verbatim
+butter_ap_test_mag.txt АЧХ фильтра
+butter_ap_test_phi.txt ФЧХ фильтра
+butter_ap_test_tau.txt ГВЗ фильтра
+\endverbatim
+
+Кроме того программа GNUPLOT произведет построение следующих графиков
+по сохраненным в файлах данным:
+
+\image html butter_ap_test.png
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API filter_freq_resp(double* b, double* a, int ord,
+ double* w, int n, int flag,
+ double* mag, double* phi, double* tau)
+{
+ int res, k, flag_analog;
+
+ complex_t *hc = NULL;
+ double *phi0 = NULL;
+ double *phi1 = NULL;
+ double *w0 = NULL;
+ double *w1 = NULL;
+
+ if(!b || !w)
+ return ERROR_PTR;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(n < 1)
+ return ERROR_SIZE;
+
+ flag_analog = flag & DSPL_FLAG_ANALOG;
+
+ hc = (complex_t*) malloc (n*sizeof(complex_t));
+
+ res = flag_analog ?
+ freqs(b, a, ord, w, n, hc) :
+ freqz(b, a, ord, w, n, hc);
+
+ if(res != RES_OK)
+ goto exit_label;
+
+
+ if(mag)
+ {
+ if(flag & DSPL_FLAG_LOGMAG)
+ {
+ for(k = 0; k < n; k++)
+ mag[k] = 10.0 * log10(ABSSQR(hc[k]));
+ }
+ else
+ {
+ for(k = 0; k < n; k++)
+ mag[k] = sqrt(ABSSQR(hc[k]));
+ }
+ }
+
+
+ if(phi)
+ {
+ for(k = 0; k < n; k++)
+ phi[k] = atan2(IM(hc[k]), RE(hc[k]));
+
+ if(flag & DSPL_FLAG_UNWRAP)
+ {
+ res = unwrap(phi, n, M_2PI, 0.8);
+ if(res != RES_OK)
+ goto exit_label;
+ }
+ }
+
+
+ if(tau)
+ res = group_delay(b, a, ord, flag, w, n, tau);
+
+
+
+exit_label:
+ if(hc)
+ free(hc);
+ if(phi0)
+ free(phi0);
+ if(phi1)
+ free(phi1);
+ if(w0)
+ free(w0);
+ if(w1)
+ free(w1);
+ return res;
+}
+
+
diff --git a/dspl/src/filter_design/filter_ws1.c b/dspl/src/filter_design/filter_ws1.c
new file mode 100644
index 0000000..5e7a745
--- /dev/null
+++ b/dspl/src/filter_design/filter_ws1.c
@@ -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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+double DSPL_API filter_ws1(int ord, double rp, double rs, int type)
+{
+ double es2, ep2, gs2, x, ws;
+
+ if(ord<1 || rp < 0.0 || rs < 0.0)
+ return -1.0;
+
+ es2 = pow(10.0, rs*0.1) - 1.0;
+ ep2 = pow(10.0, rp*0.1) - 1.0;
+ gs2 = 1.0 / (1.0 + es2);
+
+ x = (1.0 - gs2) / (gs2 * ep2);
+
+ switch( type & DSPL_FILTER_APPROX_MASK)
+ {
+ case DSPL_FILTER_BUTTER:
+ ws = pow(x, 0.5 / (double)ord);
+ break;
+ case DSPL_FILTER_CHEBY1:
+ case DSPL_FILTER_CHEBY2:
+ x = sqrt(x) + sqrt(x - 1.0);
+ x = log(x) / (double)ord;
+ ws = 0.5 * (exp(-x) + exp(x));
+ break;
+ case DSPL_FILTER_ELLIP:
+ {
+ double k, k1;
+ complex_t y, z;
+ int res;
+ k = sqrt(ep2 / es2);
+ res = ellip_modulareq(rp, rs, ord, &k1);
+ if(res != RES_OK)
+ {
+ ws = -1.0;
+ break;
+ }
+ RE(z) = sqrt(x);
+ IM(z) = 0.0;
+
+ res = ellip_acd_cmplx(&z, 1, k, &y);
+ if(res != RES_OK)
+ {
+ ws = -1.0;
+ break;
+ }
+ RE(y) /= (double)ord;
+ IM(y) /= (double)ord;
+ res = ellip_cd_cmplx(&y, 1, k1, &z);
+ if(res != RES_OK)
+ {
+ ws = -1.0;
+ break;
+ }
+ ws = RE(z);
+ break;
+ }
+ default:
+ ws = -1.0;
+ break;
+ }
+ return ws;
+}
+
diff --git a/dspl/src/filter_design/filter_zp2ab.c b/dspl/src/filter_design/filter_zp2ab.c
new file mode 100644
index 0000000..0b35d38
--- /dev/null
+++ b/dspl/src/filter_design/filter_zp2ab.c
@@ -0,0 +1,204 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int filter_zp2ab(complex_t *z, int nz, complex_t *p, int np, int ord,
+ double* b, double* a)
+\brief
+Function recalculates complex zeros and poles of transfer function \f$ H(s) \f$
+to the coefficients of \f$ H(s) \f$ numerator and denominator polynomials.
+
+Transfer function can we described as:
+\f[
+H(s) =
+\frac{\sum\limits_{n = 0}^{N_z} b_n s^n}{\sum\limits_{m = 0}^{N_p} a_m s^m} =
+\frac{\prod\limits_{n = 0}^{N_z}(s-z_n)}{\prod\limits_{m = 0}^{N_p} (s-p_m)}
+\f]
+
+\param[in] z
+Pointer to the vector of transfer function zeros. \n
+Vector size is `[nz x 1]`. \n
+Pointer can be `NULL` if filter has no finite zeros (`nz=0`). \n
+\n
+
+\param[in] nz
+Number of fitite zeros (can be zero). \n
+\n
+
+\param[in] p
+Pointer to the vector of transfer function poles. \n
+Vector size is `[np x 1]`. \n
+This pointer cannot be `NULL`. \n
+\n
+
+\param[in] np
+Size of vector of transfer function poles (`p` vector size). \n
+\n
+
+\param[in] ord
+Filter order. \n
+Number of \f$H(s)\f$ numerator and denominator coefficients equals `ord+1`. \n
+\n
+
+\param[out] b
+Pointer to the vector of transfer function \f$H(s)\f$
+numerator coefficient. \n
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\param[out] a
+Pointer to the vector of transfer function \f$H(s)\f$
+denominator coefficient. \n
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\return
+`RES_OK` if filter coefficients is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+\n
+
+\note
+Function calculates real `b` and `a` coefficients of \f$H(s)\f$.
+It means that zeros and poles vectors must have real values or conjugate pairs
+to get zeros image part of `b` and `a` coefficients. This function ignores
+image part of `b` and `a` coeeffitients if the requirements for zeros
+and poles are not fulfilled.
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int filter_zp2ab(complex_t *z, int nz, complex_t *p, int np, int ord,
+ double* b, double* a)
+\brief Функция пересчета нулей и полюсов аналогового фильтра в коэффициенты
+ передаточной характеристики \f$ H(s) \f$
+
+\f[
+H(s) =
+\frac{\sum_{n = 0}^{N_z} b_n \cdot s^n}{\sum_{m = 0}^{N_p} a_m \cdot s^m} =
+\frac{\prod_{n = 0}^{N_z}(s-z_n)}{\prod_{m = 0}^{N_p} (s-p_m)}
+\f]
+
+\param[in] z
+Указатель на массив нулей передаточной характеристики. \n
+Размер вектора `[nz x 1]`. \n
+Указатель может быть `NULL` если фильтр не имеет конечных нулей (`nz=0`). \n
+\n
+
+\param[in] nz
+Размер вектора нулей передаточной характеристики (может быть равен 0). \n
+\n
+
+\param[in] p
+Указатель на массив полюсов передаточной характеристики. \n
+Размер вектора `[np x 1]`. \n
+Указатель не может быть `NULL`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in] np
+Размер вектора полюсов передаточной характеристики (не может быть равен 0). \n
+\n
+
+\param[in] ord
+Порядок фильтра для которого рассчитаны нули и полюса. \n
+Количество коэффициентов числителя и знаменателя
+передаточной функции \f$H(s)\f$ равно `ord+1`. \n \n
+
+\param[out] b
+Указатель на вектор коэффициентов числителя передаточной функции \f$H(s)\f$. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] a
+Указатель на вектор коэффициентов знаменателя
+передаточной функции \f$H(s)\f$. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\return
+`RES_OK` --- пересчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\note
+Функция возвращает вещественные значения коэффициентов `b` и `a`
+передаточной функции. Это означает, что вектора нулей и полюсов
+должны хранить вещественные значения или комплексно-сопряженные пары
+нулей и полюсов, потому что мнимая часть коэффициентов `b` и `a`
+игнорируется и не сохраняется.
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API filter_zp2ab(complex_t* z, int nz, complex_t* p, int np,
+ int ord, double* b, double* a)
+{
+ complex_t *acc = NULL;
+ int res;
+
+ if(!z || !p || !b || !a)
+ return ERROR_PTR;
+ if(nz < 0 || np < 0)
+ return ERROR_SIZE;
+ if(nz > ord || np > ord)
+ return ERROR_POLY_ORD;
+
+ acc = (complex_t*) malloc((ord+1) * sizeof(complex_t));
+ res = poly_z2a_cmplx(z, nz, ord, acc);
+ if(res != RES_OK)
+ goto exit_label;
+
+ res = cmplx2re(acc, ord+1, b, NULL);
+ if(res != RES_OK)
+ goto exit_label;
+
+ res = poly_z2a_cmplx(p, np, ord, acc);
+ if(res != RES_OK)
+ goto exit_label;
+
+ res = cmplx2re(acc, ord+1, a, NULL);
+ if(res != RES_OK)
+ goto exit_label;
+
+exit_label:
+ if(acc)
+ free(acc);
+ return res;
+
+}
+
diff --git a/dspl/src/filter_fir.c b/dspl/src/filter_design/fir_linphase.c
similarity index 94%
rename from dspl/src/filter_fir.c
rename to dspl/src/filter_design/fir_linphase.c
index 180d335..b334979 100644
--- a/dspl/src/filter_fir.c
+++ b/dspl/src/filter_design/fir_linphase.c
@@ -1,414 +1,375 @@
-/*
-* 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 .
-*/
-
-#include
-#include
-#include
-#include "dspl.h"
-#include "dspl_internal.h"
-
-
-/******************************************************************************
- * Linear phase lowpass filter
- ******************************************************************************/
-int fir_linphase_lpf(int ord, double wp, int win_type,
- double win_param, double* h)
-{
- int n, err = RES_OK;
- double *w = NULL;
-
-
- w = (double*)malloc((ord+1)*sizeof(double));
-
- err = linspace(-(double)ord*0.5, (double)ord*0.5, ord+1, DSPL_SYMMETRIC, w);
-
- if(err!=RES_OK)
- goto error_proc;
-
- err = sinc(w, ord+1, M_PI*wp, h);
-
- if(err!=RES_OK)
- goto error_proc;
-
- err = window(w, ord+1, win_type | DSPL_SYMMETRIC, win_param);
-
- if(err!=RES_OK)
- goto error_proc;
-
- for(n = 0; n < ord+1; n++)
- h[n] *= w[n] * wp;
-
-error_proc:
- if(w)
- free(w);
- return err;
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup FIR_FILTER_DESIGN_GROUP
-\fn int DSPL_API fir_linphase(int ord, double w0, double w1, int filter_type,
-int win_type, double win_param, double* h)
-\brief
-Function calculates linear-phase FIR filter coefficients by window method
-
-FIR filter transfer function is
-\f[
-H(z) = \sum_{n = 0}^{ord} h_n z^{-n}.
-\f]
-
-\param[in] ord
-Filter order. \n
-Number of FIR filter coefficients is `ord+1`. \n
-\n
-
-\param[in] w0
-Normalized cutoff frequency for lowpass and highpass filter,
-or left cutoff frequency for bandpass or bandstop filter. \n
-\n
-
-\param[in] w1
-Right normalized cutoff frequency for bandpass or bandstop filter. \n
-This parameter is ignored for lowpass or highpass filters. \n
-Frequecny `w1` must be higher than `w0`. \n
-\n
-
-\param[in] filter_type
-Filter type. \n
-This parameter can be one of follow: \n
-\verbatim
-DSPL_FILTER_LPF - lowpass filter;
-DSPL_FILTER_HPF - highpass filter;
-DSPL_FILTER_BPASS - bandpass filter;
-DSPL_FILTER_BSTOP - bandstop filter.
-\endverbatim
-\n
-\n
-
-\param [in] win_type
-Window function type. \n
-This parameter can be one of follow: \n
-\verbatim
--------------------------------------------------------------------------
- win_type | Description
------------------------------|-------------------------------------------
- DSPL_WIN_BARTLETT | Nonparametric Bartlett window
------------------------------|-------------------------------------------
- DSPL_WIN_BARTLETT_HANN | Nonparametric Bartlett-Hann window
------------------------------|-------------------------------------------
- DSPL_WIN_BLACKMAN | Nonparametric Blackman window
------------------------------|-------------------------------------------
- DSPL_WIN_BLACKMAN_HARRIS | Nonparametric Blackman-Harris window
------------------------------|-------------------------------------------
- DSPL_WIN_BLACKMAN_NUTTALL | Nonparametric Blackman-Nuttall
------------------------------|-------------------------------------------
- DSPL_WIN_CHEBY | Parametric Dolph-Chebyshev window.
- | Parametr `win_param` sets sidelobe attenuation
- | level in dB.
------------------------------|-------------------------------------------
- DSPL_WIN_COS | Nonparametric Cosine window
------------------------------|-------------------------------------------
- DSPL_WIN_FLAT_TOP | Nonparametric maxflat window
------------------------------|-------------------------------------------
- DSPL_WIN_GAUSSIAN | Nonparametric Gauss window
------------------------------|-------------------------------------------
- DSPL_WIN_HAMMING | Nonparametric Hamming window
------------------------------|-------------------------------------------
- DSPL_WIN_HANN | Nonparametric Hann window
------------------------------|-------------------------------------------
- DSPL_WIN_KAISER | Parametric Kaiser window
------------------------------|-------------------------------------------
- DSPL_WIN_LANCZOS | Nonparametric Lanczos window
------------------------------|-------------------------------------------
- DSPL_WIN_NUTTALL | Nonparametric Nuttall window
------------------------------|-------------------------------------------
- DSPL_WIN_RECT | Nonparametric rectangular window
--------------------------------------------------------------------------
-\endverbatim
-\n
-\n
-
-\param [in] win_param
-Parameter value for parametric windows. \n
-This parameter is used for parametric windows only and is ignored for
-nonparametric windows. \n
-\n
-
-\param[out] h
-Pointer to the linear-phase FIR filter coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n
-Memoru must be allocated. \n
-\n
-
-\note
-Only symmetric windows can achieve linear-phase FIR filter. \n \n
-Bandstop filter type (`filter_type = DSPL_FILTER_BSTOP`) requires
-only even filter order `ord`.
-If `filter_type = DSPL_FILTER_BSTOP` and `ord` is odd then function
-returns `ERROR_FILTER_ORD` code.
-\n
-
-\return
-`RES_OK` if filter coefficients is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-
-Example:
-
-\include fir_linphase_test.c
-
-This function calculates coeffictiens of lowpass, highpass, bandpass
- and bandstop linear-phase FIR filters by using different kind of windows.
- Also program calculates filter magnitudes and plots. \n
-
-\image html fir_linphase_test.png
-
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup FIR_FILTER_DESIGN_GROUP
-\fn int DSPL_API fir_linphase(int ord, double w0, double w1, int filter_type,
- int win_type, double win_param, double* h)
-\brief
-Расчет коэффициентов линейно-фазового КИХ-фильтра
-методом оконного взвешивания.
-
-Функция рассчитывает коэффициенты передаточной характеристики
-\f[
-H(z) = \sum_{n = 0}^{ord} h_n z^{-n}
-\f]
-цифрового линейно-фазового КИХ-фильтра фильтра.
-
-\param[in] ord
-Порядок фильтра (количество элементов задержки). \n
-Количество коэффициентов фильтра равно `ord+1`. \n
-\n
-
-\param[in] w0
-Нормированная частота среза ФНЧ или ФВЧ,
-или левая частота среза для полосового и режекторного фильтра. \n
-\n
-
-\param[in] w1
-Правая частота среза полосового и режекторного фильтра. \n
-Данный параметр игнорируется для ФНЧ и ФВЧ. \n
-Частота `w1` должна быть больше `w0`. \n
-\n
-
-\param[in] filter_type
-Тип фильтра. \n
-Данный параметр определяет тип фильтра
-и может принимать одно из значений: \n
-\verbatim
-DSPL_FILTER_LPF - фильтр нижних частот;
-DSPL_FILTER_HPF - фильтр верхних частот;
-DSPL_FILTER_BPASS - полосовой фильтр;
-DSPL_FILTER_BSTOP - режекторный фильтр.
-\endverbatim
-\n
-\n
-
-\param [in] win_type
-Тип оконной функции. \n
-Может принимать одно из следующих значений: \n
-\verbatim
--------------------------------------------------------------------------
-Значение win_type | Описание
------------------------------|-------------------------------------------
- DSPL_WIN_BARTLETT | Непараметрическое окно Бартлетта
------------------------------|-------------------------------------------
- DSPL_WIN_BARTLETT_HANN | Непараметрическое окно Бартлетта-Ханна
------------------------------|-------------------------------------------
- DSPL_WIN_BLACKMAN | Непараметрическое окно Блэкмана
------------------------------|-------------------------------------------
- DSPL_WIN_BLACKMAN_HARRIS | Непараметрическое окно Блэкмана-Харриса
------------------------------|-------------------------------------------
- DSPL_WIN_BLACKMAN_NUTTALL | Непараметрическое окно Блэкмана-Натталла
------------------------------|-------------------------------------------
- DSPL_WIN_CHEBY | Параметрическое окно Дольф-Чебышева.
- | Параметр win_param задает уровень
- | боковых лепестков в дБ.
------------------------------|-------------------------------------------
- DSPL_WIN_COS | Непараметрическое косинус-окно
------------------------------|-------------------------------------------
- DSPL_WIN_FLAT_TOP | Непараметрическое окно с максимально
- | плоской вершиной
------------------------------|-------------------------------------------
- DSPL_WIN_GAUSSIAN | Параметрическое окно Гаусса
------------------------------|-------------------------------------------
- DSPL_WIN_HAMMING | Непараметрическое окно Хемминга
------------------------------|-------------------------------------------
- DSPL_WIN_HANN | Непараметрическое окно Ханна
------------------------------|-------------------------------------------
- DSPL_WIN_KAISER | Параметрическое окно Кайзера
------------------------------|-------------------------------------------
- DSPL_WIN_LANCZOS | Непараметрическое окно Ланкзоса
------------------------------|-------------------------------------------
- DSPL_WIN_NUTTALL | Непараметрическое окно Натталла
------------------------------|-------------------------------------------
- DSPL_WIN_RECT | Непараметрическое прямоугольное окно
--------------------------------------------------------------------------
-\endverbatim
-\n
-\n
-
-\param [in] win_param
-Параметр окна. \n
-Данный параметр применяется только для параметрических оконных функций. \n
-Для непараметрических окон игнорируется. \n
-\n
-
-\param[out] h
-Указатель на вектор коэффициентов линейно-фазового КИХ-фильтра \f$H(z)\f$. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\note
-Для соблюдения условия линейной ФЧХ используются
-только симметричные окна. \n \n
-Расчет режекторного линейно-фазового КИХ-фильтра
-(если `filter_type = DSPL_FILTER_BSTOP`) производится только
-для фильтров чётного порядка `ord`.
-В случае нечетного порядка `ord` функция вернет код ошибки `ERROR_FILTER_ORD`.
-\n
-
-\return
-`RES_OK`
-Фильтр рассчитан успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-
-Пример использования функции:
-
-\include fir_linphase_test.c
-
-Программа расчитывает коэффициенты и АЧХ линейно-фазовых КИХ-фильтров нижних,
-верхних частот, полосовых и режекторных с применением различных весовых окон:
-прямоугольное, Хемминга, Блэкмана и Блэкмана-Харриса. \n
-Полученные АЧХ выводятся на график
-
-\image html fir_linphase_test.png
-
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API fir_linphase(int ord, double w0, double w1, int filter_type,
- int win_type, double win_param, double* h)
-{
- int n, err;
- double wc, b, del;
-
- if(ord<1)
- return ERROR_FILTER_ORD;
- if(w0 <= 0.0)
- return ERROR_FILTER_WP;
- if(!h)
- return ERROR_PTR;
-
- switch(filter_type & DSPL_FILTER_TYPE_MASK)
- {
- /* Lowpass FIR coefficients calculation */
- case DSPL_FILTER_LPF:
- err = fir_linphase_lpf(ord, w0, win_type, win_param, h);
- break;
-
- /* Highpass FIR coefficients calculation */
- case DSPL_FILTER_HPF:
- err = fir_linphase_lpf(ord, 1.0-w0, win_type, win_param, h);
- if(err == RES_OK)
- {
- /* LPF filter frequency inversion */
- for(n = 0; n < ord+1; n+=2)
- h[n] = -h[n];
- }
- break;
-
- /* Bandpass FIR coefficients calculation */
- case DSPL_FILTER_BPASS:
- if(w1 < w0)
- {
- err = ERROR_FILTER_WS;
- break;
- }
- wc = (w0 + w1) * 0.5; /* central frequency */
- b = w1 - w0; /* bandwidth */
- err = fir_linphase_lpf(ord, b*0.5, win_type, win_param, h);
- if(err == RES_OK)
- {
- /* LPF frequency shifting to the central frequency */
- del = 0.5 * (double)ord;
- for(n = 0; n < ord+1; n++)
- h[n] *= 2.0 * cos(M_PI * ((double)n - del) * wc);
- }
- break;
-
- /* BandStop FIR coefficients calculation */
- /* ATTENTION! Bandstop filter must be even order only! */
- case DSPL_FILTER_BSTOP:
- {
- double *h0 = NULL;
-
- /* check filter order. Return error if order is odd. */
- if(ord%2)
- return ERROR_FILTER_ORD;
-
- /* check frequency (w1 must be higher than w0) */
- if(w1 < w0)
- {
- err = ERROR_FILTER_WS;
- break;
- }
- /* temp coeff vector */
- h0 = (double*)malloc((ord+1) * sizeof(double));
-
- /* calculate LPF */
- err = fir_linphase(ord, w0, 0.0, DSPL_FILTER_LPF,
- win_type, win_param, h0);
- if(err!=RES_OK)
- {
- free(h0);
- return err;
- }
- /* calculate HPF */
- err = fir_linphase(ord, w1, 0.0, DSPL_FILTER_HPF,
- win_type, win_param, h);
- if(err==RES_OK)
- {
- /* Bandstop filter is sum of lowpass and highpass filters */
- for(n = 0; n < ord+1; n++)
- h[n] += h0[n];
- }
- free(h0);
- break;
- }
- default:
- err = ERROR_FILTER_FT;
- }
- return err;
-}
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup FIR_FILTER_DESIGN_GROUP
+\fn int DSPL_API fir_linphase(int ord, double w0, double w1, int filter_type,
+int win_type, double win_param, double* h)
+\brief
+Function calculates linear-phase FIR filter coefficients by window method
+
+FIR filter transfer function is
+\f[
+H(z) = \sum_{n = 0}^{ord} h_n z^{-n}.
+\f]
+
+\param[in] ord
+Filter order. \n
+Number of FIR filter coefficients is `ord+1`. \n
+\n
+
+\param[in] w0
+Normalized cutoff frequency for lowpass and highpass filter,
+or left cutoff frequency for bandpass or bandstop filter. \n
+\n
+
+\param[in] w1
+Right normalized cutoff frequency for bandpass or bandstop filter. \n
+This parameter is ignored for lowpass or highpass filters. \n
+Frequecny `w1` must be higher than `w0`. \n
+\n
+
+\param[in] filter_type
+Filter type. \n
+This parameter can be one of follow: \n
+\verbatim
+DSPL_FILTER_LPF - lowpass filter;
+DSPL_FILTER_HPF - highpass filter;
+DSPL_FILTER_BPASS - bandpass filter;
+DSPL_FILTER_BSTOP - bandstop filter.
+\endverbatim
+\n
+\n
+
+\param [in] win_type
+Window function type. \n
+This parameter can be one of follow: \n
+\verbatim
+-------------------------------------------------------------------------
+ win_type | Description
+-----------------------------|-------------------------------------------
+ DSPL_WIN_BARTLETT | Nonparametric Bartlett window
+-----------------------------|-------------------------------------------
+ DSPL_WIN_BARTLETT_HANN | Nonparametric Bartlett-Hann window
+-----------------------------|-------------------------------------------
+ DSPL_WIN_BLACKMAN | Nonparametric Blackman window
+-----------------------------|-------------------------------------------
+ DSPL_WIN_BLACKMAN_HARRIS | Nonparametric Blackman-Harris window
+-----------------------------|-------------------------------------------
+ DSPL_WIN_BLACKMAN_NUTTALL | Nonparametric Blackman-Nuttall
+-----------------------------|-------------------------------------------
+ DSPL_WIN_CHEBY | Parametric Dolph-Chebyshev window.
+ | Parametr `win_param` sets sidelobe attenuation
+ | level in dB.
+-----------------------------|-------------------------------------------
+ DSPL_WIN_COS | Nonparametric Cosine window
+-----------------------------|-------------------------------------------
+ DSPL_WIN_FLAT_TOP | Nonparametric maxflat window
+-----------------------------|-------------------------------------------
+ DSPL_WIN_GAUSSIAN | Nonparametric Gauss window
+-----------------------------|-------------------------------------------
+ DSPL_WIN_HAMMING | Nonparametric Hamming window
+-----------------------------|-------------------------------------------
+ DSPL_WIN_HANN | Nonparametric Hann window
+-----------------------------|-------------------------------------------
+ DSPL_WIN_KAISER | Parametric Kaiser window
+-----------------------------|-------------------------------------------
+ DSPL_WIN_LANCZOS | Nonparametric Lanczos window
+-----------------------------|-------------------------------------------
+ DSPL_WIN_NUTTALL | Nonparametric Nuttall window
+-----------------------------|-------------------------------------------
+ DSPL_WIN_RECT | Nonparametric rectangular window
+-------------------------------------------------------------------------
+\endverbatim
+\n
+\n
+
+\param [in] win_param
+Parameter value for parametric windows. \n
+This parameter is used for parametric windows only and is ignored for
+nonparametric windows. \n
+\n
+
+\param[out] h
+Pointer to the linear-phase FIR filter coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n
+Memoru must be allocated. \n
+\n
+
+\note
+Only symmetric windows can achieve linear-phase FIR filter. \n \n
+Bandstop filter type (`filter_type = DSPL_FILTER_BSTOP`) requires
+only even filter order `ord`.
+If `filter_type = DSPL_FILTER_BSTOP` and `ord` is odd then function
+returns `ERROR_FILTER_ORD` code.
+\n
+
+\return
+`RES_OK` if filter coefficients is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+
+Example:
+
+\include fir_linphase_test.c
+
+This function calculates coeffictiens of lowpass, highpass, bandpass
+ and bandstop linear-phase FIR filters by using different kind of windows.
+ Also program calculates filter magnitudes and plots. \n
+
+\image html fir_linphase_test.png
+
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup FIR_FILTER_DESIGN_GROUP
+\fn int DSPL_API fir_linphase(int ord, double w0, double w1, int filter_type,
+ int win_type, double win_param, double* h)
+\brief
+Расчет коэффициентов линейно-фазового КИХ-фильтра
+методом оконного взвешивания.
+
+Функция рассчитывает коэффициенты передаточной характеристики
+\f[
+H(z) = \sum_{n = 0}^{ord} h_n z^{-n}
+\f]
+цифрового линейно-фазового КИХ-фильтра фильтра.
+
+\param[in] ord
+Порядок фильтра (количество элементов задержки). \n
+Количество коэффициентов фильтра равно `ord+1`. \n
+\n
+
+\param[in] w0
+Нормированная частота среза ФНЧ или ФВЧ,
+или левая частота среза для полосового и режекторного фильтра. \n
+\n
+
+\param[in] w1
+Правая частота среза полосового и режекторного фильтра. \n
+Данный параметр игнорируется для ФНЧ и ФВЧ. \n
+Частота `w1` должна быть больше `w0`. \n
+\n
+
+\param[in] filter_type
+Тип фильтра. \n
+Данный параметр определяет тип фильтра
+и может принимать одно из значений: \n
+\verbatim
+DSPL_FILTER_LPF - фильтр нижних частот;
+DSPL_FILTER_HPF - фильтр верхних частот;
+DSPL_FILTER_BPASS - полосовой фильтр;
+DSPL_FILTER_BSTOP - режекторный фильтр.
+\endverbatim
+\n
+\n
+
+\param [in] win_type
+Тип оконной функции. \n
+Может принимать одно из следующих значений: \n
+\verbatim
+-------------------------------------------------------------------------
+Значение win_type | Описание
+-----------------------------|-------------------------------------------
+ DSPL_WIN_BARTLETT | Непараметрическое окно Бартлетта
+-----------------------------|-------------------------------------------
+ DSPL_WIN_BARTLETT_HANN | Непараметрическое окно Бартлетта-Ханна
+-----------------------------|-------------------------------------------
+ DSPL_WIN_BLACKMAN | Непараметрическое окно Блэкмана
+-----------------------------|-------------------------------------------
+ DSPL_WIN_BLACKMAN_HARRIS | Непараметрическое окно Блэкмана-Харриса
+-----------------------------|-------------------------------------------
+ DSPL_WIN_BLACKMAN_NUTTALL | Непараметрическое окно Блэкмана-Натталла
+-----------------------------|-------------------------------------------
+ DSPL_WIN_CHEBY | Параметрическое окно Дольф-Чебышева.
+ | Параметр win_param задает уровень
+ | боковых лепестков в дБ.
+-----------------------------|-------------------------------------------
+ DSPL_WIN_COS | Непараметрическое косинус-окно
+-----------------------------|-------------------------------------------
+ DSPL_WIN_FLAT_TOP | Непараметрическое окно с максимально
+ | плоской вершиной
+-----------------------------|-------------------------------------------
+ DSPL_WIN_GAUSSIAN | Параметрическое окно Гаусса
+-----------------------------|-------------------------------------------
+ DSPL_WIN_HAMMING | Непараметрическое окно Хемминга
+-----------------------------|-------------------------------------------
+ DSPL_WIN_HANN | Непараметрическое окно Ханна
+-----------------------------|-------------------------------------------
+ DSPL_WIN_KAISER | Параметрическое окно Кайзера
+-----------------------------|-------------------------------------------
+ DSPL_WIN_LANCZOS | Непараметрическое окно Ланкзоса
+-----------------------------|-------------------------------------------
+ DSPL_WIN_NUTTALL | Непараметрическое окно Натталла
+-----------------------------|-------------------------------------------
+ DSPL_WIN_RECT | Непараметрическое прямоугольное окно
+-------------------------------------------------------------------------
+\endverbatim
+\n
+\n
+
+\param [in] win_param
+Параметр окна. \n
+Данный параметр применяется только для параметрических оконных функций. \n
+Для непараметрических окон игнорируется. \n
+\n
+
+\param[out] h
+Указатель на вектор коэффициентов линейно-фазового КИХ-фильтра \f$H(z)\f$. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\note
+Для соблюдения условия линейной ФЧХ используются
+только симметричные окна. \n \n
+Расчет режекторного линейно-фазового КИХ-фильтра
+(если `filter_type = DSPL_FILTER_BSTOP`) производится только
+для фильтров чётного порядка `ord`.
+В случае нечетного порядка `ord` функция вернет код ошибки `ERROR_FILTER_ORD`.
+\n
+
+\return
+`RES_OK`
+Фильтр рассчитан успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+
+Пример использования функции:
+
+\include fir_linphase_test.c
+
+Программа расчитывает коэффициенты и АЧХ линейно-фазовых КИХ-фильтров нижних,
+верхних частот, полосовых и режекторных с применением различных весовых окон:
+прямоугольное, Хемминга, Блэкмана и Блэкмана-Харриса. \n
+Полученные АЧХ выводятся на график
+
+\image html fir_linphase_test.png
+
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API fir_linphase(int ord, double w0, double w1, int filter_type,
+ int win_type, double win_param, double* h)
+{
+ int n, err;
+ double wc, b, del;
+
+ if(ord<1)
+ return ERROR_FILTER_ORD;
+ if(w0 <= 0.0)
+ return ERROR_FILTER_WP;
+ if(!h)
+ return ERROR_PTR;
+
+ switch(filter_type & DSPL_FILTER_TYPE_MASK)
+ {
+ /* Lowpass FIR coefficients calculation */
+ case DSPL_FILTER_LPF:
+ err = fir_linphase_lpf(ord, w0, win_type, win_param, h);
+ break;
+
+ /* Highpass FIR coefficients calculation */
+ case DSPL_FILTER_HPF:
+ err = fir_linphase_lpf(ord, 1.0-w0, win_type, win_param, h);
+ if(err == RES_OK)
+ {
+ /* LPF filter frequency inversion */
+ for(n = 0; n < ord+1; n+=2)
+ h[n] = -h[n];
+ }
+ break;
+
+ /* Bandpass FIR coefficients calculation */
+ case DSPL_FILTER_BPASS:
+ if(w1 < w0)
+ {
+ err = ERROR_FILTER_WS;
+ break;
+ }
+ wc = (w0 + w1) * 0.5; /* central frequency */
+ b = w1 - w0; /* bandwidth */
+ err = fir_linphase_lpf(ord, b*0.5, win_type, win_param, h);
+ if(err == RES_OK)
+ {
+ /* LPF frequency shifting to the central frequency */
+ del = 0.5 * (double)ord;
+ for(n = 0; n < ord+1; n++)
+ h[n] *= 2.0 * cos(M_PI * ((double)n - del) * wc);
+ }
+ break;
+
+ /* BandStop FIR coefficients calculation */
+ /* ATTENTION! Bandstop filter must be even order only! */
+ case DSPL_FILTER_BSTOP:
+ {
+ double *h0 = NULL;
+
+ /* check filter order. Return error if order is odd. */
+ if(ord%2)
+ return ERROR_FILTER_ORD;
+
+ /* check frequency (w1 must be higher than w0) */
+ if(w1 < w0)
+ {
+ err = ERROR_FILTER_WS;
+ break;
+ }
+ /* temp coeff vector */
+ h0 = (double*)malloc((ord+1) * sizeof(double));
+
+ /* calculate LPF */
+ err = fir_linphase(ord, w0, 0.0, DSPL_FILTER_LPF,
+ win_type, win_param, h0);
+ if(err!=RES_OK)
+ {
+ free(h0);
+ return err;
+ }
+ /* calculate HPF */
+ err = fir_linphase(ord, w1, 0.0, DSPL_FILTER_HPF,
+ win_type, win_param, h);
+ if(err==RES_OK)
+ {
+ /* Bandstop filter is sum of lowpass and highpass filters */
+ for(n = 0; n < ord+1; n++)
+ h[n] += h0[n];
+ }
+ free(h0);
+ break;
+ }
+ default:
+ err = ERROR_FILTER_FT;
+ }
+ return err;
+}
diff --git a/dspl/src/filter_design/fir_linphase_lpf.c b/dspl/src/filter_design/fir_linphase_lpf.c
new file mode 100644
index 0000000..d4077d9
--- /dev/null
+++ b/dspl/src/filter_design/fir_linphase_lpf.c
@@ -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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+
+/******************************************************************************
+ * Linear phase lowpass filter
+ ******************************************************************************/
+int fir_linphase_lpf(int ord, double wp, int win_type,
+ double win_param, double* h)
+{
+ int n, err = RES_OK;
+ double *w = NULL;
+
+
+ w = (double*)malloc((ord+1)*sizeof(double));
+
+ err = linspace(-(double)ord*0.5, (double)ord*0.5, ord+1, DSPL_SYMMETRIC, w);
+
+ if(err!=RES_OK)
+ goto error_proc;
+
+ err = sinc(w, ord+1, M_PI*wp, h);
+
+ if(err!=RES_OK)
+ goto error_proc;
+
+ err = window(w, ord+1, win_type | DSPL_SYMMETRIC, win_param);
+
+ if(err!=RES_OK)
+ goto error_proc;
+
+ for(n = 0; n < ord+1; n++)
+ h[n] *= w[n] * wp;
+
+error_proc:
+ if(w)
+ free(w);
+ return err;
+}
+
+
diff --git a/dspl/src/filter_design/freqs.c b/dspl/src/filter_design/freqs.c
new file mode 100644
index 0000000..efbc2d2
--- /dev/null
+++ b/dspl/src/filter_design/freqs.c
@@ -0,0 +1,203 @@
+/*
+* 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 .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup FILTER_ANALYSIS_GROUP
+\fn int freqs(double* b, double* a, int ord, double* w, int n, complex_t *h)
+\brief Analog filter frequency response \f$ H(j \omega) \f$ calculation
+
+Function calculates analog filter frequency response \f$ H(j \omega)\f$
+corresponds to transfer function \f$ H(s) \f$:
+
+\f[
+ H(s) = \frac {\sum_{k = 0}^{N} b_k s^k}
+ {\sum_{m = 0}^{N} a_m s^m},
+\f]
+here \f$ N \f$ - filter order (equals to `ord`).
+
+\param[in] b
+Pointer to the transfer function \f$ H(s) \f$
+numerator coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n \n
+
+\param[in] a
+Pointer to the transfer function \f$ H(s) \f$
+denominator coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n \n
+
+\param[in] ord
+Filter order. \n
+Transfer function \f$ H(s) \f$ numerator and denominator
+coefficients number equals `ord+1`. \n \n
+
+\param[in] w
+Pointer to the angular frequency \f$ \omega \f$ (rad/s),
+which used for frequency response \f$ H(j \omega) \f$ calculation. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+The size of the angular frequency vector `w`. \n \n
+
+\param[out] h
+Pointer to the frequency response vector \f$ H(j \omega) \f$,
+corresponds to angular frequency `w`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return `RES_OK` if frequency response vector is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup FILTER_ANALYSIS_GROUP
+\fn int freqs(double* b, double* a, int ord, double* w, int n, complex_t *h)
+
+\brief Расчет комплексного коэффициента передачи
+\f$ H(j \omega) \f$ аналогового фильтра.
+
+Функция рассчитывает значения комплексного коэффициента передачи
+\f$ H(j \omega)\f$ аналогового фильтра, заданного коэффициентами
+передаточной функции \f$ H(s) \f$:
+
+\f[
+ H(s) = \frac {\sum_{k = 0}^{N} b_k s^k}
+ {\sum_{m = 0}^{N} a_m s^m},
+\f]
+где \f$ N \f$ - порядок фильтра (параметр `ord`).
+
+Комплексный коэффициент передачи рассчитывается путем
+подстановки \f$ s = j \omega \f$.
+
+\param[in] b
+Указатель на вектор коэффициентов числителя
+передаточной функции \f$ H(s) \f$. \n
+Размер вектора `[ord+1 x 1]`. \n \n
+
+
+\param[in] a
+Указатель на вектор коэффициентов знаменателя
+передаточной функции \f$ H(s) \f$. \n
+Размер вектора `[ord+1 x 1]`. \n \n
+
+
+\param[in] ord
+Порядок фильтра. Количество коэффициентов числителя и
+знаменателя передаточной функции \f$ H(s) \f$
+равно `ord+1`. \n \n
+
+
+\param[in] w
+Указатель на вектор значений циклической частоты \f$ \omega \f$ (рад/с),
+для которого будет рассчитан комплексный
+коэффициент передачи \f$ H(j \omega) \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+
+\param[in] n
+Размер вектора циклической частоты `w`. \n \n
+
+
+\param[out] h
+Указатель на вектор комплексного коэффициента передачи \f$ H(j \omega) \f$,
+рассчитанного для циклической частоты `w`. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` Комплексный коэффициент передачи рассчитан успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API freqs(double* b, double* a, int ord,
+ double* w, int n, complex_t *h)
+{
+ complex_t jw;
+ complex_t *bc = NULL;
+ complex_t *ac = NULL;
+ complex_t num, den;
+ double mag;
+ int k;
+ int res;
+
+ if(!b || !a || !w || !h)
+ return ERROR_PTR;
+ if(ord<0)
+ return ERROR_FILTER_ORD;
+ if(n<1)
+ return ERROR_SIZE;
+
+ RE(jw) = 0.0;
+
+ bc = (complex_t*) malloc((ord+1) * sizeof(complex_t));
+ res = re2cmplx(b, ord+1, bc);
+
+ if( res!=RES_OK )
+ goto exit_label;
+
+ ac = (complex_t*) malloc((ord+1) * sizeof(complex_t));
+ res = re2cmplx(a, ord+1, ac);
+ if( res!=RES_OK )
+ goto exit_label;
+
+ for(k = 0; k < n; k++)
+ {
+ IM(jw) = w[k];
+ res = polyval_cmplx(bc, ord, &jw, 1, &num);
+ if(res != RES_OK)
+ goto exit_label;
+ res = polyval_cmplx(ac, ord, &jw, 1, &den);
+ if(res != RES_OK)
+ goto exit_label;
+ mag = ABSSQR(den);
+ if(mag == 0.0)
+ {
+ res = ERROR_DIV_ZERO;
+ goto exit_label;
+ }
+ mag = 1.0 / mag;
+ RE(h[k]) = CMCONJRE(num, den) * mag;
+ IM(h[k]) = CMCONJIM(num, den) * mag;
+ }
+ res = RES_OK;
+exit_label:
+ if(bc)
+ free(bc);
+ if(ac)
+ free(ac);
+ return res;
+}
+
+
+
diff --git a/dspl/src/filter_design/freqs2time.c b/dspl/src/filter_design/freqs2time.c
new file mode 100644
index 0000000..bde751a
--- /dev/null
+++ b/dspl/src/filter_design/freqs2time.c
@@ -0,0 +1,92 @@
+/*
+* 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 .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API freqs2time(double* b, double* a, int ord, double fs,
+ int n, fft_t* pfft, double *t, double *h)
+{
+ double *w = NULL;
+ complex_t *hs = NULL;
+ complex_t *ht = NULL;
+ int err, k;
+
+ if(!b || !a || !t || !h)
+ return ERROR_PTR;
+ if(ord<1)
+ return ERROR_FILTER_ORD;
+ if(n<1)
+ return ERROR_SIZE;
+
+ w = (double*)malloc(n*sizeof(double));
+ hs = (complex_t*)malloc(n*sizeof(complex_t));
+
+
+ err = linspace(-fs*0.5, fs*0.5, n, DSPL_PERIODIC, w);
+ if(err != RES_OK)
+ goto exit_label;
+
+ err = freqs(b, a, ord, w, n, hs);
+ if(err != RES_OK)
+ goto exit_label;
+
+ err = fft_shift_cmplx(hs, n, hs);
+ if(err != RES_OK)
+ goto exit_label;
+
+ ht = (complex_t*)malloc(n*sizeof(complex_t));
+
+ err = ifft_cmplx(hs, n, pfft, ht);
+ if(err != RES_OK)
+ {
+ err = idft_cmplx(hs, n, ht);
+ if(err != RES_OK)
+ goto exit_label;
+ }
+
+ for(k = 0; k < n; k++)
+ {
+ t[k] = (double)k/fs;
+ h[k] = RE(ht[k]) * fs;
+ }
+
+exit_label:
+ if(w)
+ free(w);
+ if(hs)
+ free(hs);
+ if(ht)
+ free(ht);
+ return err;
+}
diff --git a/dspl/src/filter_design/freqs_cmplx.c b/dspl/src/filter_design/freqs_cmplx.c
new file mode 100644
index 0000000..bd1a0e5
--- /dev/null
+++ b/dspl/src/filter_design/freqs_cmplx.c
@@ -0,0 +1,93 @@
+/*
+* 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 .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API freqs_cmplx(double* b, double* a, int ord,
+ complex_t* s, int n, complex_t *h)
+{
+ complex_t *bc = NULL;
+ complex_t *ac = NULL;
+ complex_t num, den;
+ double mag;
+ int k;
+ int res;
+
+ if(!b || !a || !s || !h)
+ return ERROR_PTR;
+ if(ord<0)
+ return ERROR_FILTER_ORD;
+ if(n<1)
+ return ERROR_SIZE;
+
+
+ bc = (complex_t*) malloc((ord+1) * sizeof(complex_t));
+ res = re2cmplx(b, ord+1, bc);
+
+ if( res!=RES_OK )
+ goto exit_label;
+
+ ac = (complex_t*) malloc((ord+1) * sizeof(complex_t));
+ res = re2cmplx(a, ord+1, ac);
+ if( res!=RES_OK )
+ goto exit_label;
+
+ for(k = 0; k < n; k++)
+ {
+ res = polyval_cmplx(bc, ord, s+k, 1, &num);
+ if(res != RES_OK)
+ goto exit_label;
+ res = polyval_cmplx(ac, ord, s+k, 1, &den);
+ if(res != RES_OK)
+ goto exit_label;
+ mag = ABSSQR(den);
+ if(mag == 0.0)
+ {
+ res = ERROR_DIV_ZERO;
+ goto exit_label;
+ }
+ mag = 1.0 / mag;
+ RE(h[k]) = CMCONJRE(num, den) * mag;
+ IM(h[k]) = CMCONJIM(num, den) * mag;
+
+ }
+ res = RES_OK;
+ exit_label:
+ if(bc)
+ free(bc);
+ if(ac)
+ free(ac);
+ return res;
+}
diff --git a/dspl/src/filter_design/freqz.c b/dspl/src/filter_design/freqz.c
new file mode 100644
index 0000000..fe0428e
--- /dev/null
+++ b/dspl/src/filter_design/freqz.c
@@ -0,0 +1,229 @@
+/*
+* 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 .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup FILTER_ANALYSIS_GROUP
+\fn int freqz(double* b, double* a, int ord, double* w, int n, complex_t *h)
+
+\brief Function calculates the digital filter frequency response
+\f$ H \left(e^{j \omega} \right)\f$ corresponds to transfer function \f$H(z)\f$.
+
+Digital filter transfer function:
+\f[
+H(z) = \frac{\sum\limits_{k = 0}^{N} b_k z^{-k}}
+ {\sum\limits_{m = 0}^{N} a_m z^{-m}},
+\f]
+here \f$N\f$ --- filter order (parameter `ord`). \n
+
+Frequency response \f$ H \left(e^{j \omega} \right)\f$ we can get
+if substitute \f$z = e^{j \omega} \f$. \n
+
+\param[in] b
+Pointer to the \f$ H(z) \f$ transfer function
+numerator coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n \n
+
+\param[in] a
+Pointer to the \f$H(z)\f$ transfer function
+denominator coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n \n
+
+\param[in] ord
+Filter order. \n
+Transfer function \f$H(z)\f$ numerator
+and denominator coefficients number equals `ord+1`. \n \n
+
+\param[in] w
+Pointer to the normalized frequency of digital filter
+frequency response \f$ H \left(\mathrm{e}^{j\omega} \right) \f$. \n
+Digital filter frequency response is \f$ 2\pi \f$-periodic function,
+and vector `w` advisable to set from 0 to \f$ \pi \f$,
+or from 0 to \f$ 2\pi \f$, or from \f$ -\pi \f$ to \f$ \pi \f$.
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of frequency vector `w`. \n \n
+
+\param[out] h
+Pointer to the frequency response vector
+\f$ H \left(\mathrm{e}^{j\omega} \right) \f$,
+corresponds to normalized frequency `w`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return `RES_OK` if frequency response vector is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup FILTER_ANALYSIS_GROUP
+\fn int freqz(double* b, double* a, int ord, double* w, int n, complex_t *h)
+
+\brief Расчет комплексного коэффициента передачи
+ \f$ H \left(e^{j \omega} \right)\f$ цифрового фильтра.
+
+Функция рассчитывает значения комплексного коэффициента передачи
+\f$ H \left(e^{j \omega} \right)\f$ цифрового фильтра, заданного
+коэффициентами передаточной функции \f$H(z)\f$:
+
+\f[
+H(z) = \frac {\sum_{k = 0}^{N} b_k z^{-k}}
+ {\sum_{m = 0}^{N} a_m z^{-m}},
+\f]
+
+где \f$N\f$ --- порядок фильтра (параметр `ord`). \n
+
+Комплексный коэффициент передачи рассчитывается путем
+подстановки \f$z = e^{j \omega} \f$. \n
+
+\param[in] b
+Указатель на вектор коэффициентов числителя
+передаточной функции \f$H(z)\f$. \n
+Размер вектора `[ord+1 x 1]`. \n \n
+
+\param[in] a
+Указатель на вектор коэффициентов знаменателя
+передаточной функции \f$H(z)\f$. \n
+Размер вектора `[ord+1 x 1]`. \n \n
+
+\param[in] ord
+Порядок фильтра. Количество коэффициентов числителя и знаменателя
+передаточной функции \f$H(z)\f$ равно `ord+1`. \n \n
+
+\param[in] w
+Указатель на вектор значений нормированной циклической частоты \f$\omega\f$,
+для которого будет рассчитан комплексный коэффициент передачи
+\f$ H \left(e^{j \omega} \right)\f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер вектора нормированной циклической частоты `w`. \n \n
+
+\param[out] h
+Указатель на вектор комплексного коэффициента передачи
+\f$ H \left(e^{j \omega} \right)\f$, рассчитанного для
+циклической частоты `w`. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` Комплексный коэффициент передачи рассчитан успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\note
+Комплексный коэффициент передачи \f$ H \left(e^{j \omega} \right)\f$
+цифрового фильтра представляет собой \f$ 2 \pi-\f$периодическую функцию
+нормированной циклической частоты \f$\omega\f$.
+Поэтому анализ цифровых фильтров целесообразно вести на одном периоде
+повторения \f$ H \left(e^{j \omega} \right)\f$, т.е. в интервале
+\f$\omega\f$ от 0 до \f$2 \pi\f$, или от \f$-\pi\f$ до \f$ \pi\f$. \n
+Кроме того известно, что для фильтра с вещественными коэффициентами
+\f$ H \left(e^{j \omega} \right) = H^* \left(e^{-j \omega} \right)\f$,
+а значит, анализ цифрового фильтра с вещественными коэффициентами
+достаточно вести для нормированной частоты \f$\omega\f$ от 0 до \f$\pi\f$.
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API freqz(double* b, double* a, int ord, double* w,
+ int n, complex_t *h)
+{
+ complex_t jw;
+ complex_t *bc = NULL;
+ complex_t *ac = NULL;
+ complex_t num, den;
+ double mag;
+ int k;
+ int res;
+
+ if(!b || !w || !h)
+ return ERROR_PTR;
+ if(ord<0)
+ return ERROR_FILTER_ORD;
+ if(n<1)
+ return ERROR_SIZE;
+
+
+ bc = (complex_t*) malloc((ord+1) * sizeof(complex_t));
+ res = re2cmplx(b, ord+1, bc);
+ if( res!=RES_OK )
+ goto exit_label;
+
+ if(a)
+ {
+ /* IIR filter if a != NULL */
+ ac = (complex_t*) malloc((ord+1) * sizeof(complex_t));
+ res = re2cmplx(a, ord+1, ac);
+ if( res!=RES_OK )
+ goto exit_label;
+ for(k = 0; k < n; k++)
+ {
+ RE(jw) = cos(w[k]);
+ IM(jw) = -sin(w[k]);
+ res = polyval_cmplx(bc, ord, &jw, 1, &num);
+ if(res != RES_OK)
+ goto exit_label;
+ res = polyval_cmplx(ac, ord, &jw, 1, &den);
+ if(res != RES_OK)
+ goto exit_label;
+ mag = ABSSQR(den);
+ if(mag == 0.0)
+ {
+ res = ERROR_DIV_ZERO;
+ goto exit_label;
+ }
+ mag = 1.0 / mag;
+ RE(h[k]) = CMCONJRE(num, den) * mag;
+ IM(h[k]) = CMCONJIM(num, den) * mag;
+ }
+ }
+ else
+ {
+ /* FIR filter if a == NULL */
+ for(k = 0; k < n; k++)
+ {
+ RE(jw) = cos(w[k]);
+ IM(jw) = -sin(w[k]);
+ res = polyval_cmplx(bc, ord, &jw, 1, h+k);
+ if(res != RES_OK)
+ goto exit_label;
+ }
+ }
+ res = RES_OK;
+exit_label:
+ if(bc)
+ free(bc);
+ if(ac)
+ free(ac);
+ return res;
+}
+
diff --git a/dspl/src/filter_design/group_delay.c b/dspl/src/filter_design/group_delay.c
new file mode 100644
index 0000000..92373b9
--- /dev/null
+++ b/dspl/src/filter_design/group_delay.c
@@ -0,0 +1,252 @@
+/*
+* 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 .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup FILTER_ANALYSIS_GROUP
+\fn int DSPL_API group_delay(double* b, double* a, int ord, int flag,
+ double* w, int n, double* tau)
+
+\brief
+Group delay calculation for digital or analog filter corresponds to
+\f$H(s)\f$, or \f$H(z)\f$ transfer function.
+
+Group delay is describes as:
+\f[
+\tau_g(\omega) = - \frac{d\Phi(\omega)}{d\omega},
+\f]
+here \f$\Phi(\omega)\f$ -- filter phase response, \f$\omega\f$ is angular
+frequency for analog filter, or normalized frequency for digital filter.
+
+\param[in] b
+Pointer to the \f$ H(s) \f$ or \f$H(z)\f$ transfer function
+numerator coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n \n
+
+\param[in] a
+Pointer to the \f$ H(s) \f$ or \f$H(z)\f$ transfer function
+denominator coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n \n
+
+\param[in] ord
+Filter order. \n
+Transfer function \f$ H(s) \f$ or \f$H(z)\f$ numerator
+and denominator coefficients number equals `ord+1`. \n \n
+
+\param[in] flag
+Binary flags to set calculation rules: \n
+\verbatim
+DSPL_FLAG_ANALOG Coefficients corresponds to analog filter
+DSPL_FLAG_DIGITAL Coefficients corresponds to digital filter
+\endverbatim
+\n \n
+
+\param[in] w
+Pointer to the angular frequency \f$ \omega \f$ (rad/s),
+which used for analog filter characteristics calculation
+(flag sets as `DSPL_FLAG_ANALOG`). \n
+For digital filter (flag sets as `DSPL_FLAG_DIGITAL`),
+ parameter `w` describes normalized frequency of
+frequency response \f$ H \left(\mathrm{e}^{j\omega} \right) \f$.
+Digital filter frequency response is \f$ 2\pi \f$-periodic function,
+and vector `w` advisable to set from 0 to \f$ \pi \f$,
+or from 0 to \f$ 2\pi \f$, or from \f$ -\pi \f$ to \f$ \pi \f$.
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of frequency vector `w`. \n \n
+
+\param[out] tau
+Pointer to the group delay vector. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+\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 FILTER_ANALYSIS_GROUP
+\fn int DSPL_API group_delay(double* b, double* a, int ord, int flag,
+ double* w, int n, double* tau)
+\brief
+Расчет группового времени запаздывания цифрового или аналогового фильтра.
+
+Групповое время запаздывания определяется как:
+\f[
+\tau_g(\omega) = - \frac{d\Phi(\omega)}{d\omega},
+\f]
+где \f$\Phi(\omega)\f$ -- ФЧХ фильтра, \f$\omega\f$ циктическая частот в случае
+аналогового фильтра, или нормированная частота цифрового фильтра.
+
+\param[in] b
+Указатель на вектор коэффициентов числителя передаточной функции
+аналогового фильтра \f$ H(s) \f$ или цифрового фильтра \f$ H(z) \f$. \n
+Размер вектора `[ord+1 x 1]`. \n \n
+
+\param[in] a
+Указатель на вектор коэффициентов числителя передаточной функции
+аналогового фильтра \f$ H(s) \f$ или цифрового фильтра \f$ H(z) \f$. \n
+Размер вектора `[ord+1 x 1]`. \n
+Параметр может быть `NULL`. В этом случае расчет производится для цифрового
+КИХ-фильтра с коэффициентами, заданными вектором `b`. \n\n
+
+\param[in] ord
+Порядок фильтра. Количество коэффициентов
+числителя и знаменателя передаточной
+функции \f$ H(s) \f$ или \f$ H(z) \f$ равно `ord+1`. \n \n
+
+\param[in] flag
+Флаг который задает тип фильтра: \n
+\verbatim
+DSPL_FLAG_ANALOG Коэффициенты относятся к аналоговому фильтру
+DSPL_FLAG_DIGITAL Коэффициенты относятся к цифровому фильтру
+\endverbatim
+
+\param[in] w
+Указатель на вектор значений циклической частоты \f$ \omega \f$ (рад/с),
+для которого будет рассчитаны АЧХ, ФЧХ и ГВЗ аналогового фильтра,
+если установлен флаг `DSPL_FLAG_ANALOG`. \n
+В случае если флаг `DSPL_FLAG_ANALOG` не установлен, то вектор частоты `w`
+используется как нормированная частота комплексного коэффициента передачи
+\f$ H \left(\mathrm{e}^{j\omega} \right) \f$ цифрового фильтра. \n
+В этом случае характеристика цифрового фильтра является
+\f$ 2\pi \f$-периодической, и вектор частоты может содержать
+произвольные значения, однако целесообразно задавать
+его от 0 до \f$ \pi \f$, а такжет от 0 до \f$ 2\pi \f$, или
+от \f$ -\pi \f$ до \f$ \pi \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер вектора циклической частоты `w`. \n \n
+
+\param[out] tau
+Указатель на вектор групповой задержки. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n
+
+\return
+`RES_OK` групповая задержка фильтра рассчитана успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API group_delay(double* pb, double* pa, int ord, int flag,
+ double* w, int n, double* tau)
+{
+ double a, b, c, d, da, db, dc, dd, f, e;
+ int t, m;
+
+ double *qa = NULL;
+
+ if(!pb || !w || !tau || (!pa && (flag & DSPL_FLAG_ANALOG)))
+ return ERROR_PTR;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(n < 1)
+ return ERROR_SIZE;
+
+
+ if(pa)
+ qa = pa;
+ else
+ {
+ qa = (double*)malloc((ord+1) * sizeof(double));
+ memset(qa, 0, (ord+1) * sizeof(double));
+ qa[0] = 1.0;
+ }
+
+ for(t = 0; t < n; t++)
+ {
+ a = b = c = d = da = db = dc = dd = 0.0;
+ if(flag & DSPL_FLAG_ANALOG)
+ {
+ for(m = 0; m < ord+1; m+=4)
+ {
+ a += pb[m] * pow(w[t], (double)m);
+ c += qa[m] * pow(w[t], (double)m);
+ da += pb[m] * (double) m * pow(w[t], (double)(m-1));
+ dc += qa[m] * (double) m * pow(w[t], (double)(m-1));
+ }
+ for(m = 2; m < ord+1; m+=4)
+ {
+ a -= pb[m] * pow(w[t], (double)m);
+ c -= qa[m] * pow(w[t], (double)m);
+ da -= pb[m] * (double) m * pow(w[t], (double)(m-1));
+ dc -= qa[m] * (double) m * pow(w[t], (double)(m-1));
+ }
+
+ for(m = 1; m < ord+1; m+=4)
+ {
+ b += pb[m] * pow(w[t], (double)m) ;
+ d += qa[m] * pow(w[t], (double)m) ;
+ db += pb[m] * (double) m * pow(w[t], (double)(m-1)) ;
+ dd += qa[m] * (double) m * pow(w[t], (double)(m-1)) ;
+ }
+
+ for(m = 3; m < ord+1; m+=4)
+ {
+ b -= pb[m] * pow(w[t], (double)m) ;
+ d -= qa[m] * pow(w[t], (double)m) ;
+ db -= pb[m] * (double) m * pow(w[t], (double)(m-1)) ;
+ dd -= qa[m] * (double) m * pow(w[t], (double)(m-1)) ;
+ }
+
+ }
+ else
+ {
+ for(m = 0; m < ord+1; m++)
+ {
+ a += pb[m] * cos(w[t]*(double)m);
+ b -= pb[m] * sin(w[t]*(double)m);
+ c += qa[m] * cos(w[t]*(double)m);
+ d -= qa[m] * sin(w[t]*(double)m);
+
+ da -= pb[m] *(double)m * sin(w[t]*(double)m);
+ db -= pb[m] *(double)m * cos(w[t]*(double)m);
+ dc -= qa[m] *(double)m * sin(w[t]*(double)m);
+ dd -= qa[m] *(double)m * cos(w[t]*(double)m);
+ }
+ }
+
+ f = da * c + a * dc + db * d + b * dd;
+ e = db * c + b * dc - da * d - a * dd;
+ tau[t] = (f * (b * c - a * d) - e * (a * c + b * d)) /
+ ((a * a + b * b) * (c * c + d * d));
+ }
+
+ if(qa != pa)
+ free(qa);
+
+ return RES_OK;
+}
diff --git a/dspl/src/filter_iir.c b/dspl/src/filter_design/iir.c
similarity index 57%
rename from dspl/src/filter_iir.c
rename to dspl/src/filter_design/iir.c
index e1c4dc5..be1bb7d 100644
--- a/dspl/src/filter_iir.c
+++ b/dspl/src/filter_design/iir.c
@@ -1,538 +1,310 @@
-/*
-* 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 .
-*/
-
-#include
-#include
-#include
-#include "dspl.h"
-#include "dspl_internal.h"
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int bilinear(double* bs, double* as, int ord, double* bz, double* az)
-
-\brief
-Transform a s-plane analog filter transfer function \f$H(s)\f$ to the
-digital filter transfer function \f$H(z)\f$.
-
-Bilinear transform is rational composition:
-
-\f[
-s \leftarrow \frac{1 - z^{-1}}{1 - z^{-1}}.
-\f]
-
-Digital filter order, passband magnitude ripple and stopband suppression
-still the same after bilinear transform as analog filter.
-
-Frequency \f$\Omega\f$ of analog filter and frequency
-\f$\omega\f$ of digital filter relations:
-
-\f[
-\Omega = \tan(\omega / 2).
-\f]
-
-
-\param[in] bs
-Pointer to the vector of analog filter \f$H(s)\f$
-numerator coefficients.
-Vector size is `[ord+1 x 1]`. \n
-\n
-
-\param[in] as
-Pointer to the vector of analog filter \f$H(s)\f$
-denominator coefficients vector.
-Vector size is `[ord+1 x 1]`. \n
-\n
-
-\param[in] ord
-Analog and digital filters order. \n
-\n
-
-\param[out] bz
-Pointer to the vector of digital filter \f$H(z)\f$
-numerator coefficients after bilinear transform.
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\param[out] az
-Pointer to the vector of digital filter \f$H(z)\f$
-denominator coefficients after bilinear transform.
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\return
-`RES_OK` if bilinear transform is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-
-Example:
-
-\include bilinear_test.c
-
-This program calculates the transfer function \f$H(s)\f$ of analog
-Chebyshev filter of the first kind, with a cutoff frequency of 1 rad/s,
-and produces bilinear trandform to digital filter,
-with a normilized cutoff frequency equals 0.5.
-
-Result:
-
-\verbatim
-bz[0] = 0.246 az[0] = 4.425
-bz[1] = 0.983 az[1] = -3.318
-bz[2] = 1.474 az[2] = 4.746
-bz[3] = 0.983 az[3] = -2.477
-bz[4] = 0.246 az[4] = 1.034
-err = 0
-\endverbatim
-
-In addition, the frequency response of the resulting digital filter
-is calculated and plotted by GNUPLOT package.
-
-\image html bilinear.png
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int bilinear(double* bs, double* as, int ord, double* bz, double* az)
-
-\brief
-Билинейное преобразование передаточной характеристики аналогового
-фильтра \f$H(s)\f$, в передаточную характеристику цифрового фильтра \f$H(z)\f$.
-
-Функция рассчитывает коэффициенты передаточной характеристики \f$H(z)\f$
-цифрового фильтра путем дробно-рациональной подстановки вида
-
-\f[
-s \leftarrow \frac{1 - z^{-1}}{1 - z^{-1}}.
-\f]
-
-Порядок цифрового фильтра при этом остается равным порядку аналогового фильтра,
-а ось частот \f$\Omega\f$ аналогового фильтра связана c осью частот
-\f$\omega\f$ цифрового фильтра соотношением:
-
-\f[
-\Omega = \tan(\omega / 2).
-\f]
-
-
-
-\param[in] bs
-Указатель на вектор коэффициентов числителя передаточной функции \f$H(s)\f$
-исходного аналогового фильтра. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in] as
-Указатель на вектор коэффициентов знаменателя передаточной функции \f$H(s)\f$
-исходного аналогового фильтра. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in] ord
-Порядок фильтра. \n
-Количество коэффициентов числителя и знаменателя передаточных функций
-\f$H(s)\f$ и \f$H(z)\f$ аналогового и цифрового фильтров равно `ord+1`. \n
-\n
-
-\param[out] bz
-Указатель на вектор коэффициентов числителя передаточной функции \f$H(z)\f$
-полученного цифрового фильтра. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] az
-Указатель на вектор коэффициентов знаменателя передаточной функции \f$H(z)\f$
-полученного цифрового фильтра. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\return
-`RES_OK` --- фильтр рассчитан успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-
-Пример использования функции `bilinear`:
-
-\include bilinear_test.c
-
-Данная программа производит расчет передаточной характеристики аналогового
-фильтра Чебышева первого рода, с частотой среза равной 1 рад/с, и производит
-билинейное преобразование в цифровой, с частотой среза равной 0.5.
-
-Результат работы программы:
-
-\verbatim
-bz[0] = 0.246 az[0] = 4.425
-bz[1] = 0.983 az[1] = -3.318
-bz[2] = 1.474 az[2] = 4.746
-bz[3] = 0.983 az[3] = -2.477
-bz[4] = 0.246 az[4] = 1.034
-err = 0
-\endverbatim
-
-Кроме этого производится расчет АЧХ полученного цифрового фильтра и строится
-график АЧХ пакетом GNUPLOT
-
-\image html bilinear.png
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API bilinear(double* bs, double* as, int ord, double* bz, double* az)
-{
- double c[2] = {1.0, -1.0};
- double d[2] = {1.0, 1.0};
- return ratcompos(bs, as, ord, c, d, 1, bz, az);
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int iir(double rp, double rs, int ord, double w0, double w1,
- int type, double* b, double* a)
-\brief
-Digital IIR filter design.
-
-The function calculates the coefficients of the digital IIR filter
-transfer fucntion \f$ H(z) \f$.
-Filter coeffitients can be used in \ref filter_iir function
-
-\param[in] rp
-Magnitude ripple in passband (dB). \n
-\n
-
-
-\param[in] rs
-Suppression level in stopband (dB). \n
-\n
-
-\param[in] ord
-Filter order. \n
-Number of \f$H(z)\f$ numerator and denominator coefficients is `ord+1`. \n
-For bandpass and bandstop filters `ord` must be even. \n
-\n
-
-\param[in] w0
-Normalized cutoff frequency (from 0 to 1) for lowpass or highpass filter. \n
-Or left normalized cutoff frequency (from 0 to 1) for
-bandpass and bandstop filter. \n
-\n
-
-
-\param[in] w1
-Right normalized cutoff frequency (from 0 to 1) for
-bandpass and bandstop filter. \n
-This parameter is ingnored for lowpass and highpass filters.
-\n
-
-\param[in] type
-Filter type. \n
-This patameter sets combination of filter type (one of follow): \n
-\verbatim
-DSPL_FILTER_LPF - lowpass filter;
-DSPL_FILTER_HPF - highpass filter;
-DSPL_FILTER_BPASS - bandpass filter;
-DSPL_FILTER_BSTOP - bandstop filter,
-\endverbatim
-and of filter approximation type (one of follow):
-\verbatim
-DSPL_FILTER_BUTTER - Butterworth filter;
-DSPL_FILTER_CHEBY1 - Chebyshev of the first kind filter;
-DSPL_FILTER_CHEBY2 - Chebyshev of the second kind filter;
-DSPL_FILTER_ELLIP - Elliptic filter.
-\endverbatim
-\n
-\n
-
-\param[out] b
-Pointer to the transfer function \f$H(z)\f$
-numerator coefficients vector. \n
-Vector size is `ord+1`. \n
-Memory must be allocated. \n
-\n
-
-\param[out] a
-Pointer to the transfer function \f$H(z)\f$
-denominator coefficients vector. \n
-Vector size is `ord+1`. \n
-\n
-
-\return
-`RES_OK` if filter is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-Example:
-
-\include iir_test.c
-
-This program calcultes filter coefficients for different flags `type`.
-
-In addition, the filters magnitudes
-is calculated and plotted by GNUPLOT package.
-
-\image html iir_test.png
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int iir(double rp, double rs, int ord, double w0, double w1,
- int type, double* b, double* a)
-\brief
-Функция расчета коэффициентов передаточной характеристики \f$H(z)\f$
-цифрового фильтра БИХ.
-
-Функция рассчитывает коэффициенты передаточной характеристики \f$H(z)\f$
-цифрового фильтра, которые могут быть использованы в функции \ref filter_iir
-
-\param[in] rp
-Уровень неравномерности квадрата АЧХ в полосе пропускания фильтра (дБ). \n
-Размер вектора `[ord+1 x 1]`. \n
-\n
-
-
-\param[in] rs
-Уровень подавления в полосе заграждения фильтра (дБ).\n
-\n
-
-\param[in] ord
-Порядок фильтра. \n
-Количество коэффициентов числителя и знаменателя передаточной
-функции \f$H(z)\f$ цифрового фильтров равно `ord+1`. \n
-Для полосовых и режекторных фильтров параметр `ord` должен быть чётным. \n
-\n
-
-\param[in] w0
-Нормированная частота среза ФНЧ или ФВЧ, или левая частота среза для
-полосового и режекторного фильтра.\n
-\n
-
-
-\param[in] w1
-Правая частота среза полосового и режекторного фильтра. \n
-Данный параметр игнорируется для ФНЧ и ФВЧ. \n
-\n
-
-\param[in] type
-Тип фильтра. \n
-Данный параметр определяет тип фильтра и образуется
-набором флагов типа фильтра: \n
-\verbatim
-DSPL_FILTER_LPF - фильтр нижних частот;
-DSPL_FILTER_HPF - фильтр верхних частот;
-DSPL_FILTER_BPASS - полосовой фильтр;
-DSPL_FILTER_BSTOP - режекторный фильтр,
-\endverbatim
-а также флагов типа аппроксимации АЧХ фильтра:
-\verbatim
-DSPL_FILTER_BUTTER - фильтр Баттерворта;
-DSPL_FILTER_CHEBY1 - фильтр Чебышева первого рода;
-DSPL_FILTER_CHEBY2 - фильтр Чебышева второго рода;
-DSPL_FILTER_ELLIP - эллиптический фильтр.
-\endverbatim
-\n
-\n
-
-\param[out] b
-Указатель на вектор коэффициентов
-числителя передаточной функции \f$H(z)\f$. \n
-Размер вектора `ord+1`. \n
-Память должна быть выделена. \n
-\n
-
-\param[out] a
-Указатель на вектор коэффициентов знаменателя передаточной
-функции \f$H(z)\f$. \n
-Размер вектора `ord+1`. \n
-Память должна быть выделена. \n
-\n
-
-\return
-`RES_OK` --- Фильтр рассчитан успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-Пример использования функции:
-
-\include iir_test.c
-
-Данная программа производит расчет коэффициентов фильтров
-при различном сочетании флагов параметра `type`.
-
-Кроме этого производится расчет АЧХ полученных цифровых фильтров и выводится на
-график АЧХ пакетом GNUPLOT
-
-\image html iir_test.png
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API iir(double rp, double rs, int ord, double w0, double w1,
- int type, double* b, double* a)
-{
- double *bs = NULL;
- double *as = NULL;
- double *bt = NULL;
- double *at = NULL;
- double wa0, wa1, ws;
- int err, ord_ap = ord;
- int i;
-
- if(((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_LPF) ||
- ((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_HPF))
- {
- bs = (double*)malloc((ord_ap+1)*sizeof(double));
- as = (double*)malloc((ord_ap+1)*sizeof(double));
- bt = (double*)malloc((ord_ap+1)*sizeof(double));
- at = (double*)malloc((ord_ap+1)*sizeof(double));
- }
-
-
- if(((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_BPASS) ||
- ((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_BSTOP))
- {
- if(ord % 2)
- return ERROR_FILTER_ORD_BP;
- else
- {
- ord_ap = ord / 2;
- bs = (double*)malloc((ord_ap + 1)*sizeof(double));
- as = (double*)malloc((ord_ap + 1)*sizeof(double));
- bt = (double*)malloc((ord + 1)*sizeof(double));
- at = (double*)malloc((ord + 1)*sizeof(double));
- }
- }
- err = iir_ap(rp, rs, ord_ap, type, bs, as);
- if(err != RES_OK)
- goto error_proc;
-
- /* frequency transformation */
- wa0 = tan(w0 * M_PI * 0.5);
- wa1 = tan(w1 * M_PI * 0.5);
-
- switch(type & DSPL_FILTER_TYPE_MASK)
- {
-
- case DSPL_FILTER_LPF:
- err = low2low(bs, as, ord_ap, 1.0, wa0, bt, at);
- break;
-
- case DSPL_FILTER_HPF:
- ws = filter_ws1(ord_ap, rp, rs, type);
- err = low2low( bs, as, ord_ap, 1.0, 1.0 / ws, bs, as);
- err = low2high(bs, as, ord_ap, 1.0, wa0, bt, at);
- break;
-
- case DSPL_FILTER_BPASS:
- err = low2bp(bs, as, ord_ap, 1.0, wa0, wa1, bt, at);
- break;
-
- case DSPL_FILTER_BSTOP:
- /* need frequency transform ws -> 1 rad/s */
-
- ws = filter_ws1(ord_ap, rp, rs, type);
- err = low2low( bs, as, ord_ap, 1.0, 1.0 / ws, bs, as);
- err = low2bs(bs, as, ord_ap, 1.0, wa0, wa1, bt, at);
- break;
-
- default:
- err = ERROR_FILTER_TYPE;
- break;
- }
- if(err != RES_OK)
- goto error_proc;
-
-
- err = bilinear(bt, at, ord, b, a);
-
- for(i = 1; i <= ord; i++)
- {
- a[i] /= a[0];
- b[i] /= a[0];
- }
- b[0] /= a[0];
- a[0] = 1.0;
-
-error_proc:
-
- if(bs)
- free(bs);
- if(as)
- free(as);
- if(bt)
- free(bt);
- if(at)
- free(at);
-
- return err;
-
-}
-
-
-
-
-
-
-/******************************************************************************
-Analog prototype for IIR
-*******************************************************************************/
-int iir_ap(double rp, double rs, int ord, int type, double* b, double* a)
-{
- int err;
- switch(type & DSPL_FILTER_APPROX_MASK)
- {
- case DSPL_FILTER_BUTTER:
- err = butter_ap(rp, ord, b, a);
- break;
- case DSPL_FILTER_CHEBY1:
- err = cheby1_ap(rp, ord, b, a);
- break;
- case DSPL_FILTER_CHEBY2:
- err = cheby2_ap_wp1(rp, rs, ord, b, a);
- break;
- case DSPL_FILTER_ELLIP:
- err = ellip_ap(rp, rs, ord, b, a);
- break;
- default:
- err = ERROR_FILTER_APPROX;
- }
- return err;
-}
-
-
-
-
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int iir(double rp, double rs, int ord, double w0, double w1,
+ int type, double* b, double* a)
+\brief
+Digital IIR filter design.
+
+The function calculates the coefficients of the digital IIR filter
+transfer fucntion \f$ H(z) \f$.
+Filter coeffitients can be used in \ref filter_iir function
+
+\param[in] rp
+Magnitude ripple in passband (dB). \n
+\n
+
+
+\param[in] rs
+Suppression level in stopband (dB). \n
+\n
+
+\param[in] ord
+Filter order. \n
+Number of \f$H(z)\f$ numerator and denominator coefficients is `ord+1`. \n
+For bandpass and bandstop filters `ord` must be even. \n
+\n
+
+\param[in] w0
+Normalized cutoff frequency (from 0 to 1) for lowpass or highpass filter. \n
+Or left normalized cutoff frequency (from 0 to 1) for
+bandpass and bandstop filter. \n
+\n
+
+
+\param[in] w1
+Right normalized cutoff frequency (from 0 to 1) for
+bandpass and bandstop filter. \n
+This parameter is ingnored for lowpass and highpass filters.
+\n
+
+\param[in] type
+Filter type. \n
+This patameter sets combination of filter type (one of follow): \n
+\verbatim
+DSPL_FILTER_LPF - lowpass filter;
+DSPL_FILTER_HPF - highpass filter;
+DSPL_FILTER_BPASS - bandpass filter;
+DSPL_FILTER_BSTOP - bandstop filter,
+\endverbatim
+and of filter approximation type (one of follow):
+\verbatim
+DSPL_FILTER_BUTTER - Butterworth filter;
+DSPL_FILTER_CHEBY1 - Chebyshev of the first kind filter;
+DSPL_FILTER_CHEBY2 - Chebyshev of the second kind filter;
+DSPL_FILTER_ELLIP - Elliptic filter.
+\endverbatim
+\n
+\n
+
+\param[out] b
+Pointer to the transfer function \f$H(z)\f$
+numerator coefficients vector. \n
+Vector size is `ord+1`. \n
+Memory must be allocated. \n
+\n
+
+\param[out] a
+Pointer to the transfer function \f$H(z)\f$
+denominator coefficients vector. \n
+Vector size is `ord+1`. \n
+\n
+
+\return
+`RES_OK` if filter is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+Example:
+
+\include iir_test.c
+
+This program calcultes filter coefficients for different flags `type`.
+
+In addition, the filters magnitudes
+is calculated and plotted by GNUPLOT package.
+
+\image html iir_test.png
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int iir(double rp, double rs, int ord, double w0, double w1,
+ int type, double* b, double* a)
+\brief
+Функция расчета коэффициентов передаточной характеристики \f$H(z)\f$
+цифрового фильтра БИХ.
+
+Функция рассчитывает коэффициенты передаточной характеристики \f$H(z)\f$
+цифрового фильтра, которые могут быть использованы в функции \ref filter_iir
+
+\param[in] rp
+Уровень неравномерности квадрата АЧХ в полосе пропускания фильтра (дБ). \n
+Размер вектора `[ord+1 x 1]`. \n
+\n
+
+
+\param[in] rs
+Уровень подавления в полосе заграждения фильтра (дБ).\n
+\n
+
+\param[in] ord
+Порядок фильтра. \n
+Количество коэффициентов числителя и знаменателя передаточной
+функции \f$H(z)\f$ цифрового фильтров равно `ord+1`. \n
+Для полосовых и режекторных фильтров параметр `ord` должен быть чётным. \n
+\n
+
+\param[in] w0
+Нормированная частота среза ФНЧ или ФВЧ, или левая частота среза для
+полосового и режекторного фильтра.\n
+\n
+
+
+\param[in] w1
+Правая частота среза полосового и режекторного фильтра. \n
+Данный параметр игнорируется для ФНЧ и ФВЧ. \n
+\n
+
+\param[in] type
+Тип фильтра. \n
+Данный параметр определяет тип фильтра и образуется
+набором флагов типа фильтра: \n
+\verbatim
+DSPL_FILTER_LPF - фильтр нижних частот;
+DSPL_FILTER_HPF - фильтр верхних частот;
+DSPL_FILTER_BPASS - полосовой фильтр;
+DSPL_FILTER_BSTOP - режекторный фильтр,
+\endverbatim
+а также флагов типа аппроксимации АЧХ фильтра:
+\verbatim
+DSPL_FILTER_BUTTER - фильтр Баттерворта;
+DSPL_FILTER_CHEBY1 - фильтр Чебышева первого рода;
+DSPL_FILTER_CHEBY2 - фильтр Чебышева второго рода;
+DSPL_FILTER_ELLIP - эллиптический фильтр.
+\endverbatim
+\n
+\n
+
+\param[out] b
+Указатель на вектор коэффициентов
+числителя передаточной функции \f$H(z)\f$. \n
+Размер вектора `ord+1`. \n
+Память должна быть выделена. \n
+\n
+
+\param[out] a
+Указатель на вектор коэффициентов знаменателя передаточной
+функции \f$H(z)\f$. \n
+Размер вектора `ord+1`. \n
+Память должна быть выделена. \n
+\n
+
+\return
+`RES_OK` --- Фильтр рассчитан успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+Пример использования функции:
+
+\include iir_test.c
+
+Данная программа производит расчет коэффициентов фильтров
+при различном сочетании флагов параметра `type`.
+
+Кроме этого производится расчет АЧХ полученных цифровых фильтров и выводится на
+график АЧХ пакетом GNUPLOT
+
+\image html iir_test.png
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API iir(double rp, double rs, int ord, double w0, double w1,
+ int type, double* b, double* a)
+{
+ double *bs = NULL;
+ double *as = NULL;
+ double *bt = NULL;
+ double *at = NULL;
+ double wa0, wa1, ws;
+ int err, ord_ap = ord;
+ int i;
+
+ if(((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_LPF) ||
+ ((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_HPF))
+ {
+ bs = (double*)malloc((ord_ap+1)*sizeof(double));
+ as = (double*)malloc((ord_ap+1)*sizeof(double));
+ bt = (double*)malloc((ord_ap+1)*sizeof(double));
+ at = (double*)malloc((ord_ap+1)*sizeof(double));
+ }
+
+
+ if(((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_BPASS) ||
+ ((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_BSTOP))
+ {
+ if(ord % 2)
+ return ERROR_FILTER_ORD_BP;
+ else
+ {
+ ord_ap = ord / 2;
+ bs = (double*)malloc((ord_ap + 1)*sizeof(double));
+ as = (double*)malloc((ord_ap + 1)*sizeof(double));
+ bt = (double*)malloc((ord + 1)*sizeof(double));
+ at = (double*)malloc((ord + 1)*sizeof(double));
+ }
+ }
+ err = iir_ap(rp, rs, ord_ap, type, bs, as);
+ if(err != RES_OK)
+ goto error_proc;
+
+ /* frequency transformation */
+ wa0 = tan(w0 * M_PI * 0.5);
+ wa1 = tan(w1 * M_PI * 0.5);
+
+ switch(type & DSPL_FILTER_TYPE_MASK)
+ {
+
+ case DSPL_FILTER_LPF:
+ err = low2low(bs, as, ord_ap, 1.0, wa0, bt, at);
+ break;
+
+ case DSPL_FILTER_HPF:
+ ws = filter_ws1(ord_ap, rp, rs, type);
+ err = low2low( bs, as, ord_ap, 1.0, 1.0 / ws, bs, as);
+ err = low2high(bs, as, ord_ap, 1.0, wa0, bt, at);
+ break;
+
+ case DSPL_FILTER_BPASS:
+ err = low2bp(bs, as, ord_ap, 1.0, wa0, wa1, bt, at);
+ break;
+
+ case DSPL_FILTER_BSTOP:
+ /* need frequency transform ws -> 1 rad/s */
+
+ ws = filter_ws1(ord_ap, rp, rs, type);
+ err = low2low( bs, as, ord_ap, 1.0, 1.0 / ws, bs, as);
+ err = low2bs(bs, as, ord_ap, 1.0, wa0, wa1, bt, at);
+ break;
+
+ default:
+ err = ERROR_FILTER_TYPE;
+ break;
+ }
+ if(err != RES_OK)
+ goto error_proc;
+
+
+ err = bilinear(bt, at, ord, b, a);
+
+ for(i = 1; i <= ord; i++)
+ {
+ a[i] /= a[0];
+ b[i] /= a[0];
+ }
+ b[0] /= a[0];
+ a[0] = 1.0;
+
+error_proc:
+
+ if(bs)
+ free(bs);
+ if(as)
+ free(as);
+ if(bt)
+ free(bt);
+ if(at)
+ free(at);
+
+ return err;
+
+}
\ No newline at end of file
diff --git a/dspl/src/filter_design/iir_ap.c b/dspl/src/filter_design/iir_ap.c
new file mode 100644
index 0000000..bba2900
--- /dev/null
+++ b/dspl/src/filter_design/iir_ap.c
@@ -0,0 +1,57 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+#include "dspl_internal.h"
+
+
+
+/******************************************************************************
+Analog prototype for IIR
+*******************************************************************************/
+int iir_ap(double rp, double rs, int ord, int type, double* b, double* a)
+{
+ int err;
+ switch(type & DSPL_FILTER_APPROX_MASK)
+ {
+ case DSPL_FILTER_BUTTER:
+ err = butter_ap(rp, ord, b, a);
+ break;
+ case DSPL_FILTER_CHEBY1:
+ err = cheby1_ap(rp, ord, b, a);
+ break;
+ case DSPL_FILTER_CHEBY2:
+ err = cheby2_ap_wp1(rp, rs, ord, b, a);
+ break;
+ case DSPL_FILTER_ELLIP:
+ err = ellip_ap(rp, rs, ord, b, a);
+ break;
+ default:
+ err = ERROR_FILTER_APPROX;
+ }
+ return err;
+}
+
+
+
+
diff --git a/dspl/src/filter_design/low2bp.c b/dspl/src/filter_design/low2bp.c
new file mode 100644
index 0000000..fcc79ab
--- /dev/null
+++ b/dspl/src/filter_design/low2bp.c
@@ -0,0 +1,56 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API low2bp(double* b, double* a, int ord,
+ double w0, double wpl, double wph,
+ double* beta, double* alpha)
+{
+
+ double num[3] = {0.0, 0.0, 1.0};
+ double den[3] = {0.0, 0.0, 0.0};
+
+ if(!b || !a || !beta || !alpha)
+ return ERROR_PTR;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(w0 <= 0.0 || wpl <= 0.0 || wph <= 0.0 || wph <= wpl)
+ return ERROR_FILTER_FT;
+
+ num[0] = (wph * wpl) / (w0 * w0);
+ den[1] = (wph - wpl) / w0;
+
+ return ratcompos(b, a, ord, num, den, 2, beta, alpha);
+}
+
+
diff --git a/dspl/src/filter_design/low2bs.c b/dspl/src/filter_design/low2bs.c
new file mode 100644
index 0000000..4efa217
--- /dev/null
+++ b/dspl/src/filter_design/low2bs.c
@@ -0,0 +1,54 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API low2bs(double* b, double* a, int ord,
+ double w0, double wsl, double wsh,
+ double* beta, double* alpha)
+{
+
+ double den[3] = {0.0, 0.0, 1.0};
+ double num[3] = {0.0, 0.0, 0.0};
+
+ if(!b || !a || !beta || !alpha)
+ return ERROR_PTR;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(w0 <= 0.0 || wsl <= 0.0 || wsh <= 0.0 || wsh <= wsl)
+ return ERROR_FILTER_FT;
+
+ den[0] = (wsh * wsl) / (w0 * w0);
+ num[1] = (wsh - wsl) / w0;
+
+ return ratcompos(b, a, ord, num, den, 2, beta, alpha);
+}
+
diff --git a/dspl/src/filter_design/low2high.c b/dspl/src/filter_design/low2high.c
new file mode 100644
index 0000000..84f9b92
--- /dev/null
+++ b/dspl/src/filter_design/low2high.c
@@ -0,0 +1,168 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int low2high (double* b, double* a, int ord, double w0, double w1,
+ double* beta, double* alpha)
+\brief Lowpass to highpass filter frequency transform
+
+Function transforms lowpass filter transfer function \f$ H(s) \f$
+to the highpass filter transfer function \f$ F(s) \f$.
+
+Filter order, magnitude ripple in passband and stopband
+supression still the same.
+
+\param[in] b
+Pointer to the lowpass filter transfer function \f$H(s)\f$ numerator
+coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n
+\n
+
+\param[in] a
+Pointer to the lowpass filter transfer function \f$H(s)\f$ denominator
+coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n
+\n
+
+\param[in] ord
+Filter order. \n
+\n
+
+\param[in] w0
+Lowpass filter cutoff frequency. \n
+\n
+
+\param[in] w1
+Highpass filter cutoff frequency after transformation. \n
+\n
+
+\param[in,out] beta
+Pointer to the highwpass filter transfer function \f$F(s)\f$ numerator
+coefficients vector after transformation. \n
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\param[in,out] alpha
+Pointer to the highwpass filter transfer function \f$F(s)\f$ denominator
+coefficients vector after transformation. \n
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\return
+`RES_OK` if filter coefficients is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int low2high (double* b, double* a, int ord, double w0, double w1,
+ double* beta, double* alpha)
+\brief Частотное преобразование ФНЧ-ФВЧ
+
+Функция производит перобразование передаточной функции \f$ H(s) \f$
+аналогового ФНЧ с частотой среза `w0` рад/c
+в передаточную функцию \f$ F(s) \f$ аналоговго ФВЧ с частотой среза `w1` рад/c.
+
+Неравномерность АЧХ в полосе пропускания, уровень подавления в полосе
+заграждения и порядок фильтра остаются неизменными.
+
+\param[in] b
+Указатель на вектор коэффициентов числителя передаточной функции \f$H(s)\f$
+исходного аналогового ФНЧ. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in] a
+Указатель на вектор коэффициентов знаменателя передаточной функции \f$H(s)\f$
+исходного аналогового ФНЧ. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in] ord
+Порядок исходного фильтра и фильтра после переобразования. \n
+\n
+
+\param[in] w0
+Частота среза исходного ФНЧ. \n
+\n
+
+\param[in] w1
+Требуемая частота среза ФВЧ после преобразования. \n
+\n
+
+\param[in,out] beta
+Указатель на вектор коэффициентов числителя передаточной функции \f$F(s)\f$
+ФВЧ после преобразования. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in,out] alpha
+Указатель на вектор коэффициентов знаменателя передаточной функции \f$F(s)\f$
+аналогового ФВЧ после преобразования. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\return
+`RES_OK` --- преобразование рассчитано успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API low2high(double* b, double* a, int ord, double w0, double w1,
+ double* beta, double* alpha)
+{
+
+ double num[2] = {0.0, 0.0};
+ double den[2] = {0.0, 1.0};
+
+ if(!b || !a || !beta || !alpha)
+ return ERROR_PTR;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(w0 <= 0.0 || w1 <= 0.0)
+ return ERROR_FILTER_FT;
+
+ num[0] = w1 / w0;
+
+ return ratcompos(b, a, ord, num, den, 1, beta, alpha);
+}
+
+
+
diff --git a/dspl/src/filter_design/low2low.c b/dspl/src/filter_design/low2low.c
new file mode 100644
index 0000000..eddce73
--- /dev/null
+++ b/dspl/src/filter_design/low2low.c
@@ -0,0 +1,167 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int low2low(double* b, double* a, int ord, double w0, double w1,
+ double* beta, double* alpha)
+
+Lowpass to lowpass filter frequency transform
+
+Function transforms lowpass filter transfer function \f$ H(s) \f$
+to the lowpass filter transfer function \f$ F(s) \f$
+with other cutoff frequency.
+
+Filter order, magnitude ripple in passband and stopband
+supression still the same.
+
+\param[in] b
+Pointer to the input lowpass filter transfer function \f$H(s)\f$ numerator
+coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n
+\n
+
+\param[in] a
+Pointer to the input lowpass filter transfer function \f$H(s)\f$ denominator
+coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n
+\n
+
+\param[in] ord
+Filter order. \n
+\n
+
+\param[in] w0
+Input lowpass filter cutoff frequency. \n
+\n
+
+\param[in] w1
+Lowpass filter cutoff frequency after transformation. \n
+\n
+
+\param[in,out] beta
+Pointer to the lowpass filter transfer function \f$F(s)\f$ numerator
+coefficients vector after transformation. \n
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\param[in,out] alpha
+Pointer to the lowpass filter transfer function \f$F(s)\f$ denominator
+coefficients vector after transformation. \n
+Vector size is `[ord+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\return
+`RES_OK` if filter coefficients is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int low2low(double* b, double* a, int ord, double w0, double w1,
+ double* beta, double* alpha)
+\brief Частотное преобразование ФНЧ-ФНЧ
+
+Функция производит преобразование передаточной функции \f$ H(s) \f$
+аналогового ФНЧ с частотой среза `w0` рад/c
+в передаточную функцию \f$ F(s) \f$ аналоговго ФНЧ с частотой среза `w1` рад/c.
+
+Неравномерность АЧХ в полосе пропускания, уровень подавления в полосе
+заграждения и порядок фильтра остаются неизменными.
+
+\param[in] b
+Указатель на вектор коэффициентов числителя передаточной функции \f$H(s)\f$
+исходного аналогового ФНЧ. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in] a
+Указатель на вектор коэффициентов знаменателя передаточной функции \f$H(s)\f$
+исходного аналогового ФНЧ. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in] ord
+Порядок исходного фильтра и фильтра после преобразования. \n
+\n
+
+\param[in] w0
+Частота среза исходного ФНЧ. \n
+\n
+
+\param[in] w1
+Требуемая частота среза ФНЧ после преобразования. \n
+\n
+
+\param[in,out] beta Указатель на вектор коэффициентов числителя
+передаточной функции \f$F(s)\f$ ФНЧ после преобразования. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in,out] alpha
+Указатель на вектор коэффициентов знаменателя передаточной функции \f$F(s)\f$
+аналогового ФНЧ после преобразования. \n
+Размер вектора `[ord+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\return
+`RES_OK` --- Преоборазование расчитано успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API low2low(double* b, double* a, int ord, double w0, double w1,
+ double* beta, double* alpha)
+{
+
+ double num[2] = {0.0, 1.0};
+ double den[2] = {0.0, 0.0};
+
+ if(!b || !a || !beta || !alpha)
+ return ERROR_PTR;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(w0 <= 0.0 || w1 <= 0.0)
+ return ERROR_FILTER_FT;
+
+ den[0] = w1 / w0;
+
+ return ratcompos(b, a, ord, num, den, 1, beta, alpha);
+}
+
diff --git a/dspl/src/filter_design/phase_delay.c b/dspl/src/filter_design/phase_delay.c
new file mode 100644
index 0000000..f2abeb4
--- /dev/null
+++ b/dspl/src/filter_design/phase_delay.c
@@ -0,0 +1,189 @@
+/*
+* 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 .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup FILTER_ANALYSIS_GROUP
+\fn int DSPL_API phase_delay(double* b, double* a, int ord, int flag,
+ double* w, int n, double* tau)
+
+\brief
+Phase delay calculation for digital or analog filter corresponds to
+\f$H(s)\f$, or \f$H(z)\f$ transfer function.
+
+Group delay is describes as:
+\f[
+\tau_{\varphi}(\omega) = - \frac{\Phi(\omega)}{\omega},
+\f]
+here \f$\Phi(\omega)\f$ -- filter phase response, \f$\omega\f$ is angular
+frequency for analog filter, or normalized frequency for digital filter.
+
+\param[in] b
+Pointer to the \f$ H(s) \f$ or \f$H(z)\f$ transfer function
+numerator coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n \n
+
+\param[in] a
+Pointer to the \f$ H(s) \f$ or \f$H(z)\f$ transfer function
+denominator coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n \n
+
+\param[in] ord
+Filter order. \n
+Transfer function \f$ H(s) \f$ or \f$H(z)\f$ numerator
+and denominator coefficients number equals `ord+1`. \n \n
+
+\param[in] flag
+Binary flags to set calculation rules: \n
+\verbatim
+DSPL_FLAG_ANALOG Coefficients corresponds to analog filter
+DSPL_FLAG_DIGITAL Coefficients corresponds to digital filter
+\endverbatim
+\n \n
+
+\param[in] w
+Pointer to the angular frequency \f$ \omega \f$ (rad/s),
+which used for analog filter characteristics calculation
+(flag sets as `DSPL_FLAG_ANALOG`). \n
+For digital filter (flag sets as `DSPL_FLAG_DIGITAL`),
+ parameter `w` describes normalized frequency of
+frequency response \f$ H \left(\mathrm{e}^{j\omega} \right) \f$.
+Digital filter frequency response is \f$ 2\pi \f$-periodic function,
+and vector `w` advisable to set from 0 to \f$ \pi \f$,
+or from 0 to \f$ 2\pi \f$, or from \f$ -\pi \f$ to \f$ \pi \f$.
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of frequency vector `w`. \n \n
+
+\param[out] tau
+Pointer to the phase delay vector. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+\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 FILTER_ANALYSIS_GROUP
+\fn int DSPL_API phase_delay(double* b, double* a, int ord, int flag,
+ double* w, int n, double* tau)
+\brief
+Расчет фазовой задержки цифрового или аналогового фильтра.
+
+Фазовая задержка определяется как:
+\f[
+\tau_{\varphi}(\omega) = - \frac{\Phi(\omega)}{\omega},
+\f]
+где \f$\Phi(\omega)\f$ -- ФЧХ фильтра, \f$\omega\f$ циктическая частот в случае
+аналогового фильтра, или нормированная частота цифрового фильтра.
+
+\param[in] b
+Указатель на вектор коэффициентов числителя передаточной функции
+аналогового фильтра \f$ H(s) \f$ или цифрового фильтра \f$ H(z) \f$. \n
+Размер вектора `[ord+1 x 1]`. \n \n
+
+\param[in] a
+Указатель на вектор коэффициентов числителя передаточной функции
+аналогового фильтра \f$ H(s) \f$ или цифрового фильтра \f$ H(z) \f$. \n
+Размер вектора `[ord+1 x 1]`. \n
+Параметр может быть `NULL`. В этом случае расчет производится для цифрового
+КИХ-фильтра с коэффициентами, заданными вектором `b`. \n\n
+
+\param[in] ord
+Порядок фильтра. Количество коэффициентов
+числителя и знаменателя передаточной
+функции \f$ H(s) \f$ или \f$ H(z) \f$ равно `ord+1`. \n \n
+
+\param[in] flag
+Флаг который задает тип фильтра: \n
+\verbatim
+DSPL_FLAG_ANALOG Коэффициенты относятся к аналоговому фильтру
+DSPL_FLAG_DIGITAL Коэффициенты относятся к цифровому фильтру
+\endverbatim
+
+\param[in] w
+Указатель на вектор значений циклической частоты \f$ \omega \f$ (рад/с),
+для которого будет рассчитаны АЧХ, ФЧХ и ГВЗ аналогового фильтра,
+если установлен флаг `DSPL_FLAG_ANALOG`. \n
+В случае если флаг `DSPL_FLAG_ANALOG` не установлен, то вектор частоты `w`
+используется как нормированная частота комплексного коэффициента передачи
+\f$ H \left(\mathrm{e}^{j\omega} \right) \f$ цифрового фильтра. \n
+В этом случае характеристика цифрового фильтра является
+\f$ 2\pi \f$-периодической, и вектор частоты может содержать
+произвольные значения, однако целесообразно задавать
+его от 0 до \f$ \pi \f$, а такжет от 0 до \f$ 2\pi \f$, или
+от \f$ -\pi \f$ до \f$ \pi \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер вектора циклической частоты `w`. \n \n
+
+\param[out] tau
+Указатель на вектор фазовой задержки. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n
+
+\return
+`RES_OK` фазовая задержка фильтра рассчитана успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API phase_delay(double* b, double* a, int ord, int flag,
+ double* w, int n, double* tau)
+{
+ int err, i;
+ double *phi = NULL;
+
+ if(n > 0)
+ phi = (double*)malloc(n*sizeof(double));
+ else
+ return ERROR_SIZE;
+
+ err = filter_freq_resp(b, a, ord, w, n, flag | DSPL_FLAG_UNWRAP,
+ NULL, phi, NULL);
+ if(err!=RES_OK)
+ goto exit_label;
+ for(i = 0; i < n; i++)
+ {
+ tau[i] = w[i] ? ( - phi[i] / w[i]) : ( - phi[i] / (w[i] + 1E-9) );
+ }
+exit_label:
+ if(phi)
+ free(phi);
+ return err;
+}
+
diff --git a/dspl/src/filter_design/ratcompos.c b/dspl/src/filter_design/ratcompos.c
new file mode 100644
index 0000000..04f3855
--- /dev/null
+++ b/dspl/src/filter_design/ratcompos.c
@@ -0,0 +1,286 @@
+/*
+* 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 .
+*/
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int ratcompos( double* b, double* a, int n,
+ double* c, double* d, int p,
+ double* beta, double* alpha)
+\brief Rational composition
+
+Function calcultes composition \f$Y(s) = (H \circ F)(s) = H(F(s))\f$, here
+
+\f[
+H(s) = \frac{\sum\limits_{m = 0}^{n} b_m s^m}
+{\sum\limits_{k = 0}^{n} a_k s^k}, \quad
+F(s) = \frac{\sum\limits_{m = 0}^{p} d_m s^m}
+{\sum\limits_{k = 0}^{p} c_k s^k}, \quad
+Y(s) = \frac{\sum\limits_{m = 0}^{n p} \beta_m s^m}
+{\sum\limits_{k = 0}^{n p} \alpha_k s^k}
+\f]
+
+This function is using for filter frequency transform.
+
+\param[in] b
+Pointer to the \f$H(s)\f$ polynomial function
+numerator coefficients vector. \n
+Vector size is `[n+1 x 1]`. \n
+\n
+
+\param[in] a
+Pointer to the \f$H(s)\f$ polynomial function
+denominator coefficients vector. \n
+Vector size is `[n+1 x 1]`. \n
+\n
+
+\param[in] n
+Order of \f$H(s)\f$ numerator and denominator polynomials. \n
+\n
+
+\param[in] c
+Pointer to the \f$F(s)\f$ polynomial function
+numerator coefficients vector. \n
+Vector size is `[p+1 x 1]`. \n
+\n
+
+\param[in] d
+Pointer to the \f$F(s)\f$ polynomial function
+denominator coefficients vector. \n
+Vector size is `[p+1 x 1]`. \n
+\n
+
+\param[in] p
+Order of \f$F(s)\f$ numerator and denominator polynomials. \n
+\n
+
+\param[in,out] beta
+Pointer to the numerator coefficients vector of
+\f$Y(s) = (H \circ F)(s)\f$. \n
+Vector size is `[n*p+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\param[in,out] alpha
+Pointer to the denominator coefficients vector of
+\f$Y(s) = (H \circ F)(s)\f$. \n
+Vector size is `[n*p+1 x 1]`. \n
+Memory must be allocated. \n
+\n
+
+
+\return
+`RES_OK` if rational composition is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup IIR_FILTER_DESIGN_GROUP
+\fn int ratcompos( double* b, double* a, int n,
+ double* c, double* d, int p,
+ double* beta, double* alpha)
+\brief Рациональная композиця
+
+Функция рассчитывает композицию вида \f$Y(s) = (H \circ F)(s) = H(F(s))\f$, где
+
+\f[
+H(s) = \frac{\sum\limits_{m = 0}^{n} b_m s^m}
+{\sum\limits_{k = 0}^{n} a_k s^k}, \quad
+F(s) = \frac{\sum\limits_{m = 0}^{p} d_m s^m}
+{\sum\limits_{k = 0}^{p} c_k s^k}, \quad
+Y(s) = \frac{\sum\limits_{m = 0}^{n p} \beta_m s^m}
+{\sum\limits_{k = 0}^{n p} \alpha_k s^k}
+\f]
+
+Функция рациональной композиции необходима для произведения частотных
+преобразований передаточных характеристик аналоговых и цифровых фильтров,
+а также для билинейного преобразования передаточных характеристик аналоговых
+фильтров в соответствующие передаточные характеристики цифровых фильтров.
+
+\param[in] b
+Указатель на вектор коэффициентов числителя функции \f$H(s)\f$. \n
+Размер вектора `[n+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in] a
+Указатель на вектор коэффициентов знаменателя функции \f$H(s)\f$. \n
+Размер вектора `[n+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in] n
+Порядок полиномов рациональной функции \f$H(s)\f$. \n
+\n
+
+\param[in] c
+Указатель на вектор коэффициентов числителя функции \f$F(s)\f$. \n
+Размер вектора `[p+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in] d
+Указатель на вектор коэффициентов знаменателя функции \f$F(s)\f$. \n
+Размер вектора `[p+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in] p
+Порядок полиномов рациональной
+функции \f$F(s)\f$. \n
+\n
+
+\param[in,out] beta
+Указатель на вектор коэффициентов
+числителя функции \f$Y(s) = (H \circ F)(s)\f$. \n
+Размер вектора `[n*p+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+\param[in,out] alpha
+Указатель на вектор коэффициентов знаменателя
+функции \f$Y(s) = (H \circ F)(s)\f$. \n
+Размер вектора `[n*p+1 x 1]`. \n
+Память должна быть выделена. \n
+\n
+
+
+\return
+`RES_OK` --- Рациональная композиция рассчитана успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API ratcompos(double* b, double* a, int n,
+ double* c, double* d, int p,
+ double* beta, double* alpha)
+{
+
+ int k2, i, k, pn, pd, ln, ld, k2s, nk2s;
+ double *num = NULL, *den = NULL, *ndn = NULL, *ndd = NULL;
+ int res;
+
+ if (!a || !b || !c || !d || !beta || !alpha)
+ {
+ res = ERROR_PTR;
+ goto exit_label;
+ }
+ if(n < 1 || p < 1)
+ {
+ res = ERROR_SIZE;
+ goto exit_label;
+ }
+
+ k2 = (n*p)+1;
+ k2s = k2*sizeof(double); /* alpha and beta size */
+ nk2s = (n+1)*k2*sizeof(double); /* num, den, ndn and ndd size */
+
+ num = (double*)malloc(nk2s);
+ den = (double*)malloc(nk2s);
+ ndn = (double*)malloc(nk2s);
+ ndd = (double*)malloc(nk2s);
+
+ memset(num, 0, nk2s);
+ memset(den, 0, nk2s);
+ memset(ndn, 0, nk2s);
+ memset(ndd, 0, nk2s);
+
+
+ num[0] = den[0] = 1.0;
+ pn = 0;
+ ln = 1;
+ for(i = 1; i < n+1; i++)
+ {
+ res = conv(num+pn, ln, c, p+1, num+pn+k2);
+ if(res!=RES_OK)
+ goto exit_label;
+ res = conv(den+pn, ln, d, p+1, den+pn+k2);
+ if(res!=RES_OK)
+ goto exit_label;
+ pn += k2;
+ ln += p;
+ }
+
+ pn = 0;
+ pd = n*k2;
+ ln = 1;
+ ld = k2;
+
+ for (i = 0; i < n+1; i++)
+ {
+ res = conv(num + pn, ln, den + pd, ld, ndn + i*k2);
+ if(res!=RES_OK)
+ goto exit_label;
+ ln += p;
+ ld -= p;
+ pn += k2;
+ pd -= k2;
+ }
+
+ for (i = 0; i < n+1; i++)
+ {
+ for (k = 0; k < k2; k++)
+ {
+ ndd[i*k2 + k] = ndn[i*k2 + k] * a[i];
+ ndn[i*k2 + k] *= b[i];
+ }
+ }
+
+
+ memset(alpha, 0, k2s);
+ memset(beta, 0, k2s);
+
+ for (k = 0; k < k2; k++)
+ {
+ for (i = 0; i < n+1; i++)
+ {
+ beta[k] += ndn[i*k2 + k];
+ alpha[k] += ndd[i*k2 + k];
+ }
+ }
+
+ res = RES_OK;
+
+exit_label:
+ if(num)
+ free(num);
+ if(den)
+ free(den);
+ if(ndn)
+ free(ndn);
+ if(ndd)
+ free(ndd);
+
+ return res;
+}
+
diff --git a/dspl/src/filter_ft.c b/dspl/src/filter_ft.c
deleted file mode 100644
index 21cbac3..0000000
--- a/dspl/src/filter_ft.c
+++ /dev/null
@@ -1,704 +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 .
- */
-
-#include
-#include
-#include
-#include "dspl.h"
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-double DSPL_API filter_ws1(int ord, double rp, double rs, int type)
-{
- double es2, ep2, gs2, x, ws;
-
- if(ord<1 || rp < 0.0 || rs < 0.0)
- return -1.0;
-
- es2 = pow(10.0, rs*0.1) - 1.0;
- ep2 = pow(10.0, rp*0.1) - 1.0;
- gs2 = 1.0 / (1.0 + es2);
-
- x = (1.0 - gs2) / (gs2 * ep2);
-
- switch( type & DSPL_FILTER_APPROX_MASK)
- {
- case DSPL_FILTER_BUTTER:
- ws = pow(x, 0.5 / (double)ord);
- break;
- case DSPL_FILTER_CHEBY1:
- case DSPL_FILTER_CHEBY2:
- x = sqrt(x) + sqrt(x - 1.0);
- x = log(x) / (double)ord;
- ws = 0.5 * (exp(-x) + exp(x));
- break;
- case DSPL_FILTER_ELLIP:
- {
- double k, k1;
- complex_t y, z;
- int res;
- k = sqrt(ep2 / es2);
- res = ellip_modulareq(rp, rs, ord, &k1);
- if(res != RES_OK)
- {
- ws = -1.0;
- break;
- }
- RE(z) = sqrt(x);
- IM(z) = 0.0;
-
- res = ellip_acd_cmplx(&z, 1, k, &y);
- if(res != RES_OK)
- {
- ws = -1.0;
- break;
- }
- RE(y) /= (double)ord;
- IM(y) /= (double)ord;
- res = ellip_cd_cmplx(&y, 1, k1, &z);
- if(res != RES_OK)
- {
- ws = -1.0;
- break;
- }
- ws = RE(z);
- break;
- }
- default:
- ws = -1.0;
- break;
- }
- return ws;
-}
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API low2bp(double* b, double* a, int ord,
- double w0, double wpl, double wph,
- double* beta, double* alpha)
-{
-
- double num[3] = {0.0, 0.0, 1.0};
- double den[3] = {0.0, 0.0, 0.0};
-
- if(!b || !a || !beta || !alpha)
- return ERROR_PTR;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(w0 <= 0.0 || wpl <= 0.0 || wph <= 0.0 || wph <= wpl)
- return ERROR_FILTER_FT;
-
- num[0] = (wph * wpl) / (w0 * w0);
- den[1] = (wph - wpl) / w0;
-
- return ratcompos(b, a, ord, num, den, 2, beta, alpha);
-}
-
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-
-#endif
-#ifdef DOXYGEN_RUSSIAN
-
-#endif
-int DSPL_API low2bs(double* b, double* a, int ord,
- double w0, double wsl, double wsh,
- double* beta, double* alpha)
-{
-
- double den[3] = {0.0, 0.0, 1.0};
- double num[3] = {0.0, 0.0, 0.0};
-
- if(!b || !a || !beta || !alpha)
- return ERROR_PTR;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(w0 <= 0.0 || wsl <= 0.0 || wsh <= 0.0 || wsh <= wsl)
- return ERROR_FILTER_FT;
-
- den[0] = (wsh * wsl) / (w0 * w0);
- num[1] = (wsh - wsl) / w0;
-
- return ratcompos(b, a, ord, num, den, 2, beta, alpha);
-}
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int low2high (double* b, double* a, int ord, double w0, double w1,
- double* beta, double* alpha)
-\brief Lowpass to highpass filter frequency transform
-
-Function transforms lowpass filter transfer function \f$ H(s) \f$
-to the highpass filter transfer function \f$ F(s) \f$.
-
-Filter order, magnitude ripple in passband and stopband
-supression still the same.
-
-\param[in] b
-Pointer to the lowpass filter transfer function \f$H(s)\f$ numerator
-coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n
-\n
-
-\param[in] a
-Pointer to the lowpass filter transfer function \f$H(s)\f$ denominator
-coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n
-\n
-
-\param[in] ord
-Filter order. \n
-\n
-
-\param[in] w0
-Lowpass filter cutoff frequency. \n
-\n
-
-\param[in] w1
-Highpass filter cutoff frequency after transformation. \n
-\n
-
-\param[in,out] beta
-Pointer to the highwpass filter transfer function \f$F(s)\f$ numerator
-coefficients vector after transformation. \n
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\param[in,out] alpha
-Pointer to the highwpass filter transfer function \f$F(s)\f$ denominator
-coefficients vector after transformation. \n
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\return
-`RES_OK` if filter coefficients is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int low2high (double* b, double* a, int ord, double w0, double w1,
- double* beta, double* alpha)
-\brief Частотное преобразование ФНЧ-ФВЧ
-
-Функция производит перобразование передаточной функции \f$ H(s) \f$
-аналогового ФНЧ с частотой среза `w0` рад/c
-в передаточную функцию \f$ F(s) \f$ аналоговго ФВЧ с частотой среза `w1` рад/c.
-
-Неравномерность АЧХ в полосе пропускания, уровень подавления в полосе
-заграждения и порядок фильтра остаются неизменными.
-
-\param[in] b
-Указатель на вектор коэффициентов числителя передаточной функции \f$H(s)\f$
-исходного аналогового ФНЧ. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in] a
-Указатель на вектор коэффициентов знаменателя передаточной функции \f$H(s)\f$
-исходного аналогового ФНЧ. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in] ord
-Порядок исходного фильтра и фильтра после переобразования. \n
-\n
-
-\param[in] w0
-Частота среза исходного ФНЧ. \n
-\n
-
-\param[in] w1
-Требуемая частота среза ФВЧ после преобразования. \n
-\n
-
-\param[in,out] beta
-Указатель на вектор коэффициентов числителя передаточной функции \f$F(s)\f$
-ФВЧ после преобразования. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in,out] alpha
-Указатель на вектор коэффициентов знаменателя передаточной функции \f$F(s)\f$
-аналогового ФВЧ после преобразования. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\return
-`RES_OK` --- преобразование рассчитано успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API low2high(double* b, double* a, int ord, double w0, double w1,
- double* beta, double* alpha)
-{
-
- double num[2] = {0.0, 0.0};
- double den[2] = {0.0, 1.0};
-
- if(!b || !a || !beta || !alpha)
- return ERROR_PTR;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(w0 <= 0.0 || w1 <= 0.0)
- return ERROR_FILTER_FT;
-
- num[0] = w1 / w0;
-
- return ratcompos(b, a, ord, num, den, 1, beta, alpha);
-}
-
-
-
-
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int low2low(double* b, double* a, int ord, double w0, double w1,
- double* beta, double* alpha)
-
-Lowpass to lowpass filter frequency transform
-
-Function transforms lowpass filter transfer function \f$ H(s) \f$
-to the lowpass filter transfer function \f$ F(s) \f$
-with other cutoff frequency.
-
-Filter order, magnitude ripple in passband and stopband
-supression still the same.
-
-\param[in] b
-Pointer to the input lowpass filter transfer function \f$H(s)\f$ numerator
-coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n
-\n
-
-\param[in] a
-Pointer to the input lowpass filter transfer function \f$H(s)\f$ denominator
-coefficients vector. \n
-Vector size is `[ord+1 x 1]`. \n
-\n
-
-\param[in] ord
-Filter order. \n
-\n
-
-\param[in] w0
-Input lowpass filter cutoff frequency. \n
-\n
-
-\param[in] w1
-Lowpass filter cutoff frequency after transformation. \n
-\n
-
-\param[in,out] beta
-Pointer to the lowpass filter transfer function \f$F(s)\f$ numerator
-coefficients vector after transformation. \n
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\param[in,out] alpha
-Pointer to the lowpass filter transfer function \f$F(s)\f$ denominator
-coefficients vector after transformation. \n
-Vector size is `[ord+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\return
-`RES_OK` if filter coefficients is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int low2low(double* b, double* a, int ord, double w0, double w1,
- double* beta, double* alpha)
-\brief Частотное преобразование ФНЧ-ФНЧ
-
-Функция производит преобразование передаточной функции \f$ H(s) \f$
-аналогового ФНЧ с частотой среза `w0` рад/c
-в передаточную функцию \f$ F(s) \f$ аналоговго ФНЧ с частотой среза `w1` рад/c.
-
-Неравномерность АЧХ в полосе пропускания, уровень подавления в полосе
-заграждения и порядок фильтра остаются неизменными.
-
-\param[in] b
-Указатель на вектор коэффициентов числителя передаточной функции \f$H(s)\f$
-исходного аналогового ФНЧ. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in] a
-Указатель на вектор коэффициентов знаменателя передаточной функции \f$H(s)\f$
-исходного аналогового ФНЧ. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in] ord
-Порядок исходного фильтра и фильтра после преобразования. \n
-\n
-
-\param[in] w0
-Частота среза исходного ФНЧ. \n
-\n
-
-\param[in] w1
-Требуемая частота среза ФНЧ после преобразования. \n
-\n
-
-\param[in,out] beta Указатель на вектор коэффициентов числителя
-передаточной функции \f$F(s)\f$ ФНЧ после преобразования. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in,out] alpha
-Указатель на вектор коэффициентов знаменателя передаточной функции \f$F(s)\f$
-аналогового ФНЧ после преобразования. \n
-Размер вектора `[ord+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\return
-`RES_OK` --- Преоборазование расчитано успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API low2low(double* b, double* a, int ord, double w0, double w1,
- double* beta, double* alpha)
-{
-
- double num[2] = {0.0, 1.0};
- double den[2] = {0.0, 0.0};
-
- if(!b || !a || !beta || !alpha)
- return ERROR_PTR;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(w0 <= 0.0 || w1 <= 0.0)
- return ERROR_FILTER_FT;
-
- den[0] = w1 / w0;
-
- return ratcompos(b, a, ord, num, den, 1, beta, alpha);
-}
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int ratcompos( double* b, double* a, int n,
- double* c, double* d, int p,
- double* beta, double* alpha)
-\brief Rational composition
-
-Function calcultes composition \f$Y(s) = (H \circ F)(s) = H(F(s))\f$, here
-
-\f[
-H(s) = \frac{\sum\limits_{m = 0}^{n} b_m s^m}
-{\sum\limits_{k = 0}^{n} a_k s^k}, \quad
-F(s) = \frac{\sum\limits_{m = 0}^{p} d_m s^m}
-{\sum\limits_{k = 0}^{p} c_k s^k}, \quad
-Y(s) = \frac{\sum\limits_{m = 0}^{n p} \beta_m s^m}
-{\sum\limits_{k = 0}^{n p} \alpha_k s^k}
-\f]
-
-This function is using for filter frequency transform.
-
-\param[in] b
-Pointer to the \f$H(s)\f$ polynomial function
-numerator coefficients vector. \n
-Vector size is `[n+1 x 1]`. \n
-\n
-
-\param[in] a
-Pointer to the \f$H(s)\f$ polynomial function
-denominator coefficients vector. \n
-Vector size is `[n+1 x 1]`. \n
-\n
-
-\param[in] n
-Order of \f$H(s)\f$ numerator and denominator polynomials. \n
-\n
-
-\param[in] c
-Pointer to the \f$F(s)\f$ polynomial function
-numerator coefficients vector. \n
-Vector size is `[p+1 x 1]`. \n
-\n
-
-\param[in] d
-Pointer to the \f$F(s)\f$ polynomial function
-denominator coefficients vector. \n
-Vector size is `[p+1 x 1]`. \n
-\n
-
-\param[in] p
-Order of \f$F(s)\f$ numerator and denominator polynomials. \n
-\n
-
-\param[in,out] beta
-Pointer to the numerator coefficients vector of
-\f$Y(s) = (H \circ F)(s)\f$. \n
-Vector size is `[n*p+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-\param[in,out] alpha
-Pointer to the denominator coefficients vector of
-\f$Y(s) = (H \circ F)(s)\f$. \n
-Vector size is `[n*p+1 x 1]`. \n
-Memory must be allocated. \n
-\n
-
-
-\return
-`RES_OK` if rational composition is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int ratcompos( double* b, double* a, int n,
- double* c, double* d, int p,
- double* beta, double* alpha)
-\brief Рациональная композиця
-
-Функция рассчитывает композицию вида \f$Y(s) = (H \circ F)(s) = H(F(s))\f$, где
-
-\f[
-H(s) = \frac{\sum\limits_{m = 0}^{n} b_m s^m}
-{\sum\limits_{k = 0}^{n} a_k s^k}, \quad
-F(s) = \frac{\sum\limits_{m = 0}^{p} d_m s^m}
-{\sum\limits_{k = 0}^{p} c_k s^k}, \quad
-Y(s) = \frac{\sum\limits_{m = 0}^{n p} \beta_m s^m}
-{\sum\limits_{k = 0}^{n p} \alpha_k s^k}
-\f]
-
-Функция рациональной композиции необходима для произведения частотных
-преобразований передаточных характеристик аналоговых и цифровых фильтров,
-а также для билинейного преобразования передаточных характеристик аналоговых
-фильтров в соответствующие передаточные характеристики цифровых фильтров.
-
-\param[in] b
-Указатель на вектор коэффициентов числителя функции \f$H(s)\f$. \n
-Размер вектора `[n+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in] a
-Указатель на вектор коэффициентов знаменателя функции \f$H(s)\f$. \n
-Размер вектора `[n+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in] n
-Порядок полиномов рациональной функции \f$H(s)\f$. \n
-\n
-
-\param[in] c
-Указатель на вектор коэффициентов числителя функции \f$F(s)\f$. \n
-Размер вектора `[p+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in] d
-Указатель на вектор коэффициентов знаменателя функции \f$F(s)\f$. \n
-Размер вектора `[p+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in] p
-Порядок полиномов рациональной
-функции \f$F(s)\f$. \n
-\n
-
-\param[in,out] beta
-Указатель на вектор коэффициентов
-числителя функции \f$Y(s) = (H \circ F)(s)\f$. \n
-Размер вектора `[n*p+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-\param[in,out] alpha
-Указатель на вектор коэффициентов знаменателя
-функции \f$Y(s) = (H \circ F)(s)\f$. \n
-Размер вектора `[n*p+1 x 1]`. \n
-Память должна быть выделена. \n
-\n
-
-
-\return
-`RES_OK` --- Рациональная композиция рассчитана успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API ratcompos(double* b, double* a, int n,
- double* c, double* d, int p,
- double* beta, double* alpha)
-{
-
- int k2, i, k, pn, pd, ln, ld, k2s, nk2s;
- double *num = NULL, *den = NULL, *ndn = NULL, *ndd = NULL;
- int res;
-
- if (!a || !b || !c || !d || !beta || !alpha)
- {
- res = ERROR_PTR;
- goto exit_label;
- }
- if(n < 1 || p < 1)
- {
- res = ERROR_SIZE;
- goto exit_label;
- }
-
- k2 = (n*p)+1;
- k2s = k2*sizeof(double); /* alpha and beta size */
- nk2s = (n+1)*k2*sizeof(double); /* num, den, ndn and ndd size */
-
- num = (double*)malloc(nk2s);
- den = (double*)malloc(nk2s);
- ndn = (double*)malloc(nk2s);
- ndd = (double*)malloc(nk2s);
-
- memset(num, 0, nk2s);
- memset(den, 0, nk2s);
- memset(ndn, 0, nk2s);
- memset(ndd, 0, nk2s);
-
-
- num[0] = den[0] = 1.0;
- pn = 0;
- ln = 1;
- for(i = 1; i < n+1; i++)
- {
- res = conv(num+pn, ln, c, p+1, num+pn+k2);
- if(res!=RES_OK)
- goto exit_label;
- res = conv(den+pn, ln, d, p+1, den+pn+k2);
- if(res!=RES_OK)
- goto exit_label;
- pn += k2;
- ln += p;
- }
-
- pn = 0;
- pd = n*k2;
- ln = 1;
- ld = k2;
-
- for (i = 0; i < n+1; i++)
- {
- res = conv(num + pn, ln, den + pd, ld, ndn + i*k2);
- if(res!=RES_OK)
- goto exit_label;
- ln += p;
- ld -= p;
- pn += k2;
- pd -= k2;
- }
-
- for (i = 0; i < n+1; i++)
- {
- for (k = 0; k < k2; k++)
- {
- ndd[i*k2 + k] = ndn[i*k2 + k] * a[i];
- ndn[i*k2 + k] *= b[i];
- }
- }
-
-
- memset(alpha, 0, k2s);
- memset(beta, 0, k2s);
-
- for (k = 0; k < k2; k++)
- {
- for (i = 0; i < n+1; i++)
- {
- beta[k] += ndn[i*k2 + k];
- alpha[k] += ndd[i*k2 + k];
- }
- }
-
- res = RES_OK;
-
-exit_label:
- if(num)
- free(num);
- if(den)
- free(den);
- if(ndn)
- free(ndn);
- if(ndd)
- free(ndd);
-
- return res;
-}
-
diff --git a/dspl/src/math_ellipj.c b/dspl/src/math_ellipj.c
new file mode 100644
index 0000000..a467ef7
--- /dev/null
+++ b/dspl/src/math_ellipj.c
@@ -0,0 +1,11 @@
+#include "math_ellipj/ellip_acd.c"
+#include "math_ellipj/ellip_acd_cmplx.c"
+#include "math_ellipj/ellip_asn.c"
+#include "math_ellipj/ellip_asn_cmplx.c"
+#include "math_ellipj/ellip_cd.c"
+#include "math_ellipj/ellip_cd_cmplx.c"
+#include "math_ellipj/ellip_landen.c"
+#include "math_ellipj/ellip_modulareq.c"
+#include "math_ellipj/ellip_rat.c"
+#include "math_ellipj/ellip_sn.c"
+#include "math_ellipj/ellip_sn_cmplx.c"
diff --git a/dspl/src/math_ellipj/ellip_acd.c b/dspl/src/math_ellipj/ellip_acd.c
new file mode 100644
index 0000000..b2a019e
--- /dev/null
+++ b/dspl/src/math_ellipj/ellip_acd.c
@@ -0,0 +1,130 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_acd(double* w, int n, double k, double* u)
+\brief Inverse Jacobi elliptic function \f$ u = \textrm{cd}^{-1}(w, k)\f$
+of the real vector argument
+
+Function calculates inverse Jacobi elliptic function
+\f$ u = \textrm{cd}^{-1}(w, k)\f$ of the real vector `w`. \n
+
+\param[in] w
+Pointer to the argument vector \f$ w \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\param[in] n
+Size of vector `w`. \n
+
+\param[in] k
+Elliptical modulus \f$ k \f$. \n
+Elliptical modulus is real parameter,
+which values can be from 0 to 1. \n \n
+
+\param[out] u
+Pointer to the vector of inverse Jacobi elliptic function
+\f$ u = \textrm{cd}^{-1}(w, k)\f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_acd(double* w, int n, double k, double* u)
+\brief Обратная эллиптическая функция Якоби
+ \f$ u = \textrm{cd}^{-1}(w, k)\f$ вещественного аргумента
+
+Функция рассчитывает значения обратной эллиптической функции
+\f$ u = \textrm{cd}^{-1}(w, k)\f$ для вещественного вектора `w`. \n
+
+Для расчета используется итерационный алгоритм на основе преобразования
+Ландена. \n
+
+\param[in] w
+Указатель на массив вектора переменной \f$ w \f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\param[in] n
+Размер вектора `w`. \n
+
+\param[in] k Значение эллиптического модуля \f$ k \f$.
+Эллиптический модуль -- вещественный параметр,
+принимающий значения от 0 до 1. \n \n
+
+\param[out] u
+Указатель на вектор значений обратной эллиптической
+функции \f$ u = \textrm{cd}^{-1}(w, k)\f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` Расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API ellip_acd(double* w, int n, double k, double* u)
+{
+ double lnd[ELLIP_ITER], t;
+ int i, m;
+
+ if(!u || !w)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+ if(k < 0.0 || k>= 1.0)
+ return ERROR_ELLIP_MODULE;
+
+ ellip_landen(k,ELLIP_ITER, lnd);
+
+ for(m = 0; m < n; m++)
+ {
+ u[m] = w[m];
+ for(i = 1; i < ELLIP_ITER; i++)
+ {
+ t = lnd[i-1]*u[m];
+ t *= t;
+ t = 1.0 + sqrt(1.0 - t);
+ u[m] = 2.0 * u[m] / (t+t*lnd[i]);
+ }
+ u[m] = 2.0 * acos(u[m]) / M_PI;
+ }
+ return RES_OK;
+}
+
diff --git a/dspl/src/math_ellipj/ellip_acd_cmplx.c b/dspl/src/math_ellipj/ellip_acd_cmplx.c
new file mode 100644
index 0000000..8547a9a
--- /dev/null
+++ b/dspl/src/math_ellipj/ellip_acd_cmplx.c
@@ -0,0 +1,151 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_acd_cmplx(complex_t* w, int n, double k, complex_t* u)
+\brief Inverse Jacobi elliptic function \f$ u = \textrm{cd}^{-1}(w, k)\f$
+of complex vector argument
+
+Function calculates inverse Jacobi elliptic function
+\f$ u = \textrm{cd}^{-1}(w, k)\f$ of complex vector `w`. \n
+
+\param[in] w
+Pointer to the argument vector \f$ w \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\param[in] n
+Size of vector `w`. \n \n
+
+\param[in] k
+Elliptical modulus \f$ k \f$. \n
+Elliptical modulus is real parameter,
+which values can be from 0 to 1. \n \n
+
+\param[out] u
+Pointer to the vector of inverse Jacobi elliptic function
+\f$ u = \textrm{cd}^{-1}(w, k)\f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_acd_cmplx(complex_t* w, int n, double k, complex_t* u)
+\brief Обратная эллиптическая функция Якоби
+ \f$ u = \textrm{cd}^{-1}(w, k)\f$ комплексного аргумента
+
+Функция рассчитывает значения значения обратной эллиптической функции
+\f$ u = \textrm{cd}^{-1}(w, k)\f$ для комплексного вектора `w`. \n
+
+Для расчета используется итерационный алгоритм на основе преобразования
+Ландена. \n
+
+\param[in] w
+Указатель на массив вектора переменной \f$ w \f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\param[in] n
+Размер вектора `w`. \n \n
+
+\param[in] k
+Значение эллиптического модуля \f$ k \f$. \n
+Эллиптический модуль -- вещественный параметр,
+принимающий значения от 0 до 1. \n \n
+
+\param[out] u
+Указатель на вектор значений обратной эллиптической
+функции \f$ u = \textrm{cd}^{-1}(w, k)\f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` Расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API ellip_acd_cmplx(complex_t* w, int n, double k, complex_t* u)
+{
+ double lnd[ELLIP_ITER], t;
+ complex_t tmp0, tmp1;
+ int i, m;
+
+ if(!u || !w)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+ if(k < 0.0 || k>= 1.0)
+ return ERROR_ELLIP_MODULE;
+
+ ellip_landen(k,ELLIP_ITER, lnd);
+
+ for(m = 0; m < n; m++)
+ {
+ RE(u[m]) = RE(w[m]);
+ IM(u[m]) = IM(w[m]);
+ for(i = 1; i < ELLIP_ITER; i++)
+ {
+ RE(tmp0) = lnd[i-1]*RE(u[m]);
+ IM(tmp0) = lnd[i-1]*IM(u[m]);
+ RE(tmp1) = 1.0 - CMRE(tmp0, tmp0);
+ IM(tmp1) = - CMIM(tmp0, tmp0);
+
+ sqrt_cmplx(&tmp1, 1, &tmp0);
+ RE(tmp0) += 1.0;
+
+ RE(tmp1) = RE(tmp0) * (1.0 + lnd[i]);
+ IM(tmp1) = IM(tmp0) * (1.0 + lnd[i]);
+
+ t = 2.0 / ABSSQR(tmp1);
+
+ RE(tmp0) = t * CMCONJRE(u[m], tmp1);
+ IM(tmp0) = t * CMCONJIM(u[m], tmp1);
+
+ RE(u[m]) = RE(tmp0);
+ IM(u[m]) = IM(tmp0);
+ }
+ acos_cmplx(&tmp0, 1, u+m);
+ t = 2.0 / M_PI;
+ RE(u[m]) *= t;
+ IM(u[m]) *= t;
+ }
+ return RES_OK;
+}
+
diff --git a/dspl/src/math_ellipj/ellip_asn.c b/dspl/src/math_ellipj/ellip_asn.c
new file mode 100644
index 0000000..aca2bea
--- /dev/null
+++ b/dspl/src/math_ellipj/ellip_asn.c
@@ -0,0 +1,134 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_asn(double* w, int n, double k, double* u)
+\brief Inverse Jacobi elliptic function \f$ u = \textrm{sn}^{-1}(w, k)\f$
+of real vector argument
+
+Function calculates inverse Jacobi elliptic function
+\f$ u = \textrm{sn}^{-1}(w, k)\f$ of real vector `w`. \n
+
+\param[in] w
+Pointer to the argument vector \f$ w \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\param[in] n
+Size of vector `w`. \n
+
+\param[in] k
+Elliptical modulus \f$ k \f$. \n
+Elliptical modulus is real parameter,
+which values can be from 0 to 1. \n \n
+
+\param[out] u
+Pointer to the vector of inverse Jacobi elliptic function
+\f$ u = \textrm{sn}^{-1}(w, k)\f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_asn(double* w, int n, double k, double* u)
+\brief Обратная эллиптическая функция Якоби
+ \f$ u = \textrm{sn}^{-1}(w, k)\f$ вещественного аргумента
+
+Функция рассчитывает значения значения обратной эллиптической функции
+\f$ u = \textrm{sn}^{-1}(w, k)\f$ для вещественного вектора `w`. \n
+
+Для расчета используется итерационный алгоритм на основе преобразования
+Ландена. \n
+
+\param[in] w
+Указатель на массив вектора переменной \f$ w \f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\param[in] n
+Размер вектора `w`. \n \n
+
+\param[in] k
+Значение эллиптического модуля \f$ k \f$. \n
+Эллиптический модуль -- вещественный параметр,
+принимающий значения от 0 до 1. \n \n
+
+\param[out] u
+Указатель на вектор значений обратной эллиптической
+функции \f$ u = \textrm{sn}^{-1}(w, k)\f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` Расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API ellip_asn(double* w, int n, double k, double* u)
+{
+ double lnd[ELLIP_ITER], t;
+ int i, m;
+
+ if(!u || !w)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+ if(k < 0.0 || k>= 1.0)
+ return ERROR_ELLIP_MODULE;
+
+ ellip_landen(k,ELLIP_ITER, lnd);
+
+ for(m = 0; m < n; m++)
+ {
+ u[m] = w[m];
+ for(i = 1; i < ELLIP_ITER; i++)
+ {
+ t = lnd[i-1]*u[m];
+ t *= t;
+ t = 1.0 + sqrt(1.0 - t);
+ u[m] = 2.0 * u[m] / (t+t*lnd[i]);
+ }
+ u[m] = 2.0 * asin(u[m]) / M_PI;
+ }
+ return RES_OK;
+}
+
diff --git a/dspl/src/math_ellipj/ellip_asn_cmplx.c b/dspl/src/math_ellipj/ellip_asn_cmplx.c
new file mode 100644
index 0000000..82409e6
--- /dev/null
+++ b/dspl/src/math_ellipj/ellip_asn_cmplx.c
@@ -0,0 +1,152 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_asn_cmplx(complex_t* w, int n, double k, complex_t* u)
+\brief Inverse Jacobi elliptic function \f$ u = \textrm{sn}^{-1}(w, k)\f$
+of complex vector argument
+
+Function calculates inverse Jacobi elliptic function
+\f$ u = \textrm{sn}^{-1}(w, k)\f$ of complex vector `w`. \n
+
+\param[in] w
+Pointer to the argument vector \f$ w \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\param[in] n
+Size of vector `w`. \n
+
+\param[in] k
+Elliptical modulus \f$ k \f$. \n
+Elliptical modulus is real parameter,
+which values can be from 0 to 1. \n \n
+
+\param[out] u
+Pointer to the vector of inverse Jacobi elliptic function
+\f$ u = \textrm{sn}^{-1}(w, k)\f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_asn_cmplx(complex_t* w, int n, double k, complex_t* u)
+\brief Обратная эллиптическая функция Якоби
+ \f$ u = \textrm{sn}^{-1}(w, k)\f$ комплексного аргумента
+
+Функция рассчитывает значения значения обратной эллиптической функции
+\f$ u = \textrm{sn}^{-1}(w, k)\f$ для комплексного вектора `w`. \n
+
+Для расчета используется итерационный алгоритм на основе преобразования
+Ландена. \n
+
+
+\param[in] w
+Указатель на массив вектора переменной \f$ w \f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\param[in] n
+Размер вектора `w`. \n \n
+
+\param[in] k
+Значение эллиптического модуля \f$ k \f$. \n
+Эллиптический модуль -- вещественный параметр,
+принимающий значения от 0 до 1. \n \n
+
+\param[out] u
+Указатель на вектор значений обратной эллиптической
+функции \f$ u = \textrm{sn}^{-1}(w, k)\f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK`Расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API ellip_asn_cmplx(complex_t* w, int n, double k, complex_t* u)
+{
+ double lnd[ELLIP_ITER], t;
+ complex_t tmp0, tmp1;
+ int i, m;
+
+ if(!u || !w)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+ if(k < 0.0 || k>= 1.0)
+ return ERROR_ELLIP_MODULE;
+
+ ellip_landen(k,ELLIP_ITER, lnd);
+
+ for(m = 0; m < n; m++)
+ {
+ RE(u[m]) = RE(w[m]);
+ IM(u[m]) = IM(w[m]);
+ for(i = 1; i < ELLIP_ITER; i++)
+ {
+ RE(tmp0) = lnd[i-1]*RE(u[m]);
+ IM(tmp0) = lnd[i-1]*IM(u[m]);
+ RE(tmp1) = 1.0 - CMRE(tmp0, tmp0);
+ IM(tmp1) = - CMIM(tmp0, tmp0);
+
+ sqrt_cmplx(&tmp1, 1, &tmp0);
+ RE(tmp0) += 1.0;
+
+ RE(tmp1) = RE(tmp0) * (1.0 + lnd[i]);
+ IM(tmp1) = IM(tmp0) * (1.0 + lnd[i]);
+
+ t = 2.0 / ABSSQR(tmp1);
+
+ RE(tmp0) = t * CMCONJRE(u[m], tmp1);
+ IM(tmp0) = t * CMCONJIM(u[m], tmp1);
+
+ RE(u[m]) = RE(tmp0);
+ IM(u[m]) = IM(tmp0);
+ }
+
+ asin_cmplx(&tmp0, 1, u+m);
+ t = 2.0 / M_PI;
+ RE(u[m]) *= t;
+ IM(u[m]) *= t;
+ }
+ return RES_OK;
+}
diff --git a/dspl/src/math_ellipj/ellip_cd.c b/dspl/src/math_ellipj/ellip_cd.c
new file mode 100644
index 0000000..b899bd6
--- /dev/null
+++ b/dspl/src/math_ellipj/ellip_cd.c
@@ -0,0 +1,150 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_cd(double* u, int n, double k, double* y)
+\brief Jacobi elliptic function \f$ y = \textrm{cd}(u K(k), k)\f$
+of real vector argument
+
+Function calculates Jacobi elliptic function
+\f$ y = \textrm{cd}(u K(k), k)\f$ of real vector `u` and
+elliptical modulus `k`. \n
+
+\param[in] u
+Pointer to the argument vector \f$ u \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\param[in] n
+Size of vector `u`. \n
+
+\param[in] k
+Elliptical modulus \f$ k \f$. \n
+Elliptical modulus is real parameter,
+which values can be from 0 to 1. \n \n
+
+\param[out] y
+Pointer to the vector of Jacobi elliptic function
+\f$ y = \textrm{cd}(u K(k), k)\f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
+
+Example
+\include ellip_cd_test.c
+
+The program calculates two periods of the \f$ y = \textrm{cd}(u K(k), k)\f$
+function for different modulus values `k = 0`, `k= 0.9` и `k = 0.99`.
+Also program draws the plot of calculated elliptic functions.
+
+\image html ellip_cd.png
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_cd(double* u, int n, double k, double* y)
+\brief Эллиптическая функция Якоби
+\f$ y = \textrm{cd}(u K(k), k)\f$ вещественного аргумента
+
+Функция рассчитывает значения значения эллиптической функции
+\f$ y = \textrm{cd}(u K(k), k)\f$ для вещественного вектора `u` и
+эллиптического модуля `k`. \n
+
+Для расчета используется итерационный алгоритм на основе преобразования
+Ландена. \n
+
+\param[in] u
+Указатель на массив вектора переменной \f$ u \f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\param[in] n
+Размер вектора `u`. \n \n
+
+\param[in] k
+Значение эллиптического модуля \f$ k \f$. \n
+Эллиптический модуль -- вещественный параметр,
+принимающий значения от 0 до 1. \n \n
+
+\param[out] y
+Указатель на вектор значений эллиптической
+функции \f$ y = \textrm{cd}(u K(k), k)\f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` Расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+Пример представлен в следующем листинге:
+
+\include ellip_cd_test.c
+
+Программа рассчитывает два периода эллиптической функции
+\f$ y = \textrm{cd}(u K(k), k)\f$ для `k = 0`, `k= 0.9` и `k = 0.99`,
+а также выводит графики данных функций
+
+\image html ellip_cd.png
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API ellip_cd(double* u, int n, double k, double* y)
+{
+ double lnd[ELLIP_ITER];
+ int i, m;
+
+ if(!u || !y)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+ if(k < 0.0 || k>= 1.0)
+ return ERROR_ELLIP_MODULE;
+
+ ellip_landen(k,ELLIP_ITER, lnd);
+
+ for(m = 0; m < n; m++)
+ {
+ y[m] = cos(u[m] * M_PI * 0.5);
+ for(i = ELLIP_ITER-1; i>0; i--)
+ {
+ y[m] = (1.0 + lnd[i]) / (1.0 / y[m] + lnd[i]*y[m]);
+ }
+ }
+ return RES_OK;
+}
+
+
diff --git a/dspl/src/math_ellipj/ellip_cd_cmplx.c b/dspl/src/math_ellipj/ellip_cd_cmplx.c
new file mode 100644
index 0000000..d9e6d05
--- /dev/null
+++ b/dspl/src/math_ellipj/ellip_cd_cmplx.c
@@ -0,0 +1,143 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_cd_cmplx(complex_t* u, int n, double k, complex_t* y)
+\brief Jacobi elliptic function \f$ y = \textrm{cd}(u K(k), k)\f$
+of complex vector argument
+
+Function calculates Jacobi elliptic function
+\f$ y = \textrm{cd}(u K(k), k)\f$ of complex vector `u` and
+elliptical modulus `k`. \n
+
+\param[in] u
+Pointer to the argument vector \f$ u \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\param[in] n
+Size of vector `u`. \n
+
+\param[in] k
+Elliptical modulus \f$ k \f$. \n
+Elliptical modulus is real parameter,
+which values can be from 0 to 1. \n \n
+
+\param[out] y
+Pointer to the vector of Jacobi elliptic function
+\f$ y = \textrm{cd}(u K(k), k)\f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_cd_cmplx(complex_t* u, int n, double k, complex_t* y)
+\brief Эллиптическая функция Якоби
+ \f$ y = \textrm{cd}(u K(k), k)\f$ комплексного аргумента
+
+Функция рассчитывает значения значения эллиптической функции
+\f$ y = \textrm{cd}(u K(k), k)\f$ для комплексного вектора `u` и
+эллиптического модуля `k`. \n
+
+Для расчета используется итерационный алгоритм на основе преобразования
+Ландена. \n
+
+\param[in] u
+Указатель на массив вектора переменной \f$ u \f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\param[in] n
+Размер вектора `u`. \n \n
+
+\param[in] k
+Значение эллиптического модуля \f$ k \f$. \n
+Эллиптический модуль -- вещественный параметр,
+принимающий значения от 0 до 1. \n \n
+
+\param[out] y
+Указатель на вектор значений эллиптической
+функции \f$ y = \textrm{cd}(u K(k), k)\f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` Расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API ellip_cd_cmplx(complex_t* u, int n, double k, complex_t* y)
+{
+ double lnd[ELLIP_ITER], t;
+ int i, m;
+ complex_t tmp;
+
+ if(!u || !y)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+ if(k < 0.0 || k>= 1.0)
+ return ERROR_ELLIP_MODULE;
+
+ ellip_landen(k,ELLIP_ITER, lnd);
+
+ for(m = 0; m < n; m++)
+ {
+ RE(tmp) = RE(u[m]) * M_PI * 0.5;
+ IM(tmp) = IM(u[m]) * M_PI * 0.5;
+
+ cos_cmplx(&tmp, 1, y+m);
+
+ for(i = ELLIP_ITER-1; i>0; i--)
+ {
+ t = 1.0 / ABSSQR(y[m]);
+
+ RE(tmp) = RE(y[m]) * t + RE(y[m]) * lnd[i];
+ IM(tmp) = -IM(y[m]) * t + IM(y[m]) * lnd[i];
+
+ t = (1.0 + lnd[i]) / ABSSQR(tmp);
+
+ RE(y[m]) = RE(tmp) * t;
+ IM(y[m]) = -IM(tmp) * t;
+ }
+ }
+ return RES_OK;
+}
+
+
diff --git a/dspl/src/math_ellipj/ellip_landen.c b/dspl/src/math_ellipj/ellip_landen.c
new file mode 100644
index 0000000..a717f8e
--- /dev/null
+++ b/dspl/src/math_ellipj/ellip_landen.c
@@ -0,0 +1,197 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_landen(double k, int n, double* y)
+\brief Function calculates complete elliptical integral
+coefficients \f$ k_i \f$
+
+Complete elliptical integral \f$ K(k) \f$ can be described as:
+
+\f[
+ K(k) = \frac{\pi}{2} \prod_{i = 1}^{\infty}(1+k_i),
+\f]
+
+here \f$ k_i \f$ -- coefficients which calculated
+iterative from \f$ k_0 = k\f$:
+
+\f[
+ k_i = \left( \frac{k_{i-1}}{1+\sqrt{1-k_{i-1}^2}}\right)^2
+\f]
+
+This function calculates `n` fist coefficients \f$ k_i \f$, which can
+be used for Complete elliptical integral.
+
+\param[in] k
+Elliptical modulus \f$ k \f$. \n
+Elliptical modulus is real parameter, which values can be from 0 to 1. \n \n
+
+\param[in] n
+Number of \f$ k_i \f$ which need to calculate. \n
+Parameter `n` is size of output vector `y`. \n
+
+\param[out] y
+pointer to the real vector which keep \f$ k_i \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+ `RES_OK` -- successful exit, else \ref ERROR_CODE_GROUP "error code". \n
+
+Example:
+
+\include ellip_landen_test.c
+
+Result:
+
+\verbatim
+ i k[i]
+
+ 1 4.625e-01
+ 2 6.009e-02
+ 3 9.042e-04
+ 4 2.044e-07
+ 5 1.044e-14
+ 6 2.727e-29
+ 7 1.859e-58
+ 8 8.640e-117
+ 9 1.866e-233
+10 0.000e+00
+11 0.000e+00
+12 0.000e+00
+13 0.000e+00
+\endverbatim
+
+\note Complete elliptical integral converges enough fast
+ if modulus \f$ k<1 \f$. There are 10 to 20 coefficients \f$ k_i \f$
+ are sufficient for practical applications
+ to ensure complete elliptic integral precision within EPS.
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_landen(double k, int n, double* y)
+\brief Расчет коэффициентов \f$ k_i \f$ ряда полного эллиптического интеграла.
+
+Полный эллиптический интеграл \f$ K(k) \f$ может быть представлен рядом:
+
+\f[
+K(k) = \frac{\pi}{2} \prod_{i = 1}^{\infty}(1+k_i),
+\f]
+
+где \f$ k_i \f$ вычисляется итерационно при начальных условиях \f$ k_0 = k\f$:
+
+\f[
+ k_i = \left( \frac{k_{i-1}}{1+\sqrt{1-k_{i-1}^2}}\right)^2
+\f]
+
+Данная функция рассчитывает ряд первых `n` значений \f$ k_i \f$, которые в
+дальнейшем могут быть использованы для расчета эллиптического интеграла и
+эллиптических функций.
+
+\param[in] k
+Эллиптический модуль \f$ k \f$. \n
+
+\param[in] n
+Размер вектора `y` соответствующих коэффициентам \f$ k_i \f$. \n \n
+
+\param[out] y
+Указатель на вектор значений коэффициентов \f$ k_i \f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+
+\return
+`RES_OK` Расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+Пример использования функции `ellip_landen`:
+
+\include ellip_landen_test.c
+
+Результат работы программы:
+
+\verbatim
+ i k[i]
+
+ 1 4.625e-01
+ 2 6.009e-02
+ 3 9.042e-04
+ 4 2.044e-07
+ 5 1.044e-14
+ 6 2.727e-29
+ 7 1.859e-58
+ 8 8.640e-117
+ 9 1.866e-233
+10 0.000e+00
+11 0.000e+00
+12 0.000e+00
+13 0.000e+00
+\endverbatim
+
+\note
+Ряд полного эллиптического интеграла сходится при значениях
+эллиптического модуля \f$ k<1 \f$. При этом сходимость ряда достаточно
+быстрая и для практический приложений достаточно от 10 до 20 значений
+\f$ k_i \f$ для обеспечения погрешности при расчете полного
+эллиптического интеграла в пределах машинной точности.
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API ellip_landen(double k, int n, double* y)
+{
+ int i;
+ y[0] = k;
+
+ if(!y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+ if(k < 0.0 || k>= 1.0)
+ return ERROR_ELLIP_MODULE;
+
+ for(i = 1; i < n; i++)
+ {
+ y[i] = y[i-1] / (1.0 + sqrt(1.0 - y[i-1] * y[i-1]));
+ y[i] *= y[i];
+ }
+
+ return RES_OK;
+}
+
+
+
diff --git a/dspl/src/math_ellipj/ellip_modulareq.c b/dspl/src/math_ellipj/ellip_modulareq.c
new file mode 100644
index 0000000..2606b88
--- /dev/null
+++ b/dspl/src/math_ellipj/ellip_modulareq.c
@@ -0,0 +1,75 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API ellip_modulareq(double rp, double rs, int ord, double *k)
+{
+ double ep, es, ke, kp, t, sn = 0.0;
+ int i, L, r;
+
+ if(rp < 0 || rp == 0)
+ return ERROR_FILTER_RP;
+ if(rs < 0 || rs == 0)
+ return ERROR_FILTER_RS;
+ if(ord < 1)
+ return ERROR_FILTER_ORD;
+ if(!k)
+ return ERROR_PTR;
+
+
+ ep = sqrt(pow(10.0, rp*0.1)-1.0);
+ es = sqrt(pow(10.0, rs*0.1)-1.0);
+
+ ke = ep/es;
+
+ ke = sqrt(1.0 - ke*ke);
+
+ r = ord % 2;
+ L = (ord-r)/2;
+
+ kp = 1.0;
+ for(i = 0; i < L; i++)
+ {
+ t = (double)(2*i+1) / (double)ord;
+ ellip_sn(&t, 1, ke, &sn);
+ sn*=sn;
+ kp *= sn*sn;
+ }
+
+ kp *= pow(ke, (double)ord);
+ *k = sqrt(1.0 - kp*kp);
+
+ return RES_OK;
+
+}
+
diff --git a/dspl/src/math_ellipj/ellip_rat.c b/dspl/src/math_ellipj/ellip_rat.c
new file mode 100644
index 0000000..8c3daee
--- /dev/null
+++ b/dspl/src/math_ellipj/ellip_rat.c
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API ellip_rat(double* w, int n, int ord, double k, double* u)
+{
+ double t, xi, w2, xi2, k2;
+ int i, m, r, L;
+
+ if(!u || !w)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+ if(k < 0.0 || k>= 1.0)
+ return ERROR_ELLIP_MODULE;
+
+ r = ord%2;
+ L = (ord-r)/2;
+
+ if(r)
+ memcpy(u, w, n*sizeof(double));
+ else
+ {
+ for(m = 0; m < n; m++)
+ {
+ u[m] = 1.0;
+ }
+ }
+
+ k2 = k*k;
+ for(i = 0; i < L; i++)
+ {
+ t = (double)(2*i+1) / (double)ord;
+ ellip_cd(&t, 1, k, &xi);
+ xi2 = xi*xi;
+ for(m = 0; m < n; m++)
+ {
+ w2 = w[m]*w[m];
+ u[m] *= (w2 - xi2) / (1.0 - w2 * k2 * xi2);
+ u[m] *= (1.0 - k2*xi2) / (1.0 - xi2);
+ }
+ }
+ return RES_OK;
+}
+
+
diff --git a/dspl/src/math_ellipj/ellip_sn.c b/dspl/src/math_ellipj/ellip_sn.c
new file mode 100644
index 0000000..e75a270
--- /dev/null
+++ b/dspl/src/math_ellipj/ellip_sn.c
@@ -0,0 +1,152 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_sn(double* u, int n, double k, double* y)
+\brief Jacobi elliptic function \f$ y = \textrm{sn}(u K(k), k)\f$
+of real vector argument
+
+Function calculates Jacobi elliptic function
+\f$ y = \textrm{sn}(u K(k), k)\f$ of real vector `u` and
+elliptical modulus `k`. \n
+
+\param[in] u
+Pointer to the argument vector \f$ u \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\param[in] n
+Size of vector `u`. \n \n
+
+\param[in] k
+Elliptical modulus \f$ k \f$. \n
+Elliptical modulus is real parameter,
+which values can be from 0 to 1. \n \n
+
+\param[out] y
+Pointer to the vector of Jacobi elliptic function
+\f$ y = \textrm{sn}(u K(k), k)\f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
+
+Example
+\include ellip_sn_test.c
+
+The program calculates two periods of the \f$ y = \textrm{sn}(u K(k), k)\f$
+function for different modulus values `k = 0`, `k= 0.9` и `k = 0.99`.
+Also program draws the plot of calculated elliptic functions.
+
+\image html ellip_sn.png
+
+\author Sergey Bakhurin www.dsplib.org
+ **************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_sn(double* u, int n, double k, double* y)
+\brief Эллиптическая функция Якоби
+\f$ y = \textrm{sn}(u K(k), k)\f$ вещественного аргумента
+
+Функция рассчитывает значения значения эллиптической функции
+\f$ y = \textrm{sn}(u K(k), k)\f$ для вещественного вектора `u` и
+эллиптического модуля `k`. \n
+
+Для расчета используется итерационный алгоритм на основе преобразования
+Ландена. \n
+
+\param[in] u
+Указатель на массив вектора переменной \f$ u \f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\param[in] n
+Размер вектора `u`. \n \n
+
+\param[in] k
+Значение эллиптического модуля \f$ k \f$. \n
+Эллиптический модуль -- вещественный параметр,
+принимающий значения от 0 до 1. \n \n
+
+\param[out] y
+Указатель на вектор значений эллиптической
+функции \f$ y = \textrm{sn}(u K(k), k)\f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` Расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+
+Пример представлен в следующем листинге:
+
+\include ellip_sn_test.c
+
+Программа рассчитывает два периода эллиптической функции
+\f$ y = \textrm{sn}(u K(k), k)\f$ для `k = 0`, `k= 0.9` и `k = 0.99`,
+а также выводит графики данных функций
+
+\image html ellip_sn.png
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API ellip_sn(double* u, int n, double k, double* y)
+{
+ double lnd[ELLIP_ITER];
+ int i, m;
+
+ if(!u || !y)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+ if(k < 0.0 || k>= 1.0)
+ return ERROR_ELLIP_MODULE;
+
+ ellip_landen(k,ELLIP_ITER, lnd);
+
+
+ for(m = 0; m < n; m++)
+ {
+ y[m] = sin(u[m] * M_PI * 0.5);
+ for(i = ELLIP_ITER-1; i>0; i--)
+ {
+ y[m] = (1.0 + lnd[i]) / (1.0 / y[m] + lnd[i]*y[m]);
+ }
+ }
+ return RES_OK;
+}
+
diff --git a/dspl/src/math_ellipj/ellip_sn_cmplx.c b/dspl/src/math_ellipj/ellip_sn_cmplx.c
new file mode 100644
index 0000000..7055eef
--- /dev/null
+++ b/dspl/src/math_ellipj/ellip_sn_cmplx.c
@@ -0,0 +1,143 @@
+/*
+* Copyright (c) 2015-2019 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_sn_cmplx(complex_t* u, int n, double k, complex_t* y)
+\brief Jacobi elliptic function \f$ y = \textrm{sn}(u K(k), k)\f$ of
+complex vector argument
+
+Function calculates Jacobi elliptic function
+\f$ y = \textrm{sn}(u K(k), k)\f$ of complex vector `u` and
+elliptical modulus `k`. \n
+
+\param[in] u
+Pointer to the argument vector \f$ u \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\param[in] n
+Size of vector `u`. \n
+
+\param[in] k
+Elliptical modulus \f$ k \f$. \n
+Elliptical modulus is real parameter,
+which values can be from 0 to 1. \n \n
+
+\param[out] y
+Pointer to the vector of Jacobi elliptic function
+\f$ y = \textrm{sn}(u K(k), k)\f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` successful exit, else \ref ERROR_CODE_GROUP "error code". \n
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_ELLIP_GROUP
+\fn int ellip_sn_cmplx(complex_t* u, int n, double k, complex_t* y)
+\brief Эллиптическая функция Якоби
+\f$ y = \textrm{sn}(u K(k), k)\f$ комплексного аргумента
+
+Функция рассчитывает значения значения эллиптической функции
+\f$ y = \textrm{sn}(u K(k), k)\f$ для комплексного вектора `u` и
+эллиптического модуля `k`. \n
+
+Для расчета используется итерационный алгоритм на основе преобразования
+Ландена. \n
+
+\param[in] u
+Указатель на массив вектора переменной \f$ u \f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\param[in] n
+Размер вектора `u`. \n \n
+
+\param[in] k
+Значение эллиптического модуля \f$ k \f$. \n
+Эллиптический модуль -- вещественный параметр,
+принимающий значения от 0 до 1. \n \n
+
+\param[out] y
+Указатель на вектор значений эллиптической
+функции \f$ y = \textrm{sn}(u K(k), k)\f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` Расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API ellip_sn_cmplx(complex_t* u, int n, double k, complex_t* y)
+{
+ double lnd[ELLIP_ITER], t;
+ int i, m;
+ complex_t tmp;
+
+ if(!u || !y)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+ if(k < 0.0 || k>= 1.0)
+ return ERROR_ELLIP_MODULE;
+
+ ellip_landen(k,ELLIP_ITER, lnd);
+
+
+ for(m = 0; m < n; m++)
+ {
+ RE(tmp) = RE(u[m]) * M_PI * 0.5;
+ IM(tmp) = IM(u[m]) * M_PI * 0.5;
+
+ sin_cmplx(&tmp, 1, y+m);
+
+ for(i = ELLIP_ITER-1; i>0; i--)
+ {
+ t = 1.0 / ABSSQR(y[m]);
+
+ RE(tmp) = RE(y[m]) * t + RE(y[m]) * lnd[i];
+ IM(tmp) = -IM(y[m]) * t + IM(y[m]) * lnd[i];
+
+ t = (1.0 + lnd[i]) / ABSSQR(tmp);
+
+ RE(y[m]) = RE(tmp) * t;
+ IM(y[m]) = -IM(tmp) * t;
+
+ }
+ }
+ return RES_OK;
+}
diff --git a/dspl/src/types.c b/dspl/src/types.c
new file mode 100644
index 0000000..82869f6
--- /dev/null
+++ b/dspl/src/types.c
@@ -0,0 +1,2 @@
+#include "types/cmplx2re.c"
+#include "types/re2cmplx.c"
\ No newline at end of file
diff --git a/dspl/src/complex.c b/dspl/src/types/cmplx2re.c
similarity index 60%
rename from dspl/src/complex.c
rename to dspl/src/types/cmplx2re.c
index c6ef540..db8a142 100644
--- a/dspl/src/complex.c
+++ b/dspl/src/types/cmplx2re.c
@@ -1,262 +1,150 @@
-/*
-* Copyright (c) 2015-2020 Sergey Bakhurin
-* Digital Signal Processing Library [http://dsplib.org]
-*
-* This file is part of DSPL.
-*
-* is free software: you can redistribute it and/or modify
-* it under the terms of the GNU 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 General Public License
-* along with Foobar. If not, see .
-*/
-
-
-#include
-#include
-#include "dspl.h"
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! ****************************************************************************
-\ingroup TYPES_GROUP
-\fn int cmplx2re(complex_t* x, int n, double* re, double* im)
-\brief Separate complex vector to the real and image vectors
-
-Function fills `re` and `im` vectors corresponds to real and image
-parts of the input complex array `x`. \n
-
-
-\param[in] x
-Pointer to the real complex vector. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of the input complex vector `x` and real and image
-vectors `re` and `im`. \n \n
-
-\param[out] re
-Pointer to the real part vector. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\param[out] im
-Pointer to the image part vector. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if function converts complex vector successfully. \n
-Else \ref ERROR_CODE_GROUP "code error". \n
-
-Example: \n
-\code{.cpp}
- complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
- double re[3], im[3];
-
- cmplx2re(x, 3, re, im);
-\endcode
-
-Vectors `re` and `im` will contains:
-
-\verbatim
-re[0] = 1.0; im[0] = 2.0;
-re[1] = 3.0; im[1] = 4.0;
-re[2] = 5.0; im[2] = 6.0;
-\endverbatim
-
-\author Sergey Bakhurin. www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup TYPES_GROUP
-\fn int cmplx2re(complex_t* x, int n, double* re, double* im)
-\brief Преобразование массива комплексных данных в два массива
- вещественных данных, содержащих реальную и мнимую части
- исходного массива
-
-Функция заполняет реальные массивы `re` и `im` соответствующими значениями
-реальной и мнимой частей исходного комплексного массива `x`. \n
-
-
-\param[in] x
-Указатель на массив комплексных данных. \n
-Размер массива `[n x 1]`. \n \n
-
-\param[in] n
-Размер массивов входных и выходных данных. \n \n
-
-\param[out] re
-Указатель на адрес массива реальной части данных. \n
-Размер массива `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\param[out] im
-Указатель на адрес массива мнимой части данных. \n
-Размер массива `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если преобразование произведено успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки": \n
-
-Например при выполнении следующего кода
-\code{.cpp}
- complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
- double re[3], im[3];
-
- cmplx2re(x, 3, re, im);
-\endcode
-
-Элементам массивов `re` и `im` будут присвоены значения:
-
-\verbatim
-re[0] = 1.0; im[0] = 2.0;
-re[1] = 3.0; im[1] = 4.0;
-re[2] = 5.0; im[2] = 6.0;
-\endverbatim
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API cmplx2re(complex_t* x, int n, double* re, double* im)
-{
- int k;
- if(!x)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
-
- if(re)
- {
- for(k = 0; k < n; k++)
- re[k] = RE(x[k]);
- }
- if(im)
- {
- for(k = 0; k < n; k++)
- im[k] = IM(x[k]);
- }
- return RES_OK;
-}
-
-
-
-
-#ifdef DOXYGEN_ENGLISH
-/*! *****************************************************************************
-\ingroup TYPES_GROUP
-\fn int re2cmplx(double* x, int n, complex_t *y)
-\brief Convert real array to the complex array.
-
-Function copies the vector `x` to the real part of vector `y`.
-Image part of the vector `y` sets as zero. \n
-So complex vector contains data: \n
-`y[i] = x[i] + j0, here i = 0,1,2 ... n-1`
-
-\param[in] x
-Pointer to the real vector `x`. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of the real vector `x` and complex vector `y`. \n \n
-
-\param[out] y
-Pointer to the complex vector `y`. \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 "code error": \n
-
-Example:
-\code{.cpp}
- double x[3] = {1.0, 2.0, 3.0};
- complex_t y[3];
-
- re2cmplx(x, 3, y);
-\endcode
-
-Vector `y` will keep:
-
-\verbatim
- y[0] = 1+0j;
- y[1] = 2+0j;
- y[2] = 3+0j.
-\endverbatim
-
-\author Sergey Bakhurin. www.dsplib.org
-***************************************************************************** */
-#endif
-#ifdef DOXYGEN_RUSSIAN
-/*! ****************************************************************************
-\ingroup TYPES_GROUP
-\fn int re2cmplx(double* x, int n, complex_t *y)
-\brief Преобразование массива вещественных данных в массив комплексных данных.
-
-Функция заполняет реальные части массива `y` данных соответсвующими значениями
-исходного вещественного массива `x`. \n
-
-
-\param[in] x
-Указатель на массив вещественных данных. \n
-Размер массива `[n x 1]`. \n \n
-
-\param[in] n
-Размер массивов входных и выходных данных. \n \n
-
-\param[out] y
-Указатель на адрес массива комплексных данных. \n
-Размер массива `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-
-\return
-`RES_OK` если преобразование произведено успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки": \n
-
-Например при выполнении следующего кода
-\code{.cpp}
- double x[3] = {1.0, 2.0, 3.0};
- complex_t y[3];
-
- re2cmplx(x, 3, y);
-\endcode
-
-Значениям `y` будут присвоены значения:
-
-\verbatim
- y[0] = 1+0j;
- y[1] = 2+0j;
- y[2] = 3+0j.
-\endverbatim
-
-\author Бахурин Сергей www.dsplib.org
-***************************************************************************** */
-#endif
-int DSPL_API re2cmplx(double* x, int n, complex_t* y)
-{
- int k;
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
-
- for(k = 0; k < n; k++)
- {
- RE(y[k]) = x[k];
- IM(y[k]) = 0.0;
- }
- return RES_OK;
-}
-
-
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include "dspl.h"
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup TYPES_GROUP
+\fn int cmplx2re(complex_t* x, int n, double* re, double* im)
+\brief Separate complex vector to the real and image vectors
+
+Function fills `re` and `im` vectors corresponds to real and image
+parts of the input complex array `x`. \n
+
+
+\param[in] x
+Pointer to the real complex vector. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of the input complex vector `x` and real and image
+vectors `re` and `im`. \n \n
+
+\param[out] re
+Pointer to the real part vector. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\param[out] im
+Pointer to the image part vector. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if function converts complex vector successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
+
+Example: \n
+\code{.cpp}
+ complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
+ double re[3], im[3];
+
+ cmplx2re(x, 3, re, im);
+\endcode
+
+Vectors `re` and `im` will contains:
+
+\verbatim
+re[0] = 1.0; im[0] = 2.0;
+re[1] = 3.0; im[1] = 4.0;
+re[2] = 5.0; im[2] = 6.0;
+\endverbatim
+
+\author Sergey Bakhurin. www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup TYPES_GROUP
+\fn int cmplx2re(complex_t* x, int n, double* re, double* im)
+\brief Преобразование массива комплексных данных в два массива
+ вещественных данных, содержащих реальную и мнимую части
+ исходного массива
+
+Функция заполняет реальные массивы `re` и `im` соответствующими значениями
+реальной и мнимой частей исходного комплексного массива `x`. \n
+
+
+\param[in] x
+Указатель на массив комплексных данных. \n
+Размер массива `[n x 1]`. \n \n
+
+\param[in] n
+Размер массивов входных и выходных данных. \n \n
+
+\param[out] re
+Указатель на адрес массива реальной части данных. \n
+Размер массива `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\param[out] im
+Указатель на адрес массива мнимой части данных. \n
+Размер массива `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если преобразование произведено успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки": \n
+
+Например при выполнении следующего кода
+\code{.cpp}
+ complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
+ double re[3], im[3];
+
+ cmplx2re(x, 3, re, im);
+\endcode
+
+Элементам массивов `re` и `im` будут присвоены значения:
+
+\verbatim
+re[0] = 1.0; im[0] = 2.0;
+re[1] = 3.0; im[1] = 4.0;
+re[2] = 5.0; im[2] = 6.0;
+\endverbatim
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API cmplx2re(complex_t* x, int n, double* re, double* im)
+{
+ int k;
+ if(!x)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+
+ if(re)
+ {
+ for(k = 0; k < n; k++)
+ re[k] = RE(x[k]);
+ }
+ if(im)
+ {
+ for(k = 0; k < n; k++)
+ im[k] = IM(x[k]);
+ }
+ return RES_OK;
+}
+
diff --git a/dspl/src/types/re2cmplx.c b/dspl/src/types/re2cmplx.c
new file mode 100644
index 0000000..be5cb40
--- /dev/null
+++ b/dspl/src/types/re2cmplx.c
@@ -0,0 +1,136 @@
+/*
+* Copyright (c) 2015-2020 Sergey Bakhurin
+* Digital Signal Processing Library [http://dsplib.org]
+*
+* This file is part of DSPL.
+*
+* is free software: you can redistribute it and/or modify
+* it under the terms of the GNU 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 General Public License
+* along with Foobar. If not, see .
+*/
+
+
+#include
+#include
+#include "dspl.h"
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! *****************************************************************************
+\ingroup TYPES_GROUP
+\fn int re2cmplx(double* x, int n, complex_t *y)
+\brief Convert real array to the complex array.
+
+Function copies the vector `x` to the real part of vector `y`.
+Image part of the vector `y` sets as zero. \n
+So complex vector contains data: \n
+`y[i] = x[i] + j0, here i = 0,1,2 ... n-1`
+
+\param[in] x
+Pointer to the real vector `x`. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of the real vector `x` and complex vector `y`. \n \n
+
+\param[out] y
+Pointer to the complex vector `y`. \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 "code error": \n
+
+Example:
+\code{.cpp}
+ double x[3] = {1.0, 2.0, 3.0};
+ complex_t y[3];
+
+ re2cmplx(x, 3, y);
+\endcode
+
+Vector `y` will keep:
+
+\verbatim
+ y[0] = 1+0j;
+ y[1] = 2+0j;
+ y[2] = 3+0j.
+\endverbatim
+
+\author Sergey Bakhurin. www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup TYPES_GROUP
+\fn int re2cmplx(double* x, int n, complex_t *y)
+\brief Преобразование массива вещественных данных в массив комплексных данных.
+
+Функция заполняет реальные части массива `y` данных соответсвующими значениями
+исходного вещественного массива `x`. \n
+
+
+\param[in] x
+Указатель на массив вещественных данных. \n
+Размер массива `[n x 1]`. \n \n
+
+\param[in] n
+Размер массивов входных и выходных данных. \n \n
+
+\param[out] y
+Указатель на адрес массива комплексных данных. \n
+Размер массива `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+
+\return
+`RES_OK` если преобразование произведено успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки": \n
+
+Например при выполнении следующего кода
+\code{.cpp}
+ double x[3] = {1.0, 2.0, 3.0};
+ complex_t y[3];
+
+ re2cmplx(x, 3, y);
+\endcode
+
+Значениям `y` будут присвоены значения:
+
+\verbatim
+ y[0] = 1+0j;
+ y[1] = 2+0j;
+ y[2] = 3+0j.
+\endverbatim
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API re2cmplx(double* x, int n, complex_t* y)
+{
+ int k;
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+
+ for(k = 0; k < n; k++)
+ {
+ RE(y[k]) = x[k];
+ IM(y[k]) = 0.0;
+ }
+ return RES_OK;
+}
+
+
diff --git a/dspl/src/unwrap.c b/dspl/src/unwrap.c
new file mode 100644
index 0000000..6a0214f
--- /dev/null
+++ b/dspl/src/unwrap.c
@@ -0,0 +1,83 @@
+/*
+* 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 .
+*/
+
+
+#include
+#include
+#include
+#include "dspl.h"
+
+
+
+
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API unwrap(double* phi, int n, double lev, double mar)
+{
+ double a[2] = {0.0, 0.0};
+ double d;
+ double th;
+ int k;
+ int flag = 1;
+
+ if(!phi)
+ return ERROR_PTR;
+
+ if(n<1)
+ return ERROR_SIZE;
+
+ if(lev<=0 || mar <=0)
+ return ERROR_UNWRAP;
+
+ th = mar*lev;
+ while(flag)
+ {
+ flag = 0;
+ a[0] = a[1] = 0.0;
+ for(k = 0; k th)
+ {
+ a[0] -= lev;
+ flag = 1;
+ }
+ if( d < -th)
+ {
+ a[0] += lev;
+ flag = 1;
+ }
+ phi[k]+=a[1];
+ a[1] = a[0];
+ }
+ phi[n-1]+=a[1];
+ }
+
+ return RES_OK;
+}
+