iir function is using normlization:

a[m] = a[m] / a[0], m = 1... ord
b[m] = b[m] / a[0], m = 1... ord
a[0] = 1.0

added doc for individual functions group_delay and phase_delay

filter_iir is also using normlization
a[m] = a[m] / a[0], m = 1... ord
b[m] = b[m] / a[0], m = 1... ord
a[0] = 1.0

Changes to be committed:
modified:   dspl/src/conv.c
modified:   dspl/src/filter_an.c
modified:   dspl/src/filter_iir.c
pull/6/merge
Dsplib 2020-08-29 16:10:42 +03:00
rodzic ea9bbcfee9
commit 52a33913b3
3 zmienionych plików z 163 dodań i 13 usunięć

Wyświetl plik

@ -993,15 +993,16 @@ dat/sf.txt - сигнал на выходе фильтра.
int DSPL_API filter_iir(double* b, double* a, int ord,
double* x, int n, double* y)
{
double* buf = NULL;
double* an = NULL;
double *buf = NULL;
double *an = NULL;
double *bn = NULL;
double u;
int k;
int m;
int count;
if(!b || !x || !y)
return ERROR_PTR;
return ERROR_PTR;
if(ord < 1 || n < 1)
return ERROR_SIZE;
@ -1016,10 +1017,19 @@ int DSPL_API filter_iir(double* b, double* a, int ord,
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++)
{
@ -1032,13 +1042,15 @@ int DSPL_API filter_iir(double* b, double* a, int ord,
buf[0] = x[k] - u;
y[k] = 0.0;
for(m = 0; m < count; m++)
y[k] += buf[m] * b[m];
y[k] += buf[m] * bn[m];
}
if(buf)
free(buf);
if(an)
free(an);
if(bn && (bn != b))
free(bn);
return RES_OK;
}

Wyświetl plik

@ -31,7 +31,7 @@
#ifdef DOXYGEN_ENGLISH
/*! ****************************************************************************
\ingroup FILTER_ANALYSIS_GROUP
int DSPL_API group_delay(double* b, double* a, int ord, int flag,
\fn int DSPL_API group_delay(double* b, double* a, int ord, int flag,
double* w, int n, double* tau)
\brief
@ -40,7 +40,7 @@ Group delay calculation for digital or analog filter corresponds to
Group delay is describes as:
\f[
\tau_g(\omega) = - \dfrac{d\Phi(\omega)}{d\omega},
\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.
@ -98,14 +98,14 @@ Else \ref ERROR_CODE_GROUP "code error".
#ifdef DOXYGEN_RUSSIAN
/*! ****************************************************************************
\ingroup FILTER_ANALYSIS_GROUP
int DSPL_API group_delay(double* b, double* a, int ord, int flag,
\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) = - \dfrac{d\Phi(\omega)}{d\omega},
\tau_g(\omega) = - \frac{d\Phi(\omega)}{d\omega},
\f]
где \f$\Phi(\omega)\f$ -- ФЧХ фильтра, \f$\omega\f$ циктическая частот в случае
аналогового фильтра, или нормированная частота цифрового фильтра.
@ -157,7 +157,7 @@ DSPL_FLAG_DIGITAL Коэффициенты относятся к цифрово
Память должна быть выделена. \n
\return
`RES_OK` Параметры фильтра рассчитаны успешно. \n
`RES_OK` групповая задержка фильтра рассчитана успешно. \n
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
\author Бахурин Сергей www.dsplib.org
@ -1053,10 +1053,139 @@ exit_label:
#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_g(\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)
@ -1069,13 +1198,13 @@ int DSPL_API phase_delay(double* b, double* a, int ord, int flag,
else
return ERROR_SIZE;
err = filter_freq_resp(b, a, ord, w, n,
flag | DSPL_FLAG_UNWRAP, NULL, phi, NULL);
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);

Wyświetl plik

@ -410,7 +410,8 @@ int DSPL_API iir(double rp, double rs, int ord, double w0, double w1,
double *at = NULL;
double wa0, wa1, ws;
int err, ord_ap = ord;
int i;
if(((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_LPF) ||
((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_HPF))
{
@ -477,6 +478,14 @@ int DSPL_API iir(double rp, double rs, int ord, double w0, double w1,
err = bilinear(bt, at, ord, b, a);
for(i = 1; i <= ord; i++)
{
a[i] /= a[0];
b[i] /= a[0];
}
b[0] /= a[0];
a[0] = 1.0;
error_proc: