New project structure for filter design algorithms

Changes to be committed:
	deleted:    dspl/src/conv.c
	new file:   dspl/src/convolution.c
	new file:   dspl/src/convolution/conv.c
	new file:   dspl/src/convolution/conv_cmplx.c
	new file:   dspl/src/convolution/conv_fft.c
	new file:   dspl/src/convolution/conv_fft_cmplx.c
	new file:   dspl/src/convolution/filter_iir.c
	deleted:    dspl/src/ellipj.c
	deleted:    dspl/src/filter_an.c
	deleted:    dspl/src/filter_ap.c
	new file:   dspl/src/filter_design.c
	new file:   dspl/src/filter_design/bilinear.c
	new file:   dspl/src/filter_design/butter_ap.c
	new file:   dspl/src/filter_design/butter_ap_zp.c
	new file:   dspl/src/filter_design/cheby1_ap.c
	new file:   dspl/src/filter_design/cheby1_ap_zp.c
	new file:   dspl/src/filter_design/cheby2_ap.c
	new file:   dspl/src/filter_design/cheby2_ap_wp1.c
	new file:   dspl/src/filter_design/cheby2_ap_zp.c
	new file:   dspl/src/filter_design/ellip_ap.c
	new file:   dspl/src/filter_design/ellip_ap_zp.c
	new file:   dspl/src/filter_design/filter_freq_resp.c
	new file:   dspl/src/filter_design/filter_ws1.c
	new file:   dspl/src/filter_design/filter_zp2ab.c
	renamed:    dspl/src/filter_fir.c -> dspl/src/filter_design/fir_linphase.c
	new file:   dspl/src/filter_design/fir_linphase_lpf.c
	new file:   dspl/src/filter_design/freqs.c
	new file:   dspl/src/filter_design/freqs2time.c
	new file:   dspl/src/filter_design/freqs_cmplx.c
	new file:   dspl/src/filter_design/freqz.c
	new file:   dspl/src/filter_design/group_delay.c
	renamed:    dspl/src/filter_iir.c -> dspl/src/filter_design/iir.c
	new file:   dspl/src/filter_design/iir_ap.c
	new file:   dspl/src/filter_design/low2bp.c
	new file:   dspl/src/filter_design/low2bs.c
	new file:   dspl/src/filter_design/low2high.c
	new file:   dspl/src/filter_design/low2low.c
	new file:   dspl/src/filter_design/phase_delay.c
	new file:   dspl/src/filter_design/ratcompos.c
	deleted:    dspl/src/filter_ft.c
	new file:   dspl/src/math_ellipj.c
	new file:   dspl/src/math_ellipj/ellip_acd.c
	new file:   dspl/src/math_ellipj/ellip_acd_cmplx.c
	new file:   dspl/src/math_ellipj/ellip_asn.c
	new file:   dspl/src/math_ellipj/ellip_asn_cmplx.c
	new file:   dspl/src/math_ellipj/ellip_cd.c
	new file:   dspl/src/math_ellipj/ellip_cd_cmplx.c
	new file:   dspl/src/math_ellipj/ellip_landen.c
	new file:   dspl/src/math_ellipj/ellip_modulareq.c
	new file:   dspl/src/math_ellipj/ellip_rat.c
	new file:   dspl/src/math_ellipj/ellip_sn.c
	new file:   dspl/src/math_ellipj/ellip_sn_cmplx.c
	new file:   dspl/src/types.c
	renamed:    dspl/src/complex.c -> dspl/src/types/cmplx2re.c
	new file:   dspl/src/types/re2cmplx.c
	new file:   dspl/src/unwrap.c
pull/6/merge
Dsplib 2021-12-29 16:31:00 +03:00
rodzic c76bd63ace
commit 945a7fd417
56 zmienionych plików z 8585 dodań i 7541 usunięć

Plik diff jest za duży Load Diff

Wyświetl plik

@ -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"

Wyświetl plik

@ -0,0 +1,193 @@
/*
* Copyright (c) 2015-2020 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of 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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#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;
}

Plik diff jest za duży Load Diff

Plik diff jest za duży Load Diff

Plik diff jest za duży Load Diff

Wyświetl plik

@ -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"

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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);
}

Wyświetl plik

@ -0,0 +1,209 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -0,0 +1,96 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -18,52 +18,13 @@
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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
/*! ****************************************************************************

Wyświetl plik

@ -0,0 +1,65 @@
/*
* Copyright (c) 2015-2019 Sergey Bakhurin
* Digital Signal Processing Library [http://dsplib.org]
*
* This file is part of libdspl-2.0.
*
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DSPL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API 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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API 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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -18,206 +18,13 @@
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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
@ -501,38 +308,3 @@ error_proc:
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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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);
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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);
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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);
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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);
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

Wyświetl plik

@ -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"

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}

2
dspl/src/types.c 100644
Wyświetl plik

@ -0,0 +1,2 @@
#include "types/cmplx2re.c"
#include "types/re2cmplx.c"

Wyświetl plik

@ -148,115 +148,3 @@ int DSPL_API cmplx2re(complex_t* x, int n, double* re, double* im)
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;
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#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;
}

83
dspl/src/unwrap.c 100644
Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
#ifdef DOXYGEN_ENGLISH
#endif
#ifdef DOXYGEN_RUSSIAN
#endif
int DSPL_API 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<n-1; k++)
{
d = phi[k+1] - phi[k];
if( d > 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;
}