diff --git a/dspl/dox/doxyfile_en b/dspl/dox/doxyfile_en
index de9a690..367247b 100644
--- a/dspl/dox/doxyfile_en
+++ b/dspl/dox/doxyfile_en
@@ -2168,7 +2168,7 @@ ENABLE_PREPROCESSING = YES
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-MACRO_EXPANSION = YES
+MACRO_EXPANSION = NO
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
# the macro expansion is limited to the macros specified with the PREDEFINED and
@@ -2176,7 +2176,7 @@ MACRO_EXPANSION = YES
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-EXPAND_ONLY_PREDEF = YES
+EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES, the include files in the
# INCLUDE_PATH will be searched if a #include is found.
@@ -2209,7 +2209,8 @@ INCLUDE_FILE_PATTERNS =
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = DSPL_API \
- BUILD_LIB
+ BUILD_LIB \
+ DOXYGEN_ENGLISH
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
@@ -2219,7 +2220,8 @@ PREDEFINED = DSPL_API \
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_AS_DEFINED = DSPL_API \
- BUILD_LIB
+ BUILD_LIB \
+ DOXYGEN_ENGLISH
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have
diff --git a/dspl/dox/doxyfile_ru b/dspl/dox/doxyfile_ru
index 7ac3ce4..53af314 100644
--- a/dspl/dox/doxyfile_ru
+++ b/dspl/dox/doxyfile_ru
@@ -2209,7 +2209,8 @@ INCLUDE_FILE_PATTERNS =
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = DSPL_API \
- BUILD_LIB
+ BUILD_LIB \
+ DOXYGEN_RUSSIAN
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
@@ -2219,7 +2220,8 @@ PREDEFINED = DSPL_API \
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_AS_DEFINED = DSPL_API \
- BUILD_LIB
+ BUILD_LIB \
+ DOXYGEN_RUSSIAN
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have
diff --git a/dspl/dox/en/array.dox b/dspl/dox/en/array.dox
deleted file mode 100644
index cb894fe..0000000
--- a/dspl/dox/en/array.dox
+++ /dev/null
@@ -1,655 +0,0 @@
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int array_scale_lin(double* x, int n,
- double xmin, double xmax, double dx,
- double h, double* y)
-\brief Vector `x` linear transformation
-
-Function transforms values \f$x(i)\f$, \f$i = 0,1,\ldots n\f$
-to the \f$y(i)\f$, accordint to equation:
-
-\f[
-y(i) = k_x x(i) + d_x, \qquad k_x =
-\frac{h}{x_{\textrm{max}} - x_{\textrm{min}}}.
-\f]
-
-All values of the vector `x` between
-\f$x_{\textrm{min}}\f$ and \f$x_{\textrm{max}}\f$, transforms to
-the vector `y` between \f$d_x\f$ and \f$h + d_x\f$.
-Parameter \f$d_x\f$ sets mean shift of the vector `y`.
-
-This function is convenient for translating values
-of different dimensions. For example it can be used
-to transfer the values of the vector `x`
-to the graph of the height of` h`, where the height can
-be set in the number of pixels, in centimeters, etc.
-
-\param[in] x
-Pointer to the input vector `x`. \n
-Vector size is `[n x 1]`. \n
-\n
-
-\param[in] n
-Size of vector `x`. \n
-\n
-
-\param[in] xmin
-Parameter \f$x_{\textrm{min}}\f$. \n
-\n
-
-\param[in] xmax
-Parameter \f$x_{\textrm{min}}\f$. \n
-Value `xmax` must be more than `xmin`. \n
-\n
-
-\param[in] dx
-Displacement after transformation. \n
-This parameter must have output vector `y`
-dimensions (pixels, centimeters). \n
-\n
-
-\param[in] h
-Height of vector `y` after transforming between `dx` and `h+dx`. \n
-\n
-
-\param[out] y
-Pointer to the output vector `y`. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n
-\note
-Pointer `y` can be equal to `x`.
-Velues of vector `x` will be rewritten in this case. \n
-\n
-
-\return
-`RES_OK` if function returns successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\author Sergey Bakhurin www.dsplib.org
-**************************************************************************** */
-
-
-
-/*! ****************************************************************************
-\fn int concat(void* a, size_t na, void* b, size_t nb, void* c)
-\brief
-Concatenate arrays `a` and `b`
-
-Let's arrays `a` and `b` are vectors: \n
-`a = [a(0), a(1), ... a(na-1)]`, \n
-`b = [b(0), b(1), ... b(nb-1)]`, \n
-concatenation of these arrays will be array `c` size `na+nb`: \n
-`c = [a(0), a(1), ... a(na-1), b(0), b(1), ... b(nb-1)]`.
-
-
-\param[in] a
-Pointer to the first array `a`. \n
-Array `a` size is `na` bytes. \n
-\n
-
-\param[in] na
-Array `a` size (bytes). \n
-\n
-
-\param[in] b
-Pointer to the second array `b`. \n
-Array `b` size is `nb` bytes. \n
-\n
-
-\param[in] nb
-Array `a` size (bytes). \n
-\n
-
-\param[out] c
-Pointer to the concatenation result array `c`. \n
-Array `c` size is `na + nb` bytes. \n
-Memory must be allocated. \n
-\n
-
-\return
-`RES_OK` if function returns successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-Function uses pointer type `void*` and can be useful for an arrays
-concatenation with different types. \n
-For example two `double` arrays concatenation:
-\code{.cpp}
-double a[3] = {1.0, 2.0, 3.0};
-double b[2] = {4.0, 5.0};
-double c[5];
-
-concat((void*)a, 3*sizeof(double), (void*)b, 2*sizeof(double), (void*)c);
-\endcode
-Vector `c` keeps follow data:
-\verbatim
-c = [1.0, 2.0, 3.0, 4.0, 5.0]
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-****************************************************************************** */
-
-
-/*! *****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int decimate(double* x, int n, int d, double* y, int* cnt)
-\brief
-Real vector decimation
-
-Function `d` times decimates real vector `x`. \n
-Output vector `y` keeps values corresponds to:
-`y(k) = x(k*d), k = 0...n/d-1` \n
-
-\param[in] x
-Pointer to the input real vector `x`. \n
-Vector `x` size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of input vector `x`. \n \n
-
-\param[in] d
-Decimation coefficient. \n
-Each d-th vector will be copy from vector `x` to the
-output vector `y`. \n \n
-
-\param[out] y
-Pointer to the output decimated vector `y`. \n
-Output vector size is `[n/d x 1]` will be copy
-to the address `cnt`. \n
-
-\param[out] cnt
-Address which will keep decimated vector `y` size. \n
-Pointer can be `NULL`, vector `y` will not return
-in this case. \n \n
-
-\return
-`RES_OK` if function calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-Two-times decimation example:
-\code{.cpp}
-double x[10] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
-double y[5];
-int d = 2;
-int cnt;
-
-decimate(x, 10, d, y, &cnt);
-\endcode
-As result variable `cnt` will be written value 5 and
-vector `y` will keep array:
-\verbatim
-c = [0.0, 2.0, 4.0, 6.0, 8.0]
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-****************************************************************************** */
-
-
-/*! *****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int decimate_cmplx(complex_t* x, int n, int d, complex_t* y, int* cnt)
-\brief
-Complex vector decimation
-
-Function `d` times decimates a complex vector `x`. \n
-Output vector `y` keeps values corresponds to:
-`y(k) = x(k*d), k = 0...n/d-1` \n
-
-\param[in] x
-Pointer to the input complex vector `x`. \n
-Vector `x` size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of input vector `x`. \n \n
-
-\param[in] d
-Decimation coefficient. \n
-Each d-th vector will be copy from vector `x` to the
-output vector `y`. \n \n
-
-\param[out] y
-Pointer to the output decimated vector `y`. \n
-Output vector size is `[n/d x 1]` will be copy
-to the address `cnt`. \n
-Memory must be allocated. \n \n
-
-\param[out] cnt
-Address which will keep decimated vector `y` size. \n
-Pointer can be `NULL`, vector `y` will not return
-in this case. \n \n
-
-\return
-`RES_OK` if function calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-Two-times complex vector decimation example:
-
-\code{.cpp}
-compex_t x[10] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0},
-{5.0, 5.0}, {6.0, 6.0}, {7.0, 7.0}, {8.0, 8.0}, {9.0, 9.0}};
-compex_t y[5];
-int d = 2;
-int cnt;
-
-decimate_cmplx(x, 10, d, y, &cnt);
-\endcode
-
-As result variable `cnt` will be written value 5 and
-vector `y` will keep array:
-
-\verbatim
-c = [0.0+0.0j, 2.0+2.0j, 4.0+4.0j, 6.0+6.0j, 8.0+8.0j]
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-****************************************************************************** */
-
-
-
-
-
-/*! *****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int flipip(double* x, int n)
-\brief
-Flip real vector `x` in place
-
-Function flips real vector `x` length `n` in the memory. \n
-For example real vector `x` length 6:\n
-\verbatim
-x = [0, 1, 2, 3, 4, 5]
-\endverbatim
-After flipping it will be as follow:
-\verbatim
-x = [5, 4, 3, 2, 1, 0]
-\endverbatim
-
-\param[in, out] x
-Pointer to the real vector `x`. \n
-Vector size is `[n x 1]`. \n
-Flipped vector will be on the same address. \n
-\n
-
-\param[in] n
-Length of the vector `x`. \n
-\n
-
-\return
-`RES_OK` if function returns successfully. \n
- Else \ref ERROR_CODE_GROUP "error code".
-
-Example:
-\code{.cpp}
-double x[5] = {0.0, 1.0, 2.0, 3.0, 4.0};
-int i;
-for(i = 0; i < 5; i++)
- printf("%6.1f ", x[i]);
-flipip(x, 5);
-printf("\n");
-for(i = 0; i < 5; i++)
- printf("%6.1f ", x[i]);
-\endcode
-\n
-Program result:
-\verbatim
- 0.0 1.0 2.0 3.0 4.0
- 4.0 3.0 2.0 1.0 0.0
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-****************************************************************************** */
-
-
-
-
-/*! *****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int flipip_cmplx(complex_t* x, int n)
-\brief Flip complex vector `x` in place
-
-Function flips complex vector `x` length `n` in the memory
- \n
-For example complex vector `x` length 6: \n
-\verbatim
-x = [0+0j, 1+1j, 2+2j, 3+3j, 4+4j, 5+5j]
-\endverbatim
-After flipping it will be as follow:
-\verbatim
-x = [5+5j, 4+4j, 3+3j, 2+2j, 1+1j, 0+0j]
-\endverbatim
-
-\param[in, out] x
-Pointer to the complex vector `x`. \n
-Vector size is `[n x 1]`. \n
-Flipped vector will be on the same address. \n
-
-\param[in] n
-Length of the vector `x`. \n \n
-
-\return
-`RES_OK` if function returns successfully. \n
-Else \ref ERROR_CODE_GROUP "error code".
-
-Example:
-\code{.cpp}
-complex_t y[5] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}};
-for(i = 0; i < 5; i++)
- printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
-flipip_cmplx(y, 5);
-printf("\n");
-for(i = 0; i < 5; i++)
- printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
-\endcode
- \n
-Program result:
-\verbatim
- 0.0+0.0j 1.0+1.0j 2.0+2.0j 3.0+3.0j 4.0+4.0j
- 4.0+4.0j 3.0+3.0j 2.0+2.0j 1.0+1.0j 0.0+0.0j
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-****************************************************************************** */
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int linspace(double x0, double x1, int n, int type, double* x)
-\brief Function fills a vector with `n` linearly spaced elements
-between `x0` and `x1`.
-
-Function supports two kinds of filling according to `type` parameter: \n
-
-Symmetric fill (parameter `type=DSPL_SYMMETRIC`): \n
-
-\f$x(k) = x_0 + k \cdot dx\f$,
-\f$dx = \frac{x_1 - x_0}{n-1}\f$, \f$k = 0 \ldots n-1.\f$
-
-Periodic fill (parameter `type=DSPL_PERIODIC`): \n
-
-\f$x(k) = x_0 + k \cdot dx\f$,
-\f$dx = \frac{x_1 - x_0}{n}\f$, \f$k = 0 \ldots n-1.\f$
-
-\param[in] x0
-Start point \f$x_0\f$. \n \n
-
-\param[in] x1
-End point \f$x_1\f$. \n \n
-
-\param[in] n
-Number of points `x` (size of vector `x`). \n \n
-
-\param[in] type
-Fill type: \n
-`DSPL_SYMMETRIC` --- symmetric, \n
-`DSPL_PERIODIC` --- periodic. \n \n
-
-\param[in,out] x
-Pointer to the output linearly spaced vector `x` . \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if function returns successfully. \n
- Else \ref ERROR_CODE_GROUP "error code".
-
-\note
-Difference between symmetric and periodic filling we can
-understand from the follow examples. \n
-Example 1. Periodic fill.
- double x[5];
- linspace(0, 5, 5, DSPL_PERIODIC, x);
-\endcode
-Values in the vector `x` are:
-\verbatim
-0, 1, 2, 3, 4
-\endverbatim
- \n \n
-Example 2. Symmetric fill.
-\code{.cpp}
- double x[5];
- linspace(0, 5, 5, DSPL_SYMMETRIC, x);
-\endcode
-Values in the vector `x` are:
-\verbatim
-0, 1.25, 2.5, 3.75, 5
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int logspace(double x0, double x1, int n, int type, double* x)
-\brief Function fills a vector with `n` logarithmically spaced elements
-between \f$10^{x_0}\f$ and \f$10^{x_1}\f$.
-
-
-Function supports two kinds of filling according to `type` parameter: \n
-
-Symmetric fill (parameter `type=DSPL_SYMMETRIC`): \n
-
-\f$x(k) = 10^{x_0} \cdot dx^k\f$, here \f$dx = \sqrt[n-1]{10^{x_1 - x_0}}\f$,
-\f$k = 0 \ldots n-1.\f$
-
-Periodic fill (parameter `type=DSPL_PERIODIC`): \n
-
-\f$x(k) = 10^{x_0} \cdot dx^k\f$, here \f$dx = \sqrt[n]{10^{x_1 - x_0}}\f$,
-\f$k = 0 \ldots n-1.\f$ \n
-
-
-\param[in] x0
-Start exponent value \f$x_0\f$. \n \n
-
-\param[in] x1
-End exponent value \f$x_1\f$. \n \n
-
-\param[in] n
-Number of points `x` (size of vector `x`). \n \n
-
-\param[in] type
-Fill type: \n
-`DSPL_SYMMETRIC` --- symmetric, \n
-`DSPL_PERIODIC` --- periodic. \n \n
-
-\param[in,out] x
-Pointer to the output logarithmically spaced vector `x` . \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if function returns successfully. \n
- Else \ref ERROR_CODE_GROUP "error code".
-
-\note
-Difference between symmetric and periodic filling we can
-understand from the follow examples. \n
-Example 1. Periodic fill.
-\code{.cpp}
- double x[5];
- logspace(-2, 3, 5, DSPL_PERIODIC, x);
-\endcode
-
-Values in the vector `x` are:
-
-\verbatim
-0.01, 0.1, 1, 10, 100
-\endverbatim
-
-\n \n
-
-Example 2. Symmetric fill.
-\code{.cpp}
- double x[5];
- logspace(-2, 3, 5, DSPL_SYMMETRIC, x);
-\endcode
-
-Values in the vector `x` are:
-
-\verbatim
-0.01 0.178 3.162 56.234 1000
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-
-
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int ones(double* x, int n)
-\brief Function fills all real vector `x` by ones values.
-
-\param[in, out] x
-Pointer to the vector `x`. \n
-Vector size is `[n x 1]`. \n
-All elements on this vector will be set to one. \n
-\n
-
-\param[in] n
-Size of vector `x`. \n
-\n
-
-\return
-`RES_OK` if function returns successfully. \n
- Else \ref ERROR_CODE_GROUP "error code".
-
-Example:
-\code{.cpp}
-double y[5] = {0};
-int i;
-ones(y, 5);
-for(i = 0; i < 5; i++)
- printf("%6.1f% ", y[i]);
-\endcode
- \n
-Vector `y` values are:
-\verbatim
- 1.0 1.0 1.0 1.0 1.0
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-**************************************************************************** */
-
-
-
-
-
-
-
-
-
-/*! *****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int verif(double* x, double* y, size_t n, double eps, double* err)
-\brief Real arrays verification
-
-Function calculates a maximum relative error between two real arrays `x`
-and `y` (both length equals `n`):
-
-\f[
-e = \max \left( \frac{|x(k) - y(k)| }{ |x(k)|} \right), \quad if \quad |x(k)| > 0,
-\f]
-or
-\f[
-e = \max(|x(k) - y(k)| ), ~\qquad if \quad~|x(k)| = 0,
-\f]
-Return `DSPL_VERIF_SUCCESS` if maximum relative error \f$ e\f$ less than `eps`.
-Else returns `DSPL_VERIF_FAILED`. \n
-
-This function can be used for algorithms verification if vector `x` is user
-algorithm result and vector `y` -- reference vector.
-
-\param[in] x
-Pointer to the first vector `x`. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] y
-Pointer to the second vector `y`. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of vectors `x` and `y`. \n \n
-
-\param[in] eps
-Relative error threshold. \n
-If error less than `eps`, then function returns
-`DSPL_VERIF_SUCCESS`, else `DSPL_VERIF_FAILED`. \n \n
-
-\param[in, out] err
-Pointer to the variable which keep
-maximum relative error. \n
-Pointer can be `NULL`, maximum error will not be returned
-in this case. \n \n
-
-\return
-`DSPL_VERIF_SUCCESS` if maximum relative error less than `eps`. \n
-Otherwise `DSPL_VERIF_FAILED`.
-
-\author Sergey Bakhurin www.dsplib.org
-****************************************************************************** */
-
-
-
-
-
-/*! *****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int verif_cmplx(complex_t* x, complex_t* y, size_t n,
- double eps, double* err)
-\brief
-Complex arrays verification
-
-Function calculates a maximum relative error between two complex arrays `x`
-and `y` (both length equals `n`):
-
-\f[
-e = \max \left( \frac{|x(k) - y(k)| }{ |x(k)|} \right), \quad if \quad |x(k)| > 0,
-\f]
-or
-\f[
-e = \max(|x(k) - y(k)| ), ~\qquad if \quad~|x(k)| = 0,
-\f]
-Return `DSPL_VERIF_SUCCESS` if maximum relative error \f$ e\f$ less than `eps`.
-Else returns `DSPL_VERIF_FAILED`. \n
-
-This function can be used for algorithms verification if vector `x` is user
-algorithm result and vector `y` -- reference vector.
-
-\param[in] x
-Pointer to the first vector `x`. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] y
-Pointer to the second vector `y`. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of vectors `x` and `y`. \n \n
-
-\param[in] eps
-Relative error threshold. \n
-If error less than `eps`, then function returns
-`DSPL_VERIF_SUCCESS`, else `DSPL_VERIF_FAILED`. \n \n
-
-\param[in, out] err
-Pointer to the variable which keep
-maximum relative error. \n
-Pointer can be `NULL`, maximum error will not be returned
-in this case. \n \n
-
-\return
-`DSPL_VERIF_SUCCESS` if maximum relative error less than `eps`. \n
-Otherwise `DSPL_VERIF_FAILED`.
-
-\author
-Sergey Bakhurin
-www.dsplib.org
-****************************************************************************** */
\ No newline at end of file
diff --git a/dspl/dox/en/cheby.dox b/dspl/dox/en/cheby.dox
deleted file mode 100644
index e26f740..0000000
--- a/dspl/dox/en/cheby.dox
+++ /dev/null
@@ -1,111 +0,0 @@
-
-/*! *****************************************************************************
-\ingroup SPEC_MATH_TRANSCEND
-\fn int cheby_poly1(double* x, int n, int ord, double* y)
-\brief Chebyshev polynomial of the first kind order `ord`
-
-Function calculates Chebyshev polynomial \f$ C_ord(x)\f$ of the first kind
-order `ord` for the real vector `x` (length `n`) by recurrent equation:
-\f[
-C_ord(x) = 2 x C_{ord-1}(x) - C_{ord-2}(x),
-\f]
-where \f$ C_0(x) = 1 \f$, \f$ C_1(x) = x\f$
-
-\param[in] x
-Pointer to the real argument vector `x`. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of vectors `x` and `y`. \n \n
-
-\param[in] ord
-Chebyshev polynomial order. \n \n
-
-\param[out] y
-Pointer to the Chebyshev polynomial values, corresponds to the argument `x`. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if Chebyshev polynomial is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error". \n
-
-Example:
-
-\include cheby_poly1_test.c
-
- \n \n
-Text files will be created in `dat` directory: \n
-
-
-cheby_poly1_ord1.txt
-cheby_poly1_ord2.txt
-cheby_poly1_ord3.txt
-cheby_poly1_ord4.txt
-
-
-GNUPLOT package will create Chebyshev polynomials plot from saved text-files:
-
-\image html cheby_poly1.png
-
-GNUPLOT script is follow:
-\include cheby_poly1.plt
-
-\author Sergey Bakhurin www.dsplib.org
-****************************************************************************** */
-
-
-/*! *****************************************************************************
-\ingroup SPEC_MATH_TRANSCEND
-\fn int cheby_poly2(double* x, int n, int ord, double* y)
-\brief Chebyshev polynomial of the second kind order `ord`
-
-Function calculates Chebyshev polynomial \f$ U_ord(x)\f$ of the first kind
-order `ord` for the real vector `x` (length `n`) by recurrent equation:
-\f[
-U_ord(x) = 2 x U_{ord-1}(x) - U_{ord-2}(x),
-\f]
-where \f$ U_0(x) = 1 \f$, \f$ U_1(x) = 2x\f$
-
-\param[in] x
-Pointer to the real argument vector `x`. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of vectors `x` and `y`. \n \n
-
-\param[in] ord
-Chebyshev polynomial order. \n \n
-
-\param[out] y
-Pointer to the Chebyshev polynomial values, corresponds to the argument `x`. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if Chebyshev polynomial is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error". \n
-
-Example:
-
-\include cheby_poly2_test.c
-
- \n \n
-Text files will be created in `dat` directory: \n
-
-
-cheby_poly2_ord1.txt
-cheby_poly2_ord2.txt
-cheby_poly2_ord3.txt
-cheby_poly2_ord4.txt
-
-
-GNUPLOT package will create Chebyshev polynomials plot from saved text-files:
-
-\image html cheby_poly2.png
-
-GNUPLOT script is follow:
-\include cheby_poly2.plt
-
-\author Sergey Bakhurin www.dsplib.org
-****************************************************************************** */
\ No newline at end of file
diff --git a/dspl/dox/en/complex.dox b/dspl/dox/en/complex.dox
deleted file mode 100644
index 1965b16..0000000
--- a/dspl/dox/en/complex.dox
+++ /dev/null
@@ -1,234 +0,0 @@
-/*! ****************************************************************************
-\ingroup TYPES_GROUP
-\typedef complex_t
-\brief Complex data type.
-
-DSPL-2.0 decribes complex numbers data type as an array
-of two `double` elements.
-First element sets real part, second --- imaginary part.
-
-For example:
-
-\code{.cpp}
- complex_t z;
- z[0] = 1.0;
- z[1] = -2.0;
-\endcode
-
-Variable `z = 1-2j`, here `j` - imaginary unit.
-
-For the convenience of working with complex numbers implemented
-special macros: \ref RE, \ref IM, \ref ABSSQR
-***************************************************************************** */
-
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup TYPES_GROUP
-\def ABSSQR(x)
-\brief
-The macro returns the square of the modulus of a complex number `x`.
-
-Square of the modulus of a complex number \f$ x = a + j b \f$ equals:
-
-\f[
- |x|^2 = x x^* = a^2 + b^2.
-\f]
-
-Example:
-\code{.cpp}
- complex_t z;
- double y;
- RE(z) = 1.0;
- IM(z) = -2.0;
- y = ABSSQR(z);
-\endcode
-
-Variable `z = 1-2j`, here `j` - imaginary unit, but variable `y = 5`.
-***************************************************************************** */
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup TYPES_GROUP
-\def IM(x)
-\brief Macro sets imaginary part of the complex number.
-
-Example:
-\code{.cpp}
- complex_t z;
- RE(z) = 1.0;
- IM(z) = -2.0;
-\endcode
-
-Variable `z = 1-2j`, here `j` - imaginary unit.
-
-This macro can be used to return
-imaginary part of the complex number:
-\code{.cpp}
- complex_t z = {3.0, -4.0};
- double r;
- r = IM(z);
-\endcode
-In this example `z = 3-4i`,
-but variable `r` will keep -4.
-***************************************************************************** */
-
-
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup TYPES_GROUP
-\def RE(x)
-\brief Macro sets real part of the complex number.
-
-Example:
-\code{.cpp}
- complex_t z;
- RE(z) = 1.0;
- IM(z) = -2.0;
-\endcode
-
-Variable `z = 1-2j`, here `j` - imaginary unit.
-
-This macro can be used to return
-real part of the complex number:
-
-\code{.cpp}
- complex_t z = {3.0, -4.0};
- double r;
- r = RE(z);
-\endcode
-In this example `z = 3-4i`,
-but variable `r` will keep 3.
-***************************************************************************** */
-
-
-
-
-
-/*! *****************************************************************************
-\ingroup TYPES_GROUP
-\fn int cmplx2re(complex_t* x, int n, double* re, double* im)
-\brief Separate complex vector to the real and image vectors
-
-Function fills `re` and `im` vectors corresponds to real and image
-parts of the input complex array `x`. \n
-
-
-\param[in] x
-Pointer to the real complex vector. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Size of the input complex vector `x` and real and image
-vectors `re` and `im`. \n \n
-
-\param[out] re
-Pointer to the real part vector. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\param[out] im
-Pointer to the image part vector. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if function converts complex vector successfully. \n
-Else \ref ERROR_CODE_GROUP "code error". \n
-
-Example: \n
-\code{.cpp}
- complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
- double re[3], im[3];
-
- cmplx2re(x, 3, re, im);
-\endcode
-
-Vectors `re` and `im` will contains:
-
-\verbatim
-re[0] = 1.0; im[0] = 2.0;
-re[1] = 3.0; im[1] = 4.0;
-re[2] = 5.0; im[2] = 6.0;
-\endverbatim
-
-\author Sergey Bakhurin. www.dsplib.org
-****************************************************************************** */
-
-
-
-
-
-
-
-
-/*! *****************************************************************************
-\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
-****************************************************************************** */
-
-
-
diff --git a/dspl/dox/en/dft.dox b/dspl/dox/en/dft.dox
deleted file mode 100644
index 3498ec6..0000000
--- a/dspl/dox/en/dft.dox
+++ /dev/null
@@ -1,216 +0,0 @@
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int dft(double* x, int n, complex_t* y)
-\brief Discrete Fourier transform of a real signal.
-
-The function calculates the \f$ n \f$ -point discrete Fourier transform
-real signal \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y (k) = \sum_ {m = 0} ^ {n-1} x (m)
- \exp \left (-j \frac {2 \pi} {n} m k \right),
-\f]
-where \f$ k = 0 \ldots n-1 \f$.
-
-\param [in] x
-Pointer to the vector of the real input signal \f$ x (m) \f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-The size of the vector is `[n x 1]`. \n \n
-
-\param [in] n
-The size of the DFT \f$ n \f$
-(the size of the vectors of the input signal and the result of the DFT). \n \n
-
-\param [out] y
-Pointer to the complex vector of the DFT result \f$ Y (k) \f$,
-\f$ k = 0 \ldots n-1 \f$.
-The size of the vector is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-
-\return
-`RES_OK` if the DFT is calculated successfully. \n
-Otherwise, \ref ERROR_CODE_GROUP "error code".
-
-An example of using the `dft` function:
-
-\include dft_test.c
-
-The result of the program:
-
-\verbatim
-y [0] = 120.000 0.000
-y [1] = -8.000 40.219
-y [2] = -8.000 19.314
-y [3] = -8.000 11.973
-y [4] = -8.000 8.000
-y [5] = -8.000 5.345
-y [6] = -8.000 3.314
-y [7] = -8.000 1.591
-y [8] = -8.000 0.000
-y [9] = -8.000 -1.591
-y [10] = -8.000 -3.314
-y [11] = -8.000 -5.345
-y [12] = -8.000 -8.000
-y [13] = -8.000 -11.973
-y [14] = -8.000 -19.314
-y [15] = -8.000 -40.219
-\endverbatim
-
-\note
-This function performs the DFT calculation using the naive method and requires \f$ n ^ 2 \f$
-complex multiplications. \n
-To increase the calculation speed, it is recommended to use
-fast Fourier transform algorithms.
-
-\author
-Bakhurin Sergey
-www.dsplib.org
-**************************************************************************** */
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int dft_cmplx(complex_t* x, int n, complex_t* y)
-\brief Discrete Fourier transform of a complex signal.
-
-The function calculates the \f$ n \f$ -point discrete Fourier transform
-complex signal \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y (k) = \sum_ {m = 0} ^ {n-1} x (m)
- \exp \left (-j \frac {2 \pi} {n} m k \right),
-\f]
-where \f$ k = 0 \ldots n-1 \f$.
-
-\param [in] x
-Pointer to a vector of complex
-input signal \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-The size of the vector is `[n x 1]`. \n \n
-
-\param [in] n
-The size of the DFT \f$ n \f$
-(the size of the vectors of the input signal and the result of the DFT). \n \n
-
-\param [out] y
-Integrated Vector Pointer
-DFT result \f$ Y (k) \f$, \f$ k = 0 \ldots n-1 \f$. \n
-The size of the vector is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-
-\return
-`RES_OK` if the DFT is calculated successfully. \n
-Otherwise, \ref ERROR_CODE_GROUP "error code".
-
-An example of using the `dft_cmplx` function:
-
-\include dft_cmplx_test.c
-
-The result of the program:
-
-\verbatim
-y [0] = 120.000 0.000
-y [1] = -8.000 40.219
-y [2] = -8.000 19.314
-y [3] = -8.000 11.973
-y [4] = -8.000 8.000
-y [5] = -8.000 5.345
-y [6] = -8.000 3.314
-y [7] = -8.000 1.591
-y [8] = -8.000 0.000
-y [9] = -8.000 -1.591
-y [10] = -8.000 -3.314
-y [11] = -8.000 -5.345
-y [12] = -8.000 -8.000
-y [13] = -8.000 -11.973
-y [14] = -8.000 -19.314
-y [15] = -8.000 -40.219
-\endverbatim
-
-\note
-This function performs the calculation of the DFT by the naive method
-and requires \f$ n ^ 2 \f$ complex multiplications. \n
-To increase the calculation speed, it is recommended
-use fast Fourier transform algorithms.
-
-\author
-Bakhurin Sergey
-www.dsplib.org
-***************************************************************************** */
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int idft_cmplx(complex_t* x, int n, complex_t* y)
-\brief Inverse discrete Fourier transform of the complex spectrum.
-
-The function calculates the \f$ n \f$ -point inverse discrete transform
-Fourier complex spectrum \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- y (k) = \sum_ {m = 0} ^ {n-1} x (m)
- \exp \left (j \frac {2 \pi} {n} m k \right),
-\f]
-where \f$ k = 0 \ldots n-1 \f$.
-
-\param [in] x
-Pointer to the vector of the input complex signal spectrum \f$ x (m) \f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-The size of the vector is `[n x 1]`. \n \n
-
-\param [in] n
-The size of the ODPF \f$ n \f$
-(the size of the vectors of the input spectrum and the result of the ODPF). \n \n
-
-\param [out] y
-Pointer to the complex vector of the ODPF result \f$ y (k) \f$,
-\f$ k = 0 \ldots n-1 \f$.
-The size of the vector is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-
-\return
-`RES_OK` if the ODPF is calculated successfully. \n
-Otherwise, \ref ERROR_CODE_GROUP "error code".
-
-An example of using the `dft_cmplx` function:
-
-\include idft_cmplx_test.c
-
-The result of the program:
-
-\verbatim
-x [0] = 0.000 + 0.000j, z [0] = 0.000 -0.000
-x [1] = 1.000 + 0.000j, z [1] = 1.000 -0.000
-x [2] = 2.000 + 0.000j, z [2] = 2.000 -0.000
-x [3] = 3.000 + 0.000j, z [3] = 3.000 -0.000
-x [4] = 4.000 + 0.000j, z [4] = 4.000 -0.000
-x [5] = 5.000 + 0.000j, z [5] = 5.000 -0.000
-x [6] = 6.000 + 0.000j, z [6] = 6.000 -0.000
-x [7] = 7.000 + 0.000j, z [7] = 7.000 -0.000
-x [8] = 8.000 + 0.000j, z [8] = 8.000 -0.000
-x [9] = 9.000 + 0.000j, z [9] = 9.000 -0.000
-x [10] = 10.000 + 0.000j, z [10] = 10.000 -0.000
-x [11] = 11.000 + 0.000j, z [11] = 11.000 +0.000
-x [12] = 12.000 + 0.000j, z [12] = 12.000 +0.000
-x [13] = 13.000 + 0.000j, z [13] = 13.000 +0.000
-x [14] = 14.000 + 0.000j, z [14] = 14.000 +0.000
-x [15] = 15.000 + 0.000j, z [15] = 15.000 -0.000
-\endverbatim
-
-\note
-This function performs the calculation of the DFT using the naive method.
-and requires \f$ n ^ 2 \f$ complex multiplications. \n
-To increase the calculation speed, it is recommended
-use fast Fourier transform algorithms.
-
-\author
-Bakhurin Sergey
-www.dsplib.org
-***************************************************************************** */
-
-
-
-
diff --git a/dspl/dox/en/ellipj.dox b/dspl/dox/en/ellipj.dox
deleted file mode 100644
index c3f7b5a..0000000
--- a/dspl/dox/en/ellipj.dox
+++ /dev/null
@@ -1,418 +0,0 @@
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-
-\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
-***************************************************************************** */
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
-/*! ****************************************************************************
-\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
-
-\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
- ***************************************************************************** */
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
diff --git a/dspl/dox/en/fft.dox b/dspl/dox/en/fft.dox
deleted file mode 100644
index 1ecefb9..0000000
--- a/dspl/dox/en/fft.dox
+++ /dev/null
@@ -1,435 +0,0 @@
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\struct fft_t
-\brief Fast Fourier Transform Object Data Structure
-
-The structure stores pointers to twiddle factors and arrays of intermediate
-data of the fast Fourier transform algorithm.
-
-The DSPL library uses an FFT algorithm for composite size.
-
-
-\param n
-The size of the FFT vector for which memory is allocated
-in the structure arrays. \n
-The parameter `n` must be equal to an integer power of two (radix 2). \n \n
-
-
-\param w
-Pointer to the vector of twiddle factors. \n
-The size of the vector is `[n x 1]`. \n
-The memory must be allocated and an array of twiddle factors
-must be filled with the \ref fft_create function. \n\n
-
-
-\param t0
-Pointer to the vector of intermediate results of the FFT algorithm. \n
-The size of the vector is `[n x 1]`. \n
-Memory must be allocated by \ref fft_create function. \n\n
-
-
-\param t1
-Pointer to the vector of intermediate results. \n
-The size of the vector is `[n x 1]`. \n
-The memory must be allocated with the \ref fft_create function. \n\n
-The structure is populated with the \ref fft_create function once
-before using the FFT algorithm. \n
-A pointer to an object of this structure may be
-reused when calling FFT functions. \n
-Before exiting the program, dedicated memory for twiddle factors and arrays of
-intermediate data must be cleared by the \ref fft_free function.
-For example:
-\code
-fft_t pfft = {0}; /* Structure fft_t and clear all fields */
-int n = 64; /* FFT size */
-
-int err;
-
-/* Create and fill FFT structure for 64-points FFT */
-err = fft_create(&pfft, n);
-
-/* FFT calculation here */
-/* FFT calculation here one more */
-/* ... */
-
-/* Clear fft structure */
-fft_free(&pfft);
-\endcode
-
-\note
-It is important to note that if the object `fft_t` was created for the FFT size
-equal to` n`, it can only be used for FFT of size `n`. \n \n
-It’s also worth noting that the FFT functions independently control the size,
-and independently allocate the memory of the FFT object, if necessary.
-So if you call any function using the `fft_t` structure with filled
-data for the FFT length `k` for calculating the FFT of length`n`,
-then the structure arrays will be automatically recreated for the length `n`.
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-
-
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int ifft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
-\brief Inverse fast Fourier transform
-
-Function calculates \f$ n \f$-point IFFT of complex data
-\f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \frac{1}{N} \sum_{m = 0}^{n-1} x(m) \exp
- \left( j \frac{2\pi}{n} m k \right),
-\f]
-here \f$ k = 0 \ldots n-1 \f$.
-
-
-\param[in] x
-Pointer to the input vector \f$x(m)\f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-IFFT size \f$n\f$. \n
-IFFT size can be composite:
-\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
-here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
-simple number less than 46340
-(see \ref fft_create function). \n \n
-
-\param[in] pfft
-Pointer to the `fft_t` object. \n
-This pointer cannot be `NULL`. \n
-Structure \ref fft_t should be previously once
-filled with the \ref fft_create function, and the memory should be
-cleared before exiting by the \ref fft_free function. \n \n
-
-\param[out] y
-Pointer to the IFFT result vector \f$Y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if IFFT is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-
-IFFT example:
-
-\include ifft_cmplx_test.c
-
-Result:
-
-\verbatim
-| x[ 0] = 1.000 0.000 | y[ 0] = -0.517 0.686 | z[ 0] = 1.000 0.000 |
-| x[ 1] = 0.540 0.841 | y[ 1] = -0.943 0.879 | z[ 1] = 0.540 0.841 |
-| x[ 2] = -0.416 0.909 | y[ 2] = -2.299 1.492 | z[ 2] = -0.416 0.909 |
-| x[ 3] = -0.990 0.141 | y[ 3] = 16.078 -6.820 | z[ 3] = -0.990 0.141 |
-| x[ 4] = -0.654 -0.757 | y[ 4] = 2.040 -0.470 | z[ 4] = -0.654 -0.757 |
-| x[ 5] = 0.284 -0.959 | y[ 5] = 1.130 -0.059 | z[ 5] = 0.284 -0.959 |
-| x[ 6] = 0.960 -0.279 | y[ 6] = 0.786 0.097 | z[ 6] = 0.960 -0.279 |
-| x[ 7] = 0.754 0.657 | y[ 7] = 0.596 0.183 | z[ 7] = 0.754 0.657 |
-| x[ 8] = -0.146 0.989 | y[ 8] = 0.470 0.240 | z[ 8] = -0.146 0.989 |
-| x[ 9] = -0.911 0.412 | y[ 9] = 0.375 0.283 | z[ 9] = -0.911 0.412 |
-| x[10] = -0.839 -0.544 | y[10] = 0.297 0.318 | z[10] = -0.839 -0.544 |
-| x[11] = 0.004 -1.000 | y[11] = 0.227 0.350 | z[11] = 0.004 -1.000 |
-| x[12] = 0.844 -0.537 | y[12] = 0.161 0.380 | z[12] = 0.844 -0.537 |
-| x[13] = 0.907 0.420 | y[13] = 0.094 0.410 | z[13] = 0.907 0.420 |
-| x[14] = 0.137 0.991 | y[14] = 0.023 0.442 | z[14] = 0.137 0.991 |
-| x[15] = -0.760 0.650 | y[15] = -0.059 0.479 | z[15] = -0.760 0.650 |
-| x[16] = -0.958 -0.288 | y[16] = -0.161 0.525 | z[16] = -0.958 -0.288 |
-| x[17] = -0.275 -0.961 | y[17] = -0.300 0.588 | z[17] = -0.275 -0.961 |
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft(double* x, int n, fft_t* pfft, complex_t* y)
-\brief Fast Fourier transform for the real vector.
-
-Function calculated \f$ n \f$-points FFT for the real vector
-\f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \sum_{m = 0}^{n-1} x(m) \exp
- \left( -j \frac{2\pi}{n} m k \right),
-\f]
-here \f$ k = 0 \ldots n-1 \f$.
-
-
-\param[in] x
-Pointer to the input real vector \f$x(m)\f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-FFT size \f$n\f$. \n
-FFT size can be composite:
-\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
-here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
-simple number less than 46340
-(see \ref fft_create function). \n \n
-
-\param[in] pfft
-Pointer to the `fft_t` object. \n
-This pointer cannot be `NULL`. \n
-Structure \ref fft_t should be previously once
-filled with the \ref fft_create function, and the memory should be
-cleared before exiting by the \ref fft_free function. \n \n
-
-\param[out] y
-Pointer to the FFT result complex vector \f$Y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if FFT is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-
-Example:
-
-\include fft_test.c
-
-Result:
-
-\verbatim
-y[ 0] = 91.000 0.000
-y[ 1] = -7.000 30.669
-y[ 2] = -7.000 14.536
-y[ 3] = -7.000 8.778
-y[ 4] = -7.000 5.582
-y[ 5] = -7.000 3.371
-y[ 6] = -7.000 1.598
-y[ 7] = -7.000 0.000
-y[ 8] = -7.000 -1.598
-y[ 9] = -7.000 -3.371
-y[10] = -7.000 -5.582
-y[11] = -7.000 -8.778
-y[12] = -7.000 -14.536
-y[13] = -7.000 -30.669
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
-\brief Fast Fourier transform for the complex vector.
-
-Function calculated \f$ n \f$-points FFT for the complex vector
-\f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \sum_{m = 0}^{n-1} x(m) \exp
- \left( -j \frac{2\pi}{n} m k \right),
-\f]
-here \f$ k = 0 \ldots n-1 \f$.
-
-\param[in] x
-Pointer to the input complex vector \f$x(m)\f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-FFT size \f$n\f$. \n
-FFT size can be composite:
-\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
-here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
-simple number less than 46340
-(see \ref fft_create function). \n \n
-
-\param[in] pfft
-Pointer to the `fft_t` object. \n
-This pointer cannot be `NULL`. \n
-Structure \ref fft_t should be previously once
-filled with the \ref fft_create function, and the memory should be
-cleared before exiting by the \ref fft_free function. \n \n
-
-\param[out] y
-Pointer to the FFT result complex vector \f$Y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-\return
-`RES_OK` if FFT is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-
-Example:
-
-\include fft_cmplx_test.c
-
-Result:
-
-\verbatim
-y[ 0] = -0.517 0.686
-y[ 1] = -0.943 0.879
-y[ 2] = -2.299 1.492
-y[ 3] = 16.078 -6.820
-y[ 4] = 2.040 -0.470
-y[ 5] = 1.130 -0.059
-y[ 6] = 0.786 0.097
-y[ 7] = 0.596 0.183
-y[ 8] = 0.470 0.240
-y[ 9] = 0.375 0.283
-y[10] = 0.297 0.318
-y[11] = 0.227 0.350
-y[12] = 0.161 0.380
-y[13] = 0.094 0.410
-y[14] = 0.023 0.442
-y[15] = -0.059 0.479
-y[16] = -0.161 0.525
-y[17] = -0.300 0.588
-\endverbatim
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft_create(fft_t* pfft, int n)
-\brief Function creates and fill `fft_t` structure.
-
-The function allocates memory and calculates twiddle factors
- of the `n`-point FFT for the structure` fft_t`.
-
-\param[in,out] pfft
-Pointer to the `fft_t` object. \n
-Pointer cannot be `NULL`. \n \n
-
-\param[in] n
-FFT size \f$n\f$. \n
-FFT size can be composite
-\f$n = n_0 \times n_1 \times n_2 \ldots \times n_p \times m\f$,
-here \f$n_i = 2,3,5,7\f$, and \f$m \f$ --
- arbitrary prime factor not exceeding 46340. \n
-Thus, the FFT algorithm supports arbitrary integer lengths.
-degrees of numbers 2,3,5,7, as well as their various combinations. \n
-For example, with \f$ n = 725760 \f$ the structure will be successfully filled,
-because
-\f$ 725760 = 2 \cdot 3 \cdot 4 \cdot 5 \cdot 6 \cdot 7 \cdot 9 \cdot 16 \f$. \n
-If \f$ n = 172804 = 43201 \cdot 4 \f$ then the structure will also be
-successfully filled, because the simple factor in \f$ n \f$ does not
-exceed 46340. \n
-For size \f$ n = 13 \cdot 17 \cdot 23 \cdot 13 = 66079 \f$
-the function will return an error since 66079 is greater than 46340 and is
-not the result of the product of numbers 2,3,5,7. \n \n
-
-\return
-`RES_OK` if FFT structure is created and filled successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\note
-Some compilers do not nullify its contents when creating a structure.
-Therefore, it is recommended to reset the structure after its declaration:
-\code{.cpp}
-fft_t pfft = {0}; /* fill and fields of fft_t as zeros*/
-int n = 64; /* FFT size */
-
-int err;
-
-/* Create fft_t object for 64-points FFT */
-
-err = fft_create(&pfft, n);
-
-/* ................................... */
-
-/* Clear fft_t structure */
-
-fft_free(&pfft);
-\endcode
-
-Before exiting the program, the memory allocated in the structure
-need to clear by \ref fft_free function. \n \n
-
-\note
-The "magic number" 46340 because \f$\sqrt{2^{31}} = 46340.95\f$. \n
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn void fft_free(fft_t *pfft)
-\brief Free `fft_t` structure.
-
-The function clears the intermediate data memory
-and vectors of FFT twiddle factors of the structure `fft_t`.
-
-\param[in] pfft
-Pointer to the `fft_t` object. \n
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft_shift(double* x, int n, double* y)
-\brief Perform a shift of the vector `x`, for use with the `fft` and `ifft`
-functions, in order
-
- to move the frequency 0 to the center
- of the vector `y`.
-
-\param[in] x
-Pointer to the input vector (FFT or IFFT result). \n
-Vector size is `[n x 1]`. \n \n
-
-\param[in] n
-Input and output vector size. \n \n
-
-\param[out] y
-Pointer to the output vector with frequency 0 in the center. \n
-Vector size is `[n x 1]`. \n
-Memory must be allocated. \n \n
-
-
-\return
-`RES_OK` if function is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
diff --git a/dspl/dox/en/filter_an.dox b/dspl/dox/en/filter_an.dox
deleted file mode 100644
index 6e1ded5..0000000
--- a/dspl/dox/en/filter_an.dox
+++ /dev/null
@@ -1,221 +0,0 @@
-
-/*! ****************************************************************************
-\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 frequaency 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
-***************************************************************************** */
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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 substitude \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 frequaency response vector is calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error".
-
-\author Sergey Bakhurin www.dsplib.org
-***************************************************************************** */
diff --git a/dspl/dox/en/filter_ap.dox b/dspl/dox/en/filter_ap.dox
index 23494dd..f76ea5f 100644
--- a/dspl/dox/en/filter_ap.dox
+++ b/dspl/dox/en/filter_ap.dox
@@ -255,7 +255,7 @@ In addition, GNUPLOT will build the following graphs from data stored in files:
/*! ****************************************************************************
\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int cheby1_ap_zp( int ord, double rp, complex_t *z, int* nz,
+\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
@@ -309,6 +309,33 @@ Else \ref ERROR_CODE_GROUP "code error".
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
***************************************************************************** */
@@ -450,30 +477,39 @@ Pointer cannot be `NULL`. \n
Else \ref ERROR_CODE_GROUP "code error".
\n
-Example:
-
+Example of normalized Chebyshev type 2 lowpass filter
+ zeros and poles calculation:
\include cheby2_ap_zp_test.c
Result:
\verbatim
- Chebyshev type 2 zeros:
- 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 poles:
- 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
+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
***************************************************************************** */
@@ -562,6 +598,97 @@ In addition, GNUPLOT will build the following graphs from data stored in files:
+/*! ****************************************************************************
+\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
+***************************************************************************** */
diff --git a/dspl/dox/en/groups_define.dox b/dspl/dox/en/groups_define.dox
index 85ea3d5..179abd9 100644
--- a/dspl/dox/en/groups_define.dox
+++ b/dspl/dox/en/groups_define.dox
@@ -30,8 +30,14 @@ groupdelay, impulse response and other.
\defgroup RESAMPLING_GROUP Digital samplerate conversion (resampling)
+
+\defgroup ARRAY_GROUP Basic operations for real and complex arrays.
+
+
\defgroup SPEC_MATH_COMMON_GROUP Basic math functions of the real and complex arguments.
+\defgroup SPEC_MATH_POLY_GROUP Polynomial functions and analysis.
+
\defgroup SPEC_MATH_TRIG_GROUP Trigonometric and hyperbolic of functions the real and complex arguments.
\defgroup SPEC_MATH_TRANSCEND Transcendent math functions
diff --git a/dspl/dox/en/mainpage.dox b/dspl/dox/en/mainpage.dox
index 5ec9d2d..7da482e 100644
--- a/dspl/dox/en/mainpage.dox
+++ b/dspl/dox/en/mainpage.dox
@@ -42,7 +42,9 @@ Dsplib toolchain includes GCC, GNUPLOT, CodeBlocks IDE, Far file manager and als
\subsection sec_doc_content Documentation content
Mathematical sections: \n
+ - \ref ARRAY_GROUP \n
- \ref SPEC_MATH_COMMON_GROUP \n
+ - \ref SPEC_MATH_POLY_GROUP \n
- \ref SPEC_MATH_TRIG_GROUP \n
- \ref SPEC_MATH_TRANSCEND \n
- \ref SPEC_MATH_ELLIP_GROUP \n
diff --git a/dspl/dox/en/math.dox b/dspl/dox/en/math.dox
index 8420252..3a7a9c0 100644
--- a/dspl/dox/en/math.dox
+++ b/dspl/dox/en/math.dox
@@ -1,96 +1,395 @@
+/*****************************************************************************
+\ingroup SPEC_MATH_TRIG_GROUP
+\fn int acos_cmplx(complex_t* x, int n, complex_t *y)
+\brief The inverse of the cosine function the complex vector argument `x`
+
+Function calculates the inverse of the cosine function as: \n
+
+\f[
+\textrm{Arccos}(x) = \frac{\pi}{2} - \textrm{Arcsin}(x) =
+\frac{\pi}{2} -j \textrm{Ln}\left( j x + \sqrt{1 - x^2} \right)
+\f]
+
+
+\param[in] x
+Pointer to the argument vector `x`. \n
+Vector size is `[n x 1]`. \n
+\n
+
+\param[in] n
+Input vector `x` and the inverse cosine vector `y` size. \n
+\n
+
+
+\param[out] y
+Pointer to the output complex vector `y`,
+corresponds to the input vector `x`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\return
+`RES_OK` if function calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
+
+Example: \n
+\code{.cpp}
+ complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
+ complex_t y[3];
+ int k;
+
+ acos_cmplx(x, 3, y);
+
+ for(k = 0; k < 3; k++)
+ printf("acos_cmplx(%.1f%+.1fj) = %.3f%+.3fj\n",
+ RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
+\endcode
+\n
+
+Output is: \n
+\verbatim
+acos_cmplx(1.0+2.0j) = 1.144-1.529j
+acos_cmplx(3.0+4.0j) = 0.937-2.306j
+acos_cmplx(5.0+6.0j) = 0.880-2.749j
+\endverbatim
+
+\author
+Sergey Bakhurin www.dsplib.org
+******************************************************************************/
+
+
+
+
+/*! ****************************************************************************
+\ingroup SPEC_MATH_TRIG_GROUP
+\fn int asin_cmplx(complex_t* x, int n, complex_t *y)
+\brief The inverse of the sine function the complex vector argument `x`
+
+Function calculates the inverse of the sine function as: \n
+
+\f[
+\textrm{Arcsin}(x) = j \textrm{Ln}\left( j x + \sqrt{1 - x^2} \right)
+\f]
+
+
+\param[in] x
+Pointer to the argument vector `x`. \n
+Vector size is `[n x 1]`. \n
+\n
+
+\param[in] n
+Input vector `x` and the inverse sine vector `y` size. \n
+\n
+
+\param[out] y
+Pointer to the output complex vector `y`,
+corresponds to the input vector `x`.\n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n
+\n
+
+\return
+`RES_OK` if function calculated successfully.\n
+Else \ref ERROR_CODE_GROUP "code error". \n
+
+Example: \n
+\code{.cpp}
+ complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
+ complex_t y[3];
+ int k;
+
+ asin_cmplx(x, 3, y);
+ for(k = 0; k < 3; k++)
+ printf("asin_cmplx(%.1f%+.1fj) = %.3f%+.3fj\n",
+ RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
+
+\endcode
+\n
+
+Output is: \n
+\verbatim
+asin_cmplx(1.0+2.0j) = 0.427+1.529j
+asin_cmplx(3.0+4.0j) = 0.634+2.306j
+asin_cmplx(5.0+6.0j) = 0.691+2.749j
+\endverbatim
+
+\author
+Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+
+
+
+
+
+
/*! ****************************************************************************
\ingroup SPEC_MATH_TRANSCEND
\fn int bessel_i0(double* x, int n, double* y)
\brief
-Модифицированная функция Бесселя первого рода \f$ I_0(x)\f$
+Modified Bessel Function of the First Kind – \f$ I_0(x)\f$ [1]
-Функция рассчитывает значения функции для вещественного вектора `x`,
-который должен принимать неотрицательные значения. \n
-\param[in] x
-Указатель на вектор переменной \f$ x \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n
+\param[in] x
+Pointer to the function argument vector \f$ x \f$. \n
+Vector size is `[n x 1]`. \n
+Input vector must contain nonnegative values. \n
\n
-\param[in] n
-Размер входного вектора `x`. \n
+\param[in] n
+Input vector size `x`. \n
\n
\param[out] y
-Указатель на вектор значений функции \f$ I_0(x)\f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n
+Pointer to \f$ I_0(x)\f$ function vector. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n
\n
\return
-`RES_OK` --- расчёт произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+`RES_OK` if function calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
\note
-Используемый алгоритм описа в статье:
-Rational Approximations for the Modified Bessel Function
-of the First Kind – I0(x) for Computations with Double Precision
-by PAVEL HOLOBORODKO on NOVEMBER 11, 2015
+[1] Rational Approximations for the Modified Bessel Function
+ of the First Kind – I0(x) for Computations with Double Precision
+ by PAVEL HOLOBORODKO on NOVEMBER 11, 2015
-Пример использования функции `bessel_i0`:
+Example:
\include bessel_i0.c
-Данная программа рассчитывает значения функции \f$ I_0(x)\f$ переменной `x`
-в интервале \f$[0 \ 3]\f$.
-Рассчитанные данные сохраняются в текстовый файл `dat/dat0.txt`
-и выводятся на график `img/bessel_i0.png`
+Program calcultes \f$ I_0(x)\f$ function for `x`
+in \f$[0 \ 3]\f$ interval.
+Data saved if `dat/dat0.txt` file and shows on the plot
\image html bessel_i0.png
\author
-Бахурин Сергей
-www.dsplib.org
+Sergey Bakhurin www.dsplib.org
***************************************************************************** */
+
+
+/*! ****************************************************************************
+\ingroup SPEC_MATH_TRIG_GROUP
+\fn int cos_cmplx(complex_t* x, int n, complex_t *y)
+\brief The cosine function the complex vector argument `x`
+
+Function calculates the cosine function as: \n
+
+\f[
+\textrm{cos}(x) = \frac{\exp(jx) + \exp(-jx)}{2}
+\f]
+
+
+\param[in] x
+Pointer to the argument vector `x`. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Input vector `x` and the cosine vector `y` size. \n \n
+
+
+\param[out] y
+Pointer to the output complex vector `y`,
+corresponds to the input vector `x`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if function calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
+
+Example: \n
+\code{.cpp}
+ complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
+ complex_t y[3];
+ int k;
+
+ cos_cmplx(x, 3, y);
+
+ for(k = 0; k < 3; k++)
+ printf("cos_cmplx(%.1f%+.1fj) = %9.3f%+9.3fj\n",
+ RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
+
+\endcode
+ \n
+
+Output is: \n
+\verbatim
+cos_cmplx(1.0+2.0j) = 2.033 -3.052j
+cos_cmplx(3.0+4.0j) = -27.035 -3.851j
+cos_cmplx(5.0+6.0j) = 57.219 +193.428j
+\endverbatim
+
+\author
+Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+
+
+
+
+
+
+/*! ****************************************************************************
+\ingroup SPEC_MATH_COMMON_GROUP
+\fn int log_cmplx(complex_t* x, int n, complex_t *y)
+\brief The logarithm function the complex vector argument `x`
+
+Function calculates the logarithm function as: \n
+
+\f[
+\textrm{Ln}(x) = j \varphi + \ln(|x|),
+\f]
+here \f$\varphi\f$ - the complex number phase.
+
+\param[in] x
+Pointer to the argument vector `x`. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Input vector `x` and the logarithm vector `y` size. \n \n
+
+
+\param[out] y
+Pointer to the output complex vector `y`,
+corresponds to the input vector `x`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if function calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
+
+Example: \n
+\code{.cpp}
+ complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
+ complex_t y[3];
+ int k;
+
+ log_cmplx(x, 3, y);
+
+ for(k = 0; k < 3; k++)
+ printf("log_cmplx(%.1f%+.1fj) = %.3f%+.3fj\n",
+ RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
+\endcode
+ \n
+
+Output is: \n
+\verbatim
+log_cmplx(1.0+2.0j) = 0.805+1.107j
+log_cmplx(3.0+4.0j) = 1.609+0.927j
+log_cmplx(5.0+6.0j) = 2.055+0.876j
+\endverbatim
+
+\author
+Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+
+
+
+
+
+
+
+
+/*! ****************************************************************************
+\ingroup SPEC_MATH_TRIG_GROUP
+\fn int sin_cmplx(complex_t* x, int n, complex_t *y)
+\brief The sine function the complex vector argument `x`
+
+Function calculates the sine function as: \n
+
+\f[
+\textrm{cos}(x) = \frac{\exp(jx) - \exp(-jx)}{2j}
+\f]
+
+
+\param[in] x
+Pointer to the argument vector `x`. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Input vector `x` and the sine vector `y` size. \n \n
+
+
+\param[out] y
+Pointer to the output complex vector `y`,
+corresponds to the input vector `x`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if function calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
+
+Example: \n
+\code{.cpp}
+ complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
+ complex_t y[3];
+ int k;
+
+ sin_cmplx(x, 3, y);
+
+ for(k = 0; k < 3; k++)
+ printf("sin_cmplx(%.1f%+.1fj) = %9.3f%+9.3fj\n",
+ RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
+
+\endcode
+ \n
+
+Output is: \n
+\verbatim
+sin_cmplx(1.0+2.0j) = 3.166 +1.960j
+sin_cmplx(3.0+4.0j) = 3.854 -27.017j
+sin_cmplx(5.0+6.0j) = -193.430 +57.218j
+\endverbatim
+
+\author
+Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+
+
+
+
/*! ****************************************************************************
\ingroup SPEC_MATH_COMMON_GROUP
\fn int sinc(double* x, int n, double a, double* y)
\brief
-Функция \f$ \textrm{sinc}(x,a) = \frac{\sin(ax)}{ax}\f$
+Function \f$ \textrm{sinc}(x,a) = \frac{\sin(ax)}{ax}\f$
+for the real vector `x`.
-Функция рассчитывает значения функции для вещественного вектора `x`.
-
-
-\param[in] x
-Указатель на вектор переменной \f$ x \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n
+\param[in] x
+Pointer to the input vector \f$ x \f$. \n
+Vector size is `[n x 1]`. \n
\n
-\param[in] n
-Размер входного вектора `x`. \n
+\param[in] n
+Input and output vectors size. \n
\n
-\param[in] a
-Параметр функции \f$ \textrm{sinc}(x,a) = \frac{\sin(ax)}{ax}\f$. \n
+\param[in] a
+Function parameter \f$ \textrm{sinc}(x,a) = \frac{\sin(ax)}{ax}\f$. \n
\n
-\param[out] y
-Указатель на вектор значений функции. \n
- Размер вектора `[n x 1]`. \n
- Память должна быть выделена. \n
- \n
+\param[out] y
+Pointer to the `sinc` function output vector. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n
+\n
\return
-`RES_OK` --- расчёт произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+`RES_OK` if function calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
\author
-Бахурин Сергей
-www.dsplib.org
+Sergey Bakhurin www.dsplib.org
***************************************************************************** */
@@ -100,52 +399,108 @@ www.dsplib.org
\fn int sine_int(double* x, int n, double* si)
\brief
-Функция интегрального синуса
+Sine integral function \f$\textrm{Si}(x)\f$ for the real vector `x`.
\f[ \textrm{Si}(x) = \int_{0}^{x} \frac{\sin(x)}{x} \, dx\f]
-Функция рассчитывает значения функции для интегрального синуса
-для произвольного вещественного вектора `x`.
+This function uses
+
+Padé approximants of the convergent Taylor series.
+
+
\param[in] x
-Указатель на вектор переменной \f$ x \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n
+Pointer to the input vector \f$ x \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n
\n
\param[in] n
-Размер входного вектора `x`. \n
+Size of input vector `x`. \n
\n
\param[out] si
-Указатель на вектор значений функции интегрального синуса. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n
+Pointer to the `Si` function vector. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n
\n
\return
-`RES_OK` --- расчёт произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+`RES_OK` if function calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
-Пример использования функции `sine_int`:
+Example:
\include sine_int_test.c
-Данная программа рассчитывает значения функции интегрального синуса и
-функции \ref sinc для вектора переменной `x`
-в интервале \f$[-6\pi \ 6\pi]\f$.
-Рассчитанные данные сохраняются в текстовые файлы
-`dat/dat0.txt` и `dat/dat1.txt`
-
-и выводятся на график `img/sine_int.png`
+This program calcultes sine integral \f$\textrm{Si}(x)\f$ and
+\f$\textrm{sinc}(x)\f$ functions for input `x` vector in interval
+\f$[-6\pi \ 6\pi]\f$.
+Functions values saved to th
+`dat/dat0.txt` and `dat/dat1.txt` files and showed on the figure:
\image html sine_int.png
\author
-Бахурин Сергей
-www.dsplib.org
+Sergey Bakhurin www.dsplib.org
***************************************************************************** */
+
+
+
+/*! ****************************************************************************
+\ingroup SPEC_MATH_COMMON_GROUP
+\fn int sqrt_cmplx(complex_t* x, int n, complex_t *y)
+\brief Square root of the complex vector argguument `x`.
+
+Function calculates square root value of vector `x` length `n`: \n
+\f[
+y(k) = \sqrt{x(k)}, \qquad k = 0 \ldots n-1.
+\f]
+
+
+\param[in] x
+Pointer to the input complex vector `x`. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of input and output vectors `x` and `y`. \n \n
+
+
+\param[out] y
+Pointer to the square root vector `y`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return `RES_OK` if function is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
+
+Example
+\code{.cpp}
+ complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
+ complex_t y[3]
+ int k;
+
+ sqrt_cmplx(x, 3, y);
+
+ for(k = 0; k < 3; k++)
+ printf("sqrt_cmplx(%.1f%+.1fj) = %.3f%+.3fj\n",
+ RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
+
+ \endcode
+ \n
+
+Результатом работы будет
+
+\verbatim
+sqrt_cmplx(1.0+2.0j) = 1.272+0.786j
+sqrt_cmplx(3.0+4.0j) = 2.000+1.000j
+sqrt_cmplx(5.0+6.0j) = 2.531+1.185j
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+
diff --git a/dspl/dox/ru/array.dox b/dspl/dox/ru/array.dox
deleted file mode 100644
index 53072ea..0000000
--- a/dspl/dox/ru/array.dox
+++ /dev/null
@@ -1,662 +0,0 @@
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int array_scale_lin(double* x, int n,
- double xmin, double xmax, double dx,
- double h, double* y)
-\brief Линейное растяжение вектора данных `x`
-Функция производит преобразование значений \f$x(i)\f$, \f$i = 0,1,\ldots n\f$
-в значения \f$y(i)\f$, в соответствии с формулой:
-
-\f[
-y(i) = k_x x(i) + d_x, \qquad k_x =
-\frac{h}{x_{\textrm{max}} - x_{\textrm{min}}}.
-\f]
-
-Таким образом, все значения входного вектора `x` в диапазоне от
-\f$x_{\textrm{min}}\f$ до \f$x_{\textrm{max}}\f$, линейно растягиваются в
-значения вектора `y` в диапазоне от \f$d_x\f$ до \f$h + d_x\f$.
-Заметим, что \f$d_x\f$ задает линейное смещение значений вектора `y`.
-
-Данная функция удобна для перевода величин разных размерностей, в частности,
-для переноса значений вектора `x` на график высоты `h`, где высота может
-быть задана в количестве пикселей, в сантиметрах и т.д.
-
-\param[in] x
-Указатель на вектор входных значений `x`. \n
-Размер вектора `[n x 1]`. \n
-\n
-
-\param[in] n
-Размер вектора `x`. \n
-\n
-
-\param[in] xmin
-Нижняя граница диапазона трансформации. \n
-\n
-
-\param[in] xmax
-Верхняя граница диапазона трансформации. \n
-Значение `xmax` должно быть строго больше значения `xmin`. \n
-\n
-
-\param[in] dx
-Смещение после трансформации. \n
-Данный параметр должен иметь размерность выходного вектора `y`. \n
-\n
-
-\param[in] h
-Диапазон значений вектора `y` после трансформации от `dx` до `h+dx`. \n
-\n
-
-\param[out] y
-Указатель на вектора данных после трансформации. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n
-\note
-Указатель `y` может совпадать с `x`, в этом случае,
-данные вектора `x` будут перезаписаны линейно измененными в соответствии
-с формулой выше. \n
-\n
-
-\return
-`RES_OK` если функция выполнена успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-\author
-Бахурин Сергей
-www.dsplib.org
-**************************************************************************** */
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int concat(void* a, size_t na, void* b, size_t nb, void* c)
-\brief Конкатенация двух массивов данных
-
-Функция производит конкатенацию двух массивов. Пусть массивы `a` и `b`
-заданы как векторы: \n
-`a = [a(0), a(1), ... a(na-1)]`, \n
-`b = [b(0), b(1), ... b(nb-1)]`, \n
-тогда результатом конкатенации будет вектор размера `na+nb` вида: \n
-`c = [a(0), a(1), ... a(na-1), b(0), b(1), ... b(nb-1)]`.
-
-
-\param[in] a
-Указатель на первый вектор `a`. \n
-Размер вектора `na` байт. \n \n
-
-\param[in] na
-Размер первого вектора `a` в байт. \n \n
-
-\param[in] b
-Указатель на второй вектор `b`. \n
-Размер памяти вектора `nb` байт. \n \n
-
-\param[in] nb
-Размер второго вектора `b` в байт. \n \n
-
-\param[out] c
-Указатель на вектор конкатенации `c`. \n
-Размер памяти вектора `na + nb` байт. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если функция выполнена успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-\note
-Функция использует указатели типа `void*` и может быть использована для
-конкатенации данных различного типа. \n
-Например конкатенация массивов типа `double`:
-\code{.cpp}
-double a[3] = {1.0, 2.0, 3.0};
-double b[2] = {4.0, 5.0};
-double c[5];
-concat((void*)a, 3*sizeof(double), (void*)b, 2*sizeof(double), (void*)c);
-\endcode
-в результате вектор `c` будет хранить массив данных:
-\verbatim
-c = [1.0, 2.0, 3.0, 4.0, 5.0]
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-**************************************************************************** */
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int decimate(double* x, int n, int d, double* y, int* cnt)
-\brief Децимация вещественного вектора данных
-
-Функция производит децимацию вещественного вектора `x` в `d` раз. \n
-В результате выходной вектор `y` содержит значения:
-`y(k) = x(k*d), k = 0...n/d-1` \n
-
-\param[in] x
-Указатель на вектор входных данных `x`. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер входного вектора `x`. \n \n
-
-\param[in] d
-Коэффициент децимации. \n
-В результате децимации из вектора `x` будет взять каждый
-d-й элемент. \n \n
-
-\param[out] y
-Указатель на децимированный вектор `y`. \n
-Размер выходного вектора равен `[n/d x 1]`
-будет сохранен по адресу `cnt`. \n
-Память должна быть выделена. \n \n
-
-\param[out] cnt
-Указатель переменную, в которую будет сохранен
-размер выходного вектора после децимации. \n
-Указатель может быть `NULL`, в этом случае
-размер вектора `y` не возвращается. \n \n
-
-\return
-`RES_OK` если функция выполнена успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример децимации вещественного массива данных в 2 раза:
-\code{.cpp}
-double x[10] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
-double y[5];
-int d = 2;
-int cnt;
-decimate(x, 10, d, y, &cnt);
-\endcode
-В результате в переменную `cnt` будет записан размер 5,
-а вектор `y` будет хранить массив данных:
-\verbatim
-c = [0.0, 2.0, 4.0, 6.0, 8.0]
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-**************************************************************************** */
-
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int decimate_cmplx(complex_t* x, int n, int d, complex_t* y, int* cnt)
-\brief Децимация комплексного вектора данных
-
-Функция производит децимацию комплексного вектора `x` в `d` раз. \n
-В результате выходной вектор `y` содержит значения:
-`y(k) = x(k*d), k = 0...n/d-1` \n
-
-\param[in] x
-Указатель на вектор входных данных `x`. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер входного вектора `x`. \n \n
-
-\param[in] d
-Коэффициент децимации. \n
-В результате децимации из вектора `x` будет взять каждый d-й элемент. \n \n
-
-\param[out] y
-Указатель на децимированный вектор `y`. \n
-Размер выходного вектора равен `[n/d x 1]` будет сохранен по адресу `cnt`. \n
-Память должна быть выделена. \n \n
-
-\param[out] cnt
-Указатель переменную, в которую будет сохранен
-размер выходного вектора после децимации. \n
-Указатель может быть `NULL`, в этом случае
-размер вектора `y` не возвращается. \n \n
-
-\return
-`RES_OK` если функция выполнена успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример децимации комплексного массива данных в 2 раза:
-\code{.cpp}
-compex_t x[10] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0},
- {5.0, 5.0}, {6.0, 6.0}, {7.0, 7.0}, {8.0, 8.0}, {9.0, 9.0}};
-compex_t y[5];
-int d = 2;
-int cnt;
-decimate_cmplx(x, 10, d, y, &cnt);
-\endcode
-В результате в переменную `cnt` будет записан размер 5, а вектор `y` будет
-хранить массив данных:
-\verbatim
-c = [0.0+0.0j, 2.0+2.0j, 4.0+4.0j, 6.0+6.0j, 8.0+8.0j]
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-**************************************************************************** */
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int flipip(double* x, int n)
-\brief Функция отражения вещественного вектора `x`
-
-Функция производит отражение вещественного вектора длины `n`
-в памяти данных. \n
-Например исходный вектор `x` длины 6: \n
-\verbatim
-x = [0, 1, 2, 3, 4, 5]
-\endverbatim
-После отражения вектор `x` будет иметь вид:
-\verbatim
-x = [5, 4, 3, 2, 1, 0]
-\endverbatim
-
-\param[in, out] x
-Указатель на вещественный вектор `x`. \n
-Размер вектора `[n x 1]`. \n
-Результат отражения будет помещен по этому же адресу. \n
-
-\param[in] n
-Размер вектора `x`. \n \n
-
-\return
-`RES_OK` если функция выполнена успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример:
-\code{.cpp}
-double x[5] = {0.0, 1.0, 2.0, 3.0, 4.0};
-int i;
-for(i = 0; i < 5; i++)
- printf("%6.1f ", x[i]);
-flipip(x, 5);
-printf("\n");
-for(i = 0; i < 5; i++)
- printf("%6.1f ", x[i]);
-\endcode
-\n
-Результат выполнения:
-\verbatim
- 0.0 1.0 2.0 3.0 4.0
- 4.0 3.0 2.0 1.0 0.0
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-**************************************************************************** */
-
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int flipip_cmplx(complex_t* x, int n)
-\brief Функция отражения комплексного вектора `x`
-
-Функция производит отражение комплексного вектора длины `n`
-в памяти данных. \n
-Например исходный вектор `x` длины 6: \n
-\verbatim
-x = [0+0j, 1+1j, 2+2j, 3+3j, 4+4j, 5+5j]
-\endverbatim
-После отражения вектор `x` будет иметь вид:
-\verbatim
-x = [5+5j, 4+4j, 3+3j, 2+2j, 1+1j, 0+0j]
-\endverbatim
-
-\param[in, out] x
-Указатель на комплексный вектор `x`. \n
-Размер вектора `[n x 1]`. \n
-Результат отражения будет помещен по этому же адресу. \n
-\n
-
-\param[in] n
-Размер вектора `x`. \n
-\n
-
-\return
-`RES_OK` если функция выполнена успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример:
-\code{.cpp}
-complex_t y[5] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}};
-for(i = 0; i < 5; i++)
- printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
-flipip_cmplx(y, 5);
-printf("\n");
-for(i = 0; i < 5; i++)
- printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
-\endcode
- \n
-Результат выполнения:
-\verbatim
- 0.0+0.0j 1.0+1.0j 2.0+2.0j 3.0+3.0j 4.0+4.0j
- 4.0+4.0j 3.0+3.0j 2.0+2.0j 1.0+1.0j 0.0+0.0j
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-**************************************************************************** */
-
-
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int linspace(double x0, double x1, int n, int type, double* x)
-\brief Функция заполняет массив линейно-нарастающими, равноотстоящими
-значениями от `x0` до `x1`
-
-Заполняет массив `x` длиной `n` значениями в диапазоне
-от \f$x_0\f$ до \f$x_1\f$. Функция поддерживает два типа заполнения
-в соответствии с параметром `type`: \n
-
-Симметричное заполнение согласно выражению (параметр `type=DSPL_SYMMETRIC`): \n
-
-\f$x(k) = x_0 + k \cdot dx\f$,
-\f$dx = \frac{x_1 - x_0}{n-1}\f$, \f$k = 0 \ldots n-1.\f$
-
-Периодическое заполнение (параметр `type=DSPL_PERIODIC`) согласно выражению: \n
-
-\f$x(k) = x_0 + k \cdot dx\f$,
-\f$dx = \frac{x_1 - x_0}{n}\f$, \f$k = 0 \ldots n-1.\f$
-
-\param[in] x0
-Начальное показателя \f$x_0\f$. \n \n
-
-\param[in] x1
-Конечное значение \f$x_1\f$. \n \n
-
-\param[in] n
-Количество точек массива `x`. \n \n
-
-\param[in] type
-Тип заполнения: \n
-
-`DSPL_SYMMETRIC` --- симметричное заполнение, \n
-`DSPL_PERIODIC` --- периодическое заполнение. \n \n
-
-\param[in,out] x
-Указатель на вектор равноотстоящих значений . \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` --- функция выполнена успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
-
-\note
-Отличие периодического и симметричного заполнения можно
-понять из следующих примеров. \n
-Пример 1. Периодическое заполнение.
-\code{.cpp}
- double x[5];
- linspace(0, 5, 5, DSPL_PERIODIC, x);
-\endcode
-В массиве `x` будут лежать значения:
-\verbatim
-0, 1, 2, 3, 4
-\endverbatim
- \n \n
-Пример 2. Симметричное заполнение.
-\code{.cpp}
- double x[5];
- linspace(0, 5, 5, DSPL_SYMMETRIC, x);
-\endcode
-В массиве `x` будут лежать значения:
-\verbatim
-0, 1.25, 2.5, 3.75, 5
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-
-
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int logspace(double x0, double x1, int n, int type, double* x)
-\brief Функция заполняет массив значениями логарифмической шкале
-
-Заполняет массив `x` длиной `n` значениями в диапазоне
-от \f$10^{x_0}\f$ до \f$10^{x_1}\f$. \n
-Функция поддерживает два типа заполнения в соответствии с параметром `type`: \n
-
-Симметричное заполнение согласно выражению: \n
-
-\f$x(k) = 10^{x_0} \cdot dx^k\f$, где \f$dx = \sqrt[n-1]{10^{x_1 - x_0}}\f$,
-\f$k = 0 \ldots n-1.\f$
-
-Периодическое заполнение согласно выражению:
-
-\f$x(k) = 10^{x_0} \cdot dx^k\f$, где \f$dx = \sqrt[n]{10^{x_1 - x_0}}\f$,
-\f$k = 0 \ldots n-1.\f$ \n
-
-\param[in] x0
-Начальное значение показателя \f$x_0\f$. \n \n
-
-\param[in] x1
-Конечное значение показателя \f$x_1\f$. \n \n
-
-\param[in] n
-Количество точек массива `x`. \n \n
-
-\param[in] type
-Тип заполнения: \n
-`DSPL_SYMMETRIC` --- симметричное заполнение, \n
-`DSPL_PERIODIC` --- периодическое заполнение. \n \n
-
-\param[in,out] x
-Указатель на вектор значений в логарифмической шкале. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` --- функция выполнена успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-\note
-Отличие периодического и симметричного заполнения можно
-понять из следующих примеров. \n
-
-Пример 1. Периодическое заполнение.
-\code{.cpp}
- double x[5];
- logspace(-2, 3, 5, DSPL_PERIODIC, x);
-\endcode
-В массиве `x` будут лежать значения:
-\verbatim
-0.01, 0.1, 1, 10, 100
-\endverbatim
-
-\n \n
-
-Пример 2. Симметричное заполнение.
-\code{.cpp}
- double x[5];
- logspace(-2, 3, 5, DSPL_SYMMETRIC, x);
-\endcode
-
-В массиве `x` будут лежать значения:
-
-\verbatim
-0.01 0.178 3.162 56.234 1000
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int ones(double* x, int n)
-\brief Функция заполнения вещественного массива единицами
-
-\param[in, out] x
-Указатель на вещественный вектор `x`. \n
-Размер вектора `[n x 1]`. \n
-Значения данного вектора будут установлены в единицу. \n
-\n
-
-\param[in] n
-Размер вектора `x`. \n
-\n
-
-\return
-`RES_OK` если функция выполнена успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример:
-\code{.cpp}
-double y[5] = {0};
-int i;
-ones(y, 5);
-for(i = 0; i < 5; i++)
- printf("%6.1f% ", y[i]);
-\endcode
- \n
-Результат выполнения:
-\verbatim
- 1.0 1.0 1.0 1.0 1.0
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-**************************************************************************** */
-
-
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int verif(double* x, double* y, size_t n, double eps, double* err)
-\brief Верификация вещественных массивов
-
-Функция производит расчет максимальной относительной ошибки между вещественными
-векторами `x` и `y` равной длины `n`:
-
-\f[
-e = \max \left( \frac{|x(k) - y(k)| }{ |x(k)|} \right), \quad \quad |x(k)| > 0,
-\f]
-или
-\f[
-e = \max(|x(k) - y(k)| ), ~\qquad \quad~|x(k)| = 0,
-\f]
-и возвращает `DSPL_VERIF_SUCCESS` если
-разница \f$ e\f$ меньше `eps`.
-В противном случае возвращает `DSPL_VERIF_FAILED`. \n
-Данная функция используется для верификации работы алгоритмов если вектор `x`
-результат работы алгоритма пользователя, а `y` -- результат работы этого же
-алгоритма сторонней функцией.
-
-\param[in] x
-Указатель на первый вектор `x`. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] y
-Указатель на второй вектор `y`. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер векторов `x` и `y`. \n \n
-
-\param[in] eps
-Допустимая относительная ошибка. \n
-Если максимальная относительная ошибка меньше `eps`, то функция возвращает
-`DSPL_VERIF_SUCCESS`, в противном случае `DSPL_VERIF_FAILED`. \n \n
-
-\param[in, out] err
-Указатель на переменную максимальной относительной ошибки. \n
-По данному адресу будет записано значение максимальной относительной ошибки. \n
-Указатель может быть `NULL`, значение ошибки в этом случае
-не возвращается. \n \n
-
-\return
-`DSPL_VERIF_SUCCESS` если относительная ошибка меньше `eps`. \n
- В противном случае `DSPL_VERIF_FAILED`.
-
-\author Бахурин Сергей www.dsplib.org
-**************************************************************************** */
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int verif_cmplx(complex_t* x, complex_t* y, size_t n,
- double eps, double* err)
-\brief Верификация комплексных массивов
-
-Функция производит расчет максимальной относительной ошибки между комплексными
-векторами `x` и `y` равной длины `n`:
-
-\f[
-e = \max \left( \frac{|x(k) - y(k)|}{|x(k)|} \right), \quad \quad |x(k)| > 0,
-\f]
-или
-\f[
-e = \max(|x(k) - y(k)| ), ~\qquad \quad~|x(k)| = 0,
-\f]
-и возвращает `DSPL_VERIF_SUCCESS` если
-разница \f$ e\f$ меньше `eps`.
-В противном случае возвращает `DSPL_VERIF_FAILED`. \n
-Данная функция используется для верификации работы алгоритмов если вектор `x`
-результат работы алгоритма пользователя, а `y` -- результат работы этого же
-алгоритма сторонней функцией.
-
-\param[in] x
-Указатель на первый вектор `x`. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] y
-Указатель на второй вектор `y`. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер векторов `x` и `y`. \n \n
-
-\param[in] eps
-Допустимая относительная ошибка. \n
-Если максимальная относительная ошибка меньше `eps`, то функция возвращает
-`DSPL_VERIF_SUCCESS`, в противном случае `DSPL_VERIF_FAILED`. \n \n
-
-\param[in, out] err
-Указатель на переменную максимальной относительной ошибки. \n
-По данному адресу будет записано значение максимальной относительной ошибки. \n
-Указатель может быть `NULL`, значение ошибки в этом
-случае не возвращается. \n \n
-
-\return
-`DSPL_VERIF_SUCCESS` если функция выполнена успешно. \n
- В противном случае `DSPL_VERIF_FAILED`.
-
-\author
-Бахурин Сергей
-www.dsplib.org
-**************************************************************************** */
-
diff --git a/dspl/dox/ru/cheby.dox b/dspl/dox/ru/cheby.dox
deleted file mode 100644
index c1e2d25..0000000
--- a/dspl/dox/ru/cheby.dox
+++ /dev/null
@@ -1,116 +0,0 @@
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_TRANSCEND
-\fn int cheby_poly1(double* x, int n, int ord, double* y)
-\brief Многочлен Чебышева первого рода порядка `ord`
-
-Функция производит расчет многочлена Чебышева первого рода \f$ C_ord(x)\f$ для
-вещественного вектора `x` длины `n`на основе рекуррентной формулы
-\f[
-C_ord(x) = 2 x C_{ord-1}(x) - C_{ord-2}(x),
-\f]
-где \f$ C_0(x) = 1 \f$, \f$ C_1(x) = x\f$
-
-\param[in] x
-Указатель на вектор `x` аргумента полинома Чебышева первого рода. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер векторов `x` и `y`. \n \n
-
-\param[in] ord
-Порядок полинома Чебышева первого рода. \n \n
-
-\param[out] y
-Указатель на вектор значений полинома Чебышева,
-соответствующих аргументу `x`. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` Расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-Пример использования функции:
-
-\include cheby_poly1_test.c
-
- \n \n
-В каталоге `dat` будут созданы текстовые файлы значений
-полиномов порядка 1-4: \n
-
-
-cheby_poly1_ord1.txt
-cheby_poly1_ord2.txt
-cheby_poly1_ord3.txt
-cheby_poly1_ord4.txt
-
-
-Кроме того программа GNUPLOT произведет построение следующих графиков
-по сохраненным в файлах данным:
-
-\image html cheby_poly1.png
-
-\author
-Бахурин Сергей
-www.dsplib.org
-**************************************************************************** */
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup SPEC_MATH_TRANSCEND
-\fn int cheby_poly2(double* x, int n, int ord, double* y)
-\brief Многочлен Чебышева второго рода порядка `ord`
-
-Функция производит расчет многочлена Чебышева второго рода \f$ U_{ord}(x)\f$ для
-вещественного вектора `x` длины `n`на основе рекуррентной формулы
-\f[
-U_{ord}(x) = 2 x U_{ord-1}(x) - U_{ord-2}(x),
-\f]
-где \f$ U_0(x) = 1 \f$, \f$ U_1(x) = 2x\f$
-
-\param[in] x
-Указатель на вектор `x` аргумента полинома Чебышева второго рода. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер векторов `x` и `y`. \n \n
-
-\param[in] ord
-Порядок полинома Чебышева второго рода. \n \n
-
-\param[out] y
-Указатель на вектор значений полинома Чебышева,
-соответствующих аргументу `x`. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` Расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-Пример использования функции:
-
-\include cheby_poly2_test.c
-
- \n \n
-В каталоге `dat` будут созданы текстовые файлы значений
-полиномов порядка 1-4: \n
-
-
-cheby_poly2_ord1.txt
-cheby_poly2_ord2.txt
-cheby_poly2_ord3.txt
-cheby_poly2_ord4.txt
-
-
-Кроме того программа GNUPLOT произведет построение следующих графиков
-по сохраненным в файлах данным:
-
-\image html cheby_poly2.png
-
-\author Бахурин Сергей www.dsplib.org
-**************************************************************************** */
\ No newline at end of file
diff --git a/dspl/dox/ru/complex.dox b/dspl/dox/ru/complex.dox
deleted file mode 100644
index 4d2c3c6..0000000
--- a/dspl/dox/ru/complex.dox
+++ /dev/null
@@ -1,252 +0,0 @@
-/*! ****************************************************************************
-\ingroup TYPES_GROUP
-\typedef complex_t
-\brief Описание комплексного типа данных.
-
-Комплексный тип данных в библиотеке DSPL-2.0 определен как
-массив из двух элементов типа `double`.
-При этом первый элемент массива определяет реальную часть
-комплексного числа, а второй - мнимую.
-
-Например:
-
-\code{.cpp}
- complex_t z;
- z[0] = 1.0;
- z[1] = -2.0;
-\endcode
-
-Переменная `z = 1-2j`, где `j` - мнимая единица.
-
-Для удобства работы с комплексными числами реализованы
-специальные макросы: \ref RE, \ref IM, \ref ABSSQR
-***************************************************************************** */
-
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup TYPES_GROUP
-\def ABSSQR(x)
-\brief Макрос возвращает квадрат модуля комплексного числа `x`.
-
-Квадрат модуля комплексного числа \f$ x = a + j b \f$ равен:
-
-\f[
- |x|^2 = x x^* = a^2 + b^2.
-\f]
-
-Например:
-\code{.cpp}
- complex_t z;
- double y;
- RE(z) = 1.0;
- IM(z) = -2.0;
- y = ABSSQR(z);
-\endcode
-
-Переменная `z = 1-2j`, где `j` - мнимая единица, а переменная `y = 5`.
-***************************************************************************** */
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup TYPES_GROUP
-\def IM(x)
-\brief Макрос определяющий мнимую часть комплексного числа.
-
-Например:
-\code{.cpp}
- complex_t z;
- RE(z) = 1.0;
- IM(z) = -2.0;
-\endcode
-
-Переменная `z = 1-2j`, где `j` - мнимая единица.
-
-Аналогично, макрос можно использовать для получения
-мнимой части комплексного числа:
-\code{.cpp}
- complex_t z = {3.0, -4.0};
- double r;
- r = IM(z);
-\endcode
-В данном примере переменная `z = 3-4i`,
-а в переменой `r` будет храниться число -4.
-***************************************************************************** */
-
-
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup TYPES_GROUP
-\def RE(x)
-\brief Макрос определяющий реальную часть комплексного числа.
-
-Например:
-\code{.cpp}
- complex_t z;
- RE(z) = 1.0;
- IM(z) = -2.0;
-\endcode
-
-Переменная `z = 1-2j`, где `j` - мнимая единица.
-
-Аналогично, макрос можно использовать для получения
-реальной части комплексного числа:
-
-\code{.cpp}
- complex_t z = {3.0, -4.0};
- double r;
- r = RE(z);
-\endcode
-В данном примере переменная `z = 3-4i`, а в переменой `r`
-будет храниться число 3.
-***************************************************************************** */
-
-
-
-
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup TYPES_GROUP
-\fn int cmplx2re(complex_t* x, int n, double* re, double* im)
-\brief Преобразование массива комплексных данных в два массива
- вещественных данных, содержащих реальную и мнимую части
- исходного массива
-
-Функция заполняет реальные массивы `re` и `im` соответствующими значениями
-реальной и мнимой частей исходного комплексного массива `x`. \n
-
-
-\param[in] x
-Указатель на массив комплексных данных. \n
-Размер массива `[n x 1]`. \n \n
-
-\param[in] n
-Размер массивов входных и выходных данных. \n \n
-
-\param[out] re
-Указатель на адрес массива реальной части данных. \n
-Размер массива `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\param[out] im
-Указатель на адрес массива мнимой части данных. \n
-Размер массива `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если преобразование произведено успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки": \n
-
-Например при выполнении следующего кода
-\code{.cpp}
- complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
- double re[3], im[3];
-
- cmplx2re(x, 3, re, im);
-\endcode
-
-Элементам массивов `re` и `im` будут присвоены значения:
-
-\verbatim
-re[0] = 1.0; im[0] = 2.0;
-re[1] = 3.0; im[1] = 4.0;
-re[2] = 5.0; im[2] = 6.0;
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
diff --git a/dspl/dox/ru/dft.dox b/dspl/dox/ru/dft.dox
deleted file mode 100644
index 736efa1..0000000
--- a/dspl/dox/ru/dft.dox
+++ /dev/null
@@ -1,213 +0,0 @@
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int dft(double* x, int n, complex_t* y)
-\brief Дискретное преобразование Фурье вещественного сигнала.
-
-Функция рассчитывает \f$ n \f$-точечное дискретное преобразование Фурье
-вещественного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \sum_{m = 0}^{n-1} x(m)
- \exp \left( -j \frac{2\pi}{n} m k \right),
-\f]
-где \f$ k = 0 \ldots n-1 \f$.
-
-\param[in] x
-Указатель на вектор вещественного входного сигнала \f$x(m)\f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер ДПФ \f$n\f$ (размер векторов входного сигнала и результата ДПФ). \n \n
-
-\param[out] y
-Указатель на комплексный вектор результата ДПФ \f$Y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$.
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-
-\return
-`RES_OK` если ДПФ рассчитана успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример использования функции `dft`:
-
-\include dft_test.c
-
-Результат работы программы:
-
-\verbatim
-y[ 0] = 120.000 0.000
-y[ 1] = -8.000 40.219
-y[ 2] = -8.000 19.314
-y[ 3] = -8.000 11.973
-y[ 4] = -8.000 8.000
-y[ 5] = -8.000 5.345
-y[ 6] = -8.000 3.314
-y[ 7] = -8.000 1.591
-y[ 8] = -8.000 0.000
-y[ 9] = -8.000 -1.591
-y[10] = -8.000 -3.314
-y[11] = -8.000 -5.345
-y[12] = -8.000 -8.000
-y[13] = -8.000 -11.973
-y[14] = -8.000 -19.314
-y[15] = -8.000 -40.219
-\endverbatim
-
-\note
-Данная функция выполняет расчет ДПФ наивным методом и требует \f$ n^2 \f$
-комплексных умножений. \n
-Для увеличения скорости расчета рекомендуется использовать
-алгоритмы быстрого преобразования Фурье.
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int dft_cmplx(complex_t* x, int n, complex_t* y)
-\brief Дискретное преобразование Фурье комплексного сигнала.
-
-Функция рассчитывает \f$ n \f$-точечное дискретное преобразование Фурье
-комплексного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \sum_{m = 0}^{n-1} x(m)
- \exp \left( -j \frac{2\pi}{n} m k \right),
-\f]
-где \f$ k = 0 \ldots n-1 \f$.
-
-\param[in] x
-Указатель на вектор комплексного
-входного сигнала \f$x(m)\f$, \f$ m = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер ДПФ \f$n\f$ (размер векторов входного сигнала и результата ДПФ). \n \n
-
-\param[out] y
-Указатель на комплексный вектор
-результата ДПФ \f$Y(k)\f$, \f$ k = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-
-\return
-`RES_OK` если ДПФ рассчитана успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример использования функции `dft_cmplx`:
-
-\include dft_cmplx_test.c
-
-Результат работы программы:
-
-\verbatim
-y[ 0] = 120.000 0.000
-y[ 1] = -8.000 40.219
-y[ 2] = -8.000 19.314
-y[ 3] = -8.000 11.973
-y[ 4] = -8.000 8.000
-y[ 5] = -8.000 5.345
-y[ 6] = -8.000 3.314
-y[ 7] = -8.000 1.591
-y[ 8] = -8.000 0.000
-y[ 9] = -8.000 -1.591
-y[10] = -8.000 -3.314
-y[11] = -8.000 -5.345
-y[12] = -8.000 -8.000
-y[13] = -8.000 -11.973
-y[14] = -8.000 -19.314
-y[15] = -8.000 -40.219
-\endverbatim
-
-\note
-Данная функция выполняет расчет ДПФ наивным методом
-и требует \f$ n^2 \f$ комплексных умножений. \n
-Для увеличения скорости расчета рекомендуется
-использовать алгоритмы быстрого преобразования Фурье.
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int idft_cmplx(complex_t* x, int n, complex_t* y)
-\brief Обратное дискретное преобразование Фурье комплексного спектра.
-
-Функция рассчитывает \f$ n \f$-точечное обратное дискретное преобразование
-Фурье комплексного спектра \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- y(k) = \sum_{m = 0}^{n-1} x(m)
- \exp \left( j \frac{2\pi}{n} m k \right),
-\f]
-где \f$ k = 0 \ldots n-1 \f$.
-
-\param[in] x
-Указатель на вектор входного комплексного спектра сигнала \f$x(m)\f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер ОДПФ \f$n\f$ (размер векторов входного спектра и результата ОДПФ). \n \n
-
-\param[out] y
-Указатель на комплексный вектор результата ОДПФ \f$y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$.
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-
-\return
-`RES_OK` если ОДПФ рассчитана успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки".
-
-Пример использования функции `dft_cmplx`:
-
-\include idft_cmplx_test.c
-
-Результат работы программы:
-
-\verbatim
-x[ 0] = 0.000 +0.000j, z[ 0] = 0.000 -0.000
-x[ 1] = 1.000 +0.000j, z[ 1] = 1.000 -0.000
-x[ 2] = 2.000 +0.000j, z[ 2] = 2.000 -0.000
-x[ 3] = 3.000 +0.000j, z[ 3] = 3.000 -0.000
-x[ 4] = 4.000 +0.000j, z[ 4] = 4.000 -0.000
-x[ 5] = 5.000 +0.000j, z[ 5] = 5.000 -0.000
-x[ 6] = 6.000 +0.000j, z[ 6] = 6.000 -0.000
-x[ 7] = 7.000 +0.000j, z[ 7] = 7.000 -0.000
-x[ 8] = 8.000 +0.000j, z[ 8] = 8.000 -0.000
-x[ 9] = 9.000 +0.000j, z[ 9] = 9.000 -0.000
-x[10] = 10.000 +0.000j, z[10] = 10.000 -0.000
-x[11] = 11.000 +0.000j, z[11] = 11.000 +0.000
-x[12] = 12.000 +0.000j, z[12] = 12.000 +0.000
-x[13] = 13.000 +0.000j, z[13] = 13.000 +0.000
-x[14] = 14.000 +0.000j, z[14] = 14.000 +0.000
-x[15] = 15.000 +0.000j, z[15] = 15.000 -0.000
-\endverbatim
-
-\note
-Данная функция выполняет расчет ОДПФ наивным методом
-и требует \f$ n^2 \f$ комплексных умножений. \n
-Для увеличения скорости расчета рекомендуется
-использовать алгоритмы быстрого преобразования Фурье.
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-
-
-
-
diff --git a/dspl/dox/ru/ellipj.dox b/dspl/dox/ru/ellipj.dox
deleted file mode 100644
index 5857408..0000000
--- a/dspl/dox/ru/ellipj.dox
+++ /dev/null
@@ -1,464 +0,0 @@
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
diff --git a/dspl/dox/ru/error_list.dox b/dspl/dox/ru/error_list.dox
index 8de438b..d0b21db 100644
--- a/dspl/dox/ru/error_list.dox
+++ b/dspl/dox/ru/error_list.dox
@@ -183,12 +183,6 @@
*/
-
-
-
-
-
-
/*!
\ingroup ERROR_CODE_GROUP
\def ERROR_GNUPLOT_CREATE
@@ -208,7 +202,6 @@
*/
-
/*!
\ingroup ERROR_CODE_GROUP
\def ERROR_LAPACK
@@ -251,7 +244,6 @@
*/
-
/*!
\ingroup ERROR_CODE_GROUP
\def ERROR_POLY_AN
@@ -262,7 +254,6 @@
*/
-
/*!
\ingroup ERROR_CODE_GROUP
\def ERROR_POLY_ORD
@@ -271,7 +262,6 @@
*/
-
/*!
\ingroup ERROR_CODE_GROUP
\def ERROR_PTR
@@ -294,7 +284,6 @@
*/
-
/*!
\ingroup ERROR_CODE_GROUP
\def ERROR_RAND_TYPE
diff --git a/dspl/dox/ru/fft.dox b/dspl/dox/ru/fft.dox
deleted file mode 100644
index b2fb671..0000000
--- a/dspl/dox/ru/fft.dox
+++ /dev/null
@@ -1,469 +0,0 @@
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\struct fft_t
-\brief Структура данных объекта быстрого преобразования Фурье
-
-Структура хранит указатели на массивы поворотных коэффициентов
-и массивы промежуточных данных алгоритма быстрого преобразования Фурье.
-
-Библиотека DSPL использует для БПФ алгоритм для составной длины
-
-
-\param n
-Размер вектора БПФ, для которого выделена память в массивах структуры. \n
-Парметр `n` должен быть равен целой степени двойки. \n \n
-
-
-\param w
-Указатель на вектор поворотных коэффициентов алгоритма БПФ. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена и массив поворотных коэффициентов
-должен быть заполнен функцией \ref fft_create. \n \n
-
-
-\param t0
-Указатель на вектор промежуточных вычислений алгоритма БПФ. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена функцией \ref fft_create. \n \n
-
-
-\param t1
-Указатель на вектор промежуточных вычислений алгоритма БПФ. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена функцией \ref fft_create. \n \n
-Структура заполняется функцией \ref fft_create один раз
-до использования алгоритма БПФ. \n
-Указатель на объект данной структуры может быть
-многократно использован при вызове функций БПФ. \n
-Перед выходом из программы выделенную память под поворотные
-коэффициенты и массивы промежуточных данных
-необходимо очистить функцией \ref fft_free. Например:
-\code
-fft_t pfft; /* объявляем объект fft_t */
-int n = 64; /* Размер БПФ */
-
-/*
-обнуляем все поля и указатели.
-Данные шаг рекомендуется ввиду того, что некоторые
-при создании переменной не инициализируют ее нулем.
-*/
-
-memset(&pfft, 0, sizeof(fft_t));
-
-int err;
-
-/* создаем объект для 64-точечного БПФ */
-err = fft_create(&pfft, n);
-
-/* Вызов БПФ функции*/
-/* Еще раз вызов БПФ функции */
-/* ... */
-
-/* очистить память объекта БПФ */
-fft_free(&pfft);
-\endcode
-
-\note
-Важно отметить, что если объект `fft_t` был создан для размера БПФ равного `n`,
-то он может быть использован только для БПФ размера `n`. \n\n
-Также необходимо заметить, что функции БПФ самостоятельно контролируют размер,
-и самостоятельно выделяют память объекта БПФ при необходимости.
-Так если вызвать любую функцию использующую структуру `fft_t` с заполненными
-данными для длины БПФ `k` для расчета БПФ длины `n`,
-то массивы структуры будут автоматически пересозданы для длины `n`.
-
-\author
-Бахурин Сергей.
-www.dsplib.org
-***************************************************************************** */
-
-
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int ifft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
-\brief Обратное быстрое преобразование Фурье
-
-Функция рассчитывает \f$ n \f$-точечное обратное быстрое преобразование Фурье
-от \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \frac{1}{N} \sum_{m = 0}^{n-1} x(m) \exp
- \left( j \frac{2\pi}{n} m k \right),
-\f]
-где \f$ k = 0 \ldots n-1 \f$.
-
-Для расчета используется алгоритм БПФ составной длины.
-
-\param[in] x
-Указатель на входной комплексный вектор \f$x(m)\f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер ОБПФ \f$n\f$. \n
-Размер ОБПФ может быть составным вида
-\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
-где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
-произвольный простой множитель не превосходящий 46340
-(см. описание функции \ref fft_create). \n \n
-
-\param[in] pfft
-Указатель на структуру `fft_t`. \n
-Указатель не должен быть `NULL`. \n
-Структура \ref fft_t должна быть предварительно однократно
-заполнена функцией \ref fft_create, и память должна быть
-очищена перед выходом функцией \ref fft_free. \n \n
-
-\param[out] y
-Указатель на вектор результата ОБПФ \f$Y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$. Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если расчет произведен успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
-
-Пример использования функции `fft`:
-
-\include ifft_cmplx_test.c
-
-Результат работы программы:
-
-\verbatim
-| x[ 0] = 1.000 0.000 | y[ 0] = -0.517 0.686 | z[ 0] = 1.000 0.000 |
-| x[ 1] = 0.540 0.841 | y[ 1] = -0.943 0.879 | z[ 1] = 0.540 0.841 |
-| x[ 2] = -0.416 0.909 | y[ 2] = -2.299 1.492 | z[ 2] = -0.416 0.909 |
-| x[ 3] = -0.990 0.141 | y[ 3] = 16.078 -6.820 | z[ 3] = -0.990 0.141 |
-| x[ 4] = -0.654 -0.757 | y[ 4] = 2.040 -0.470 | z[ 4] = -0.654 -0.757 |
-| x[ 5] = 0.284 -0.959 | y[ 5] = 1.130 -0.059 | z[ 5] = 0.284 -0.959 |
-| x[ 6] = 0.960 -0.279 | y[ 6] = 0.786 0.097 | z[ 6] = 0.960 -0.279 |
-| x[ 7] = 0.754 0.657 | y[ 7] = 0.596 0.183 | z[ 7] = 0.754 0.657 |
-| x[ 8] = -0.146 0.989 | y[ 8] = 0.470 0.240 | z[ 8] = -0.146 0.989 |
-| x[ 9] = -0.911 0.412 | y[ 9] = 0.375 0.283 | z[ 9] = -0.911 0.412 |
-| x[10] = -0.839 -0.544 | y[10] = 0.297 0.318 | z[10] = -0.839 -0.544 |
-| x[11] = 0.004 -1.000 | y[11] = 0.227 0.350 | z[11] = 0.004 -1.000 |
-| x[12] = 0.844 -0.537 | y[12] = 0.161 0.380 | z[12] = 0.844 -0.537 |
-| x[13] = 0.907 0.420 | y[13] = 0.094 0.410 | z[13] = 0.907 0.420 |
-| x[14] = 0.137 0.991 | y[14] = 0.023 0.442 | z[14] = 0.137 0.991 |
-| x[15] = -0.760 0.650 | y[15] = -0.059 0.479 | z[15] = -0.760 0.650 |
-| x[16] = -0.958 -0.288 | y[16] = -0.161 0.525 | z[16] = -0.958 -0.288 |
-| x[17] = -0.275 -0.961 | y[17] = -0.300 0.588 | z[17] = -0.275 -0.961 |
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft(double* x, int n, fft_t* pfft, complex_t* y)
-\brief Быстрое преобразование Фурье вещественного сигнала
-
-Функция рассчитывает \f$ n \f$-точечное быстрое преобразование Фурье
-вещественного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \sum_{m = 0}^{n-1} x(m) \exp
- \left( -j \frac{2\pi}{n} m k \right),
-\f]
-где \f$ k = 0 \ldots n-1 \f$.
-
-Для расчета используется алгоритм БПФ составной длины.
-
-\param[in] x
-Указатель на вектор вещественного входного сигнала \f$x(m)\f$,
-\f$ m = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер БПФ \f$n\f$. \n
-Размер БПФ может быть составным вида
-\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
-где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
-произвольный простой множитель не превосходящий 46340
-(см. описание функции \ref fft_create). \n \n
-
-\param[in] pfft
-Указатель на структуру `fft_t`. \n
-Указатель не должен быть `NULL`. \n
-Структура \ref fft_t должна быть предварительно однократно
-заполнена функцией \ref fft_create, и память должна быть
-очищена перед выходом функцией \ref fft_free. \n \n
-
-\param[out] y
-Указатель на комплексный вектор результата БПФ \f$Y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если расчет произведен успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
-
-Пример использования функции `fft`:
-
-\include fft_test.c
-
-Результат работы программы:
-
-\verbatim
-y[ 0] = 91.000 0.000
-y[ 1] = -7.000 30.669
-y[ 2] = -7.000 14.536
-y[ 3] = -7.000 8.778
-y[ 4] = -7.000 5.582
-y[ 5] = -7.000 3.371
-y[ 6] = -7.000 1.598
-y[ 7] = -7.000 0.000
-y[ 8] = -7.000 -1.598
-y[ 9] = -7.000 -3.371
-y[10] = -7.000 -5.582
-y[11] = -7.000 -8.778
-y[12] = -7.000 -14.536
-y[13] = -7.000 -30.669
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
-\brief Быстрое преобразование Фурье комплексного сигнала
-
-Функция рассчитывает \f$ n \f$-точечное быстрое преобразование Фурье
-комплексного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
-\f[
- Y(k) = \sum_{m = 0}^{n-1} x(m) \exp
- \left( -j \frac{2\pi}{n} m k \right),
-\f]
-где \f$ k = 0 \ldots n-1 \f$.
-
-Для расчета используется алгоритм БПФ составной длины.
-
-\param[in] x
-Указатель на вектор комплексного
-входного сигнала \f$x(m)\f$, \f$ m = 0 \ldots n-1 \f$. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер БПФ \f$n\f$. \n
-Размер БПФ может быть составным вида
-\f$n = n_0 \times n_1 \times n_2 \times n_3 \times \ldots \times n_p \times m\f$,
-где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
-произвольный простой множитель не превосходящий 46340
-(см. описание функции \ref fft_create). \n \n
-
-\param[in] pfft
-Указатель на структуру `fft_t`. \n
-Указатель не должен быть `NULL`. \n
-Структура \ref fft_t должна быть предварительно однократно
-заполнена функцией \ref fft_create, и память должна быть
-очищена перед выходом функцией \ref fft_free. \n \n
-
-\param[out] y
-Указатель на комплексный вектор
-результата БПФ \f$Y(k)\f$,
-\f$ k = 0 \ldots n-1 \f$.
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-\return
-`RES_OK` если расчет произведен успешно. \n
- В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
-
-Пример использования функции `fft`:
-
-\include fft_cmplx_test.c
-
-Результат работы программы:
-
-\verbatim
-y[ 0] = -0.517 0.686
-y[ 1] = -0.943 0.879
-y[ 2] = -2.299 1.492
-y[ 3] = 16.078 -6.820
-y[ 4] = 2.040 -0.470
-y[ 5] = 1.130 -0.059
-y[ 6] = 0.786 0.097
-y[ 7] = 0.596 0.183
-y[ 8] = 0.470 0.240
-y[ 9] = 0.375 0.283
-y[10] = 0.297 0.318
-y[11] = 0.227 0.350
-y[12] = 0.161 0.380
-y[13] = 0.094 0.410
-y[14] = 0.023 0.442
-y[15] = -0.059 0.479
-y[16] = -0.161 0.525
-y[17] = -0.300 0.588
-\endverbatim
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft_create(fft_t* pfft, int n)
-\brief Заполнение структуры `fft_t` для алгоритма БПФ
-
-Функция производит выделение памяти и рассчет векторов
-поворотных коэффициентов `n`-точечного БПФ для структуры `fft_t`.
-
-\param[in,out] pfft
-Указатель на структуру `fft_t`. \n
-Указатель не должен быть `NULL`. \n \n
-
-\param[in] n
-Размер БПФ \f$n\f$. \n
-Размер БПФ может быть составным вида
-\f$n = n_0 \times n_1 \times n_2 \ldots \times n_p \times m\f$,
-где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
-произвольный простой множитель не превосходящий 46340. \n
-Таким образом алгоритм БПФ поддерживает произвольные длины, равные целой
-степени чисел 2,3,5,7, а также различные их комбинации. \n
-Так например, при \f$ n = 725760 \f$ структура будет успешно заполнена,
-потому что
-\f$725760 = 2 \cdot 3 \cdot 4 \cdot 5 \cdot 6 \cdot 7 \cdot 9 \cdot 16 \f$,
-т.е. получается как произведение множителей 2,3,5,7. \n
-При \f$ n = 172804 = 43201 \cdot 4 \f$ структура также будет успешно заполнена,
-потому что простой множитель входящий в \f$n\f$ не превосходит 46340. \n
-Для размера \f$ n = 13 \cdot 17 \cdot 23 \cdot 13 = 66079 \f$
-функция вернет ошибку, поскольку 66079 больше 46340 и не является результатом
-произведения чисел 2,3,5,7. \n \n
-
-\return
-`RES_OK` если структура заполнена успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
-
-\note
-Некоторые компиляторы при создании структуры не обнуляют ее содержимое.
-Поэтому рекомендуется произвести обнуление структуры после ее объявления:
-\code{.cpp}
-fft_t pfft; /* объявляем объект fft_t */
-int n = 64; /* Размер БПФ */
-
-/*
-бнуляем все поля и указатели.
-Данные шаг рекомендуется ввиду того, что некоторые
-компиляторы при создании переменной не инициализируют ее нулем.
-*/
-
-memset(&pfft, 0, sizeof(fft_t));
-
-int err;
-
-/* создаем объект для 64-точечного БПФ */
-
-err = fft_create(&pfft, n);
-
-/* ................................... */
-
-/* очистить память объекта БПФ */
-
-fft_free(&pfft);
-\endcode
-
-Перед выходом из программы выделенную в структуре память
-необходимо очистить функцией \ref fft_free . \n \n
-
-\note
-Магия числа 46340 заключается в том, что \f$\sqrt{2^{31}} = 46340.95\f$. \n
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn void fft_free(fft_t *pfft)
-\brief Очистить структуру `fft_t` алгоритма БПФ
-
-Функция производит очищение памяти промежуточных данных
-и векторов поворотных коэффициентов структуры `fft_t`.
-
-\param[in] pfft
-Указатель на структуру `fft_t`. \n
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\ingroup DFT_GROUP
-\fn int fft_shift(double* x, int n, double* y)
-\brief Перестановка спектральных отсчетов дискретного преобразования Фурье
-
-Функция производит
-
-перестановку спектральных отсчетов ДПФ
- и переносит нулевую частоту в центр вектора ДПФ. \n
-Данная функция обрабатывает вещественные входные и выходные вектора
-и может применяться для перестановки
-амплитудного или фазового спектра.
-
-\param[in] x
-Указатель на исходный вектор ДПФ. \n
-Размер вектора `[n x 1]`. \n \n
-
-\param[in] n
-Размер ДПФ \f$n\f$ (размер векторов до и после перестановки). \n \n
-
-\param[out] y
-Указатель на вектор результата перестановки. \n
-Размер вектора `[n x 1]`. \n
-Память должна быть выделена. \n \n
-
-
-\return
-`RES_OK` если перестановка произведена успешно. \n
-В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
-
-\author
-Бахурин Сергей
-www.dsplib.org
-***************************************************************************** */
diff --git a/dspl/dox/ru/filter_an.dox b/dspl/dox/ru/filter_an.dox
deleted file mode 100644
index 0f9e6eb..0000000
--- a/dspl/dox/ru/filter_an.dox
+++ /dev/null
@@ -1,260 +0,0 @@
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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
-***************************************************************************** */
-
-
-
-
-
-
-
-
-
-
-/*! ****************************************************************************
-\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` Комплексный коэффициент передачи расcчитан успешно. \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
-***************************************************************************** */
diff --git a/dspl/dox/ru/filter_ap.dox b/dspl/dox/ru/filter_ap.dox
index b1206fa..e1e3834 100644
--- a/dspl/dox/ru/filter_ap.dox
+++ b/dspl/dox/ru/filter_ap.dox
@@ -276,8 +276,7 @@ www.dsplib.org
/*! ****************************************************************************
\ingroup IIR_FILTER_DESIGN_GROUP
-\fn int cheby1_ap_zp( int ord, double rp, complex_t *z, int* nz,
- complex_t* p, int* np)
+\fn int cheby1_ap_zp(int ord, double rp, complex_t* z, int* nz, complex_t* p, int* np)
\brief
Расчет массивов нулей и полюсов передаточной функции \f$ H(s) \f$
аналогового нормированного ФНЧ Чебышёва первого рода.
@@ -300,7 +299,7 @@ www.dsplib.org
\param[out] z
Указатель на массив комплексных нулей
передаточной характеристики \f$ H(s)\f$. \n
-Максимальный размер вектора вектора `[ord x 1]`. \n
+Максимальный размер вектора `[ord x 1]`. \n
Память должна быть выделена. \n
\n
@@ -321,8 +320,8 @@ www.dsplib.org
\param[out] np
Указатель на переменную количества полюсов передаточной функции \f$ H(s)\f$. \n
-По данному укащзателю будет записано количество нулей фильтра, которые были
-рассчитны и помещены в вектор `p`. \n
+По данному указателю будет записано количество нулей фильтра, которые были
+рассчитаны и помещены в вектор `p`. \n
Память должна быть выделена. \n
\n
@@ -334,6 +333,35 @@ www.dsplib.org
Нормированный ФНЧ Чебышёва первого рода не имеет нулей, поэтому массив
нулей `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
@@ -485,28 +513,39 @@ www.dsplib.org
Пример использования функции `cheby2_ap_zp`:
+Пример программы рассчета нулей и полюсов нормированного
+ФНЧ Чебышева первого рода:
\include cheby2_ap_zp_test.c
-Результат работы программы:
+Результат выполнения программы:
\verbatim
- Chebyshev type 2 zeros:
- 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 poles:
- 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
+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
Бахурин Сергей
@@ -538,7 +577,7 @@ www.dsplib.org
Значение должно быть положительным. \n
\n
-\param[in] Rs
+\param[in] rs
Уровень подавления в полосе заграждения (дБ). \n
Значение должно быть положительным. \n
\n
@@ -607,6 +646,106 @@ www.dsplib.org
+/*! ****************************************************************************
+\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
+***************************************************************************** */
+
+
+
diff --git a/dspl/dox/ru/groups_define.dox b/dspl/dox/ru/groups_define.dox
index a514cfd..b35be04 100644
--- a/dspl/dox/ru/groups_define.dox
+++ b/dspl/dox/ru/groups_define.dox
@@ -32,8 +32,12 @@
\defgroup RESAMPLING_GROUP Цифровая передискретизация сигналов
+\defgroup ARRAY_GROUP Базовые функции обработки массивов вещественных и комплексных данных
+
\defgroup SPEC_MATH_COMMON_GROUP Базовые функции и работа с массивами данных
+\defgroup SPEC_MATH_POLY_GROUP Функции полиномов и их анализ.
+
\defgroup SPEC_MATH_TRIG_GROUP Тригонометрические и гиперболические функции
Тригонометрические и гиперболические функции вещественного
и комплексного аргумента.
diff --git a/dspl/dox/ru/mainpage.dox b/dspl/dox/ru/mainpage.dox
index 83882d2..a958fff 100644
--- a/dspl/dox/ru/mainpage.dox
+++ b/dspl/dox/ru/mainpage.dox
@@ -35,7 +35,9 @@ DSPL-2.0 --- свободная библиотека алгоритмов циф
\subsection sec_doc_content Разделы документации
Математические функции: \n
+ - \ref ARRAY_GROUP \n
- \ref SPEC_MATH_COMMON_GROUP \n
+ - \ref SPEC_MATH_POLY_GROUP \n
- \ref SPEC_MATH_TRIG_GROUP \n
- \ref SPEC_MATH_TRANSCEND \n
- \ref SPEC_MATH_ELLIP_GROUP \n
diff --git a/dspl/src/array.c b/dspl/src/array.c
index 5e559ed..2f3c62b 100644
--- a/dspl/src/array.c
+++ b/dspl/src/array.c
@@ -5,17 +5,17 @@
* 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
+* 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
+* 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 .
+* along with Foobar. If not, see .
*/
@@ -26,176 +26,839 @@
#include "blas.h"
-/******************************************************************************
-Vector linear transformation
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
-int array_scale_lin(double* x, int n,
- double xmin, double xmax, double dx,
- double h, double* y)
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int array_scale_lin(double* x, int n,
+ double xmin, double xmax, double dx,
+ double h, double* y)
+\brief Vector `x` linear transformation
+
+Function transforms values \f$x(i)\f$, \f$i = 0,1,\ldots n\f$
+to the \f$y(i)\f$, accordint to equation:
+
+\f[
+y(i) = k_x x(i) + d_x, \qquad k_x =
+\frac{h}{x_{\textrm{max}} - x_{\textrm{min}}}.
+\f]
+
+All values of the vector `x` between
+\f$x_{\textrm{min}}\f$ and \f$x_{\textrm{max}}\f$, transforms to
+the vector `y` between \f$d_x\f$ and \f$h + d_x\f$.
+Parameter \f$d_x\f$ sets mean shift of the vector `y`.
+
+This function is convenient for translating values
+of different dimensions. For example it can be used
+to transfer the values of the vector `x`
+to the graph of the height of` h`, where the height can
+be set in the number of pixels, in centimeters, etc.
+
+\param[in] x
+Pointer to the input vector `x`. \n
+Vector size is `[n x 1]`. \n
+\n
+
+\param[in] n
+Size of vector `x`. \n
+\n
+
+\param[in] xmin
+Parameter \f$x_{\textrm{min}}\f$. \n
+\n
+
+\param[in] xmax
+Parameter \f$x_{\textrm{min}}\f$. \n
+Value `xmax` must be more than `xmin`. \n
+\n
+
+\param[in] dx
+Displacement after transformation. \n
+This parameter must have output vector `y`
+dimensions (pixels, centimeters). \n
+\n
+
+\param[in] h
+Height of vector `y` after transforming between `dx` and `h+dx`. \n
+\n
+
+\param[out] y
+Pointer to the output vector `y`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n
+\note
+Pointer `y` can be equal to `x`.
+Velues of vector `x` will be rewritten in this case. \n
+\n
+
+\return
+`RES_OK` if function returns successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int array_scale_lin(double* x, int n,
+ double xmin, double xmax, double dx,
+ double h, double* y)
+\brief Линейное растяжение вектора данных `x`
+Функция производит преобразование значений \f$x(i)\f$, \f$i = 0,1,\ldots n\f$
+в значения \f$y(i)\f$, в соответствии с формулой:
+
+\f[
+y(i) = k_x x(i) + d_x, \qquad k_x =
+\frac{h}{x_{\textrm{max}} - x_{\textrm{min}}}.
+\f]
+
+Таким образом, все значения входного вектора `x` в диапазоне от
+\f$x_{\textrm{min}}\f$ до \f$x_{\textrm{max}}\f$, линейно растягиваются в
+значения вектора `y` в диапазоне от \f$d_x\f$ до \f$h + d_x\f$.
+Заметим, что \f$d_x\f$ задает линейное смещение значений вектора `y`.
+
+Данная функция удобна для перевода величин разных размерностей, в частности,
+для переноса значений вектора `x` на график высоты `h`, где высота может
+быть задана в количестве пикселей, в сантиметрах и т.д.
+
+\param[in] x
+Указатель на вектор входных значений `x`. \n
+Размер вектора `[n x 1]`. \n
+\n
+
+\param[in] n
+Размер вектора `x`. \n
+\n
+
+\param[in] xmin
+Нижняя граница диапазона трансформации. \n
+\n
+
+\param[in] xmax
+Верхняя граница диапазона трансформации. \n
+Значение `xmax` должно быть строго больше значения `xmin`. \n
+\n
+
+\param[in] dx
+Смещение после трансформации. \n
+Данный параметр должен иметь размерность выходного вектора `y`. \n
+\n
+
+\param[in] h
+Диапазон значений вектора `y` после трансформации от `dx` до `h+dx`. \n
+\n
+
+\param[out] y
+Указатель на вектора данных после трансформации. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n
+\note
+Указатель `y` может совпадать с `x`, в этом случае,
+данные вектора `x` будут перезаписаны линейно измененными в соответствии
+с формулой выше. \n
+\n
+
+\return
+`RES_OK` если функция выполнена успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API array_scale_lin(double* x, int n,
+ double xmin, double xmax, double dx,
+ double h, double* y)
{
- double kx;
- int k;
- if(!x)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
- if(h<0.0)
- return ERROR_NEGATIVE;
+ double kx;
+ int k;
+ if(!x)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+ if(h<0.0)
+ return ERROR_NEGATIVE;
- if(xmin >= xmax)
- return ERROR_MIN_MAX;
+ if(xmin >= xmax)
+ return ERROR_MIN_MAX;
- kx = h / (xmax - xmin);
+ kx = h / (xmax - xmin);
- for(k = 0; k < n; k++)
- y[k] = (x[k] - xmin) * kx + dx;
+ for(k = 0; k < n; k++)
+ y[k] = (x[k] - xmin) * kx + dx;
- return RES_OK;
+ return RES_OK;
}
-
-/******************************************************************************
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int concat(void* a, size_t na, void* b, size_t nb, void* c)
+\brief
Concatenate arrays `a` and `b`
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+
+Let's arrays `a` and `b` are vectors: \n
+`a = [a(0), a(1), ... a(na-1)]`, \n
+`b = [b(0), b(1), ... b(nb-1)]`, \n
+concatenation of these arrays will be array `c` size `na+nb`: \n
+`c = [a(0), a(1), ... a(na-1), b(0), b(1), ... b(nb-1)]`.
+
+
+\param[in] a
+Pointer to the first array `a`. \n
+Array `a` size is `na` bytes. \n
+\n
+
+\param[in] na
+Array `a` size (bytes). \n
+\n
+
+\param[in] b
+Pointer to the second array `b`. \n
+Array `b` size is `nb` bytes. \n
+\n
+
+\param[in] nb
+Array `a` size (bytes). \n
+\n
+
+\param[out] c
+Pointer to the concatenation result array `c`. \n
+Array `c` size is `na + nb` bytes. \n
+Memory must be allocated. \n
+\n
+
+\return
+`RES_OK` if function returns successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+Function uses pointer type `void*` and can be useful for an arrays
+concatenation with different types. \n
+For example two `double` arrays concatenation:
+\code{.cpp}
+double a[3] = {1.0, 2.0, 3.0};
+double b[2] = {4.0, 5.0};
+double c[5];
+
+concat((void*)a, 3*sizeof(double), (void*)b, 2*sizeof(double), (void*)c);
+\endcode
+Vector `c` keeps follow data:
+\verbatim
+c = [1.0, 2.0, 3.0, 4.0, 5.0]
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int concat(void* a, size_t na, void* b, size_t nb, void* c)
+\brief Конкатенация двух массивов данных
+
+Функция производит конкатенацию двух массивов. Пусть массивы `a` и `b`
+заданы как векторы: \n
+`a = [a(0), a(1), ... a(na-1)]`, \n
+`b = [b(0), b(1), ... b(nb-1)]`, \n
+тогда результатом конкатенации будет вектор размера `na+nb` вида: \n
+`c = [a(0), a(1), ... a(na-1), b(0), b(1), ... b(nb-1)]`.
+
+
+\param[in] a
+Указатель на первый вектор `a`. \n
+Размер вектора `na` байт. \n \n
+
+\param[in] na
+Размер первого вектора `a` в байт. \n \n
+
+\param[in] b
+Указатель на второй вектор `b`. \n
+Размер памяти вектора `nb` байт. \n \n
+
+\param[in] nb
+Размер второго вектора `b` в байт. \n \n
+
+\param[out] c
+Указатель на вектор конкатенации `c`. \n
+Размер памяти вектора `na + nb` байт. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если функция выполнена успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+\note
+Функция использует указатели типа `void*` и может быть использована для
+конкатенации данных различного типа. \n
+Например конкатенация массивов типа `double`:
+\code{.cpp}
+double a[3] = {1.0, 2.0, 3.0};
+double b[2] = {4.0, 5.0};
+double c[5];
+concat((void*)a, 3*sizeof(double), (void*)b, 2*sizeof(double), (void*)c);
+\endcode
+в результате вектор `c` будет хранить массив данных:
+\verbatim
+c = [1.0, 2.0, 3.0, 4.0, 5.0]
+\endverbatim
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API concat(void* a, size_t na, void* b, size_t nb, void* c)
{
- if(!a || !b || !c || c == b)
- return ERROR_PTR;
- if(na < 1 || nb < 1)
- return ERROR_SIZE;
+ if(!a || !b || !c || c == b)
+ return ERROR_PTR;
+ if(na < 1 || nb < 1)
+ return ERROR_SIZE;
- if(c != a)
- memcpy(c, a, na);
+ if(c != a)
+ memcpy(c, a, na);
- memcpy((char*)c+na, b, nb);
- return RES_OK;
+ memcpy((char*)c+na, b, nb);
+ return RES_OK;
}
-/******************************************************************************
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int decimate(double* x, int n, int d, double* y, int* cnt)
+\brief
Real vector decimation
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+
+Function `d` times decimates real vector `x`. \n
+Output vector `y` keeps values corresponds to:
+`y(k) = x(k*d), k = 0...n/d-1` \n
+
+\param[in] x
+Pointer to the input real vector `x`. \n
+Vector `x` size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of input vector `x`. \n \n
+
+\param[in] d
+Decimation coefficient. \n
+Each d-th vector will be copy from vector `x` to the
+output vector `y`. \n \n
+
+\param[out] y
+Pointer to the output decimated vector `y`. \n
+Output vector size is `[n/d x 1]` will be copy
+to the address `cnt`. \n
+
+\param[out] cnt
+Address which will keep decimated vector `y` size. \n
+Pointer can be `NULL`, vector `y` will not return
+in this case. \n \n
+
+\return
+`RES_OK` if function calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+Two-times decimation example:
+\code{.cpp}
+double x[10] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
+double y[5];
+int d = 2;
+int cnt;
+
+decimate(x, 10, d, y, &cnt);
+\endcode
+As result variable `cnt` will be written value 5 and
+vector `y` will keep array:
+\verbatim
+c = [0.0, 2.0, 4.0, 6.0, 8.0]
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int decimate(double* x, int n, int d, double* y, int* cnt)
+\brief Децимация вещественного вектора данных
+
+Функция производит децимацию вещественного вектора `x` в `d` раз. \n
+В результате выходной вектор `y` содержит значения:
+`y(k) = x(k*d), k = 0...n/d-1` \n
+
+\param[in] x
+Указатель на вектор входных данных `x`. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер входного вектора `x`. \n \n
+
+\param[in] d
+Коэффициент децимации. \n
+В результате децимации из вектора `x` будет взять каждый
+d-й элемент. \n \n
+
+\param[out] y
+Указатель на децимированный вектор `y`. \n
+Размер выходного вектора равен `[n/d x 1]`
+будет сохранен по адресу `cnt`. \n
+Память должна быть выделена. \n \n
+
+\param[out] cnt
+Указатель переменную, в которую будет сохранен
+размер выходного вектора после децимации. \n
+Указатель может быть `NULL`, в этом случае
+размер вектора `y` не возвращается. \n \n
+
+\return
+`RES_OK` если функция выполнена успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример децимации вещественного массива данных в 2 раза:
+\code{.cpp}
+double x[10] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
+double y[5];
+int d = 2;
+int cnt;
+decimate(x, 10, d, y, &cnt);
+\endcode
+В результате в переменную `cnt` будет записан размер 5,
+а вектор `y` будет хранить массив данных:
+\verbatim
+c = [0.0, 2.0, 4.0, 6.0, 8.0]
+\endverbatim
+
+\author
+Бахурин Сергей
+www.dsplib.org
+**************************************************************************** */
+#endif
int DSPL_API decimate(double* x, int n, int d, double* y, int* cnt)
{
- int k = 0, i = 0;
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
- if(d < 1)
- return ERROR_NEGATIVE;
+ int k = 0, i = 0;
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+ if(d < 1)
+ return ERROR_NEGATIVE;
- k = i = 0;
- while(k + d <= n)
- {
- y[i] = x[k];
- k+=d;
- i++;
- }
- if(cnt)
- *cnt = i;
+ k = i = 0;
+ while(k + d <= n)
+ {
+ y[i] = x[k];
+ k+=d;
+ i++;
+ }
+ if(cnt)
+ *cnt = i;
- return RES_OK;
+ return RES_OK;
}
-/******************************************************************************
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int decimate_cmplx(complex_t* x, int n, int d, complex_t* y, int* cnt)
+\brief
Complex vector decimation
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+
+Function `d` times decimates a complex vector `x`. \n
+Output vector `y` keeps values corresponds to:
+`y(k) = x(k*d), k = 0...n/d-1` \n
+
+\param[in] x
+Pointer to the input complex vector `x`. \n
+Vector `x` size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of input vector `x`. \n \n
+
+\param[in] d
+Decimation coefficient. \n
+Each d-th vector will be copy from vector `x` to the
+output vector `y`. \n \n
+
+\param[out] y
+Pointer to the output decimated vector `y`. \n
+Output vector size is `[n/d x 1]` will be copy
+to the address `cnt`. \n
+Memory must be allocated. \n \n
+
+\param[out] cnt
+Address which will keep decimated vector `y` size. \n
+Pointer can be `NULL`, vector `y` will not return
+in this case. \n \n
+
+\return
+`RES_OK` if function calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+Two-times complex vector decimation example:
+
+\code{.cpp}
+compex_t x[10] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0},
+{5.0, 5.0}, {6.0, 6.0}, {7.0, 7.0}, {8.0, 8.0}, {9.0, 9.0}};
+compex_t y[5];
+int d = 2;
+int cnt;
+
+decimate_cmplx(x, 10, d, y, &cnt);
+\endcode
+
+As result variable `cnt` will be written value 5 and
+vector `y` will keep array:
+
+\verbatim
+c = [0.0+0.0j, 2.0+2.0j, 4.0+4.0j, 6.0+6.0j, 8.0+8.0j]
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int decimate_cmplx(complex_t* x, int n, int d, complex_t* y, int* cnt)
+\brief Децимация комплексного вектора данных
+
+Функция производит децимацию комплексного вектора `x` в `d` раз. \n
+В результате выходной вектор `y` содержит значения:
+`y(k) = x(k*d), k = 0...n/d-1` \n
+
+\param[in] x
+Указатель на вектор входных данных `x`. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер входного вектора `x`. \n \n
+
+\param[in] d
+Коэффициент децимации. \n
+В результате децимации из вектора `x` будет взять каждый d-й элемент. \n \n
+
+\param[out] y
+Указатель на децимированный вектор `y`. \n
+Размер выходного вектора равен `[n/d x 1]` будет сохранен по адресу `cnt`. \n
+Память должна быть выделена. \n \n
+
+\param[out] cnt
+Указатель переменную, в которую будет сохранен
+размер выходного вектора после децимации. \n
+Указатель может быть `NULL`, в этом случае
+размер вектора `y` не возвращается. \n \n
+
+\return
+`RES_OK` если функция выполнена успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример децимации комплексного массива данных в 2 раза:
+\code{.cpp}
+compex_t x[10] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0},
+ {5.0, 5.0}, {6.0, 6.0}, {7.0, 7.0}, {8.0, 8.0}, {9.0, 9.0}};
+compex_t y[5];
+int d = 2;
+int cnt;
+decimate_cmplx(x, 10, d, y, &cnt);
+\endcode
+В результате в переменную `cnt` будет записан размер 5, а вектор `y` будет
+хранить массив данных:
+\verbatim
+c = [0.0+0.0j, 2.0+2.0j, 4.0+4.0j, 6.0+6.0j, 8.0+8.0j]
+\endverbatim
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API decimate_cmplx(complex_t* x, int n, int d, complex_t* y, int* cnt)
{
- int k = 0, i = 0;
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
- if(d < 1)
- return ERROR_NEGATIVE;
+ int k = 0, i = 0;
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+ if(d < 1)
+ return ERROR_NEGATIVE;
- k = i = 0;
- while(k + d < n)
- {
- RE(y[i]) = RE(x[k]);
- IM(y[i]) = IM(x[k]);
- k+=d;
- i++;
- }
- if(cnt)
- *cnt = i;
+ k = i = 0;
+ while(k + d < n)
+ {
+ RE(y[i]) = RE(x[k]);
+ IM(y[i]) = IM(x[k]);
+ k+=d;
+ i++;
+ }
+ if(cnt)
+ *cnt = i;
- return RES_OK;
+ return RES_OK;
}
-/******************************************************************************
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int flipip(double* x, int n)
+\brief
Flip real vector `x` in place
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+
+Function flips real vector `x` length `n` in the memory. \n
+For example real vector `x` length 6:\n
+\verbatim
+x = [0, 1, 2, 3, 4, 5]
+\endverbatim
+After flipping it will be as follow:
+\verbatim
+x = [5, 4, 3, 2, 1, 0]
+\endverbatim
+
+\param[in, out] x
+Pointer to the real vector `x`. \n
+Vector size is `[n x 1]`. \n
+Flipped vector will be on the same address. \n
+\n
+
+\param[in] n
+Length of the vector `x`. \n
+\n
+
+\return
+`RES_OK` if function returns successfully. \n
+ Else \ref ERROR_CODE_GROUP "error code".
+
+Example:
+\code{.cpp}
+double x[5] = {0.0, 1.0, 2.0, 3.0, 4.0};
+int i;
+for(i = 0; i < 5; i++)
+ printf("%6.1f ", x[i]);
+flipip(x, 5);
+printf("\n");
+for(i = 0; i < 5; i++)
+ printf("%6.1f ", x[i]);
+\endcode
+\n
+Program result:
+\verbatim
+ 0.0 1.0 2.0 3.0 4.0
+ 4.0 3.0 2.0 1.0 0.0
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int flipip(double* x, int n)
+\brief Функция отражения вещественного вектора `x`
+
+Функция производит отражение вещественного вектора длины `n`
+в памяти данных. \n
+Например исходный вектор `x` длины 6: \n
+\verbatim
+x = [0, 1, 2, 3, 4, 5]
+\endverbatim
+После отражения вектор `x` будет иметь вид:
+\verbatim
+x = [5, 4, 3, 2, 1, 0]
+\endverbatim
+
+\param[in, out] x
+Указатель на вещественный вектор `x`. \n
+Размер вектора `[n x 1]`. \n
+Результат отражения будет помещен по этому же адресу. \n
+
+\param[in] n
+Размер вектора `x`. \n \n
+
+\return
+`RES_OK` если функция выполнена успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример:
+\code{.cpp}
+double x[5] = {0.0, 1.0, 2.0, 3.0, 4.0};
+int i;
+for(i = 0; i < 5; i++)
+ printf("%6.1f ", x[i]);
+flipip(x, 5);
+printf("\n");
+for(i = 0; i < 5; i++)
+ printf("%6.1f ", x[i]);
+\endcode
+\n
+Результат выполнения:
+\verbatim
+ 0.0 1.0 2.0 3.0 4.0
+ 4.0 3.0 2.0 1.0 0.0
+\endverbatim
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API flipip(double* x, int n)
{
- int k;
- double tmp;
- if(!x)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
+ int k;
+ double tmp;
+ if(!x)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+
+ for(k = 0; k < n/2; k++)
+ {
+ tmp = x[k];
+ x[k] = x[n-1-k];
+ x[n-1-k] = tmp;
+ }
+ return RES_OK;
- for(k = 0; k < n/2; k++)
- {
- tmp = x[k];
- x[k] = x[n-1-k];
- x[n-1-k] = tmp;
- }
- return RES_OK;
-
}
-/******************************************************************************
-Flip complex vector `x` in place
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int flipip_cmplx(complex_t* x, int n)
+\brief Flip complex vector `x` in place
+
+Function flips complex vector `x` length `n` in the memory
+ \n
+For example complex vector `x` length 6: \n
+\verbatim
+x = [0+0j, 1+1j, 2+2j, 3+3j, 4+4j, 5+5j]
+\endverbatim
+After flipping it will be as follow:
+\verbatim
+x = [5+5j, 4+4j, 3+3j, 2+2j, 1+1j, 0+0j]
+\endverbatim
+
+\param[in, out] x
+Pointer to the complex vector `x`. \n
+Vector size is `[n x 1]`. \n
+Flipped vector will be on the same address. \n
+
+\param[in] n
+Length of the vector `x`. \n \n
+
+\return
+`RES_OK` if function returns successfully. \n
+Else \ref ERROR_CODE_GROUP "error code".
+
+Example:
+\code{.cpp}
+complex_t y[5] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}};
+for(i = 0; i < 5; i++)
+ printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
+flipip_cmplx(y, 5);
+printf("\n");
+for(i = 0; i < 5; i++)
+ printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
+\endcode
+ \n
+Program result:
+\verbatim
+0.0+0.0j 1.0+1.0j 2.0+2.0j 3.0+3.0j 4.0+4.0j
+4.0+4.0j 3.0+3.0j 2.0+2.0j 1.0+1.0j 0.0+0.0j
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int flipip_cmplx(complex_t* x, int n)
+\brief Функция отражения комплексного вектора `x`
+
+Функция производит отражение комплексного вектора длины `n`
+в памяти данных. \n
+Например исходный вектор `x` длины 6: \n
+\verbatim
+x = [0+0j, 1+1j, 2+2j, 3+3j, 4+4j, 5+5j]
+\endverbatim
+После отражения вектор `x` будет иметь вид:
+\verbatim
+x = [5+5j, 4+4j, 3+3j, 2+2j, 1+1j, 0+0j]
+\endverbatim
+
+\param[in, out] x
+Указатель на комплексный вектор `x`. \n
+Размер вектора `[n x 1]`. \n
+Результат отражения будет помещен по этому же адресу. \n
+\n
+
+\param[in] n
+Размер вектора `x`. \n
+\n
+
+\return
+`RES_OK` если функция выполнена успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример:
+\code{.cpp}
+complex_t y[5] = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}};
+for(i = 0; i < 5; i++)
+ printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
+flipip_cmplx(y, 5);
+printf("\n");
+for(i = 0; i < 5; i++)
+ printf("%6.1f%+.1fj ", RE(y[i]), IM(y[i]));
+\endcode
+ \n
+Результат выполнения:
+\verbatim
+0.0+0.0j 1.0+1.0j 2.0+2.0j 3.0+3.0j 4.0+4.0j
+4.0+4.0j 3.0+3.0j 2.0+2.0j 1.0+1.0j 0.0+0.0j
+\endverbatim
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API flipip_cmplx(complex_t* x, int n)
{
- int k;
- complex_t tmp;
- if(!x)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
+ int k;
+ complex_t tmp;
+ if(!x)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
- for(k = 0; k < n/2; k++)
- {
- RE(tmp) = RE(x[k]);
- RE(x[k]) = RE(x[n-1-k]);
- RE(x[n-1-k]) = RE(tmp);
+ for(k = 0; k < n/2; k++)
+ {
+ RE(tmp) = RE(x[k]);
+ RE(x[k]) = RE(x[n-1-k]);
+ RE(x[n-1-k]) = RE(tmp);
- IM(tmp) = IM(x[k]);
- IM(x[k]) = IM(x[n-1-k]);
- IM(x[n-1-k]) = IM(tmp);
- }
- return RES_OK;
+ IM(tmp) = IM(x[k]);
+ IM(x[k]) = IM(x[n-1-k]);
+ IM(x[n-1-k]) = IM(tmp);
+ }
+ return RES_OK;
}
@@ -203,186 +866,738 @@ int DSPL_API flipip_cmplx(complex_t* x, int n)
-/*******************************************************************************
-Linspace array filling
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int linspace(double x0, double x1, int n, int type, double* x)
+\brief Function fills a vector with `n` linearly spaced elements
+between `x0` and `x1`.
+
+Function supports two kinds of filling according to `type` parameter: \n
+
+Symmetric fill (parameter `type=DSPL_SYMMETRIC`): \n
+
+\f$x(k) = x_0 + k \cdot dx\f$,
+\f$dx = \frac{x_1 - x_0}{n-1}\f$, \f$k = 0 \ldots n-1.\f$
+
+Periodic fill (parameter `type=DSPL_PERIODIC`): \n
+
+\f$x(k) = x_0 + k \cdot dx\f$,
+\f$dx = \frac{x_1 - x_0}{n}\f$, \f$k = 0 \ldots n-1.\f$
+
+\param[in] x0
+Start point \f$x_0\f$. \n \n
+
+\param[in] x1
+End point \f$x_1\f$. \n \n
+
+\param[in] n
+Number of points `x` (size of vector `x`). \n \n
+
+\param[in] type
+Fill type: \n
+`DSPL_SYMMETRIC` --- symmetric, \n
+`DSPL_PERIODIC` --- periodic. \n \n
+
+\param[in,out] x
+Pointer to the output linearly spaced vector `x`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if function returns successfully. \n
+ Else \ref ERROR_CODE_GROUP "error code".
+
+\note
+Difference between symmetric and periodic filling we can
+understand from the follow examples. \n
+Example 1. Periodic fill.
+ double x[5];
+ linspace(0, 5, 5, DSPL_PERIODIC, x);
+\endcode
+Values in the vector `x` are:
+\verbatim
+0, 1, 2, 3, 4
+\endverbatim
+ \n \n
+Example 2. Symmetric fill.
+\code{.cpp}
+ double x[5];
+ linspace(0, 5, 5, DSPL_SYMMETRIC, x);
+\endcode
+Values in the vector `x` are:
+\verbatim
+0, 1.25, 2.5, 3.75, 5
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int linspace(double x0, double x1, int n, int type, double* x)
+\brief Функция заполняет массив линейно-нарастающими, равноотстоящими
+значениями от `x0` до `x1`
+
+Заполняет массив `x` длиной `n` значениями в диапазоне
+от \f$x_0\f$ до \f$x_1\f$. Функция поддерживает два типа заполнения
+в соответствии с параметром `type`: \n
+
+Симметричное заполнение согласно выражению (параметр `type=DSPL_SYMMETRIC`): \n
+
+\f$x(k) = x_0 + k \cdot dx\f$,
+\f$dx = \frac{x_1 - x_0}{n-1}\f$, \f$k = 0 \ldots n-1.\f$
+
+Периодическое заполнение (параметр `type=DSPL_PERIODIC`) согласно выражению: \n
+
+\f$x(k) = x_0 + k \cdot dx\f$,
+\f$dx = \frac{x_1 - x_0}{n}\f$, \f$k = 0 \ldots n-1.\f$
+
+\param[in] x0
+Начальное показателя \f$x_0\f$. \n \n
+
+\param[in] x1
+Конечное значение \f$x_1\f$. \n \n
+
+\param[in] n
+Количество точек массива `x`. \n \n
+
+\param[in] type
+Тип заполнения: \n
+
+`DSPL_SYMMETRIC` --- симметричное заполнение, \n
+`DSPL_PERIODIC` --- периодическое заполнение. \n \n
+
+\param[in,out] x
+Указатель на вектор равноотстоящих значений . \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` --- функция выполнена успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
+
+\note
+Отличие периодического и симметричного заполнения можно
+понять из следующих примеров. \n
+Пример 1. Периодическое заполнение.
+\code{.cpp}
+ double x[5];
+ linspace(0, 5, 5, DSPL_PERIODIC, x);
+\endcode
+В массиве `x` будут лежать значения:
+\verbatim
+0, 1, 2, 3, 4
+\endverbatim
+ \n \n
+Пример 2. Симметричное заполнение.
+\code{.cpp}
+ double x[5];
+ linspace(0, 5, 5, DSPL_SYMMETRIC, x);
+\endcode
+В массиве `x` будут лежать значения:
+\verbatim
+0, 1.25, 2.5, 3.75, 5
+\endverbatim
+
+\author
+Бахурин Сергей
+www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API linspace(double x0, double x1, int n, int type, double* x)
{
- double dx;
- int k;
+ double dx;
+ int k;
- if(n < 2)
- return ERROR_SIZE;
- if(!x)
- return ERROR_PTR;
+ if(n < 2)
+ return ERROR_SIZE;
+ if(!x)
+ return ERROR_PTR;
- switch (type)
- {
- case DSPL_SYMMETRIC:
- dx = (x1 - x0)/(double)(n-1);
- x[0] = x0;
- for(k = 1; k < n; k++)
- x[k] = x[k-1] + dx;
- break;
- case DSPL_PERIODIC:
- dx = (x1 - x0)/(double)n;
- x[0] = x0;
- for(k = 1; k < n; k++)
- x[k] = x[k-1] + dx;
- break;
- default:
- return ERROR_SYM_TYPE;
- }
- return RES_OK;
+ switch (type)
+ {
+ case DSPL_SYMMETRIC:
+ dx = (x1 - x0)/(double)(n-1);
+ x[0] = x0;
+ for(k = 1; k < n; k++)
+ x[k] = x[k-1] + dx;
+ break;
+ case DSPL_PERIODIC:
+ dx = (x1 - x0)/(double)n;
+ x[0] = x0;
+ for(k = 1; k < n; k++)
+ x[k] = x[k-1] + dx;
+ break;
+ default:
+ return ERROR_SYM_TYPE;
+ }
+ return RES_OK;
}
-/*******************************************************************************
-Logspace array filling
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int logspace(double x0, double x1, int n, int type, double* x)
+\brief Function fills a vector with `n` logarithmically spaced elements
+between \f$10^{x_0}\f$ and \f$10^{x_1}\f$.
+
+
+Function supports two kinds of filling according to `type` parameter: \n
+
+Symmetric fill (parameter `type=DSPL_SYMMETRIC`): \n
+
+\f$x(k) = 10^{x_0} \cdot dx^k\f$, here \f$dx = \sqrt[n-1]{10^{x_1 - x_0}}\f$,
+\f$k = 0 \ldots n-1.\f$
+
+Periodic fill (parameter `type=DSPL_PERIODIC`): \n
+
+\f$x(k) = 10^{x_0} \cdot dx^k\f$, here \f$dx = \sqrt[n]{10^{x_1 - x_0}}\f$,
+\f$k = 0 \ldots n-1.\f$ \n
+
+
+\param[in] x0
+Start exponent value \f$x_0\f$. \n \n
+
+\param[in] x1
+End exponent value \f$x_1\f$. \n \n
+
+\param[in] n
+Number of points `x` (size of vector `x`). \n \n
+
+\param[in] type
+Fill type: \n
+`DSPL_SYMMETRIC` --- symmetric, \n
+`DSPL_PERIODIC` --- periodic. \n \n
+
+\param[in,out] x
+Pointer to the output logarithmically spaced vector `x` . \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if function returns successfully. \n
+ Else \ref ERROR_CODE_GROUP "error code".
+
+\note
+Difference between symmetric and periodic filling we can
+understand from the follow examples. \n
+Example 1. Periodic fill.
+\code{.cpp}
+ double x[5];
+ logspace(-2, 3, 5, DSPL_PERIODIC, x);
+\endcode
+
+Values in the vector `x` are:
+
+\verbatim
+0.01, 0.1, 1, 10, 100
+\endverbatim
+
+\n \n
+
+Example 2. Symmetric fill.
+\code{.cpp}
+ double x[5];
+ logspace(-2, 3, 5, DSPL_SYMMETRIC, x);
+\endcode
+
+Values in the vector `x` are:
+
+\verbatim
+0.01 0.178 3.162 56.234 1000
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int logspace(double x0, double x1, int n, int type, double* x)
+\brief Функция заполняет массив значениями логарифмической шкале
+
+Заполняет массив `x` длиной `n` значениями в диапазоне
+от \f$10^{x_0}\f$ до \f$10^{x_1}\f$. \n
+Функция поддерживает два типа заполнения в соответствии с параметром `type`: \n
+
+Симметричное заполнение согласно выражению: \n
+
+\f$x(k) = 10^{x_0} \cdot dx^k\f$, где \f$dx = \sqrt[n-1]{10^{x_1 - x_0}}\f$,
+\f$k = 0 \ldots n-1.\f$
+
+Периодическое заполнение согласно выражению:
+
+\f$x(k) = 10^{x_0} \cdot dx^k\f$, где \f$dx = \sqrt[n]{10^{x_1 - x_0}}\f$,
+\f$k = 0 \ldots n-1.\f$ \n
+
+\param[in] x0
+Начальное значение показателя \f$x_0\f$. \n \n
+
+\param[in] x1
+Конечное значение показателя \f$x_1\f$. \n \n
+
+\param[in] n
+Количество точек массива `x`. \n \n
+
+\param[in] type
+Тип заполнения: \n
+`DSPL_SYMMETRIC` --- симметричное заполнение, \n
+`DSPL_PERIODIC` --- периодическое заполнение. \n \n
+
+\param[in,out] x
+Указатель на вектор значений в логарифмической шкале. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` --- функция выполнена успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+\note
+Отличие периодического и симметричного заполнения можно
+понять из следующих примеров. \n
+
+Пример 1. Периодическое заполнение.
+\code{.cpp}
+ double x[5];
+ logspace(-2, 3, 5, DSPL_PERIODIC, x);
+\endcode
+В массиве `x` будут лежать значения:
+\verbatim
+0.01, 0.1, 1, 10, 100
+\endverbatim
+\n \n
+
+Пример 2. Симметричное заполнение.
+\code{.cpp}
+ double x[5];
+ logspace(-2, 3, 5, DSPL_SYMMETRIC, x);
+\endcode
+
+В массиве `x` будут лежать значения:
+
+\verbatim
+0.01 0.178 3.162 56.234 1000
+\endverbatim
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API logspace(double x0, double x1, int n, int type, double* x)
{
- double mx, a, b;
- int k;
+ double mx, a, b;
+ int k;
- if(n < 2)
- return ERROR_SIZE;
- if(!x)
- return ERROR_PTR;
+ if(n < 2)
+ return ERROR_SIZE;
+ if(!x)
+ return ERROR_PTR;
- a = pow(10.0, x0);
- b = pow(10.0, x1);
+ a = pow(10.0, x0);
+ b = pow(10.0, x1);
- switch (type)
- {
- case DSPL_SYMMETRIC:
- mx = pow(b/a, 1.0/(double)(n-1));
- x[0] = a;
- for(k = 1; k < n; k++)
- x[k] = x[k-1] * mx;
- break;
- case DSPL_PERIODIC:
- mx = pow(b/a, 1.0/(double)n);
- x[0] = a;
- for(k = 1; k < n; k++)
- x[k] = x[k-1] * mx;
- break;
- default:
- return ERROR_SYM_TYPE;
- }
- return RES_OK;
+ switch (type)
+ {
+ case DSPL_SYMMETRIC:
+ mx = pow(b/a, 1.0/(double)(n-1));
+ x[0] = a;
+ for(k = 1; k < n; k++)
+ x[k] = x[k-1] * mx;
+ break;
+ case DSPL_PERIODIC:
+ mx = pow(b/a, 1.0/(double)n);
+ x[0] = a;
+ for(k = 1; k < n; k++)
+ x[k] = x[k-1] * mx;
+ break;
+ default:
+ return ERROR_SYM_TYPE;
+ }
+ return RES_OK;
}
-/*******************************************************************************
-Ones double array
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int ones(double* x, int n)
+\brief Function fills all real vector `x` by ones values.
+
+\param[in, out] x
+Pointer to the vector `x`. \n
+Vector size is `[n x 1]`. \n
+All elements on this vector will be set to one. \n
+\n
+
+\param[in] n
+Size of vector `x`. \n
+\n
+
+\return
+`RES_OK` if function returns successfully. \n
+ Else \ref ERROR_CODE_GROUP "error code".
+
+Example:
+\code{.cpp}
+double y[5] = {0};
+int i;
+ones(y, 5);
+for(i = 0; i < 5; i++)
+ printf("%6.1f% ", y[i]);
+\endcode
+ \n
+Vector `y` values are:
+\verbatim
+ 1.0 1.0 1.0 1.0 1.0
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int ones(double* x, int n)
+\brief Функция заполнения вещественного массива единицами
+
+\param[in, out] x
+Указатель на вещественный вектор `x`. \n
+Размер вектора `[n x 1]`. \n
+Значения данного вектора будут установлены в единицу. \n
+\n
+
+\param[in] n
+Размер вектора `x`. \n
+\n
+
+\return
+`RES_OK` если функция выполнена успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример:
+\code{.cpp}
+double y[5] = {0};
+int i;
+ones(y, 5);
+for(i = 0; i < 5; i++)
+ printf("%6.1f% ", y[i]);
+\endcode
+ \n
+Результат выполнения:
+\verbatim
+ 1.0 1.0 1.0 1.0 1.0
+\endverbatim
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API ones(double* x, int n)
{
- int i;
- if(!x)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
- for(i = 0; i < n; i++)
- x[i] = 1.0;
+ int i;
+ if(!x)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+ for(i = 0; i < n; i++)
+ x[i] = 1.0;
return RES_OK;
}
-/******************************************************************************
-Real arrays verification
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
-int DSPL_API verif(double* x, double* y, size_t n, double eps, double* err)
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int verif(double* x, double* y, size_t n, double eps, double* err)
+\brief Real arrays verification
+
+Function calculates a maximum relative error between two real arrays `x`
+and `y` (both length equals `n`):
+
+\f[
+e = \max \left( \frac{|x(k) - y(k)| }{ |x(k)|} \right),
+\quad if \quad |x(k)| > 0,
+\f]
+or
+\f[
+e = \max(|x(k) - y(k)| ), ~\qquad if \quad~|x(k)| = 0,
+\f]
+
+This function can be used for algorithms verification if vector `x` is user
+algorithm result and vector `y` -- reference vector.
+
+\param[in] x
+Pointer to the first vector `x`. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] y
+Pointer to the second vector `y`. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of vectors `x` and `y`. \n \n
+
+\param[in] eps
+Relative error threshold. \n
+If error less than `eps`, then function returns
+`DSPL_VERIF_SUCCESS`, else `DSPL_VERIF_FAILED`. \n \n
+
+\param[in, out] err
+Pointer to the variable which keep
+maximum relative error. \n
+Pointer can be `NULL`, maximum error will not be returned
+in this case. \n \n
+
+\return
+`DSPL_VERIF_SUCCESS` if maximum relative error less than `eps`. \n
+Otherwise `DSPL_VERIF_FAILED`.
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int verif(double* x, double* y, size_t n, double eps, double* err)
+\brief Верификация вещественных массивов
+
+Функция производит расчет максимальной относительной ошибки между вещественными
+векторами `x` и `y` равной длины `n`:
+
+\f[
+e = \max \left( \frac{|x(k) - y(k)| }{ |x(k)|} \right), \quad \quad |x(k)| > 0,
+\f]
+или
+\f[
+e = \max(|x(k) - y(k)| ), \qquad \quad~|x(k)| = 0,
+\f]
+и возвращает `DSPL_VERIF_SUCCESS` если
+разница \f$ e\f$ меньше `eps`.
+В противном случае возвращает `DSPL_VERIF_FAILED`. \n
+Данная функция используется для верификации работы алгоритмов если вектор `x`
+результат работы алгоритма пользователя, а `y` -- результат работы этого же
+алгоритма сторонней функцией.
+
+\param[in] x
+Указатель на первый вектор `x`. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] y
+Указатель на второй вектор `y`. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер векторов `x` и `y`. \n \n
+
+\param[in] eps
+Допустимая относительная ошибка. \n
+Если максимальная относительная ошибка меньше `eps`, то функция возвращает
+`DSPL_VERIF_SUCCESS`, в противном случае `DSPL_VERIF_FAILED`. \n \n
+
+\param[in, out] err
+Указатель на переменную максимальной относительной ошибки. \n
+По данному адресу будет записано значение максимальной относительной ошибки. \n
+Указатель может быть `NULL`, значение ошибки в этом случае
+не возвращается. \n \n
+
+\return
+`DSPL_VERIF_SUCCESS` если относительная ошибка меньше `eps`. \n
+ В противном случае `DSPL_VERIF_FAILED`.
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API verif(double* x, double* y, size_t n, double eps, double* err)
{
- double d, maxd;
- size_t k;
- int res;
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
- if(eps <= 0.0 )
- return ERROR_NEGATIVE;
-
- maxd = -100.0;
-
- for(k = 0; k < n; k++)
- {
- d = fabs(x[k] - y[k]);
- if(fabs(x[k]) > 0.0)
+ double d, maxd;
+ size_t k;
+ int res;
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+ if(eps <= 0.0 )
+ return ERROR_NEGATIVE;
+
+ maxd = -100.0;
+
+ for(k = 0; k < n; k++)
{
- d = d / fabs(x[k]);
- if(d > maxd)
- maxd = d;
+ d = fabs(x[k] - y[k]);
+ if(fabs(x[k]) > 0.0)
+ {
+ d = d / fabs(x[k]);
+ if(d > maxd)
+ maxd = d;
+ }
}
- }
- if(err)
- *err = maxd;
-
- if(maxd > eps)
- res = DSPL_VERIF_FAILED;
- else
- res = DSPL_VERIF_SUCCESS;
-
- return res;
+ if(err)
+ *err = maxd;
+
+ if(maxd > eps)
+ res = DSPL_VERIF_FAILED;
+ else
+ res = DSPL_VERIF_SUCCESS;
+
+ return res;
}
-/******************************************************************************
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int verif_cmplx(complex_t* x, complex_t* y, size_t n,
+ double eps, double* err)
+\brief
Complex arrays verification
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
-int DSPL_API verif_cmplx(complex_t* x, complex_t* y, size_t n,
- double eps, double* err)
+
+Function calculates a maximum relative error between two complex arrays `x`
+and `y` (both length equals `n`):
+
+\f[
+e = \max \left( \frac{|x(k) - y(k)| }{ |x(k)|} \right),
+\quad if \quad |x(k)| > 0,
+\f]
+or
+\f[
+e = \max(|x(k) - y(k)| ), ~\qquad if \quad~|x(k)| = 0,
+\f]
+Return `DSPL_VERIF_SUCCESS` if maximum relative error \f$ e\f$ less than `eps`.
+Else returns `DSPL_VERIF_FAILED`. \n
+
+This function can be used for algorithms verification if vector `x` is user
+algorithm result and vector `y` -- reference vector.
+
+\param[in] x
+Pointer to the first vector `x`. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] y
+Pointer to the second vector `y`. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of vectors `x` and `y`. \n \n
+
+\param[in] eps
+Relative error threshold. \n
+If error less than `eps`, then function returns
+`DSPL_VERIF_SUCCESS`, else `DSPL_VERIF_FAILED`. \n \n
+
+\param[in, out] err
+Pointer to the variable which keep
+maximum relative error. \n
+Pointer can be `NULL`, maximum error will not be returned
+in this case. \n \n
+
+\return
+`DSPL_VERIF_SUCCESS` if maximum relative error less than `eps`. \n
+Otherwise `DSPL_VERIF_FAILED`.
+
+\author
+Sergey Bakhurin
+www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup ARRAY_GROUP
+\fn int verif_cmplx(complex_t* x, complex_t* y, size_t n,
+ double eps, double* err)
+\brief Верификация комплексных массивов
+
+Функция производит расчет максимальной относительной ошибки между комплексными
+векторами `x` и `y` равной длины `n`:
+
+\f[
+e = \max \left( \frac{|x(k) - y(k)|}{|x(k)|} \right), \quad \quad |x(k)| > 0,
+\f]
+или
+\f[
+e = \max(|x(k) - y(k)| ), ~\qquad \quad~|x(k)| = 0,
+\f]
+и возвращает `DSPL_VERIF_SUCCESS` если
+разница \f$ e\f$ меньше `eps`.
+В противном случае возвращает `DSPL_VERIF_FAILED`. \n
+Данная функция используется для верификации работы алгоритмов если вектор `x`
+результат работы алгоритма пользователя, а `y` -- результат работы этого же
+алгоритма сторонней функцией.
+
+\param[in] x
+Указатель на первый вектор `x`. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] y
+Указатель на второй вектор `y`. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер векторов `x` и `y`. \n \n
+
+\param[in] eps
+Допустимая относительная ошибка. \n
+Если максимальная относительная ошибка меньше `eps`, то функция возвращает
+`DSPL_VERIF_SUCCESS`, в противном случае `DSPL_VERIF_FAILED`. \n \n
+
+\param[in, out] err
+Указатель на переменную максимальной относительной ошибки. \n
+По данному адресу будет записано значение максимальной относительной ошибки. \n
+Указатель может быть `NULL`, значение ошибки в этом
+случае не возвращается. \n \n
+
+\return
+`DSPL_VERIF_SUCCESS` если функция выполнена успешно. \n
+ В противном случае `DSPL_VERIF_FAILED`.
+
+\author
+Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API verif_cmplx(complex_t* x, complex_t* y, size_t n,
+ double eps, double* err)
{
-
- complex_t d;
- double mx, md, maxd;
- size_t k;
- int res;
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
- if(eps <= 0.0 )
- return ERROR_NEGATIVE;
-
- maxd = -100.0;
-
- for(k = 0; k < n; k++)
- {
- RE(d) = RE(x[k]) - RE(y[k]);
- IM(d) = IM(x[k]) - IM(y[k]);
- md = ABS(d);
- mx = ABS(x[k]);
- if(mx > 0.0)
+
+ complex_t d;
+ double mx, md, maxd;
+ size_t k;
+ int res;
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+ if(eps <= 0.0 )
+ return ERROR_NEGATIVE;
+
+ maxd = -100.0;
+
+ for(k = 0; k < n; k++)
{
- md = md / mx;
- if(md > maxd)
- maxd = md;
+ RE(d) = RE(x[k]) - RE(y[k]);
+ IM(d) = IM(x[k]) - IM(y[k]);
+ md = ABS(d);
+ mx = ABS(x[k]);
+ if(mx > 0.0)
+ {
+ md = md / mx;
+ if(md > maxd)
+ maxd = md;
+ }
}
- }
- if(err)
- *err = maxd;
-
- if(maxd > eps)
- res = DSPL_VERIF_FAILED;
- else
- res = DSPL_VERIF_SUCCESS;
-
- return res;
+ if(err)
+ *err = maxd;
+
+ if(maxd > eps)
+ res = DSPL_VERIF_FAILED;
+ else
+ res = DSPL_VERIF_SUCCESS;
+
+ return res;
}
diff --git a/dspl/src/cheby.c b/dspl/src/cheby.c
index 1b7d487..6a739bd 100644
--- a/dspl/src/cheby.c
+++ b/dspl/src/cheby.c
@@ -5,17 +5,17 @@
* 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
+* 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
+* 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 .
+* along with Foobar. If not, see .
*/
#include
@@ -24,103 +24,306 @@
#include "dspl.h"
-/******************************************************************************
-Chebyshev polynomial of the first kind order `ord`
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup SPEC_MATH_POLY_GROUP
+\fn int cheby_poly1(double* x, int n, int ord, double* y)
+\brief Chebyshev polynomial of the first kind order `ord`
+
+Function calculates Chebyshev polynomial \f$ C_ord(x)\f$ of the first kind
+order `ord` for the real vector `x` (length `n`) by recurrent equation:
+\f[
+C_{ord}(x) = 2 x C_{ord-1}(x) - C_{ord-2}(x),
+\f]
+where \f$ C_0(x) = 1 \f$, \f$ C_1(x) = x\f$
+
+\param[in] x
+Pointer to the real argument vector `x`. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of vectors `x` and `y`. \n \n
+
+\param[in] ord
+Chebyshev polynomial order. \n \n
+
+\param[out] y
+Pointer to the Chebyshev polynomial values, corresponds to the argument `x`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if Chebyshev polynomial is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
+
+Example:
+
+\include cheby_poly1_test.c
+
+Text files will be created in `dat` directory: \n
+
+\verbatim
+cheby_poly1_ord1.txt
+cheby_poly1_ord2.txt
+cheby_poly1_ord3.txt
+cheby_poly1_ord4.txt
+\endverbatim
+
+GNUPLOT package will create Chebyshev polynomials plot from saved text-files:
+
+\image html cheby_poly1.png
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_POLY_GROUP
+\fn int cheby_poly1(double* x, int n, int ord, double* y)
+\brief Многочлен Чебышева первого рода порядка `ord`
+
+Функция производит расчет многочлена Чебышева первого рода \f$ C_ord(x)\f$ для
+вещественного вектора `x` длины `n`на основе рекуррентной формулы
+\f[
+C_{ord}(x) = 2 x C_{ord-1}(x) - C_{ord-2}(x),
+\f]
+где \f$ C_0(x) = 1 \f$, \f$ C_1(x) = x\f$
+
+\param[in] x
+Указатель на вектор `x` аргумента полинома Чебышева первого рода. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер векторов `x` и `y`. \n \n
+
+\param[in] ord
+Порядок полинома Чебышева первого рода. \n \n
+
+\param[out] y
+Указатель на вектор значений полинома Чебышева,
+соответствующих аргументу `x`. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` Расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+Пример использования функции:
+
+\include cheby_poly1_test.c
+
+В каталоге `dat` будут созданы текстовые файлы значений
+полиномов порядка 1-4: \n
+
+\verbatim
+cheby_poly1_ord1.txt
+cheby_poly1_ord2.txt
+cheby_poly1_ord3.txt
+cheby_poly1_ord4.txt
+\endverbatim
+
+Кроме того программа GNUPLOT произведет построение следующих графиков
+по сохраненным в файлах данным:
+
+\image html cheby_poly1.png
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API cheby_poly1(double* x, int n, int ord, double* y)
{
- int k, m;
- double t[2];
+ int k, m;
+ double t[2];
+
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+ if(ord<0)
+ return ERROR_POLY_ORD;
+ if(ord==0)
+ {
+ for(k = 0; k < n; k++)
+ {
+ y[k] = 1.0;
+ }
+ return RES_OK;
+ }
+
+ if(ord==1)
+ {
+ memcpy(y, x, n*sizeof(double));
+ return RES_OK;
+ }
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
- if(ord<0)
- return ERROR_POLY_ORD;
- if(ord==0)
- {
for(k = 0; k < n; k++)
{
- y[k] = 1.0;
+ m = 2;
+ t[1] = x[k];
+ t[0] = 1.0;
+ while(m <= ord)
+ {
+ y[k] = 2.0 * x[k] *t[1] - t[0];
+ t[0] = t[1];
+ t[1] = y[k];
+ m++;
+ }
}
return RES_OK;
- }
-
- if(ord==1)
- {
- memcpy(y, x, n*sizeof(double));
- return RES_OK;
- }
-
- for(k = 0; k < n; k++)
- {
- m = 2;
- t[1] = x[k];
- t[0] = 1.0;
- while(m <= ord)
- {
- y[k] = 2.0 * x[k] *t[1] - t[0];
- t[0] = t[1];
- t[1] = y[k];
- m++;
- }
- }
- return RES_OK;
}
-/******************************************************************************
-Chebyshev polynomial of the second kind order `ord`
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup SPEC_MATH_POLY_GROUP
+\fn int cheby_poly2(double* x, int n, int ord, double* y)
+\brief Chebyshev polynomial of the second kind order `ord`
+
+Function calculates Chebyshev polynomial \f$ U_ord(x)\f$ of the first kind
+order `ord` for the real vector `x` (length `n`) by recurrent equation:
+\f[
+U_{ord}(x) = 2 x U_{ord-1}(x) - U_{ord-2}(x),
+\f]
+where \f$ U_0(x) = 1 \f$, \f$ U_1(x) = 2x\f$
+
+\param[in] x
+Pointer to the real argument vector `x`. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of vectors `x` and `y`. \n \n
+
+\param[in] ord
+Chebyshev polynomial order. \n \n
+
+\param[out] y
+Pointer to the Chebyshev polynomial values, corresponds to the argument `x`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if Chebyshev polynomial is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
+
+Example:
+\include cheby_poly2_test.c
+
+Text files will be created in `dat` directory: \n
+
+\verbatim
+cheby_poly2_ord1.txt
+cheby_poly2_ord2.txt
+cheby_poly2_ord3.txt
+cheby_poly2_ord4.txt
+\endverbatim
+
+GNUPLOT package will create Chebyshev polynomials plot from saved text-files:
+
+\image html cheby_poly2.png
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_POLY_GROUP
+\fn int cheby_poly2(double* x, int n, int ord, double* y)
+\brief Многочлен Чебышева второго рода порядка `ord`
+
+Функция производит расчет многочлена Чебышева второго рода \f$ U_{ord}(x)\f$
+для вещественного вектора `x` длины `n`на основе рекуррентной формулы
+\f[
+U_{ord}(x) = 2 x U_{ord-1}(x) - U_{ord-2}(x),
+\f]
+где \f$ U_0(x) = 1 \f$, \f$ U_1(x) = 2x\f$
+
+\param[in] x
+Указатель на вектор `x` аргумента полинома Чебышева второго рода. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер векторов `x` и `y`. \n \n
+
+\param[in] ord
+Порядок полинома Чебышева второго рода. \n \n
+
+\param[out] y
+Указатель на вектор значений полинома Чебышева,
+соответствующих аргументу `x`. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` Расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+Пример использования функции:
+
+\include cheby_poly2_test.c
+
+В каталоге `dat` будут созданы текстовые файлы значений
+полиномов порядка 1-4: \n
+
+\verbatim
+cheby_poly2_ord1.txt
+cheby_poly2_ord2.txt
+cheby_poly2_ord3.txt
+cheby_poly2_ord4.txt
+\endverbatim
+
+Кроме того программа GNUPLOT произведет построение следующих графиков
+по сохраненным в файлах данным:
+
+\image html cheby_poly2.png
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API cheby_poly2(double* x, int n, int ord, double* y)
{
- int k, m;
- double t[2];
+ int k, m;
+ double t[2];
+
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+ if(ord<0)
+ return ERROR_POLY_ORD;
+ if(ord==0)
+ {
+ for(k = 0; k < n; k++)
+ {
+ y[k] = 1.0;
+ }
+ return RES_OK;
+ }
+
+ if(ord==1)
+ {
+ for(k = 0; k < n; k++)
+ {
+ y[k] = 2.0*x[k];
+ };
+ return RES_OK;
+ }
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
- if(ord<0)
- return ERROR_POLY_ORD;
- if(ord==0)
- {
for(k = 0; k < n; k++)
{
- y[k] = 1.0;
+ m = 2;
+ t[1] = 2.0*x[k];
+ t[0] = 1.0;
+ while(m <= ord)
+ {
+ y[k] = 2.0 * x[k] *t[1] - t[0];
+ t[0] = t[1];
+ t[1] = y[k];
+ m++;
+ }
}
return RES_OK;
- }
-
- if(ord==1)
- {
- for(k = 0; k < n; k++)
- {
- y[k] = 2.0*x[k];
- };
- return RES_OK;
- }
-
- for(k = 0; k < n; k++)
- {
- m = 2;
- t[1] = 2.0*x[k];
- t[0] = 1.0;
- while(m <= ord)
- {
- y[k] = 2.0 * x[k] *t[1] - t[0];
- t[0] = t[1];
- t[1] = y[k];
- m++;
- }
- }
- return RES_OK;
}
diff --git a/dspl/src/complex.c b/dspl/src/complex.c
index df2f916..4e83915 100644
--- a/dspl/src/complex.c
+++ b/dspl/src/complex.c
@@ -24,57 +24,239 @@
#include "dspl.h"
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup TYPES_GROUP
+\fn int cmplx2re(complex_t* x, int n, double* re, double* im)
+\brief Separate complex vector to the real and image vectors
+
+Function fills `re` and `im` vectors corresponds to real and image
+parts of the input complex array `x`. \n
-/******************************************************************************
-Separate complex vector to the real and image vectors
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+\param[in] x
+Pointer to the real complex vector. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of the input complex vector `x` and real and image
+vectors `re` and `im`. \n \n
+
+\param[out] re
+Pointer to the real part vector. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\param[out] im
+Pointer to the image part vector. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if function converts complex vector successfully. \n
+Else \ref ERROR_CODE_GROUP "code error". \n
+
+Example: \n
+\code{.cpp}
+ complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
+ double re[3], im[3];
+
+ cmplx2re(x, 3, re, im);
+\endcode
+
+Vectors `re` and `im` will contains:
+
+\verbatim
+re[0] = 1.0; im[0] = 2.0;
+re[1] = 3.0; im[1] = 4.0;
+re[2] = 5.0; im[2] = 6.0;
+\endverbatim
+
+\author Sergey Bakhurin. www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup TYPES_GROUP
+\fn int cmplx2re(complex_t* x, int n, double* re, double* im)
+\brief Преобразование массива комплексных данных в два массива
+ вещественных данных, содержащих реальную и мнимую части
+ исходного массива
+
+Функция заполняет реальные массивы `re` и `im` соответствующими значениями
+реальной и мнимой частей исходного комплексного массива `x`. \n
+
+
+\param[in] x
+Указатель на массив комплексных данных. \n
+Размер массива `[n x 1]`. \n \n
+
+\param[in] n
+Размер массивов входных и выходных данных. \n \n
+
+\param[out] re
+Указатель на адрес массива реальной части данных. \n
+Размер массива `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\param[out] im
+Указатель на адрес массива мнимой части данных. \n
+Размер массива `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если преобразование произведено успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки": \n
+
+Например при выполнении следующего кода
+\code{.cpp}
+ complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
+ double re[3], im[3];
+
+ cmplx2re(x, 3, re, im);
+\endcode
+
+Элементам массивов `re` и `im` будут присвоены значения:
+
+\verbatim
+re[0] = 1.0; im[0] = 2.0;
+re[1] = 3.0; im[1] = 4.0;
+re[2] = 5.0; im[2] = 6.0;
+\endverbatim
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API cmplx2re(complex_t* x, int n, double* re, double* im)
{
- int k;
- if(!x)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
+ int k;
+ if(!x)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
- if(re)
- {
- for(k = 0; k < n; k++)
- re[k] = RE(x[k]);
- }
- if(im)
- {
- for(k = 0; k < n; k++)
- im[k] = IM(x[k]);
- }
- return RES_OK;
+ if(re)
+ {
+ for(k = 0; k < n; k++)
+ re[k] = RE(x[k]);
+ }
+ if(im)
+ {
+ for(k = 0; k < n; k++)
+ im[k] = IM(x[k]);
+ }
+ return RES_OK;
}
+#ifdef DOXYGEN_ENGLISH
+/*! *****************************************************************************
+\ingroup TYPES_GROUP
+\fn int re2cmplx(double* x, int n, complex_t *y)
+\brief Convert real array to the complex array.
-/******************************************************************************
-Convert real array to the complex array.
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+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;
+ 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;
+ for(k = 0; k < n; k++)
+ {
+ RE(y[k]) = x[k];
+ IM(y[k]) = 0.0;
+ }
+ return RES_OK;
}
diff --git a/dspl/src/dft.c b/dspl/src/dft.c
index 128d205..e5ef5ab 100644
--- a/dspl/src/dft.c
+++ b/dspl/src/dft.c
@@ -5,17 +5,17 @@
* 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
+* 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
+* 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 .
+* along with Foobar. If not, see .
*/
@@ -25,117 +25,508 @@
-/******************************************************************************
-`n`-points discrete Fourier transform of the real vector `x`.
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int dft(double* x, int n, complex_t* y)
+\brief Discrete Fourier transform of a real signal.
+
+The function calculates the \f$ n \f$ -point discrete Fourier transform
+real signal \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y (k) = \sum_ {m = 0} ^ {n-1} x (m)
+ \exp \left (-j \frac {2 \pi} {n} m k \right),
+\f]
+where \f$ k = 0 \ldots n-1 \f$.
+
+\param [in] x
+Pointer to the vector of the real input signal \f$ x (m) \f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+The size of the vector is `[n x 1]`. \n \n
+
+\param [in] n
+The size of the DFT \f$ n \f$
+(the size of the vectors of the input signal and the result of the DFT). \n \n
+
+\param [out] y
+Pointer to the complex vector of the DFT result \f$ Y (k) \f$,
+\f$ k = 0 \ldots n-1 \f$.
+The size of the vector is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+
+\return
+`RES_OK` if the DFT is calculated successfully. \n
+Otherwise, \ref ERROR_CODE_GROUP "error code".
+
+An example of using the `dft` function:
+
+\include dft_test.c
+
+The result of the program:
+
+\verbatim
+y [0] = 120.000 0.000
+y [1] = -8.000 40.219
+y [2] = -8.000 19.314
+y [3] = -8.000 11.973
+y [4] = -8.000 8.000
+y [5] = -8.000 5.345
+y [6] = -8.000 3.314
+y [7] = -8.000 1.591
+y [8] = -8.000 0.000
+y [9] = -8.000 -1.591
+y [10] = -8.000 -3.314
+y [11] = -8.000 -5.345
+y [12] = -8.000 -8.000
+y [13] = -8.000 -11.973
+y [14] = -8.000 -19.314
+y [15] = -8.000 -40.219
+\endverbatim
+
+\note
+This function performs the DFT calculation using the naive method and
+requires \f$ n ^ 2 \f$ complex multiplications. \n
+To increase the calculation speed, it is recommended to use
+fast Fourier transform algorithms.
+
+\author Bakhurin Sergey www.dsplib.org
+**************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int dft(double* x, int n, complex_t* y)
+\brief Дискретное преобразование Фурье вещественного сигнала.
+
+Функция рассчитывает \f$ n \f$-точечное дискретное преобразование Фурье
+вещественного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \sum_{m = 0}^{n-1} x(m)
+ \exp \left( -j \frac{2\pi}{n} m k \right),
+\f]
+где \f$ k = 0 \ldots n-1 \f$.
+
+\param[in] x
+Указатель на вектор вещественного входного сигнала \f$x(m)\f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер ДПФ \f$n\f$ (размер векторов входного сигнала и результата ДПФ). \n \n
+
+\param[out] y
+Указатель на комплексный вектор результата ДПФ \f$Y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$.
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+
+\return
+`RES_OK` если ДПФ рассчитана успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример использования функции `dft`:
+
+\include dft_test.c
+
+Результат работы программы:
+
+\verbatim
+y[ 0] = 120.000 0.000
+y[ 1] = -8.000 40.219
+y[ 2] = -8.000 19.314
+y[ 3] = -8.000 11.973
+y[ 4] = -8.000 8.000
+y[ 5] = -8.000 5.345
+y[ 6] = -8.000 3.314
+y[ 7] = -8.000 1.591
+y[ 8] = -8.000 0.000
+y[ 9] = -8.000 -1.591
+y[10] = -8.000 -3.314
+y[11] = -8.000 -5.345
+y[12] = -8.000 -8.000
+y[13] = -8.000 -11.973
+y[14] = -8.000 -19.314
+y[15] = -8.000 -40.219
+\endverbatim
+
+\note
+Данная функция выполняет расчет ДПФ наивным методом и требует \f$ n^2 \f$
+комплексных умножений. \n
+Для увеличения скорости расчета рекомендуется использовать
+алгоритмы быстрого преобразования Фурье.
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API dft(double* x, int n, complex_t* y)
{
- int k;
- int m;
- double divn;
- double phi;
+ int k;
+ int m;
+ double divn;
+ double phi;
- if(!x || !y)
- return ERROR_PTR;
+ if(!x || !y)
+ return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
+ if(n<1)
+ return ERROR_SIZE;
- divn = 1.0 / (double)n;
+ divn = 1.0 / (double)n;
- for(k = 0; k < n; k++)
- {
- RE(y[k]) = IM(y[k]) = 0.0;
- for(m = 0; m < n; m++)
+ for(k = 0; k < n; k++)
{
- phi = -M_2PI * divn * (double)k * (double)m;
- RE(y[k]) += x[m] * cos(phi);
- IM(y[k]) += x[m] * sin(phi);
+ RE(y[k]) = IM(y[k]) = 0.0;
+ for(m = 0; m < n; m++)
+ {
+ phi = -M_2PI * divn * (double)k * (double)m;
+ RE(y[k]) += x[m] * cos(phi);
+ IM(y[k]) += x[m] * sin(phi);
+ }
}
- }
- return RES_OK;
+ return RES_OK;
}
-/******************************************************************************
-`n`-points discrete Fourier transform of the complex vector `x`.
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int dft_cmplx(complex_t* x, int n, complex_t* y)
+\brief Discrete Fourier transform of a complex signal.
+
+The function calculates the \f$ n \f$ -point discrete Fourier transform
+complex signal \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y (k) = \sum_ {m = 0} ^ {n-1} x (m)
+ \exp \left (-j \frac {2 \pi} {n} m k \right),
+\f]
+where \f$ k = 0 \ldots n-1 \f$.
+
+\param [in] x
+Pointer to a vector of complex
+input signal \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+The size of the vector is `[n x 1]`. \n \n
+
+\param [in] n
+The size of the DFT \f$ n \f$
+(the size of the vectors of the input signal and the result of the DFT). \n \n
+
+\param [out] y
+Integrated Vector Pointer
+DFT result \f$ Y (k) \f$, \f$ k = 0 \ldots n-1 \f$. \n
+The size of the vector is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+
+\return
+`RES_OK` if the DFT is calculated successfully. \n
+Otherwise, \ref ERROR_CODE_GROUP "error code".
+
+An example of using the `dft_cmplx` function:
+
+\include dft_cmplx_test.c
+
+The result of the program:
+
+\verbatim
+y [0] = 120.000 0.000
+y [1] = -8.000 40.219
+y [2] = -8.000 19.314
+y [3] = -8.000 11.973
+y [4] = -8.000 8.000
+y [5] = -8.000 5.345
+y [6] = -8.000 3.314
+y [7] = -8.000 1.591
+y [8] = -8.000 0.000
+y [9] = -8.000 -1.591
+y [10] = -8.000 -3.314
+y [11] = -8.000 -5.345
+y [12] = -8.000 -8.000
+y [13] = -8.000 -11.973
+y [14] = -8.000 -19.314
+y [15] = -8.000 -40.219
+\endverbatim
+
+\note
+This function performs the calculation of the DFT by the naive method
+and requires \f$ n ^ 2 \f$ complex multiplications. \n
+To increase the calculation speed, it is recommended
+use fast Fourier transform algorithms.
+
+\author Bakhurin Sergey www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int dft_cmplx(complex_t* x, int n, complex_t* y)
+\brief Дискретное преобразование Фурье комплексного сигнала.
+
+Функция рассчитывает \f$ n \f$-точечное дискретное преобразование Фурье
+комплексного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \sum_{m = 0}^{n-1} x(m)
+ \exp \left( -j \frac{2\pi}{n} m k \right),
+\f]
+где \f$ k = 0 \ldots n-1 \f$.
+
+\param[in] x
+Указатель на вектор комплексного
+входного сигнала \f$x(m)\f$, \f$ m = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер ДПФ \f$n\f$ (размер векторов входного сигнала и результата ДПФ). \n \n
+
+\param[out] y
+Указатель на комплексный вектор
+результата ДПФ \f$Y(k)\f$, \f$ k = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+
+\return
+`RES_OK` если ДПФ рассчитана успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример использования функции `dft_cmplx`:
+
+\include dft_cmplx_test.c
+
+Результат работы программы:
+
+\verbatim
+y[ 0] = 120.000 0.000
+y[ 1] = -8.000 40.219
+y[ 2] = -8.000 19.314
+y[ 3] = -8.000 11.973
+y[ 4] = -8.000 8.000
+y[ 5] = -8.000 5.345
+y[ 6] = -8.000 3.314
+y[ 7] = -8.000 1.591
+y[ 8] = -8.000 0.000
+y[ 9] = -8.000 -1.591
+y[10] = -8.000 -3.314
+y[11] = -8.000 -5.345
+y[12] = -8.000 -8.000
+y[13] = -8.000 -11.973
+y[14] = -8.000 -19.314
+y[15] = -8.000 -40.219
+\endverbatim
+
+\note
+Данная функция выполняет расчет ДПФ наивным методом
+и требует \f$ n^2 \f$ комплексных умножений. \n
+Для увеличения скорости расчета рекомендуется
+использовать алгоритмы быстрого преобразования Фурье.
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API dft_cmplx(complex_t* x, int n, complex_t* y)
{
- int k;
- int m;
- double divn;
- double phi;
- complex_t e;
+ int k;
+ int m;
+ double divn;
+ double phi;
+ complex_t e;
- if(!x || !y)
- return ERROR_PTR;
+ if(!x || !y)
+ return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
+ if(n<1)
+ return ERROR_SIZE;
- divn = 1.0 / (double)n;
+ divn = 1.0 / (double)n;
- for(k = 0; k < n; k++)
- {
- RE(y[k]) = IM(y[k]) = 0.0;
- for(m = 0; m < n; m++)
+ for(k = 0; k < n; k++)
{
- phi = -M_2PI * divn * (double)k * (double)m;
- RE(e) = cos(phi);
- IM(e) = sin(phi);
- RE(y[k]) += CMRE(x[m], e);
- IM(y[k]) += CMIM(x[m], e);
+ RE(y[k]) = IM(y[k]) = 0.0;
+ for(m = 0; m < n; m++)
+ {
+ phi = -M_2PI * divn * (double)k * (double)m;
+ RE(e) = cos(phi);
+ IM(e) = sin(phi);
+ RE(y[k]) += CMRE(x[m], e);
+ IM(y[k]) += CMIM(x[m], e);
+ }
}
- }
- return RES_OK;
+ return RES_OK;
}
-/******************************************************************************
-`n`-points inverse discrete Fourier transform of the complex vector `x`.
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int idft_cmplx(complex_t* x, int n, complex_t* y)
+\brief Inverse discrete Fourier transform of the complex spectrum.
+
+The function calculates the \f$ n \f$ -point inverse discrete transform
+Fourier complex spectrum \f$ x (m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ y (k) = \sum_ {m = 0} ^ {n-1} x (m)
+ \exp \left (j \frac {2 \pi} {n} m k \right),
+\f]
+where \f$ k = 0 \ldots n-1 \f$.
+
+\param [in] x
+Pointer to the vector of the input complex signal spectrum \f$ x (m) \f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+The size of the vector is `[n x 1]`. \n \n
+
+\param [in] n
+The size of the ODPF \f$ n \f$
+(the size of the vectors of the input spectrum and the result of the ODPF). \n
+\n
+
+\param [out] y
+Pointer to the complex vector of the ODPF result \f$ y (k) \f$,
+\f$ k = 0 \ldots n-1 \f$.
+The size of the vector is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+
+\return
+`RES_OK` if the ODPF is calculated successfully. \n
+Otherwise, \ref ERROR_CODE_GROUP "error code".
+
+An example of using the `dft_cmplx` function:
+
+\include idft_cmplx_test.c
+
+The result of the program:
+
+\verbatim
+x [0] = 0.000 + 0.000j, z [0] = 0.000 -0.000
+x [1] = 1.000 + 0.000j, z [1] = 1.000 -0.000
+x [2] = 2.000 + 0.000j, z [2] = 2.000 -0.000
+x [3] = 3.000 + 0.000j, z [3] = 3.000 -0.000
+x [4] = 4.000 + 0.000j, z [4] = 4.000 -0.000
+x [5] = 5.000 + 0.000j, z [5] = 5.000 -0.000
+x [6] = 6.000 + 0.000j, z [6] = 6.000 -0.000
+x [7] = 7.000 + 0.000j, z [7] = 7.000 -0.000
+x [8] = 8.000 + 0.000j, z [8] = 8.000 -0.000
+x [9] = 9.000 + 0.000j, z [9] = 9.000 -0.000
+x [10] = 10.000 + 0.000j, z [10] = 10.000 -0.000
+x [11] = 11.000 + 0.000j, z [11] = 11.000 +0.000
+x [12] = 12.000 + 0.000j, z [12] = 12.000 +0.000
+x [13] = 13.000 + 0.000j, z [13] = 13.000 +0.000
+x [14] = 14.000 + 0.000j, z [14] = 14.000 +0.000
+x [15] = 15.000 + 0.000j, z [15] = 15.000 -0.000
+\endverbatim
+
+\note
+This function performs the calculation of the DFT using the naive method.
+and requires \f$ n ^ 2 \f$ complex multiplications. \n
+To increase the calculation speed, it is recommended
+use fast Fourier transform algorithms.
+
+\author Bakhurin Sergey www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int idft_cmplx(complex_t* x, int n, complex_t* y)
+\brief Обратное дискретное преобразование Фурье комплексного спектра.
+
+Функция рассчитывает \f$ n \f$-точечное обратное дискретное преобразование
+Фурье комплексного спектра \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ y(k) = \sum_{m = 0}^{n-1} x(m)
+ \exp \left( j \frac{2\pi}{n} m k \right),
+\f]
+где \f$ k = 0 \ldots n-1 \f$.
+
+\param[in] x
+Указатель на вектор входного комплексного спектра сигнала \f$x(m)\f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер ОДПФ \f$n\f$ (размер векторов входного спектра и результата ОДПФ). \n \n
+
+\param[out] y
+Указатель на комплексный вектор результата ОДПФ \f$y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$.
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+
+\return
+`RES_OK` если ОДПФ рассчитана успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки".
+
+Пример использования функции `dft_cmplx`:
+
+\include idft_cmplx_test.c
+
+Результат работы программы:
+
+\verbatim
+x[ 0] = 0.000 +0.000j, z[ 0] = 0.000 -0.000
+x[ 1] = 1.000 +0.000j, z[ 1] = 1.000 -0.000
+x[ 2] = 2.000 +0.000j, z[ 2] = 2.000 -0.000
+x[ 3] = 3.000 +0.000j, z[ 3] = 3.000 -0.000
+x[ 4] = 4.000 +0.000j, z[ 4] = 4.000 -0.000
+x[ 5] = 5.000 +0.000j, z[ 5] = 5.000 -0.000
+x[ 6] = 6.000 +0.000j, z[ 6] = 6.000 -0.000
+x[ 7] = 7.000 +0.000j, z[ 7] = 7.000 -0.000
+x[ 8] = 8.000 +0.000j, z[ 8] = 8.000 -0.000
+x[ 9] = 9.000 +0.000j, z[ 9] = 9.000 -0.000
+x[10] = 10.000 +0.000j, z[10] = 10.000 -0.000
+x[11] = 11.000 +0.000j, z[11] = 11.000 +0.000
+x[12] = 12.000 +0.000j, z[12] = 12.000 +0.000
+x[13] = 13.000 +0.000j, z[13] = 13.000 +0.000
+x[14] = 14.000 +0.000j, z[14] = 14.000 +0.000
+x[15] = 15.000 +0.000j, z[15] = 15.000 -0.000
+\endverbatim
+
+\note
+Данная функция выполняет расчет ОДПФ наивным методом
+и требует \f$ n^2 \f$ комплексных умножений. \n
+Для увеличения скорости расчета рекомендуется
+использовать алгоритмы быстрого преобразования Фурье.
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API idft_cmplx(complex_t* x, int n, complex_t* y)
{
- int k;
- int m;
- double divn;
- double phi;
- complex_t e;
+ int k;
+ int m;
+ double divn;
+ double phi;
+ complex_t e;
- if(!x || !y)
- return ERROR_PTR;
+ if(!x || !y)
+ return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
+ if(n<1)
+ return ERROR_SIZE;
- divn = 1.0 / (double)n;
+ divn = 1.0 / (double)n;
- for(k = 0; k < n; k++)
- {
- RE(y[k]) = IM(y[k]) = 0.0;
- for(m = 0; m < n; m++)
+ for(k = 0; k < n; k++)
{
- phi = M_2PI * divn * (double)k * (double)m;
- RE(e) = cos(phi);
- IM(e) = sin(phi);
- RE(y[k]) += CMRE(x[m], e);
- IM(y[k]) += CMIM(x[m], e);
+ RE(y[k]) = IM(y[k]) = 0.0;
+ for(m = 0; m < n; m++)
+ {
+ phi = M_2PI * divn * (double)k * (double)m;
+ RE(e) = cos(phi);
+ IM(e) = sin(phi);
+ RE(y[k]) += CMRE(x[m], e);
+ IM(y[k]) += CMIM(x[m], e);
+ }
+ RE(y[k]) /= (double)n;
+ IM(y[k]) /= (double)n;
}
- RE(y[k]) /= (double)n;
- IM(y[k]) /= (double)n;
- }
- return RES_OK;
+ return RES_OK;
}
diff --git a/dspl/src/ellipj.c b/dspl/src/ellipj.c
index e6ff0b2..7c0877b 100644
--- a/dspl/src/ellipj.c
+++ b/dspl/src/ellipj.c
@@ -11,11 +11,11 @@
*
* 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
+* 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 .
+* along with Foobar. If not, see .
*/
@@ -27,39 +27,106 @@
-/*****************************************************************************
-Inverse Jacobi elliptic function cd^-1(w, k) for the real argument
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#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;
+ 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;
+ 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);
+ ellip_landen(k,ELLIP_ITER, lnd);
-
- for(m = 0; m < n; m++)
- {
- u[m] = w[m];
- for(i = 1; i < ELLIP_ITER; i++)
+ for(m = 0; m < n; m++)
{
- 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] = 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;
}
- u[m] = 2.0 * acos(u[m]) / M_PI;
- }
- return RES_OK;
+ return RES_OK;
}
@@ -67,191 +134,469 @@ int DSPL_API ellip_acd(double* w, int n, double k, double* u)
-/*****************************************************************************
-Inverse Jacobi elliptic function cd^-1(w, k) for the complex argument
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#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;
+ 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;
+ 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);
+ 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++)
+ for(m = 0; m < n; m++)
{
- 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);
+ 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;
+ 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]);
+ RE(tmp1) = RE(tmp0) * (1.0 + lnd[i]);
+ IM(tmp1) = IM(tmp0) * (1.0 + lnd[i]);
- t = 2.0 / ABSSQR(tmp1);
+ 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);
+ 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;
}
- acos_cmplx(&tmp0, 1, u+m);
- t = 2.0 / M_PI;
- RE(u[m]) *= t;
- IM(u[m]) *= t;
- }
- return RES_OK;
+ return RES_OK;
}
-/*****************************************************************************
-Inverse Jacobi elliptic function sn^-1(w, k) for the real argument
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#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;
+ 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;
+ 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);
+ ellip_landen(k,ELLIP_ITER, lnd);
-
- for(m = 0; m < n; m++)
- {
- u[m] = w[m];
- for(i = 1; i < ELLIP_ITER; i++)
+ for(m = 0; m < n; m++)
{
- 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] = 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;
}
- u[m] = 2.0 * asin(u[m]) / M_PI;
- }
- return RES_OK;
+ return RES_OK;
}
-/*****************************************************************************
-Inverse Jacobi elliptic function sn^-1(w, k) for the complex argument
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#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;
+ 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;
+ 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);
+ 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++)
+ for(m = 0; m < n; m++)
{
- 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);
+ 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;
+ 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]);
+ RE(tmp1) = RE(tmp0) * (1.0 + lnd[i]);
+ IM(tmp1) = IM(tmp0) * (1.0 + lnd[i]);
- t = 2.0 / ABSSQR(tmp1);
+ 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);
+ 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;
}
- asin_cmplx(&tmp0, 1, u+m);
- t = 2.0 / M_PI;
- RE(u[m]) *= t;
- IM(u[m]) *= t;
- }
- return RES_OK;
+ return RES_OK;
}
-/*****************************************************************************
-Jacobi elliptic function cd(u*K(k), k) for the real argument
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#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
+
+\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
+
+\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;
+ 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;
+ 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);
+ 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--)
+ for(m = 0; m < n; m++)
{
- y[m] = (1.0 + lnd[i]) / (1.0 / y[m] + lnd[i]*y[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;
+ return RES_OK;
}
@@ -260,49 +605,118 @@ int DSPL_API ellip_cd(double* u, int n, double k, double* y)
-/*****************************************************************************
-Jacobi elliptic function cd(u*K(k), k) for the complex argument
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#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;
+ 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;
+ 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);
+ 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--)
+ for(m = 0; m < n; m++)
{
- t = 1.0 / ABSSQR(y[m]);
+ RE(tmp) = RE(u[m]) * M_PI * 0.5;
+ IM(tmp) = IM(u[m]) * M_PI * 0.5;
- RE(tmp) = RE(y[m]) * t + RE(y[m]) * lnd[i];
- IM(tmp) = -IM(y[m]) * t + IM(y[m]) * lnd[i];
+ cos_cmplx(&tmp, 1, y+m);
- t = (1.0 + lnd[i]) / ABSSQR(tmp);
+ for(i = ELLIP_ITER-1; i>0; i--)
+ {
+ t = 1.0 / ABSSQR(y[m]);
- RE(y[m]) = RE(tmp) * t;
- IM(y[m]) = -IM(tmp) * t;
+ 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;
+ return RES_OK;
}
@@ -310,130 +724,270 @@ int DSPL_API ellip_cd_cmplx(complex_t* u, int n, double k, complex_t* y)
-/*****************************************************************************
- Function calculates complete elliptical integral coefficients \f$ k_i \f$
- by Landen transform
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#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;
+ 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;
+ 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];
- }
+ 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;
+ return RES_OK;
}
-/*****************************************************************************
- Elliptic modular equation
- --------------------------------------------------------------------------------
-Documented: NO, NO
-*******************************************************************************/
+#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;
+ 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;
+ 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);
+ ep = sqrt(pow(10.0, rp*0.1)-1.0);
+ es = sqrt(pow(10.0, rs*0.1)-1.0);
- ke = ep/es;
+ ke = ep/es;
- ke = sqrt(1.0 - ke*ke);
+ ke = sqrt(1.0 - ke*ke);
- r = ord % 2;
- L = (ord-r)/2;
+ 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 = 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);
+ kp *= pow(ke, (double)ord);
+ *k = sqrt(1.0 - kp*kp);
- return RES_OK;
+ return RES_OK;
}
-/*****************************************************************************
-Elliptic rational function
---------------------------------------------------------------------------------
-Documented: NO, NO
-*******************************************************************************/
+#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;
+ 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;
+ 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;
+ r = ord%2;
+ L = (ord-r)/2;
- if(r)
- memcpy(u, w, n*sizeof(double));
- else
- {
- for(m = 0; m < n; m++)
+ if(r)
+ memcpy(u, w, n*sizeof(double));
+ else
{
- u[m] = 1.0;
+ 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++)
+ k2 = k*k;
+ for(i = 0; i < L; i++)
{
- w2 = w[m]*w[m];
- u[m] *= (w2 - xi2) / (1.0 - w2 * k2 * xi2);
- u[m] *= (1.0 - k2*xi2) / (1.0 - xi2);
+ 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;
+ return RES_OK;
}
@@ -441,82 +995,224 @@ int DSPL_API ellip_rat(double* w, int n, int ord, double k, double* u)
-/*****************************************************************************
-Jacobi elliptic function sn(u*K(k), k) for the real vector argument
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#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
+
+\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
+
+\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;
+ 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;
+ 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);
+ 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--)
+ for(m = 0; m < n; m++)
{
- y[m] = (1.0 + lnd[i]) / (1.0 / y[m] + lnd[i]*y[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;
+ return RES_OK;
}
-/*****************************************************************************
-Jacobi elliptic function sn(u*K(k), k) for the complex vector argument
---------------------------------------------------------------------------------
-Documented: RU, EN
-*******************************************************************************/
+#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;
+ 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;
+ 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);
+ 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--)
+ for(m = 0; m < n; m++)
{
- t = 1.0 / ABSSQR(y[m]);
+ RE(tmp) = RE(u[m]) * M_PI * 0.5;
+ IM(tmp) = IM(u[m]) * M_PI * 0.5;
- RE(tmp) = RE(y[m]) * t + RE(y[m]) * lnd[i];
- IM(tmp) = -IM(y[m]) * t + IM(y[m]) * lnd[i];
+ sin_cmplx(&tmp, 1, y+m);
- t = (1.0 + lnd[i]) / ABSSQR(tmp);
+ for(i = ELLIP_ITER-1; i>0; i--)
+ {
+ t = 1.0 / ABSSQR(y[m]);
- RE(y[m]) = RE(tmp) * t;
- IM(y[m]) = -IM(tmp) * t;
+ 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;
+ return RES_OK;
}
diff --git a/dspl/src/fft.c b/dspl/src/fft.c
index 5730601..b576141 100644
--- a/dspl/src/fft.c
+++ b/dspl/src/fft.c
@@ -5,17 +5,17 @@
* 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
+* 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
+* 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 .
+* along with Foobar. If not, see .
*/
#include
@@ -24,72 +24,335 @@
#include "dspl.h"
#include "dspl_internal.h"
-/*******************************************************************************
-COMPLEX vector IFFT
-*******************************************************************************/
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int ifft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
+\brief Inverse fast Fourier transform
+
+Function calculates \f$ n \f$-point IFFT of complex data
+\f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \frac{1}{N} \sum_{m = 0}^{n-1} x(m) \exp
+ \left( j \frac{2\pi}{n} m k \right),
+\f]
+here \f$ k = 0 \ldots n-1 \f$.
+
+
+\param[in] x
+Pointer to the input vector \f$x(m)\f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+IFFT size \f$n\f$. \n
+IFFT size can be composite:
+\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
+here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
+simple number less than 46340
+(see \ref fft_create function). \n \n
+
+\param[in] pfft
+Pointer to the `fft_t` object. \n
+This pointer cannot be `NULL`. \n
+Structure \ref fft_t should be previously once
+filled with the \ref fft_create function, and the memory should be
+cleared before exiting by the \ref fft_free function. \n \n
+
+\param[out] y
+Pointer to the IFFT result vector \f$Y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if IFFT is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+IFFT example:
+
+\include ifft_cmplx_test.c
+
+Result:
+
+\verbatim
+| x[ 0] = 1.000 0.000 | y[ 0] = -0.517 0.686 | z[ 0] = 1.000 0.000 |
+| x[ 1] = 0.540 0.841 | y[ 1] = -0.943 0.879 | z[ 1] = 0.540 0.841 |
+| x[ 2] = -0.416 0.909 | y[ 2] = -2.299 1.492 | z[ 2] = -0.416 0.909 |
+| x[ 3] = -0.990 0.141 | y[ 3] = 16.078 -6.820 | z[ 3] = -0.990 0.141 |
+| x[ 4] = -0.654 -0.757 | y[ 4] = 2.040 -0.470 | z[ 4] = -0.654 -0.757 |
+| x[ 5] = 0.284 -0.959 | y[ 5] = 1.130 -0.059 | z[ 5] = 0.284 -0.959 |
+| x[ 6] = 0.960 -0.279 | y[ 6] = 0.786 0.097 | z[ 6] = 0.960 -0.279 |
+| x[ 7] = 0.754 0.657 | y[ 7] = 0.596 0.183 | z[ 7] = 0.754 0.657 |
+| x[ 8] = -0.146 0.989 | y[ 8] = 0.470 0.240 | z[ 8] = -0.146 0.989 |
+| x[ 9] = -0.911 0.412 | y[ 9] = 0.375 0.283 | z[ 9] = -0.911 0.412 |
+| x[10] = -0.839 -0.544 | y[10] = 0.297 0.318 | z[10] = -0.839 -0.544 |
+| x[11] = 0.004 -1.000 | y[11] = 0.227 0.350 | z[11] = 0.004 -1.000 |
+| x[12] = 0.844 -0.537 | y[12] = 0.161 0.380 | z[12] = 0.844 -0.537 |
+| x[13] = 0.907 0.420 | y[13] = 0.094 0.410 | z[13] = 0.907 0.420 |
+| x[14] = 0.137 0.991 | y[14] = 0.023 0.442 | z[14] = 0.137 0.991 |
+| x[15] = -0.760 0.650 | y[15] = -0.059 0.479 | z[15] = -0.760 0.650 |
+| x[16] = -0.958 -0.288 | y[16] = -0.161 0.525 | z[16] = -0.958 -0.288 |
+| x[17] = -0.275 -0.961 | y[17] = -0.300 0.588 | z[17] = -0.275 -0.961 |
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int ifft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
+\brief Обратное быстрое преобразование Фурье
+
+Функция рассчитывает \f$ n \f$-точечное обратное быстрое преобразование Фурье
+от \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \frac{1}{N} \sum_{m = 0}^{n-1} x(m) \exp
+ \left( j \frac{2\pi}{n} m k \right),
+\f]
+где \f$ k = 0 \ldots n-1 \f$.
+
+Для расчета используется алгоритм БПФ составной длины.
+
+\param[in] x
+Указатель на входной комплексный вектор \f$x(m)\f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер ОБПФ \f$n\f$. \n
+Размер ОБПФ может быть составным вида
+\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
+где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
+произвольный простой множитель не превосходящий 46340
+(см. описание функции \ref fft_create). \n \n
+
+\param[in] pfft
+Указатель на структуру `fft_t`. \n
+Указатель не должен быть `NULL`. \n
+Структура \ref fft_t должна быть предварительно однократно
+заполнена функцией \ref fft_create, и память должна быть
+очищена перед выходом функцией \ref fft_free. \n \n
+
+\param[out] y
+Указатель на вектор результата ОБПФ \f$Y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$. Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если расчет произведен успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
+
+Пример использования функции `fft`:
+
+\include ifft_cmplx_test.c
+
+Результат работы программы:
+
+\verbatim
+| x[ 0] = 1.000 0.000 | y[ 0] = -0.517 0.686 | z[ 0] = 1.000 0.000 |
+| x[ 1] = 0.540 0.841 | y[ 1] = -0.943 0.879 | z[ 1] = 0.540 0.841 |
+| x[ 2] = -0.416 0.909 | y[ 2] = -2.299 1.492 | z[ 2] = -0.416 0.909 |
+| x[ 3] = -0.990 0.141 | y[ 3] = 16.078 -6.820 | z[ 3] = -0.990 0.141 |
+| x[ 4] = -0.654 -0.757 | y[ 4] = 2.040 -0.470 | z[ 4] = -0.654 -0.757 |
+| x[ 5] = 0.284 -0.959 | y[ 5] = 1.130 -0.059 | z[ 5] = 0.284 -0.959 |
+| x[ 6] = 0.960 -0.279 | y[ 6] = 0.786 0.097 | z[ 6] = 0.960 -0.279 |
+| x[ 7] = 0.754 0.657 | y[ 7] = 0.596 0.183 | z[ 7] = 0.754 0.657 |
+| x[ 8] = -0.146 0.989 | y[ 8] = 0.470 0.240 | z[ 8] = -0.146 0.989 |
+| x[ 9] = -0.911 0.412 | y[ 9] = 0.375 0.283 | z[ 9] = -0.911 0.412 |
+| x[10] = -0.839 -0.544 | y[10] = 0.297 0.318 | z[10] = -0.839 -0.544 |
+| x[11] = 0.004 -1.000 | y[11] = 0.227 0.350 | z[11] = 0.004 -1.000 |
+| x[12] = 0.844 -0.537 | y[12] = 0.161 0.380 | z[12] = 0.844 -0.537 |
+| x[13] = 0.907 0.420 | y[13] = 0.094 0.410 | z[13] = 0.907 0.420 |
+| x[14] = 0.137 0.991 | y[14] = 0.023 0.442 | z[14] = 0.137 0.991 |
+| x[15] = -0.760 0.650 | y[15] = -0.059 0.479 | z[15] = -0.760 0.650 |
+| x[16] = -0.958 -0.288 | y[16] = -0.161 0.525 | z[16] = -0.958 -0.288 |
+| x[17] = -0.275 -0.961 | y[17] = -0.300 0.588 | z[17] = -0.275 -0.961 |
+\endverbatim
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API ifft_cmplx(complex_t *x, int n, fft_t* pfft, complex_t* y)
{
- int err, k;
- double norm;
+ int err, k;
+ double norm;
- if(!x || !pfft || !y)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
+ if(!x || !pfft || !y)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
- err = fft_create(pfft, n);
- if(err != RES_OK)
- return err;
+ err = fft_create(pfft, n);
+ if(err != RES_OK)
+ return err;
- memcpy(pfft->t1, x, n*sizeof(complex_t));
- for(k = 0; k < n; k++)
- IM(pfft->t1[k]) = -IM(pfft->t1[k]);
+ memcpy(pfft->t1, x, n*sizeof(complex_t));
+ for(k = 0; k < n; k++)
+ IM(pfft->t1[k]) = -IM(pfft->t1[k]);
- err = fft_krn(pfft->t1, pfft->t0, pfft, n, 0);
+ err = fft_krn(pfft->t1, pfft->t0, pfft, n, 0);
- if(err!=RES_OK)
- return err;
+ if(err!=RES_OK)
+ return err;
- norm = 1.0 / (double)n;
- for(k = 0; k < n; k++)
- {
- RE(y[k]) = RE(pfft->t0[k])*norm;
- IM(y[k]) = -IM(pfft->t0[k])*norm;
- }
- return RES_OK;
+ norm = 1.0 / (double)n;
+ for(k = 0; k < n; k++)
+ {
+ RE(y[k]) = RE(pfft->t0[k])*norm;
+ IM(y[k]) = -IM(pfft->t0[k])*norm;
+ }
+ return RES_OK;
}
-/*******************************************************************************
-Real vector FFT
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft(double* x, int n, fft_t* pfft, complex_t* y)
+\brief Fast Fourier transform for the real vector.
+
+Function calculated \f$ n \f$-points FFT for the real vector
+\f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \sum_{m = 0}^{n-1} x(m) \exp
+ \left( -j \frac{2\pi}{n} m k \right),
+\f]
+here \f$ k = 0 \ldots n-1 \f$.
+
+
+\param[in] x
+Pointer to the input real vector \f$x(m)\f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+FFT size \f$n\f$. \n
+FFT size can be composite:
+\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
+here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
+simple number less than 46340
+(see \ref fft_create function). \n \n
+
+\param[in] pfft
+Pointer to the `fft_t` object. \n
+This pointer cannot be `NULL`. \n
+Structure \ref fft_t should be previously once
+filled with the \ref fft_create function, and the memory should be
+cleared before exiting by the \ref fft_free function. \n \n
+
+\param[out] y
+Pointer to the FFT result complex vector \f$Y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if FFT is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+Example:
+
+\include fft_test.c
+
+Result:
+
+\verbatim
+y[ 0] = 91.000 0.000
+y[ 1] = -7.000 30.669
+y[ 2] = -7.000 14.536
+y[ 3] = -7.000 8.778
+y[ 4] = -7.000 5.582
+y[ 5] = -7.000 3.371
+y[ 6] = -7.000 1.598
+y[ 7] = -7.000 0.000
+y[ 8] = -7.000 -1.598
+y[ 9] = -7.000 -3.371
+y[10] = -7.000 -5.582
+y[11] = -7.000 -8.778
+y[12] = -7.000 -14.536
+y[13] = -7.000 -30.669
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft(double* x, int n, fft_t* pfft, complex_t* y)
+\brief Быстрое преобразование Фурье вещественного сигнала
+
+Функция рассчитывает \f$ n \f$-точечное быстрое преобразование Фурье
+вещественного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \sum_{m = 0}^{n-1} x(m) \exp
+ \left( -j \frac{2\pi}{n} m k \right),
+\f]
+где \f$ k = 0 \ldots n-1 \f$.
+
+Для расчета используется алгоритм БПФ составной длины.
+
+\param[in] x
+Указатель на вектор вещественного входного сигнала \f$x(m)\f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер БПФ \f$n\f$. \n
+Размер БПФ может быть составным вида
+\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
+где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
+произвольный простой множитель не превосходящий 46340
+(см. описание функции \ref fft_create). \n \n
+
+\param[in] pfft
+Указатель на структуру `fft_t`. \n
+Указатель не должен быть `NULL`. \n
+Структура \ref fft_t должна быть предварительно однократно
+заполнена функцией \ref fft_create, и память должна быть
+очищена перед выходом функцией \ref fft_free. \n \n
+
+\param[out] y
+Указатель на комплексный вектор результата БПФ \f$Y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если расчет произведен успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
+
+Пример использования функции `fft`:
+
+\include fft_test.c
+
+Результат работы программы:
+
+\verbatim
+y[ 0] = 91.000 0.000
+y[ 1] = -7.000 30.669
+y[ 2] = -7.000 14.536
+y[ 3] = -7.000 8.778
+y[ 4] = -7.000 5.582
+y[ 5] = -7.000 3.371
+y[ 6] = -7.000 1.598
+y[ 7] = -7.000 0.000
+y[ 8] = -7.000 -1.598
+y[ 9] = -7.000 -3.371
+y[10] = -7.000 -5.582
+y[11] = -7.000 -8.778
+y[12] = -7.000 -14.536
+y[13] = -7.000 -30.669
+\endverbatim
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API fft(double* x, int n, fft_t* pfft, complex_t* y)
-{
- int err;
-
- if(!x || !pfft || !y)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
-
-
- err = fft_create(pfft, n);
- if(err != RES_OK)
- return err;
-
- re2cmplx(x, n, pfft->t1);
-
- return fft_krn(pfft->t1, y, pfft, n, 0);
-}
-
-
-
-
-/*******************************************************************************
-COMPLEX vector FFT
-*******************************************************************************/
-int DSPL_API fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
{
int err;
@@ -99,6 +362,177 @@ int DSPL_API fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
return ERROR_SIZE;
+ err = fft_create(pfft, n);
+ if(err != RES_OK)
+ return err;
+
+ re2cmplx(x, n, pfft->t1);
+
+ return fft_krn(pfft->t1, y, pfft, n, 0);
+}
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
+\brief Fast Fourier transform for the complex vector.
+
+Function calculated \f$ n \f$-points FFT for the complex vector
+\f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \sum_{m = 0}^{n-1} x(m) \exp \left( -j \frac{2\pi}{n} m k \right),
+\f]
+here \f$ k = 0 \ldots n-1 \f$.
+
+\param[in] x
+Pointer to the input complex vector \f$x(m)\f$,
+\f$ m = 0 \ldots n-1 \f$. \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+FFT size \f$n\f$. \n
+FFT size can be composite:
+\f$n = n_0 \times n_1 \times n_2 \times \ldots \times n_p \times m\f$,
+here \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
+simple number less than 46340
+(see \ref fft_create function). \n \n
+
+\param[in] pfft
+Pointer to the `fft_t` object. \n
+This pointer cannot be `NULL`. \n
+Structure \ref fft_t should be previously once
+filled with the \ref fft_create function, and the memory should be
+cleared before exiting by the \ref fft_free function. \n \n
+
+\param[out] y
+Pointer to the FFT result complex vector \f$Y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return
+`RES_OK` if FFT is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+Example:
+
+\include fft_cmplx_test.c
+
+Result:
+
+\verbatim
+y[ 0] = -0.517 0.686
+y[ 1] = -0.943 0.879
+y[ 2] = -2.299 1.492
+y[ 3] = 16.078 -6.820
+y[ 4] = 2.040 -0.470
+y[ 5] = 1.130 -0.059
+y[ 6] = 0.786 0.097
+y[ 7] = 0.596 0.183
+y[ 8] = 0.470 0.240
+y[ 9] = 0.375 0.283
+y[10] = 0.297 0.318
+y[11] = 0.227 0.350
+y[12] = 0.161 0.380
+y[13] = 0.094 0.410
+y[14] = 0.023 0.442
+y[15] = -0.059 0.479
+y[16] = -0.161 0.525
+y[17] = -0.300 0.588
+\endverbatim
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
+\brief Быстрое преобразование Фурье комплексного сигнала
+
+Функция рассчитывает \f$ n \f$-точечное быстрое преобразование Фурье
+комплексного сигнала \f$ x(m) \f$, \f$ m = 0 \ldots n-1 \f$. \n
+\f[
+ Y(k) = \sum_{m = 0}^{n-1} x(m) \exp \left( -j \frac{2\pi}{n} m k \right),
+\f]
+где \f$ k = 0 \ldots n-1 \f$.
+
+Для расчета используется алгоритм БПФ составной длины.
+
+\param[in] x
+Указатель на вектор комплексного
+входного сигнала \f$x(m)\f$, \f$ m = 0 \ldots n-1 \f$. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер БПФ \f$n\f$. \n
+Размер БПФ может быть составным вида
+\f$ n = n_0 \times n_1 \times n_2 \times n_3 \times \ldots
+\times n_p \times m \f$,
+где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
+произвольный простой множитель не превосходящий 46340
+(см. описание функции \ref fft_create). \n \n
+
+\param[in] pfft
+Указатель на структуру `fft_t`. \n
+Указатель не должен быть `NULL`. \n
+Структура \ref fft_t должна быть предварительно однократно
+заполнена функцией \ref fft_create, и память должна быть
+очищена перед выходом функцией \ref fft_free. \n \n
+
+\param[out] y
+Указатель на комплексный вектор
+результата БПФ \f$Y(k)\f$,
+\f$ k = 0 \ldots n-1 \f$.
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если расчет произведен успешно. \n
+ В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
+
+Пример использования функции `fft`:
+
+\include fft_cmplx_test.c
+
+Результат работы программы:
+
+\verbatim
+y[ 0] = -0.517 0.686
+y[ 1] = -0.943 0.879
+y[ 2] = -2.299 1.492
+y[ 3] = 16.078 -6.820
+y[ 4] = 2.040 -0.470
+y[ 5] = 1.130 -0.059
+y[ 6] = 0.786 0.097
+y[ 7] = 0.596 0.183
+y[ 8] = 0.470 0.240
+y[ 9] = 0.375 0.283
+y[10] = 0.297 0.318
+y[11] = 0.227 0.350
+y[12] = 0.161 0.380
+y[13] = 0.094 0.410
+y[14] = 0.023 0.442
+y[15] = -0.059 0.479
+y[16] = -0.161 0.525
+y[17] = -0.300 0.588
+\endverbatim
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
+{
+ int err;
+
+ if(!x || !pfft || !y)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+
err = fft_create(pfft, n);
if(err != RES_OK)
return err;
@@ -110,265 +544,423 @@ int DSPL_API fft_cmplx(complex_t* x, int n, fft_t* pfft, complex_t* y)
-/*******************************************************************************
-composite FFT kernel
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
int fft_krn(complex_t* t0, complex_t* t1, fft_t* p, int n, int addr)
{
- int n1, n2, k, m, i;
- complex_t *pw = p->w+addr;
- complex_t tmp;
-
- n1 = 1;
- if(n%16== 0) { n1 = 16; goto label_size; }
- if(n%7 == 0) { n1 = 7; goto label_size; }
- if(n%8 == 0) { n1 = 8; goto label_size; }
- if(n%5 == 0) { n1 = 5; goto label_size; }
- if(n%4 == 0) { n1 = 4; goto label_size; }
- if(n%3 == 0) { n1 = 3; goto label_size; }
- if(n%2 == 0) { n1 = 2; goto label_size; }
+ int n1, n2, k, m, i;
+ complex_t *pw = p->w+addr;
+ complex_t tmp;
+
+ n1 = 1;
+ if(n%16== 0) { n1 = 16; goto label_size; }
+ if(n%7 == 0) { n1 = 7; goto label_size; }
+ if(n%8 == 0) { n1 = 8; goto label_size; }
+ if(n%5 == 0) { n1 = 5; goto label_size; }
+ if(n%4 == 0) { n1 = 4; goto label_size; }
+ if(n%3 == 0) { n1 = 3; goto label_size; }
+ if(n%2 == 0) { n1 = 2; goto label_size; }
label_size:
- if(n1 == 1)
- {
- for(k = 0; k < n; k++)
+ if(n1 == 1)
{
- RE(t1[k]) = IM(t1[k]) = 0.0;
- for(m = 0; m < n; m++)
- {
- i = (k*m) % n;
- RE(tmp) = CMRE(t0[m], pw[i]);
- IM(tmp) = CMIM(t0[m], pw[i]);
- RE(t1[k]) += RE(tmp);
- IM(t1[k]) += IM(tmp);
- }
- }
- }
- else
- {
- n2 = n / n1;
-
- if(n2>1)
- {
- memcpy(t1, t0, n*sizeof(complex_t));
- matrix_transpose_cmplx(t1, n2, n1, t0);
- }
-
- if(n1 == 16)
- for(k = 0; k < n2; k++)
- dft16(t0+16*k, t1+16*k);
-
- if(n1 == 7)
- for(k = 0; k < n2; k++)
- dft7(t0+7*k, t1+7*k);
-
- if(n1 == 8)
- for(k = 0; k < n2; k++)
- dft8(t0+8*k, t1+8*k);
-
- if(n1 == 5)
- for(k = 0; k < n2; k++)
- dft5(t0+5*k, t1+5*k);
-
- if(n1 == 4)
- for(k = 0; k < n2; k++)
- dft4(t0+4*k, t1+4*k);
-
- if(n1 == 3)
- for(k = 0; k < n2; k++)
- dft3(t0+3*k, t1+3*k);
-
- if(n1 == 2)
- for(k = 0; k < n2; k++)
- dft2(t0+2*k, t1+2*k);
-
- if(n2 > 1)
- {
-
- for(k =0; k < n; k++)
- {
- RE(t0[k]) = CMRE(t1[k], pw[k]);
- IM(t0[k]) = CMIM(t1[k], pw[k]);
- }
-
- matrix_transpose_cmplx(t0, n1, n2, t1);
-
- for(k = 0; k < n1; k++)
- {
- fft_krn(t1+k*n2, t0+k*n2, p, n2, addr+n);
- }
- matrix_transpose_cmplx(t0, n2, n1, t1);
- }
- }
- return RES_OK;
-
-}
-
-
-
-
-/*******************************************************************************
-FFT create for composite N
-*******************************************************************************/
-int DSPL_API fft_create(fft_t* pfft, int n)
-{
-
- int n1, n2, addr, s, k, m, nw, err;
- double phi;
- s = n;
- nw = addr = 0;
-
- if(pfft->n == n)
- return RES_OK;
-
- while(s > 1)
- {
- n2 = 1;
- if(s%16== 0) { n2 = 16; goto label_size; }
- if(s%7 == 0) { n2 = 7; goto label_size; }
- if(s%8 == 0) { n2 = 8; goto label_size; }
- if(s%5 == 0) { n2 = 5; goto label_size; }
- if(s%4 == 0) { n2 = 4; goto label_size; }
- if(s%3 == 0) { n2 = 3; goto label_size; }
- if(s%2 == 0) { n2 = 2; goto label_size; }
-
-
-label_size:
- if(n2 == 1)
- {
- if(s > FFT_COMPOSITE_MAX)
- {
- err = ERROR_FFT_SIZE;
- goto error_proc;
- }
-
- nw += s;
- pfft->w = pfft->w ? (complex_t*) realloc(pfft->w, nw*sizeof(complex_t)):
- (complex_t*) malloc( nw*sizeof(complex_t));
- for(k = 0; k < s; k++)
- {
- phi = - M_2PI * (double)k / (double)s;
- RE(pfft->w[addr]) = cos(phi);
- IM(pfft->w[addr]) = sin(phi);
- addr++;
- }
- s = 1;
+ for(k = 0; k < n; k++)
+ {
+ RE(t1[k]) = IM(t1[k]) = 0.0;
+ for(m = 0; m < n; m++)
+ {
+ i = (k*m) % n;
+ RE(tmp) = CMRE(t0[m], pw[i]);
+ IM(tmp) = CMIM(t0[m], pw[i]);
+ RE(t1[k]) += RE(tmp);
+ IM(t1[k]) += IM(tmp);
+ }
+ }
}
else
{
- n1 = s / n2;
- nw += s;
- pfft->w = pfft->w ? (complex_t*) realloc(pfft->w, nw*sizeof(complex_t)):
- (complex_t*) malloc( nw*sizeof(complex_t));
-
- for(k = 0; k < n1; k++)
- {
- for(m = 0; m < n2; m++)
+ n2 = n / n1;
+
+ if(n2>1)
{
- phi = - M_2PI * (double)(k*m) / (double)s;
- RE(pfft->w[addr]) = cos(phi);
- IM(pfft->w[addr]) = sin(phi);
- addr++;
+ memcpy(t1, t0, n*sizeof(complex_t));
+ matrix_transpose_cmplx(t1, n2, n1, t0);
+ }
+
+ if(n1 == 16)
+ for(k = 0; k < n2; k++)
+ dft16(t0+16*k, t1+16*k);
+
+ if(n1 == 7)
+ for(k = 0; k < n2; k++)
+ dft7(t0+7*k, t1+7*k);
+
+ if(n1 == 8)
+ for(k = 0; k < n2; k++)
+ dft8(t0+8*k, t1+8*k);
+
+ if(n1 == 5)
+ for(k = 0; k < n2; k++)
+ dft5(t0+5*k, t1+5*k);
+
+ if(n1 == 4)
+ for(k = 0; k < n2; k++)
+ dft4(t0+4*k, t1+4*k);
+
+ if(n1 == 3)
+ for(k = 0; k < n2; k++)
+ dft3(t0+3*k, t1+3*k);
+
+ if(n1 == 2)
+ for(k = 0; k < n2; k++)
+ dft2(t0+2*k, t1+2*k);
+
+ if(n2 > 1)
+ {
+
+ for(k =0; k < n; k++)
+ {
+ RE(t0[k]) = CMRE(t1[k], pw[k]);
+ IM(t0[k]) = CMIM(t1[k], pw[k]);
+ }
+
+ matrix_transpose_cmplx(t0, n1, n2, t1);
+
+ for(k = 0; k < n1; k++)
+ {
+ fft_krn(t1+k*n2, t0+k*n2, p, n2, addr+n);
+ }
+ matrix_transpose_cmplx(t0, n2, n1, t1);
}
- }
}
- s /= n2;
- }
+ return RES_OK;
+}
- pfft->t0 = pfft->t0 ? (complex_t*) realloc(pfft->t0, n*sizeof(complex_t)):
- (complex_t*) malloc( n*sizeof(complex_t));
- pfft->t1 = pfft->t1 ? (complex_t*) realloc(pfft->t1, n*sizeof(complex_t)):
- (complex_t*) malloc( n*sizeof(complex_t));
-
- pfft->n = n;
- return RES_OK;
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft_create(fft_t* pfft, int n)
+\brief Function creates and fill `fft_t` structure.
+
+The function allocates memory and calculates twiddle factors
+ of the `n`-point FFT for the structure` fft_t`.
+
+\param[in,out] pfft
+Pointer to the `fft_t` object. \n
+Pointer cannot be `NULL`. \n \n
+
+\param[in] n
+FFT size \f$n\f$. \n
+FFT size can be composite
+\f$n = n_0 \times n_1 \times n_2 \ldots \times n_p \times m\f$,
+here \f$n_i = 2,3,5,7\f$, and \f$m \f$ --
+ arbitrary prime factor not exceeding 46340. \n
+Thus, the FFT algorithm supports arbitrary integer lengths.
+degrees of numbers 2,3,5,7, as well as their various combinations. \n
+For example, with \f$ n = 725760 \f$ the structure will be successfully filled,
+because
+\f$ 725760 = 2 \cdot 3 \cdot 4 \cdot 5 \cdot 6 \cdot 7 \cdot 9 \cdot 16 \f$. \n
+If \f$ n = 172804 = 43201 \cdot 4 \f$ then the structure will also be
+successfully filled, because the simple factor in \f$ n \f$ does not
+exceed 46340. \n
+For size \f$ n = 13 \cdot 17 \cdot 23 \cdot 13 = 66079 \f$
+the function will return an error since 66079 is greater than 46340 and is
+not the result of the product of numbers 2,3,5,7. \n \n
+
+\return
+`RES_OK` if FFT structure is created and filled successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\note
+Some compilers do not nullify its contents when creating a structure.
+Therefore, it is recommended to reset the structure after its declaration:
+\code{.cpp}
+fft_t pfft = {0}; // fill and fields of fft_t as zeros
+int n = 64; // FFT size
+
+int err;
+
+// Create fft_t object for 64-points FFT
+
+err = fft_create(&pfft, n);
+
+// ...................................
+
+// Clear fft_t structure
+
+fft_free(&pfft);
+\endcode
+
+Before exiting the program, the memory allocated in the structure
+need to clear by \ref fft_free function. \n \n
+
+\note
+The "magic number" 46340 because \f$\sqrt{2^{31}} = 46340.95\f$. \n
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft_create(fft_t* pfft, int n)
+\brief Заполнение структуры `fft_t` для алгоритма БПФ
+
+Функция производит выделение памяти и рассчет векторов
+поворотных коэффициентов `n`-точечного БПФ для структуры `fft_t`.
+
+\param[in,out] pfft
+Указатель на структуру `fft_t`. \n
+Указатель не должен быть `NULL`. \n \n
+
+\param[in] n
+Размер БПФ \f$n\f$. \n
+Размер БПФ может быть составным вида
+\f$n = n_0 \times n_1 \times n_2 \ldots \times n_p \times m\f$,
+где \f$n_i = 2,3,5,7\f$, а \f$m \f$ --
+произвольный простой множитель не превосходящий 46340. \n
+Таким образом алгоритм БПФ поддерживает произвольные длины, равные целой
+степени чисел 2,3,5,7, а также различные их комбинации. \n
+Так например, при \f$ n = 725760 \f$ структура будет успешно заполнена,
+потому что
+\f$725760 = 2 \cdot 3 \cdot 4 \cdot 5 \cdot 6 \cdot 7 \cdot 9 \cdot 16 \f$,
+т.е. получается как произведение множителей 2,3,5,7. \n
+При \f$ n = 172804 = 43201 \cdot 4 \f$ структура также будет успешно заполнена,
+потому что простой множитель входящий в \f$n\f$ не превосходит 46340. \n
+Для размера \f$ n = 13 \cdot 17 \cdot 23 \cdot 13 = 66079 \f$
+функция вернет ошибку, поскольку 66079 больше 46340 и не является результатом
+произведения чисел 2,3,5,7. \n \n
+
+\return
+`RES_OK` если структура заполнена успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n \n
+
+\note
+Некоторые компиляторы при создании структуры не обнуляют ее содержимое.
+Поэтому рекомендуется произвести обнуление структуры после ее объявления:
+\code{.cpp}
+fft_t pfft = {0}; // объявляем объект fft_t
+int n = 64; // Размер БПФ
+
+int err;
+
+// создаем объект для 64-точечного БПФ
+
+err = fft_create(&pfft, n);
+
+// ...................................
+
+// очистить память объекта БПФ
+
+fft_free(&pfft);
+\endcode
+
+Перед выходом из программы выделенную в структуре память
+необходимо очистить функцией \ref fft_free . \n \n
+
+\note
+Магия числа 46340 заключается в том, что \f$\sqrt{2^{31}} = 46340.95\f$. \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
+int DSPL_API fft_create(fft_t* pfft, int n)
+{
+
+ int n1, n2, addr, s, k, m, nw, err;
+ double phi;
+ s = n;
+ nw = addr = 0;
+
+ if(pfft->n == n)
+ return RES_OK;
+
+ while(s > 1)
+ {
+ n2 = 1;
+ if(s%16== 0) { n2 = 16; goto label_size; }
+ if(s%7 == 0) { n2 = 7; goto label_size; }
+ if(s%8 == 0) { n2 = 8; goto label_size; }
+ if(s%5 == 0) { n2 = 5; goto label_size; }
+ if(s%4 == 0) { n2 = 4; goto label_size; }
+ if(s%3 == 0) { n2 = 3; goto label_size; }
+ if(s%2 == 0) { n2 = 2; goto label_size; }
+
+
+label_size:
+ if(n2 == 1)
+ {
+ if(s > FFT_COMPOSITE_MAX)
+ {
+ err = ERROR_FFT_SIZE;
+ goto error_proc;
+ }
+
+ nw += s;
+ pfft->w = pfft->w ?
+ (complex_t*) realloc(pfft->w, nw*sizeof(complex_t)):
+ (complex_t*) malloc( nw*sizeof(complex_t));
+ for(k = 0; k < s; k++)
+ {
+ phi = - M_2PI * (double)k / (double)s;
+ RE(pfft->w[addr]) = cos(phi);
+ IM(pfft->w[addr]) = sin(phi);
+ addr++;
+ }
+ s = 1;
+ }
+ else
+ {
+ n1 = s / n2;
+ nw += s;
+ pfft->w = pfft->w ?
+ (complex_t*) realloc(pfft->w, nw*sizeof(complex_t)):
+ (complex_t*) malloc( nw*sizeof(complex_t));
+
+ for(k = 0; k < n1; k++)
+ {
+ for(m = 0; m < n2; m++)
+ {
+ phi = - M_2PI * (double)(k*m) / (double)s;
+ RE(pfft->w[addr]) = cos(phi);
+ IM(pfft->w[addr]) = sin(phi);
+ addr++;
+ }
+ }
+ }
+ s /= n2;
+ }
+
+ pfft->t0 = pfft->t0 ? (complex_t*) realloc(pfft->t0, n*sizeof(complex_t)):
+ (complex_t*) malloc( n*sizeof(complex_t));
+
+ pfft->t1 = pfft->t1 ? (complex_t*) realloc(pfft->t1, n*sizeof(complex_t)):
+ (complex_t*) malloc( n*sizeof(complex_t));
+ pfft->n = n;
+
+ return RES_OK;
error_proc:
- if(pfft->t0) free(pfft->t0);
- if(pfft->t1) free(pfft->t1);
- if(pfft->w) free(pfft->w);
- pfft->n = 0;
- return err;
+ if(pfft->t0) free(pfft->t0);
+ if(pfft->t1) free(pfft->t1);
+ if(pfft->w) free(pfft->w);
+ pfft->n = 0;
+ return err;
}
-/*******************************************************************************
-FFT free
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn void fft_free(fft_t *pfft)
+\brief Free `fft_t` structure.
+
+The function clears the intermediate data memory
+and vectors of FFT twiddle factors of the structure `fft_t`.
+
+\param[in] pfft
+Pointer to the `fft_t` object. \n
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn void fft_free(fft_t *pfft)
+\brief Очистить структуру `fft_t` алгоритма БПФ
+
+Функция производит очищение памяти промежуточных данных
+и векторов поворотных коэффициентов структуры `fft_t`.
+
+\param[in] pfft
+Указатель на структуру `fft_t`. \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
void DSPL_API fft_free(fft_t *pfft)
{
- if(!pfft)
- return;
- if(pfft->w)
- free(pfft->w);
- if(pfft->t0)
- free(pfft->t0);
- if(pfft->t1)
- free(pfft->t1);
- memset(pfft, 0, sizeof(fft_t));
+ if(!pfft)
+ return;
+ if(pfft->w)
+ free(pfft->w);
+ if(pfft->t0)
+ free(pfft->t0);
+ if(pfft->t1)
+ free(pfft->t1);
+ memset(pfft, 0, sizeof(fft_t));
}
-/*******************************************************************************
-FFT magnitude for the real signal
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
int DSPL_API fft_mag(double* x, int n, fft_t* pfft,
double fs, int flag,
double* mag, double* freq)
{
- int k, err = RES_OK;
- complex_t *X = NULL;
-
- if(!x || !pfft)
- return ERROR_PTR;
-
- if(n<1)
- return ERROR_SIZE;
-
- if(mag)
- {
- X = (complex_t*)malloc(n*sizeof(complex_t));
- err = fft(x, n, pfft, X);
- if(err!=RES_OK)
- goto error_proc;
+ int k, err = RES_OK;
+ complex_t *X = NULL;
- if(flag & DSPL_FLAG_LOGMAG)
- for(k = 0; k < n; k++)
- mag[k] = 10.0*log10(ABSSQR(X[k]));
- else
- for(k = 0; k < n; k++)
- mag[k] = ABS(X[k]);
- if(flag & DSPL_FLAG_FFT_SHIFT)
- {
- err = fft_shift(mag, n, mag);
- if(err!=RES_OK)
- goto error_proc;
+ if(!x || !pfft)
+ return ERROR_PTR;
+
+ if(n<1)
+ return ERROR_SIZE;
+
+ if(mag)
+ {
+ X = (complex_t*)malloc(n*sizeof(complex_t));
+ err = fft(x, n, pfft, X);
+ if(err!=RES_OK)
+ goto error_proc;
+
+ if(flag & DSPL_FLAG_LOGMAG)
+ for(k = 0; k < n; k++)
+ mag[k] = 10.0*log10(ABSSQR(X[k]));
+ else
+ for(k = 0; k < n; k++)
+ mag[k] = ABS(X[k]);
+ if(flag & DSPL_FLAG_FFT_SHIFT)
+ {
+ err = fft_shift(mag, n, mag);
+ if(err!=RES_OK)
+ goto error_proc;
+ }
}
- }
-
- if(freq)
- {
- if(flag & DSPL_FLAG_FFT_SHIFT)
- if(n%2)
- err = linspace(-fs*0.5 + fs*0.5/(double)n,
- fs*0.5 - fs*0.5/(double)n,
- n, DSPL_SYMMETRIC, freq);
- else
- err = linspace(-fs*0.5, fs*0.5, n, DSPL_PERIODIC, freq);
- else
- err = linspace(0, fs, n, DSPL_PERIODIC, freq);
- }
-
-error_proc:
- if(X)
- free(X);
- return err;
+ if(freq)
+ {
+ if(flag & DSPL_FLAG_FFT_SHIFT)
+ if(n%2)
+ err = linspace(-fs*0.5 + fs*0.5/(double)n,
+ fs*0.5 - fs*0.5/(double)n,
+ n, DSPL_SYMMETRIC, freq);
+ else
+ err = linspace(-fs*0.5, fs*0.5, n, DSPL_PERIODIC, freq);
+ else
+ err = linspace(0, fs, n, DSPL_PERIODIC, freq);
+ }
+
+error_proc:
+ if(X)
+ free(X);
+
+ return err;
}
@@ -377,148 +969,214 @@ error_proc:
-/*******************************************************************************
-FFT magnitude for the complex signal
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
int DSPL_API fft_mag_cmplx(complex_t* x, int n, fft_t* pfft,
double fs, int flag,
double* mag, double* freq)
{
- int k, err = RES_OK;
- complex_t *X = NULL;
-
- if(!x || !pfft)
- return ERROR_PTR;
-
- if(n<1)
- return ERROR_SIZE;
-
- if(mag)
- {
- X = (complex_t*)malloc(n*sizeof(complex_t));
- err = fft_cmplx(x, n, pfft, X);
- if(err!=RES_OK)
- goto error_proc;
+ int k, err = RES_OK;
+ complex_t *X = NULL;
- if(flag & DSPL_FLAG_LOGMAG)
- for(k = 0; k < n; k++)
- mag[k] = 10.0*log10(ABSSQR(X[k]));
- else
- for(k = 0; k < n; k++)
- mag[k] = ABS(X[k]);
- if(flag & DSPL_FLAG_FFT_SHIFT)
- {
- err = fft_shift(mag, n, mag);
- if(err!=RES_OK)
- goto error_proc;
+ if(!x || !pfft)
+ return ERROR_PTR;
+
+ if(n<1)
+ return ERROR_SIZE;
+
+ if(mag)
+ {
+ X = (complex_t*)malloc(n*sizeof(complex_t));
+ err = fft_cmplx(x, n, pfft, X);
+ if(err!=RES_OK)
+ goto error_proc;
+
+ if(flag & DSPL_FLAG_LOGMAG)
+ for(k = 0; k < n; k++)
+ mag[k] = 10.0*log10(ABSSQR(X[k]));
+ else
+ for(k = 0; k < n; k++)
+ mag[k] = ABS(X[k]);
+ if(flag & DSPL_FLAG_FFT_SHIFT)
+ {
+ err = fft_shift(mag, n, mag);
+ if(err!=RES_OK)
+ goto error_proc;
+ }
}
- }
-
- if(freq)
- {
- if(flag & DSPL_FLAG_FFT_SHIFT)
- if(n%2)
- err = linspace(-fs*0.5 + fs*0.5/(double)n,
- fs*0.5 - fs*0.5/(double)n,
- n, DSPL_SYMMETRIC, freq);
- else
- err = linspace(-fs*0.5, fs*0.5, n, DSPL_PERIODIC, freq);
- else
- err = linspace(0, fs, n, DSPL_PERIODIC, freq);
- }
-error_proc:
- if(X)
- free(X);
- return err;
+ if(freq)
+ {
+ if(flag & DSPL_FLAG_FFT_SHIFT)
+ if(n%2)
+ err = linspace(-fs*0.5 + fs*0.5/(double)n,
+ fs*0.5 - fs*0.5/(double)n,
+ n, DSPL_SYMMETRIC, freq);
+ else
+ err = linspace(-fs*0.5, fs*0.5, n, DSPL_PERIODIC, freq);
+ else
+ err = linspace(0, fs, n, DSPL_PERIODIC, freq);
+ }
+error_proc:
+ if(X)
+ free(X);
+
+ return err;
}
-/*******************************************************************************
-FFT shifting
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft_shift(double* x, int n, double* y)
+\brief Perform a shift of the vector `x`, for use with the `fft` and `ifft`
+functions, in order
+
+ to move the frequency 0 to the center
+ of the vector `y`.
+
+\param[in] x
+Pointer to the input vector (FFT or IFFT result). \n
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Input and output vector size. \n \n
+
+\param[out] y
+Pointer to the output vector with frequency 0 in the center. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+
+\return
+`RES_OK` if function is calculated successfully. \n
+Else \ref ERROR_CODE_GROUP "code error".
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\fn int fft_shift(double* x, int n, double* y)
+\brief Перестановка спектральных отсчетов дискретного преобразования Фурье
+
+Функция производит
+
+перестановку спектральных отсчетов ДПФ
+ и переносит нулевую частоту в центр вектора ДПФ. \n
+Данная функция обрабатывает вещественные входные и выходные вектора
+и может применяться для перестановки
+амплитудного или фазового спектра.
+
+\param[in] x
+Указатель на исходный вектор ДПФ. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер ДПФ \f$n\f$ (размер векторов до и после перестановки). \n \n
+
+\param[out] y
+Указатель на вектор результата перестановки. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если перестановка произведена успешно. \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
+
+\author Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API fft_shift(double* x, int n, double* y)
{
- int n2, r;
- int k;
- double tmp;
- double *buf;
+ int n2, r;
+ int k;
+ double tmp;
+ double *buf;
- if(!x || !y)
- return ERROR_PTR;
+ if(!x || !y)
+ return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
+ if(n<1)
+ return ERROR_SIZE;
- r = n%2;
- if(!r)
- {
- n2 = n>>1;
- for(k = 0; k < n2; k++)
+ r = n%2;
+ if(!r)
{
- tmp = x[k];
- y[k] = x[k+n2];
- y[k+n2] = tmp;
+ n2 = n>>1;
+ for(k = 0; k < n2; k++)
+ {
+ tmp = x[k];
+ y[k] = x[k+n2];
+ y[k+n2] = tmp;
+ }
}
- }
- else
- {
- n2 = (n+1) >> 1;
- buf = (double*) malloc(n2*sizeof(double));
- memcpy(buf, x, n2*sizeof(double));
- memcpy(y, x+n2, (n2-1)*sizeof(double));
- memcpy(y+n2-1, buf, n2*sizeof(double));
- free(buf);
- }
- return RES_OK;
+ else
+ {
+ n2 = (n+1) >> 1;
+ buf = (double*) malloc(n2*sizeof(double));
+ memcpy(buf, x, n2*sizeof(double));
+ memcpy(y, x+n2, (n2-1)*sizeof(double));
+ memcpy(y+n2-1, buf, n2*sizeof(double));
+ free(buf);
+ }
+ return RES_OK;
}
-/*******************************************************************************
-FFT shifting for complex vector
-*******************************************************************************/
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
int DSPL_API fft_shift_cmplx(complex_t* x, int n, complex_t* y)
{
- int n2, r;
- int k;
- complex_t tmp;
- complex_t *buf;
+ int n2, r;
+ int k;
+ complex_t tmp;
+ complex_t *buf;
- if(!x || !y)
- return ERROR_PTR;
+ if(!x || !y)
+ return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
+ if(n<1)
+ return ERROR_SIZE;
- r = n%2;
- if(!r)
- {
- n2 = n>>1;
- for(k = 0; k < n2; k++)
+ r = n%2;
+ if(!r)
{
- RE(tmp) = RE(x[k]);
- IM(tmp) = IM(x[k]);
+ n2 = n>>1;
+ for(k = 0; k < n2; k++)
+ {
+ RE(tmp) = RE(x[k]);
+ IM(tmp) = IM(x[k]);
- RE(y[k]) = RE(x[k+n2]);
- IM(y[k]) = IM(x[k+n2]);
+ RE(y[k]) = RE(x[k+n2]);
+ IM(y[k]) = IM(x[k+n2]);
- RE(y[k+n2]) = RE(tmp);
- IM(y[k+n2]) = IM(tmp);
+ RE(y[k+n2]) = RE(tmp);
+ IM(y[k+n2]) = IM(tmp);
+ }
}
- }
- else
- {
- n2 = (n+1) >> 1;
- buf = (complex_t*) malloc(n2*sizeof(complex_t));
- memcpy(buf, x, n2*sizeof(complex_t));
- memcpy(y, x+n2, (n2-1)*sizeof(complex_t));
- memcpy(y+n2-1, buf, n2*sizeof(complex_t));
- free(buf);
- }
- return RES_OK;
+ else
+ {
+ n2 = (n+1) >> 1;
+ buf = (complex_t*) malloc(n2*sizeof(complex_t));
+ memcpy(buf, x, n2*sizeof(complex_t));
+ memcpy(y, x+n2, (n2-1)*sizeof(complex_t));
+ memcpy(y+n2-1, buf, n2*sizeof(complex_t));
+ free(buf);
+ }
+ return RES_OK;
}
diff --git a/dspl/src/filter_an.c b/dspl/src/filter_an.c
index 7656352..9fc9b70 100644
--- a/dspl/src/filter_an.c
+++ b/dspl/src/filter_an.c
@@ -5,17 +5,17 @@
* 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
+* 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
+* 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 .
+* along with Foobar. If not, see .
*/
@@ -28,491 +28,834 @@
-/******************************************************************************
-Magnitude, phase response and group delay of a digital filter H(z) or
-analog filter H(s)
-*******************************************************************************/
+#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;
+ int res, k, flag_analog;
- complex_t *hc = NULL;
- double *phi0 = NULL;
- double *phi1 = NULL;
- double *w0 = NULL;
- double *w1 = NULL;
+ 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;
+ 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;
+ 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(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)
+ if(res != RES_OK)
goto exit_label;
- }
- }
- if(tau)
- {
- phi0 = (double*) malloc(n*sizeof(double));
- phi1 = (double*) malloc(n*sizeof(double));
- w0 = (double*) malloc(n*sizeof(double));
- w1 = (double*) malloc(n*sizeof(double));
-
- w0[0] = w[0] - (w[1] - w[0])*0.02;
- w1[0] = w[0] + (w[1] - w[0])*0.02;
-
- for(k = 1; k < n; k++)
+ if(mag)
{
- w0[k] = w[k] - (w[k] - w[k-1])*0.02;
- w1[k] = w[k] + (w[k] - w[k-1])*0.02;
+ 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)
+ {
+ phi0 = (double*) malloc(n*sizeof(double));
+ phi1 = (double*) malloc(n*sizeof(double));
+ w0 = (double*) malloc(n*sizeof(double));
+ w1 = (double*) malloc(n*sizeof(double));
+
+ w0[0] = w[0] - (w[1] - w[0])*0.02;
+ w1[0] = w[0] + (w[1] - w[0])*0.02;
+
+ for(k = 1; k < n; k++)
+ {
+ w0[k] = w[k] - (w[k] - w[k-1])*0.02;
+ w1[k] = w[k] + (w[k] - w[k-1])*0.02;
+ }
+ res = filter_freq_resp(b, a, ord, w0, n,
+ DSPL_FLAG_UNWRAP | flag_analog,
+ NULL, phi0, NULL);
+ if(res != RES_OK)
+ goto exit_label;
+ res = filter_freq_resp(b, a, ord, w1, n,
+ DSPL_FLAG_UNWRAP | flag_analog,
+ NULL, phi1, NULL);
+ if(res != RES_OK)
+ goto exit_label;
+
+ for(k = 0; k < n; k++)
+ tau[k] = (phi0[k] - phi1[k])/(w1[k] - w0[k]);
}
- res = filter_freq_resp(b, a, ord, w0, n,
- DSPL_FLAG_UNWRAP | flag_analog, NULL, phi0, NULL);
- if(res != RES_OK)
- goto exit_label;
- res = filter_freq_resp(b, a, ord, w1, n,
- DSPL_FLAG_UNWRAP | flag_analog, NULL, phi1, NULL);
- if(res != RES_OK)
- goto exit_label;
- for(k = 0; k < n; k++)
- tau[k] = (phi0[k] - phi1[k])/(w1[k] - w0[k]);
- }
exit_label:
- if(hc)
- free(hc);
- if(phi0)
- free(phi0);
- if(phi1)
- free(phi1);
- if(w0)
- free(w0);
- if(w1)
- free(w1);
- return res;
+ if(hc)
+ free(hc);
+ if(phi0)
+ free(phi0);
+ if(phi1)
+ free(phi1);
+ if(w0)
+ free(w0);
+ if(w1)
+ free(w1);
+ return res;
}
-/******************************************************************************
-Complex frequency response of an analog filter H(s)
-*******************************************************************************/
+#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;
+ 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;
+ 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;
+ RE(jw) = 0.0;
- bc = (complex_t*) malloc((ord+1) * sizeof(complex_t));
- res = re2cmplx(b, ord+1, bc);
+ 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;
-}
-
-
-
-
-
-
-/******************************************************************************
- * Complex frequency response of an analog filter H(s), s is complex variable
- ******************************************************************************/
-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;
-}
-
-
-
-
-
-
-
-/******************************************************************************
-impulse response of an analog filter H(s)
-*******************************************************************************/
-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;
-}
-
-
-
-
-
-
-/******************************************************************************
-Magnitude, phase response and group delay of an analog filter H(s)
-
-int DSPL_API freqs_resp(double* b, double* a, int ord,
- double* w, int n, int flag,
- double *h, double* phi, double* tau)
-{
- int res, k;
-
- complex_t *hc = NULL;
- double *phi0 = NULL;
- double *phi1 = NULL;
- double *w0 = NULL;
- double *w1 = NULL;
-
- if(!b || !a || !w)
- return ERROR_PTR;
- if(ord < 1)
- return ERROR_FILTER_ORD;
- if(n < 1)
- return ERROR_SIZE;
-
-
- hc = (complex_t*) malloc (n*sizeof(complex_t));
- res = freqs(b, a, ord, w, n, hc);
- if(res != RES_OK)
- goto exit_label;
-
-
- if(h)
- {
- if(flag & DSPL_FLAG_LOG)
- {
- for(k = 0; k < n; k++)
- h[k] = 10.0 * log10(ABSSQR(hc[k]));
- }
- else
- {
- for(k = 0; k < n; k++)
- h[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)
+ if( res!=RES_OK )
goto exit_label;
- }
- }
-
- if(tau)
- {
- phi0 = (double*) malloc(n*sizeof(double));
- phi1 = (double*) malloc(n*sizeof(double));
- w0 = (double*) malloc(n*sizeof(double));
- w1 = (double*) malloc(n*sizeof(double));
-
- w0[0] = w[0] - (w[1] - w[0])*0.02;
- w1[0] = w[0] + (w[1] - w[0])*0.02;
-
- for(k = 1; k < n; k++)
- {
- w0[k] = w[k] - (w[k] - w[k-1])*0.02;
- w1[k] = w[k] + (w[k] - w[k-1])*0.02;
- }
- res = freqs_resp(b, a, ord, w0, n, DSPL_FLAG_UNWRAP, NULL, phi0, NULL);
- if(res != RES_OK)
- goto exit_label;
- res = freqs_resp(b, a, ord, w1, n, DSPL_FLAG_UNWRAP, NULL, phi1, NULL);
- if(res != RES_OK)
- goto exit_label;
- for(k = 0; k < n; k++)
- tau[k] = (phi0[k] - phi1[k])/(w1[k] - w0[k]);
- }
-
-
-exit_label:
- if(hc)
- free(hc);
- if(phi0)
- free(phi0);
- if(phi1)
- free(phi1);
- if(w0)
- free(w0);
- if(w1)
- free(w1);
- return res;
-}
-
-*******************************************************************************/
-
-
-
-
-
-
-
-
-/*******************************************************************************
-Complex frequency response of a digital filter H(z)
-*******************************************************************************/
-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;
+ 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;
+ 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;
}
- }
- 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;
+ res = RES_OK;
exit_label:
- if(bc)
- free(bc);
- if(ac)
- free(ac);
- return res;
+ if(bc)
+ free(bc);
+ if(ac)
+ free(ac);
+ return res;
+}
+
+
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API freqs_cmplx(double* b, double* a, int ord,
+ complex_t* s, int n, complex_t *h)
+{
+ complex_t *bc = NULL;
+ complex_t *ac = NULL;
+ complex_t num, den;
+ double mag;
+ int k;
+ int res;
+
+ if(!b || !a || !s || !h)
+ return ERROR_PTR;
+ if(ord<0)
+ return ERROR_FILTER_ORD;
+ if(n<1)
+ return ERROR_SIZE;
+
+
+ bc = (complex_t*) malloc((ord+1) * sizeof(complex_t));
+ res = re2cmplx(b, ord+1, bc);
+
+ if( res!=RES_OK )
+ goto exit_label;
+
+ ac = (complex_t*) malloc((ord+1) * sizeof(complex_t));
+ res = re2cmplx(a, ord+1, ac);
+ if( res!=RES_OK )
+ goto exit_label;
+
+ for(k = 0; k < n; k++)
+ {
+ res = polyval_cmplx(bc, ord, s+k, 1, &num);
+ if(res != RES_OK)
+ goto exit_label;
+ res = polyval_cmplx(ac, ord, s+k, 1, &den);
+ if(res != RES_OK)
+ goto exit_label;
+ mag = ABSSQR(den);
+ if(mag == 0.0)
+ {
+ res = ERROR_DIV_ZERO;
+ goto exit_label;
+ }
+ mag = 1.0 / mag;
+ RE(h[k]) = CMCONJRE(num, den) * mag;
+ IM(h[k]) = CMCONJIM(num, den) * mag;
+
+ }
+ res = RES_OK;
+ exit_label:
+ if(bc)
+ free(bc);
+ if(ac)
+ free(ac);
+ return res;
+}
+
+
+
+
+
+
+
+#ifdef DOXYGEN_ENGLISH
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+
+#endif
+int DSPL_API freqs2time(double* b, double* a, int ord, double fs,
+ int n, fft_t* pfft, double *t, double *h)
+{
+ double *w = NULL;
+ complex_t *hs = NULL;
+ complex_t *ht = NULL;
+ int err, k;
+
+ if(!b || !a || !t || !h)
+ return ERROR_PTR;
+ if(ord<1)
+ return ERROR_FILTER_ORD;
+ if(n<1)
+ return ERROR_SIZE;
+
+ w = (double*)malloc(n*sizeof(double));
+ hs = (complex_t*)malloc(n*sizeof(complex_t));
+
+
+ err = linspace(-fs*0.5, fs*0.5, n, DSPL_PERIODIC, w);
+ if(err != RES_OK)
+ goto exit_label;
+
+ err = freqs(b, a, ord, w, n, hs);
+ if(err != RES_OK)
+ goto exit_label;
+
+ err = fft_shift_cmplx(hs, n, hs);
+ if(err != RES_OK)
+ goto exit_label;
+
+ ht = (complex_t*)malloc(n*sizeof(complex_t));
+
+ err = ifft_cmplx(hs, n, pfft, ht);
+ if(err != RES_OK)
+ {
+ err = idft_cmplx(hs, n, ht);
+ if(err != RES_OK)
+ goto exit_label;
+ }
+
+ for(k = 0; k < n; k++)
+ {
+ t[k] = (double)k/fs;
+ h[k] = RE(ht[k]) * fs;
+ }
+
+exit_label:
+ if(w)
+ free(w);
+ if(hs)
+ free(hs);
+ if(ht)
+ free(ht);
+ return err;
+}
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup FILTER_ANALYSIS_GROUP
+\fn int freqz(double* b, double* a, int ord, double* w, int n, complex_t *h)
+
+\brief Function calculates the digital filter frequency response
+\f$ H \left(e^{j \omega} \right)\f$ corresponds to transfer function \f$H(z)\f$.
+
+Digital filter transfer function:
+\f[
+H(z) = \frac{\sum\limits_{k = 0}^{N} b_k z^{-k}}
+ {\sum\limits_{m = 0}^{N} a_m z^{-m}},
+\f]
+here \f$N\f$ --- filter order (parameter `ord`). \n
+
+Frequency response \f$ H \left(e^{j \omega} \right)\f$ we can get
+if substitute \f$z = e^{j \omega} \f$. \n
+
+\param[in] b
+Pointer to the \f$ H(z) \f$ transfer function
+numerator coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n \n
+
+\param[in] a
+Pointer to the \f$H(z)\f$ transfer function
+denominator coefficients vector. \n
+Vector size is `[ord+1 x 1]`. \n \n
+
+\param[in] ord
+Filter order. \n
+Transfer function \f$H(z)\f$ numerator
+and denominator coefficients number equals `ord+1`. \n \n
+
+\param[in] w
+Pointer to the normalized frequency of digital filter
+frequency response \f$ H \left(\mathrm{e}^{j\omega} \right) \f$. \n
+Digital filter frequency response is \f$ 2\pi \f$-periodic function,
+and vector `w` advisable to set from 0 to \f$ \pi \f$,
+or from 0 to \f$ 2\pi \f$, or from \f$ -\pi \f$ to \f$ \pi \f$.
+Vector size is `[n x 1]`. \n \n
+
+\param[in] n
+Size of frequency vector `w`. \n \n
+
+\param[out] h
+Pointer to the frequency response vector
+\f$ H \left(\mathrm{e}^{j\omega} \right) \f$,
+corresponds to normalized frequency `w`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n \n
+
+\return `RES_OK` if frequaency 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;
}
@@ -522,50 +865,52 @@ exit_label:
-/*******************************************************************************
-Unwrap function
-*******************************************************************************/
+#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;
+ double a[2] = {0.0, 0.0};
+ double d;
+ double th;
+ int k;
+ int flag = 1;
+ if(!phi)
+ return ERROR_PTR;
- if(!phi)
- return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
- if(n<1)
- return ERROR_SIZE;
+ if(lev<=0 || mar <=0)
+ return ERROR_UNWRAP;
- if(lev<=0 || mar <=0)
- return ERROR_UNWRAP;
-
- th = mar*lev;
- while(flag)
- {
- flag = 0;
- a[0] = a[1] = 0.0;
- for(k = 0; k th)
- {
- a[0] -= lev;
- flag = 1;
- }
- if( d < -th)
- {
- a[0] += lev;
- flag = 1;
- }
- phi[k]+=a[1];
- a[1] = a[0];
+ flag = 0;
+ a[0] = a[1] = 0.0;
+ for(k = 0; k th)
+ {
+ a[0] -= lev;
+ flag = 1;
+ }
+ if( d < -th)
+ {
+ a[0] += lev;
+ flag = 1;
+ }
+ phi[k]+=a[1];
+ a[1] = a[0];
+ }
+ phi[n-1]+=a[1];
}
- phi[n-1]+=a[1];
- }
return RES_OK;
}
diff --git a/dspl/src/filter_ap.c b/dspl/src/filter_ap.c
index 8be290d..b3c9c14 100644
--- a/dspl/src/filter_ap.c
+++ b/dspl/src/filter_ap.c
@@ -5,17 +5,17 @@
* 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
+* 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
+* 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 .
+* along with Foobar. If not, see .
*/
#include
@@ -32,39 +32,39 @@ Analog Normalized Butterworth filter
*******************************************************************************/
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;
+ 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;
+ 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));
+ 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 = 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;
+ res = filter_zp2ab(z, nz, p, np, ord, b, a);
+ if(res != RES_OK)
+ goto exit_label;
- b[0] = a[0];
+ b[0] = a[0];
exit_label:
- if(z)
- free(z);
- if(p)
- free(p);
- return res;
+ if(z)
+ free(z);
+ if(p)
+ free(p);
+ return res;
}
@@ -80,42 +80,42 @@ Analog Normalized Butterworth filter zeros and poles
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;
+ 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;
+ 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);
+ 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;
+ 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;
}
@@ -128,52 +128,52 @@ Analog Normalized Chebyshev type 1 filter
*******************************************************************************/
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;
+ 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;
+ 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));
+ 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 = 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;
+ 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);
+ 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;
- }
+ 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));
+ b[0] = fabs(RE(h0));
exit_label:
- if(z)
- free(z);
- if(p)
- free(p);
- return res;
+ if(z)
+ free(z);
+ if(p)
+ free(p);
+ return res;
}
@@ -184,50 +184,50 @@ exit_label:
Analog Normalized Chebyshev type 1 filter zeros and poles
*******************************************************************************/
int DSPL_API cheby1_ap_zp(int ord, double rp, complex_t* z, int* nz,
- complex_t *p, int* np)
+ complex_t* p, int* np)
{
- double theta;
- double ep;
- double beta;
- double shbeta;
- double chbeta;
- int r;
- int L;
- int ind = 0, k;
+ 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;
+ 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);
+ 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);
+ 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;
+ 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;
}
@@ -238,43 +238,43 @@ int DSPL_API cheby1_ap_zp(int ord, double rp, complex_t* z, int* nz,
******************************************************************************/
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;
+ 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;
+ 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));
+ 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 = 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;
+ res = filter_zp2ab(z, nz, p, np, ord, b, a);
+ if(res != RES_OK)
+ goto exit_label;
- norm = a[0] / b[0];
+ norm = a[0] / b[0];
- for(nz = 0; nz < ord+1; nz++)
- b[nz]*=norm;
+ for(nz = 0; nz < ord+1; nz++)
+ b[nz]*=norm;
exit_label:
- if(z)
- free(z);
- if(p)
- free(p);
- return res;
+ if(z)
+ free(z);
+ if(p)
+ free(p);
+ return res;
}
@@ -285,27 +285,27 @@ exit_label:
******************************************************************************/
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;
+ int err;
+ double es, gp, alpha, beta, y, wp;
- if(rp <= 0)
- return ERROR_FILTER_RP;
+ if(rp <= 0)
+ return ERROR_FILTER_RP;
- err = cheby2_ap(rs, ord, b, a);
- if(err!=RES_OK)
- goto exit_label;
+ 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);
+ 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;
+ return err;
}
@@ -315,67 +315,67 @@ exit_label:
Analog Normalized Chebyshev type 2 filter zeros and poles
*******************************************************************************/
int DSPL_API cheby2_ap_zp(int ord, double rs, complex_t* z, int* nz,
- complex_t *p, int* np)
+ complex_t *p, int* np)
{
- double es;
- int L, r, k;
- double beta;
- int iz, ip;
+ double es;
+ int L, r, k;
+ double beta;
+ int iz, ip;
- double alpha;
- double chb, shb, sa, ca;
- double ssh2, cch2;
+ 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;
+ 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);
+ es = sqrt(pow(10.0, rs*0.1) - 1.0);
+ r = ord % 2;
+ L = (int)((ord-r)/2);
- beta = asinh(es)/(double)ord;
+ beta = asinh(es)/(double)ord;
- chb = cosh(beta);
- shb = sinh(beta);
+ chb = cosh(beta);
+ shb = sinh(beta);
- iz = ip = 0;
+ iz = ip = 0;
- if(r)
- {
- RE(p[0]) = -1.0 / sinh(beta);
- IM(p[0]) = 0.0;
- ip = 1;
- }
+ 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;
+ 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;
+ 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(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;
+ 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;
+ return RES_OK;
}
@@ -389,53 +389,53 @@ int DSPL_API cheby2_ap_zp(int ord, double rs, complex_t* z, int* nz,
*******************************************************************************/
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;
+ 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;
+ 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));
+ 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 = 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;
+ 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);
- }
+ g0 = 1.0;
+ if(!(ord % 2))
+ {
+ g0 = 1.0 / pow(10.0, rp*0.05);
+ }
- norm = g0 * a[0] / b[0];
+ norm = g0 * a[0] / b[0];
- for(nz = 0; nz < ord+1; nz++)
- b[nz]*=norm;
+ for(nz = 0; nz < ord+1; nz++)
+ b[nz]*=norm;
- exit_label:
- if(z)
- free(z);
- if(p)
- free(p);
- return res;
+ exit_label:
+ if(z)
+ free(z);
+ if(p)
+ free(p);
+ return res;
}
@@ -447,94 +447,94 @@ int DSPL_API ellip_ap(double rp, double rs, int ord, double* b, double* a)
A *nalog Normalized Chebyshev type 2 filter zeros and poles
*******************************************************************************/
int DSPL_API ellip_ap_zp(int ord, double rp, double rs,
- complex_t* z, int* nz, complex_t* p, int* np)
+ 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;
+ 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;
+ 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;
+ 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);
+ 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);
+ res = ellip_modulareq(rp, rs, ord, &k);
if(res != RES_OK)
- return res;
- RE(p[0]) = -IM(tc);
- IM(p[0]) = RE(tc);
- ip = 1;
- }
+ return res;
+ // v0
+ RE(tc) = 0.0;
+ IM(tc) = 1.0 / ep;
- for(n = 0; n < L; n++)
- {
- u = (double)(2 * n + 1)/(double)ord;
+ ellip_asn_cmplx(&tc, 1, ke, &v0);
- res = ellip_cd(& u, 1, k, &t);
- if(res != RES_OK)
- return res;
+ t = RE(v0);
+ RE(v0) = IM(v0) / (double)ord;
+ IM(v0) = -t / (double)ord;
- 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;
+ RE(jv0) = -IM(v0);
+ IM(jv0) = RE(v0);
- }
- *nz = iz;
- *np = ip;
+ iz = ip = 0;
- return RES_OK;
+ 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;
}
@@ -544,41 +544,41 @@ int DSPL_API ellip_ap_zp(int ord, double rp, double rs,
Zeros and poles to filter coefficients recalc
*******************************************************************************/
int DSPL_API filter_zp2ab(complex_t* z, int nz, complex_t* p, int np,
- int ord, double* b, double* a)
+ int ord, double* b, double* a)
{
- complex_t *acc = NULL;
- int res;
+ 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;
+ 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;
+ 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 = 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 = 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;
+ res = cmplx2re(acc, ord+1, a, NULL);
+ if(res != RES_OK)
+ goto exit_label;
exit_label:
- if(acc)
- free(acc);
- return res;
+ if(acc)
+ free(acc);
+ return res;
}
diff --git a/dspl/src/math.c b/dspl/src/math.c
index 925b3af..0e00b52 100644
--- a/dspl/src/math.c
+++ b/dspl/src/math.c
@@ -11,11 +11,11 @@
*
* 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
+* 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 .
+* along with Foobar. If not, see .
*/
@@ -26,48 +26,54 @@
-
-/******************************************************************************
+#if DOXYGEN_ENGLISH
+/*! ****************************************************************************
\ingroup SPEC_MATH_TRIG_GROUP
\fn int acos_cmplx(complex_t* x, int n, complex_t *y)
-\brief The inverse of the cosine function the complex vector argument `x`
+\brief The inverse of the cosine function the complex vector argument `x`
Function calculates the inverse of the cosine function as: \n
\f[
\textrm{Arccos}(x) = \frac{\pi}{2} - \textrm{Arcsin}(x) =
\frac{\pi}{2} -j \textrm{Ln}\left( j x + \sqrt{1 - x^2} \right)
-\f]
+\f]
-\param[in] x Pointer to the argument vector `x`. \n
- Vector size is `[n x 1]`. \n \n
+\param[in] x
+Pointer to the argument vector `x`. \n
+Vector size is `[n x 1]`. \n
+\n
-\param[in] n Input vector `x` and the inverse cosine vector `y` size. \n \n
-
+\param[in] n
+Input vector `x` and the inverse cosine vector `y` size. \n
+\n
-\param[out] y Pointer to the output complex vector `y`,
- corresponds to the input vector `x`. \n
- Vector size is `[n x 1]`. \n
- Memory must be allocated. \n \n
+
+\param[out] y
+Pointer to the output complex vector `y`,
+corresponds to the input vector `x`. \n
+Vector size is `[n x 1]`. \n
+Memory must be allocated. \n
+\n
\return
-`RES_OK` if function calculated successfully. \n
+`RES_OK` if function calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error". \n
Example: \n
\code{.cpp}
- complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
- complex_t y[3];
- int k;
-
- acos_cmplx(x, 3, y);
-
- for(k = 0; k < 3; k++)
- printf("acos_cmplx(%.1f%+.1fj) = %.3f%+.3fj\n",
- RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
+ complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
+ complex_t y[3];
+ int k;
+
+ acos_cmplx(x, 3, y);
+
+ for(k = 0; k < 3; k++)
+ printf("acos_cmplx(%.1f%+.1fj) = %.3f%+.3fj\n",
+ RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
\endcode
- \n
+\n
Output is: \n
\verbatim
@@ -78,99 +84,115 @@ acos_cmplx(5.0+6.0j) = 0.880-2.749j
\author
Sergey Bakhurin www.dsplib.org
-*******************************************************************************/
+***************************************************************************** */
+#endif
+
+#if DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup SPEC_MATH_TRIG_GROUP
+\fn int acos_cmplx(complex_t* x, int n, complex_t *y)
+\brief Арккосинус комплексного аргумента `x`
+
+Функция рассчитывает значения арккосинуса комплексного аргумента,
+заданного вектором `x` длины `n`: \n
+\f[
+\textrm{Arccos}(x) = \frac{\pi}{2} - \textrm{Arcsin}(x) =
+\frac{\pi}{2} -j \textrm{Ln}\left( j x + \sqrt{1 - x^2} \right)
+\f]
+
+
+\param[in] x
+Указатель на вектор аргумента комплексного арккосинуса. \n
+Размер вектора `[n x 1]`. \n \n
+
+\param[in] n
+Размер входного и выходного векторов `x` и `y`. \n \n
+
+
+\param[out] y
+Указатель на вектор значений комплексного арккосинуса,
+соответствующего входному вектору `x`. \n
+Размер массива `[n x 1]`. \n
+Память должна быть выделена. \n \n
+
+\return
+`RES_OK` если значение функции рассчитано успешно . \n
+В противном случае \ref ERROR_CODE_GROUP "код ошибки": \n
+
+\note
+Функция может использоваться для расчета арккосинуса аргумента
+большего единицы, когда вещественная функция `acos` не определена.
+
+Например при выполнении следующего кода
+\code{.cpp}
+ complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
+ complex_t y[3];
+ int k;
+
+ acos_cmplx(x, 3, y);
+
+ for(k = 0; k < 3; k++)
+ printf("acos_cmplx(%.1f%+.1fj) = %.3f%+.3fj\n",
+ RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
+\endcode
+\n
+
+Результатом работы будет
+
+\verbatim
+acos_cmplx(1.0+2.0j) = 1.144-1.529j
+acos_cmplx(3.0+4.0j) = 0.937-2.306j
+acos_cmplx(5.0+6.0j) = 0.880-2.749j
+\endverbatim
+
+\author
+Бахурин Сергей www.dsplib.org
+***************************************************************************** */
+#endif
int DSPL_API acos_cmplx(complex_t* x, int n, complex_t *y)
{
- int k, res;
- double pi2 = 0.5 * M_PI;
+ int k, res;
+ double pi2 = 0.5 * M_PI;
- res = asin_cmplx(x, n, y);
- if(res != RES_OK)
- return res;
+ res = asin_cmplx(x, n, y);
+ if(res != RES_OK)
+ return res;
- for(k = 0; k < n; k++)
- {
- RE(y[k]) = pi2 - RE(y[k]);
- IM(y[k]) = - IM(y[k]);
- }
- return RES_OK;
+ for(k = 0; k < n; k++)
+ {
+ RE(y[k]) = pi2 - RE(y[k]);
+ IM(y[k]) = - IM(y[k]);
+ }
+ return RES_OK;
}
/******************************************************************************
-\ingroup SPEC_MATH_TRIG_GROUP
-\fn int asin_cmplx(complex_t* x, int n, complex_t *y)
-\brief The inverse of the sine function the complex vector argument `x`
-
-Function calculates the inverse of the sine function as: \n
-
-\f[
- \textrm{Arcsin}(x) = j \textrm{Ln}\left( j x + \sqrt{1 - x^2} \right)
-\f]
-
-
-\param[in] x Pointer to the argument vector `x`. \n
- Vector size is `[n x 1]`. \n \n
-
-\param[in] n Input vector `x` and the inverse sine vector `y` size. \n \n
-
-
-\param[out] y Pointer to the output complex vector `y`,
- corresponds to the input vector `x`. \n
- Vector size is `[n x 1]`. \n
- Memory must be allocated. \n \n
-
-\return
-`RES_OK` if function calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error". \n
-
-Example: \n
-\code{.cpp}
- complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
- complex_t y[3];
- int k;
-
- asin_cmplx(x, 3, y);
- for(k = 0; k < 3; k++)
- printf("asin_cmplx(%.1f%+.1fj) = %.3f%+.3fj\n",
- RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
-
-\endcode
- \n
-
-Output is: \n
-\verbatim
-asin_cmplx(1.0+2.0j) = 0.427+1.529j
-asin_cmplx(3.0+4.0j) = 0.634+2.306j
-asin_cmplx(5.0+6.0j) = 0.691+2.749j
-\endverbatim
-
-\author
-Sergey Bakhurin www.dsplib.org
+The inverse of the sine function the complex vector argument `x`
*******************************************************************************/
int DSPL_API asin_cmplx(complex_t* x, int n, complex_t *y)
{
- int k;
- complex_t tmp;
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
+ int k;
+ complex_t tmp;
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
- for(k = 0; k < n; k++)
- {
- RE(tmp) = 1.0 - CMRE(x[k], x[k]); /* 1-x[k]^2 */
- IM(tmp) = - CMIM(x[k], x[k]); /* 1-x[k]^2 */
- sqrt_cmplx(&tmp, 1, y+k); /* sqrt(1 - x[k]^2) */
- RE(y[k]) -= IM(x[k]); /* j * x[k] + sqrt(1 - x[k]^2) */
- IM(y[k]) += RE(x[k]); /* j * x[k] + sqrt(1 - x[k]^2) */
- log_cmplx(y+k, 1, &tmp); /* log( j * x[k] + sqrt(1 - x[k]^2) ) */
- RE(y[k]) = IM(tmp); /* -j * log( j * x[k] + sqrt(1 - x[k]^2) ) */
- IM(y[k]) = -RE(tmp); /* -j * log( j * x[k] + sqrt(1 - x[k]^2) ) */
- }
- return RES_OK;
+ for(k = 0; k < n; k++)
+ {
+ RE(tmp) = 1.0 - CMRE(x[k], x[k]); /* 1-x[k]^2 */
+ IM(tmp) = - CMIM(x[k], x[k]); /* 1-x[k]^2 */
+ sqrt_cmplx(&tmp, 1, y+k); /* sqrt(1 - x[k]^2) */
+ RE(y[k]) -= IM(x[k]); /* j * x[k] + sqrt(1 - x[k]^2) */
+ IM(y[k]) += RE(x[k]); /* j * x[k] + sqrt(1 - x[k]^2) */
+ log_cmplx(y+k, 1, &tmp); /* log( j * x[k] + sqrt(1 - x[k]^2) ) */
+ RE(y[k]) = IM(tmp); /* -j * log( j * x[k] + sqrt(1 - x[k]^2) ) */
+ IM(y[k]) = -RE(tmp); /* -j * log( j * x[k] + sqrt(1 - x[k]^2) ) */
+ }
+ return RES_OK;
}
@@ -179,83 +201,83 @@ int DSPL_API asin_cmplx(complex_t* x, int n, complex_t *y)
/*******************************************************************************
Modified Bessel Function of the First Kind – I0(x) [1]
-[1] Rational Approximations for the Modified Bessel Function
- of the First Kind – I0(x) for Computations with Double Precision
- by PAVEL HOLOBORODKO on NOVEMBER 11, 2015
-
- https://www.advanpix.com/2015/11/11/
+[1] Rational Approximations for the Modified Bessel Function
+ of the First Kind – I0(x) for Computations with Double Precision
+ by PAVEL HOLOBORODKO on NOVEMBER 11, 2015
+
+ https://www.advanpix.com/2015/11/11/
*******************************************************************************/
int DSPL_API bessel_i0(double* x, int n, double* y)
{
- double P16[17] = { 1.0000000000000000000000801e+00,
- 2.4999999999999999999629693e-01,
- 2.7777777777777777805664954e-02,
- 1.7361111111111110294015271e-03,
- 6.9444444444444568581891535e-05,
- 1.9290123456788994104574754e-06,
- 3.9367598891475388547279760e-08,
- 6.1511873265092916275099070e-10,
- 7.5940584360755226536109511e-12,
- 7.5940582595094190098755663e-14,
- 6.2760839879536225394314453e-16,
- 4.3583591008893599099577755e-18,
- 2.5791926805873898803749321e-20,
- 1.3141332422663039834197910e-22,
- 5.9203280572170548134753422e-25,
- 2.0732014503197852176921968e-27,
- 1.1497640034400735733456400e-29};
+ double P16[17] = { 1.0000000000000000000000801e+00,
+ 2.4999999999999999999629693e-01,
+ 2.7777777777777777805664954e-02,
+ 1.7361111111111110294015271e-03,
+ 6.9444444444444568581891535e-05,
+ 1.9290123456788994104574754e-06,
+ 3.9367598891475388547279760e-08,
+ 6.1511873265092916275099070e-10,
+ 7.5940584360755226536109511e-12,
+ 7.5940582595094190098755663e-14,
+ 6.2760839879536225394314453e-16,
+ 4.3583591008893599099577755e-18,
+ 2.5791926805873898803749321e-20,
+ 1.3141332422663039834197910e-22,
+ 5.9203280572170548134753422e-25,
+ 2.0732014503197852176921968e-27,
+ 1.1497640034400735733456400e-29};
- double P22[23] = { 3.9894228040143265335649948e-01,
- 4.9867785050353992900698488e-02,
- 2.8050628884163787533196746e-02,
- 2.9219501690198775910219311e-02,
- 4.4718622769244715693031735e-02,
- 9.4085204199017869159183831e-02,
- -1.0699095472110916094973951e-01,
- 2.2725199603010833194037016e+01,
- -1.0026890180180668595066918e+03,
- 3.1275740782277570164423916e+04,
- -5.9355022509673600842060002e+05,
- 2.6092888649549172879282592e+06,
- 2.3518420447411254516178388e+08,
- -8.9270060370015930749184222e+09,
- 1.8592340458074104721496236e+11,
- -2.6632742974569782078420204e+12,
- 2.7752144774934763122129261e+13,
- -2.1323049786724612220362154e+14,
- 1.1989242681178569338129044e+15,
- -4.8049082153027457378879746e+15,
- 1.3012646806421079076251950e+16,
- -2.1363029690365351606041265e+16,
- 1.6069467093441596329340754e+16};
+ double P22[23] = { 3.9894228040143265335649948e-01,
+ 4.9867785050353992900698488e-02,
+ 2.8050628884163787533196746e-02,
+ 2.9219501690198775910219311e-02,
+ 4.4718622769244715693031735e-02,
+ 9.4085204199017869159183831e-02,
+ -1.0699095472110916094973951e-01,
+ 2.2725199603010833194037016e+01,
+ -1.0026890180180668595066918e+03,
+ 3.1275740782277570164423916e+04,
+ -5.9355022509673600842060002e+05,
+ 2.6092888649549172879282592e+06,
+ 2.3518420447411254516178388e+08,
+ -8.9270060370015930749184222e+09,
+ 1.8592340458074104721496236e+11,
+ -2.6632742974569782078420204e+12,
+ 2.7752144774934763122129261e+13,
+ -2.1323049786724612220362154e+14,
+ 1.1989242681178569338129044e+15,
+ -4.8049082153027457378879746e+15,
+ 1.3012646806421079076251950e+16,
+ -2.1363029690365351606041265e+16,
+ 1.6069467093441596329340754e+16};
- double x2;
- int k;
-
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
-
- for(k =0; k < n; k++)
- {
- if(x[k] < 0.0)
- return ERROR_NEGATIVE;
-
- if(x[k] < 7.75)
+ double x2;
+ int k;
+
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
+
+ for(k =0; k < n; k++)
{
- x2 = x[k] * x[k] * 0.25;
- polyval(P16, 16, &x2, 1, y+k);
- y[k] = x2 * y[k] + 1.0;
+ if(x[k] < 0.0)
+ return ERROR_NEGATIVE;
+
+ if(x[k] < 7.75)
+ {
+ x2 = x[k] * x[k] * 0.25;
+ polyval(P16, 16, &x2, 1, y+k);
+ y[k] = x2 * y[k] + 1.0;
+ }
+ else
+ {
+ x2 = 1.0 / x[k];
+ polyval(P22, 22, &x2, 1, y+k);
+ y[k] *= exp(x[k]) / sqrt(x[k]);
+ }
}
- else
- {
- x2 = 1.0 / x[k];
- polyval(P22, 22, &x2, 1, y+k);
- y[k] *= exp(x[k]) / sqrt(x[k]);
- }
- }
- return RES_OK;
+ return RES_OK;
}
@@ -264,155 +286,58 @@ module operator for double
*******************************************************************************/
double DSPL_API dmod (double x, double y)
{
- if(y == 0.0)
- return x;
- return x - floor(x/y) * y;
+ if(y == 0.0)
+ return x;
+ return x - floor(x/y) * y;
}
/******************************************************************************
-\ingroup SPEC_MATH_TRIG_GROUP
-\fn int cos_cmplx(complex_t* x, int n, complex_t *y)
-\brief The cosine function the complex vector argument `x`
-
-Function calculates the cosine function as: \n
-
-\f[
-\textrm{cos}(x) = \frac{\exp(jx) + \exp(-jx)}{2}
-\f]
-
-
-\param[in] x Pointer to the argument vector `x`. \n
- Vector size is `[n x 1]`. \n \n
-
-\param[in] n Input vector `x` and the cosine vector `y` size. \n \n
-
-
-\param[out] y Pointer to the output complex vector `y`,
- corresponds to the input vector `x`. \n
- Vector size is `[n x 1]`. \n
- Memory must be allocated. \n \n
-
-\return
-`RES_OK` if function calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error". \n
-
-Example: \n
-\code{.cpp}
- complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
- complex_t y[3];
- int k;
-
- cos_cmplx(x, 3, y);
-
- for(k = 0; k < 3; k++)
- printf("cos_cmplx(%.1f%+.1fj) = %9.3f%+9.3fj\n",
- RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
-
-\endcode
- \n
-
-Output is: \n
-\verbatim
-cos_cmplx(1.0+2.0j) = 2.033 -3.052j
-cos_cmplx(3.0+4.0j) = -27.035 -3.851j
-cos_cmplx(5.0+6.0j) = 57.219 +193.428j
-\endverbatim
-
-\author
-Sergey Bakhurin www.dsplib.org
+The cosine function the complex vector argument `x`
*******************************************************************************/
int DSPL_API cos_cmplx(complex_t* x, int n, complex_t *y)
{
- int k;
- double ep, em, sx, cx;
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
+ int k;
+ double ep, em, sx, cx;
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
- for(k = 0; k < n; k++)
- {
- ep = exp( IM(x[k]));
- em = exp(-IM(x[k]));
- sx = 0.5 * sin(RE(x[k]));
- cx = 0.5 * cos(RE(x[k]));
- RE(y[k]) = cx * (em + ep);
- IM(y[k]) = sx * (em - ep);
- }
- return RES_OK;
+ for(k = 0; k < n; k++)
+ {
+ ep = exp( IM(x[k]));
+ em = exp(-IM(x[k]));
+ sx = 0.5 * sin(RE(x[k]));
+ cx = 0.5 * cos(RE(x[k]));
+ RE(y[k]) = cx * (em + ep);
+ IM(y[k]) = sx * (em - ep);
+ }
+ return RES_OK;
}
/******************************************************************************
-\ingroup SPEC_MATH_COMMON_GROUP
-\fn int log_cmplx(complex_t* x, int n, complex_t *y)
-\brief The logarithm function the complex vector argument `x`
-
-Function calculates the logarithm function as: \n
-
-\f[
-\textrm{Ln}(x) = j \varphi + \ln(|x|),
-\f]
-here \f$\varphi\f$ - the complex number phase.
-
-\param[in] x Pointer to the argument vector `x`. \n
- Vector size is `[n x 1]`. \n \n
-
-\param[in] n Input vector `x` and the logarithm vector `y` size. \n \n
-
-
-\param[out] y Pointer to the output complex vector `y`,
- corresponds to the input vector `x`. \n
- Vector size is `[n x 1]`. \n
- Memory must be allocated. \n \n
-
-\return
-`RES_OK` if function calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error". \n
-
-Example: \n
-\code{.cpp}
- complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
- complex_t y[3];
- int k;
-
- log_cmplx(x, 3, y);
-
- for(k = 0; k < 3; k++)
- printf("log_cmplx(%.1f%+.1fj) = %.3f%+.3fj\n",
- RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
-\endcode
- \n
-
-Output is: \n
-\verbatim
-log_cmplx(1.0+2.0j) = 0.805+1.107j
-log_cmplx(3.0+4.0j) = 1.609+0.927j
-log_cmplx(5.0+6.0j) = 2.055+0.876j
-\endverbatim
-
-\author
-Sergey Bakhurin www.dsplib.org
+The logarithm function the complex vector argument `x`
*******************************************************************************/
int DSPL_API log_cmplx(complex_t* x, int n, complex_t *y)
{
- int k;
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
+ int k;
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
- for(k = 0; k < n; k++)
- {
- RE(y[k]) = 0.5 * log(ABSSQR(x[k]));
- IM(y[k]) = atan2(IM(x[k]), RE(x[k]));
- }
- return RES_OK;
+ for(k = 0; k < n; k++)
+ {
+ RE(y[k]) = 0.5 * log(ABSSQR(x[k]));
+ IM(y[k]) = atan2(IM(x[k]), RE(x[k]));
+ }
+ return RES_OK;
}
@@ -422,76 +347,27 @@ int DSPL_API log_cmplx(complex_t* x, int n, complex_t *y)
/******************************************************************************
-\ingroup SPEC_MATH_TRIG_GROUP
-\fn int sin_cmplx(complex_t* x, int n, complex_t *y)
-\brief The sine function the complex vector argument `x`
-
-Function calculates the sine function as: \n
-
-\f[
-\textrm{cos}(x) = \frac{\exp(jx) - \exp(-jx)}{2j}
-\f]
-
-
-\param[in] x Pointer to the argument vector `x`. \n
- Vector size is `[n x 1]`. \n \n
-
-\param[in] n Input vector `x` and the sine vector `y` size. \n \n
-
-
-\param[out] y Pointer to the output complex vector `y`,
- corresponds to the input vector `x`. \n
- Vector size is `[n x 1]`. \n
- Memory must be allocated. \n \n
-
-\return
-`RES_OK` if function calculated successfully. \n
-Else \ref ERROR_CODE_GROUP "code error". \n
-
-Example: \n
-\code{.cpp}
- complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
- complex_t y[3];
- int k;
-
- sin_cmplx(x, 3, y);
-
- for(k = 0; k < 3; k++)
- printf("sin_cmplx(%.1f%+.1fj) = %9.3f%+9.3fj\n",
- RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
-
-\endcode
- \n
-
-Output is: \n
-\verbatim
-sin_cmplx(1.0+2.0j) = 3.166 +1.960j
-sin_cmplx(3.0+4.0j) = 3.854 -27.017j
-sin_cmplx(5.0+6.0j) = -193.430 +57.218j
-\endverbatim
-
-\author
-Sergey Bakhurin www.dsplib.org
+\brief The sine function the complex vector argument `x`
*******************************************************************************/
int DSPL_API sin_cmplx(complex_t* x, int n, complex_t *y)
{
- int k;
- double ep, em, sx, cx;
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
+ int k;
+ double ep, em, sx, cx;
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
- for(k = 0; k < n; k++)
- {
- ep = exp( IM(x[k]));
- em = exp(-IM(x[k]));
- sx = 0.5 * sin(RE(x[k]));
- cx = 0.5 * cos(RE(x[k]));
- RE(y[k]) = sx * (em + ep);
- IM(y[k]) = cx * (ep - em);
- }
- return RES_OK;
+ for(k = 0; k < n; k++)
+ {
+ ep = exp( IM(x[k]));
+ em = exp(-IM(x[k]));
+ sx = 0.5 * sin(RE(x[k]));
+ cx = 0.5 * cos(RE(x[k]));
+ RE(y[k]) = sx * (em + ep);
+ IM(y[k]) = cx * (ep - em);
+ }
+ return RES_OK;
}
@@ -504,17 +380,17 @@ sinc(x) = sin(pi*x)/(pi*x)
*******************************************************************************/
int DSPL_API sinc(double* x, int n, double a, double* y)
{
- int k;
+ int k;
- if(!x || !y)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
- for(k = 0; k < n; k++)
- y[k] = (x[k]==0.0) ? 1.0 : sin(a*x[k])/(a*x[k]);
+ for(k = 0; k < n; k++)
+ y[k] = (x[k]==0.0) ? 1.0 : sin(a*x[k])/(a*x[k]);
- return RES_OK;
+ return RES_OK;
}
@@ -527,159 +403,159 @@ Sine integral
This function uses Padé approximants of the convergent Taylor series [1]
-[1]
+[1]
https://www.sciencedirect.com/science/article/pii/S221313371500013X?via%3Dihub
*******************************************************************************/
int DSPL_API sine_int(double* x, int n, double* si)
{
- int k, sgn, p;
- double num, den, y, x2, x22, z, f, g;
-
- double A[8] = {+1.00000000000000000E0 ,
- -4.54393409816329991E-2 ,
- +1.15457225751016682E-3 ,
- -1.41018536821330254E-5 ,
- +9.43280809438713025E-8 ,
- -3.53201978997168357E-10 ,
- +7.08240282274875911E-13 ,
- -6.05338212010422477E-16 };
-
-
-
- double B[7] = {+1.0 ,
- +1.01162145739225565E-2 ,
- +4.99175116169755106E-5 ,
- +1.55654986308745614E-7 ,
- +3.28067571055789734E-10 ,
- +4.50490975753865810E-13 ,
- +3.21107051193712168E-16 };
-
-
-
- double FA[11] = {+1.000000000000000000000E0,
- +7.444370681619367006180E2,
- +1.963963728951468698010E5,
- +2.377503101254318340340E7,
- +1.430734038212746368880E9,
- +4.33736238870432522765E10,
- +6.40533830574022022911E11,
- +4.20968180571076940208E12,
- +1.00795182980368574617E13,
- +4.94816688199951963482E12,
- -4.94701168645415959931E11};
-
- double FB[10] = {+1.000000000000000000000E0,
- +7.464370681619276780310E2,
- +1.978652470315839514500E5,
- +2.415356701651268451440E7,
- +1.474789521929854649580E9,
- +4.58595115847765779830E10,
- +7.08501308149515401563E11,
- +5.06084464593475076774E12,
- +1.43468549171581016479E13,
- +1.11535493509914254097E13};
-
-
-
- double GA[11] = {+1.000000000000000000E0,
- +8.135952011516861500E2,
- +2.352391816264782000E5,
- +3.125575707957787310E7,
- +2.062975951467633540E9,
- +6.83052205423625007E10,
- +1.09049528450362786E12,
- +7.57664583257834349E12,
- +1.81004487464664575E13,
- +6.43291613143049485E12,
- -1.36517137670871689E12};
-
-
- double GB[10] = {+1.000000000000000000E0,
- +8.195952011514515640E2,
- +2.400367528355787770E5,
- +3.260266616470908220E7,
- +2.233555432780993600E9,
- +7.87465017341829930E10,
- +1.39866710696414565E12,
- +1.17164723371736605E13,
- +4.01839087307656620E13,
- +3.99653257887490811E13};
-
- if(!x || !si)
- return ERROR_PTR;
- if(n<1)
- return ERROR_SIZE;
-
-
- for(p = 0; p < n; p++)
- {
- sgn = x[p] > 0.0 ? 0 : 1;
- y = x[p] < 0.0 ? -x[p] : x[p];
-
- if(y < 4)
+ int k, sgn, p;
+ double num, den, y, x2, x22, z, f, g;
+
+ double A[8] = {+1.00000000000000000E0,
+ -4.54393409816329991E-2,
+ +1.15457225751016682E-3,
+ -1.41018536821330254E-5,
+ +9.43280809438713025E-8,
+ -3.53201978997168357E-10,
+ +7.08240282274875911E-13,
+ -6.05338212010422477E-16};
+
+
+
+ double B[7] = {+1.0,
+ +1.01162145739225565E-2,
+ +4.99175116169755106E-5,
+ +1.55654986308745614E-7,
+ +3.28067571055789734E-10,
+ +4.50490975753865810E-13,
+ +3.21107051193712168E-16};
+
+
+
+ double FA[11] = {+1.000000000000000000000E0,
+ +7.444370681619367006180E2,
+ +1.963963728951468698010E5,
+ +2.377503101254318340340E7,
+ +1.430734038212746368880E9,
+ +4.33736238870432522765E10,
+ +6.40533830574022022911E11,
+ +4.20968180571076940208E12,
+ +1.00795182980368574617E13,
+ +4.94816688199951963482E12,
+ -4.94701168645415959931E11};
+
+ double FB[10] = {+1.000000000000000000000E0,
+ +7.464370681619276780310E2,
+ +1.978652470315839514500E5,
+ +2.415356701651268451440E7,
+ +1.474789521929854649580E9,
+ +4.58595115847765779830E10,
+ +7.08501308149515401563E11,
+ +5.06084464593475076774E12,
+ +1.43468549171581016479E13,
+ +1.11535493509914254097E13};
+
+
+
+ double GA[11] = {+1.000000000000000000E0,
+ +8.135952011516861500E2,
+ +2.352391816264782000E5,
+ +3.125575707957787310E7,
+ +2.062975951467633540E9,
+ +6.83052205423625007E10,
+ +1.09049528450362786E12,
+ +7.57664583257834349E12,
+ +1.81004487464664575E13,
+ +6.43291613143049485E12,
+ -1.36517137670871689E12};
+
+
+ double GB[10] = {+1.000000000000000000E0,
+ +8.195952011514515640E2,
+ +2.400367528355787770E5,
+ +3.260266616470908220E7,
+ +2.233555432780993600E9,
+ +7.87465017341829930E10,
+ +1.39866710696414565E12,
+ +1.17164723371736605E13,
+ +4.01839087307656620E13,
+ +3.99653257887490811E13};
+
+ if(!x || !si)
+ return ERROR_PTR;
+ if(n<1)
+ return ERROR_SIZE;
+
+
+ for(p = 0; p < n; p++)
{
- x2 = y * y;
- z = 1.0;
- num = 0.0;
- for(k = 0; k < 8; k++)
- {
- num += A[k] * z;
- z*=x2;
- }
- z = 1.0;
- den = 0.0;
- for(k = 0; k < 7; k++)
- {
- den += B[k]*z;
- z*=x2;
- }
- si[p] = x[p] * num/den;
+ sgn = x[p] > 0.0 ? 0 : 1;
+ y = x[p] < 0.0 ? -x[p] : x[p];
+
+ if(y < 4)
+ {
+ x2 = y * y;
+ z = 1.0;
+ num = 0.0;
+ for(k = 0; k < 8; k++)
+ {
+ num += A[k] * z;
+ z*=x2;
+ }
+ z = 1.0;
+ den = 0.0;
+ for(k = 0; k < 7; k++)
+ {
+ den += B[k]*z;
+ z*=x2;
+ }
+ si[p] = x[p] * num/den;
+ }
+ else
+ {
+
+ x2 = 1.0/y;
+ x22 = x2*x2;
+ z = 1.0;
+ num = 0.0;
+ for(k = 0; k < 11; k++)
+ {
+ num += FA[k] * z;
+ z*=x22;
+ }
+ z = 1.0;
+ den = 0.0;
+ for(k = 0; k < 10; k++)
+ {
+ den += FB[k]*z;
+ z*=x22;
+ }
+
+ f = x2 * num / den;
+
+ z = 1.0;
+ num = 0.0;
+ for(k = 0; k < 11; k++)
+ {
+ num += GA[k] * z;
+ z*=x22;
+ }
+ z = 1.0;
+ den = 0.0;
+ for(k = 0; k < 10; k++)
+ {
+ den += GB[k]*z;
+ z*=x22;
+ }
+
+ g = x22 * num / den;
+
+ si[p] = sgn ? f * cos(y) + g * sin(y) - M_PI * 0.5 :
+ M_PI * 0.5 - f * cos(y) - g * sin(y);
+ }
}
- else
- {
-
- x2 = 1.0/y;
- x22 = x2*x2;
- z = 1.0;
- num = 0.0;
- for(k = 0; k < 11; k++)
- {
- num += FA[k] * z;
- z*=x22;
- }
- z = 1.0;
- den = 0.0;
- for(k = 0; k < 10; k++)
- {
- den += FB[k]*z;
- z*=x22;
- }
-
- f = x2 * num / den;
-
- z = 1.0;
- num = 0.0;
- for(k = 0; k < 11; k++)
- {
- num += GA[k] * z;
- z*=x22;
- }
- z = 1.0;
- den = 0.0;
- for(k = 0; k < 10; k++)
- {
- den += GB[k]*z;
- z*=x22;
- }
-
- g = x22 * num / den;
-
- si[p] = sgn ? f * cos(y) + g * sin(y) - M_PI * 0.5 :
- M_PI * 0.5 - f * cos(y) - g * sin(y);
- }
- }
- return RES_OK;
+ return RES_OK;
}
@@ -694,38 +570,38 @@ int DSPL_API sine_int(double* x, int n, double* si)
\fn int sqrt_cmplx(complex_t* x, int n, complex_t *y)
\brief Square root of the complex vector argguument `x`.
-Function calculates square root value of vector `x` length `n`: \n
+Function calculates square root value of vector `x` length `n`: \n
\f[
-y(k) = \sqrt{x(k)}, \qquad k = 0 \ldots n-1.
-\f]
+y(k) = \sqrt{x(k)}, \qquad k = 0 \ldots n-1.
+\f]
-\param[in] x Pointer to the input complex vector `x`. \n
- Vector size is `[n x 1]`. \n \n
+\param[in] x Pointer to the input complex vector `x`. \n
+ Vector size is `[n x 1]`. \n \n
-\param[in] n Size of input and output vectors `x` and `y`. \n \n
-
+\param[in] n Size of input and output vectors `x` and `y`. \n \n
-\param[out] y Pointer to the square root vector `y`. \n
- Vector size is `[n x 1]`. \n
- Memory must be allocated. \n \n
-\return `RES_OK` if function is calculated successfully. \n
+\param[out] y Pointer to the square root vector `y`. \n
+ Vector size is `[n x 1]`. \n
+ Memory must be allocated. \n \n
+
+\return `RES_OK` if function is calculated successfully. \n
Else \ref ERROR_CODE_GROUP "code error". \n
Example
\code{.cpp}
- complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
- complex_t y[3]
- int k;
-
- sqrt_cmplx(x, 3, y);
-
- for(k = 0; k < 3; k++)
- printf("sqrt_cmplx(%.1f%+.1fj) = %.3f%+.3fj\n",
- RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
-
- \endcode
+ complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
+ complex_t y[3]
+ int k;
+
+ sqrt_cmplx(x, 3, y);
+
+ for(k = 0; k < 3; k++)
+ printf("sqrt_cmplx(%.1f%+.1fj) = %.3f%+.3fj\n",
+ RE(x[k]), IM(x[k]), RE(y[k]), IM(y[k]));
+
+ \endcode
\n
Результатом работы будет
@@ -736,44 +612,44 @@ sqrt_cmplx(3.0+4.0j) = 2.000+1.000j
sqrt_cmplx(5.0+6.0j) = 2.531+1.185j
\endverbatim
-\author Sergey Bakhurin www.dsplib.org
+\author Sergey Bakhurin www.dsplib.org
*******************************************************************************/
int DSPL_API sqrt_cmplx(complex_t* x, int n, complex_t *y)
{
- int k;
- double r, zr, at;
- complex_t t;
- if(!x || !y)
- return ERROR_PTR;
- if(n < 1)
- return ERROR_SIZE;
+ int k;
+ double r, zr, at;
+ complex_t t;
+ if(!x || !y)
+ return ERROR_PTR;
+ if(n < 1)
+ return ERROR_SIZE;
- for(k = 0; k < n; k++)
- {
- r = ABS(x[k]);
- if(r == 0.0)
+ for(k = 0; k < n; k++)
{
- RE(y[k]) = 0.0;
- IM(y[k]) = 0.0;
+ r = ABS(x[k]);
+ if(r == 0.0)
+ {
+ RE(y[k]) = 0.0;
+ IM(y[k]) = 0.0;
+ }
+ else
+ {
+ RE(t) = RE(x[k]) + r;
+ IM(t) = IM(x[k]);
+ at = ABS(t);
+ if(at == 0.0)
+ {
+ RE(y[k]) = 0.0;
+ IM(y[k]) = sqrt(r);
+ }
+ else
+ {
+ zr = 1.0 / ABS(t);
+ r = sqrt(r);
+ RE(y[k]) = RE(t) * zr * r;
+ IM(y[k]) = IM(t) * zr * r;
+ }
+ }
}
- else
- {
- RE(t) = RE(x[k]) + r;
- IM(t) = IM(x[k]);
- at = ABS(t);
- if(at == 0.0)
- {
- RE(y[k]) = 0.0;
- IM(y[k]) = sqrt(r);
- }
- else
- {
- zr = 1.0 / ABS(t);
- r = sqrt(r);
- RE(y[k]) = RE(t) * zr * r;
- IM(y[k]) = IM(t) * zr * r;
- }
- }
- }
- return RES_OK;
+ return RES_OK;
}
\ No newline at end of file
diff --git a/examples/src/bilinear_test.c b/examples/src/bilinear_test.c
index a02366c..52c55da 100644
--- a/examples/src/bilinear_test.c
+++ b/examples/src/bilinear_test.c
@@ -10,7 +10,7 @@ int main(int argc, char* argv[])
{
void* hdspl; /* DSPL handle */
void* hplot; /* GNUPLOT handle */
- hdspl = dspl_load(); // Load DSPL function
+
double w[N], h[N];
complex_t hz[N];
@@ -18,7 +18,10 @@ int main(int argc, char* argv[])
double bz[ORD+1], az[ORD+1];
int err, k;
- // расчет аналогового фильтра Чебышева первого рода
+
+ hdspl = dspl_load(); /* Load DSPL function */
+
+ /* normalized analog lowpass filter Chebyshev type 1 */
err = cheby1_ap(1.0, ORD, bs, as);
if(err != RES_OK)
{
@@ -26,7 +29,7 @@ int main(int argc, char* argv[])
return err;
}
- // Билинейное преобразование
+ /* Bilinear transform */
err = bilinear(bs, as, ORD, bz, az);
if(err != RES_OK)
{
@@ -34,18 +37,18 @@ int main(int argc, char* argv[])
return err;
}
- // Печать коэффициентов
+ /* Print coefficients */
for(k = 0; k < ORD+1; k++)
printf("bz[%d] = %7.3f az[%d] = %7.3f\n", k, bz[k], k, az[k]);
- // Расчет АЧХ полученного цифрового фильтра
+ /* Digital filter magnitude */
linspace(0, M_PI, N, DSPL_PERIODIC, w);
freqz(bz, az, ORD, w, N, hz);
for(k = 0; k < N; k++)
{
- h[k] = 10.0 * log10 (ABSSQR(hz[k])); // АЧХ в дБ
- w[k] /= M_PI; // нормировка частоты от 0 до 1
+ h[k] = 10.0 * log10 (ABSSQR(hz[k])); /* Logarithmic scale */
+ w[k] /= M_PI; /* frequency from 0 to 1 */
}
writetxt(w,h,N,"dat/bilinear.txt");
@@ -60,7 +63,7 @@ int main(int argc, char* argv[])
gnuplot_cmd(hplot, "plot 'dat/bilinear.txt' with lines");
gnuplot_close(hplot);
- dspl_free(hdspl); // free dspl handle
+ dspl_free(hdspl); /* free dspl handle */
return err;
}
diff --git a/examples/src/cheby_poly1_test.c b/examples/src/cheby_poly1_test.c
index 3480f9e..f583cd9 100644
--- a/examples/src/cheby_poly1_test.c
+++ b/examples/src/cheby_poly1_test.c
@@ -8,13 +8,14 @@
int main(int argc, char* argv[])
{
void* hdspl; /* DSPL handle */
- void* hplot; /* GNUPLOT handle */
- hdspl = dspl_load(); // Load DSPL function
-
+ void* hplot; /* GNUPLOT handle */
double x[N], y[N];
int ord;
char fn[64];
+
+ hdspl = dspl_load(); /* Load DSPL function */
+
linspace(-1.0, 1.0, N, DSPL_SYMMETRIC, x);
for(ord = 1; ord < 5; ord++)
{
@@ -36,7 +37,7 @@ int main(int argc, char* argv[])
gnuplot_cmd(hplot, " 'dat/cheby_poly1_ord4.txt' with lines");
gnuplot_close(hplot);
- dspl_free(hdspl); // free dspl handle
+ dspl_free(hdspl); /* free dspl handle */
return 0;
}
\ No newline at end of file
diff --git a/examples/src/cheby_poly2_test.c b/examples/src/cheby_poly2_test.c
index 3aa6783..8f70d00 100644
--- a/examples/src/cheby_poly2_test.c
+++ b/examples/src/cheby_poly2_test.c
@@ -9,12 +9,12 @@ int main(int argc, char* argv[])
{
void* hdspl; /* DSPL handle */
void* hplot; /* GNUPLOT handle */
- hdspl = dspl_load(); // Load DSPL function
+
double x[N], y[N];
int ord;
char fn[64];
-
+ hdspl = dspl_load(); /* Load DSPL function */
linspace(-1.0, 1.0, N, DSPL_SYMMETRIC, x);
for(ord = 1; ord < 5; ord++)
{
@@ -36,7 +36,7 @@ int main(int argc, char* argv[])
gnuplot_cmd(hplot, " 'dat/cheby_poly2_ord4.txt' with lines");
gnuplot_close(hplot);
- dspl_free(hdspl); // free dspl handle
+ dspl_free(hdspl); /* free dspl handle */
return 0;
}
\ No newline at end of file
diff --git a/examples/src/complex_test.c b/examples/src/complex_test.c
index e780ad3..9f3afa0 100644
--- a/examples/src/complex_test.c
+++ b/examples/src/complex_test.c
@@ -5,13 +5,15 @@
int main(int argc, char* argv[])
{
- void* handle; // DSPL handle
- handle = dspl_load(); // Load DSPL function
+ void* handle; /* DSPL handle */
+
complex_t x[3] = {{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}};
complex_t y[3];
int k;
+ handle = dspl_load(); /* Load DSPL function */
+
printf("\n\nacos_cmplx\n---------------------------------\n");
acos_cmplx(x, 3, y);
for(k = 0; k < 3; k++)
@@ -50,7 +52,7 @@ int main(int argc, char* argv[])
- dspl_free(handle); // free dspl handle
+ dspl_free(handle); /* free dspl handle */
return 0;
}
diff --git a/examples/src/conv_fft_cmplx_test.c b/examples/src/conv_fft_cmplx_test.c
index 3e9f810..e499597 100644
--- a/examples/src/conv_fft_cmplx_test.c
+++ b/examples/src/conv_fft_cmplx_test.c
@@ -7,8 +7,8 @@
#define M 5
int main()
{
- void* handle; // DSPL handle
- handle = dspl_load(); // Load DSPL function
+ void* handle; /* DSPL handle */
+ handle = dspl_load(); /* Load DSPL function */
complex_t a[N], b[M], c[N+M-1], d[N+M-1];
fft_t pfft;
int n;
@@ -20,15 +20,15 @@ int main()
conv_fft_cmplx(a, N, b, M, &pfft, 8, c);
conv_cmplx(a, N, b, M, d);
- // print result
+ /* print result */
for(n = 0; n < N+M-1; n++)
{
printf("c[%3d] = %9.2f%+9.2fj ", n, RE(c[n]), IM(c[n]));
printf("d[%3d] = %9.2f%+9.2fj \n", n, RE(d[n]), IM(d[n]));
}
- fft_free(&pfft); // free fft structure memory
- dspl_free(handle); // free dspl handle
+ fft_free(&pfft); /* free fft structure memory */
+ dspl_free(handle); /* free dspl handle */
return 0;
}
diff --git a/examples/src/conv_fft_test.c b/examples/src/conv_fft_test.c
index 0ae3071..91ccccb 100644
--- a/examples/src/conv_fft_test.c
+++ b/examples/src/conv_fft_test.c
@@ -7,8 +7,8 @@
#define M 7
int main()
{
- void* handle; // DSPL handle
- handle = dspl_load(); // Load DSPL function
+ void* handle; /* DSPL handle */
+ handle = dspl_load(); /* Load DSPL function */
double a[N], b[M], c[N+M-1], d[N+M-1];
fft_t pfft;
int n, err;
@@ -23,12 +23,12 @@ int main()
err = conv(a, N, b, M, d);
printf("conv error: 0x%.8x\n", err);
- // print result
+ /* print result */
for(n = 0; n < N+M-1; n++)
printf("c[%3d] = %9.2f d[%3d] = %9.2f\n", n, c[n], n, d[n]);
- fft_free(&pfft); // free fft structure memory
- dspl_free(handle); // free dspl handle
+ fft_free(&pfft); /* free fft structure memory */
+ dspl_free(handle); /* free dspl handle */
return 0;
}
diff --git a/examples/src/conv_test.c b/examples/src/conv_test.c
index fb3b2ae..aa31769 100644
--- a/examples/src/conv_test.c
+++ b/examples/src/conv_test.c
@@ -6,8 +6,8 @@
int main()
{
- void* handle; // DSPL handle
- handle = dspl_load(); // Load DSPL function
+ void* handle; /* DSPL handle */
+ handle = dspl_load(); /* Load DSPL function */
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];
diff --git a/examples/src/ellip_landen_test.c b/examples/src/ellip_landen_test.c
index 70bdf20..8061179 100644
--- a/examples/src/ellip_landen_test.c
+++ b/examples/src/ellip_landen_test.c
@@ -6,25 +6,25 @@
int main()
{
- void* handle; // DSPL handle
- handle = dspl_load(); // Load DSPL function
-
- double k[N];
- int i, err;
-
- err = ellip_landen(0.93, N, k);
- if(err != RES_OK)
- {
- printf("Error code: %8x\n", err);
- return err;
- }
-
- printf(" i%8sk[i]\n\n", "");
- for(i = 1; i < N; i++)
- printf("%2d %11.3e\n", i, k[i]);
-
- dspl_free(handle); // free dspl handle
- return 0;
+ void* handle; // DSPL handle
+ handle = dspl_load(); // Load DSPL function
+
+ double k[N];
+ int i, err;
+
+ err = ellip_landen(0.93, N, k);
+ if(err != RES_OK)
+ {
+ printf("Error code: %8x\n", err);
+ return err;
+ }
+
+ printf(" i%8sk[i]\n\n", "");
+ for(i = 1; i < N; i++)
+ printf("%2d %11.3e\n", i, k[i]);
+
+ dspl_free(handle); // free dspl handle
+ return 0;
}
diff --git a/include/dspl.h b/include/dspl.h
index 20dd97b..f1b3da2 100644
--- a/include/dspl.h
+++ b/include/dspl.h
@@ -29,20 +29,204 @@
/* math const definition */
#ifndef M_PI
- #define M_PI 3.1415926535897932384626433832795
+ #define M_PI 3.1415926535897932384626433832795
#endif
#ifndef M_2PI
- #define M_2PI 6.283185307179586476925286766559
+ #define M_2PI 6.283185307179586476925286766559
#endif
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup TYPES_GROUP
+\typedef complex_t
+\brief Complex data type.
+
+libdspl-2.0 describes complex numbers data type as an array
+of two `double` elements.
+First element sets real part, second --- imaginary part.
+
+For example:
+
+\code{.cpp}
+ complex_t z;
+ z[0] = 1.0;
+ z[1] = -2.0;
+\endcode
+
+Variable `z = 1-2j`, here `j` - imaginary unit.
+
+For the convenience of working with complex numbers implemented
+special macros: \ref RE, \ref IM, \ref ABSSQR
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup TYPES_GROUP
+\typedef complex_t
+\brief Описание комплексного типа данных.
+
+Комплексный тип данных в библиотеке libdspl-2.0 определен как
+массив из двух элементов типа `double`.
+При этом первый элемент массива определяет реальную часть
+комплексного числа, а второй - мнимую.
+
+Например:
+
+\code{.cpp}
+ complex_t z;
+ z[0] = 1.0;
+ z[1] = -2.0;
+\endcode
+
+Переменная `z = 1-2j`, где `j` - мнимая единица.
+
+Для удобства работы с комплексными числами реализованы
+специальные макросы: \ref RE, \ref IM, \ref ABSSQR
+***************************************************************************** */
+#endif
typedef double complex_t[2];
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\struct fft_t
+\brief Fast Fourier Transform Object Data Structure
+The structure stores pointers to twiddle factors and arrays of intermediate
+data of the fast Fourier transform algorithm.
+
+The libdspl-2.0 library uses an FFT algorithm for composite size.
+
+\param n
+The size of the FFT vector for which memory is allocated
+in the structure arrays. \n
+The parameter `n` must be equal to an integer power of two (radix 2). \n \n
+
+\param w
+Pointer to the vector of twiddle factors. \n
+The size of the vector is `[n x 1]`. \n
+The memory must be allocated and an array of twiddle factors
+must be filled with the \ref fft_create function. \n\n
+
+\param t0
+Pointer to the vector of intermediate results of the FFT algorithm. \n
+The size of the vector is `[n x 1]`. \n
+Memory must be allocated by \ref fft_create function. \n\n
+
+\param t1
+Pointer to the vector of intermediate results. \n
+The size of the vector is `[n x 1]`. \n
+The memory must be allocated with the \ref fft_create function. \n\n
+The structure is populated with the \ref fft_create function once
+before using the FFT algorithm. \n
+A pointer to an object of this structure may be
+reused when calling FFT functions. \n
+Before exiting the program, dedicated memory for twiddle factors and arrays of
+intermediate data must be cleared by the \ref fft_free function.
+
+For example:
+
+\code
+fft_t pfft = {0}; // Structure fft_t and clear all fields
+int n = 64; // FFT size
+
+int err;
+
+// Create and fill FFT structure for 64-points FFT
+err = fft_create(&pfft, n);
+
+// FFT calculation here
+// FFT calculation here one more
+// ...
+
+// Clear fft structure
+fft_free(&pfft);
+\endcode
+
+\note
+It is important to note that if the object `fft_t` was created for the FFT size
+equal to` n`, it can only be used for FFT of size `n`. \n \n
+It’s also worth noting that the FFT functions independently control the size,
+and independently allocate the memory of the FFT object, if necessary.
+So if you call any function using the `fft_t` structure with filled
+data for the FFT length `k` for calculating the FFT of length`n`,
+then the structure arrays will be automatically recreated for the length `n`.
+
+\author Sergey Bakhurin www.dsplib.org
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup DFT_GROUP
+\struct fft_t
+\brief Структура данных объекта быстрого преобразования Фурье
+
+Структура хранит указатели на массивы поворотных коэффициентов
+и массивы промежуточных данных алгоритма быстрого преобразования Фурье.
+
+Библиотека libdspl-2.0 использует для БПФ алгоритм для составной длины
+
+\param n
+Размер вектора БПФ, для которого выделена память в массивах структуры. \n
+Парметр `n` должен быть равен целой степени двойки. \n \n
+
+\param w
+Указатель на вектор поворотных коэффициентов алгоритма БПФ. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена и массив поворотных коэффициентов
+должен быть заполнен функцией \ref fft_create. \n \n
+
+\param t0
+Указатель на вектор промежуточных вычислений алгоритма БПФ. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена функцией \ref fft_create. \n \n
+
+\param t1
+Указатель на вектор промежуточных вычислений алгоритма БПФ. \n
+Размер вектора `[n x 1]`. \n
+Память должна быть выделена функцией \ref fft_create. \n \n
+Структура заполняется функцией \ref fft_create один раз
+до использования алгоритма БПФ. \n
+Указатель на объект данной структуры может быть
+многократно использован при вызове функций БПФ. \n
+Перед выходом из программы выделенную память под поворотные
+коэффициенты и массивы промежуточных данных
+необходимо очистить функцией \ref fft_free. Например:
+\code
+fft_t pfft = {0}; // объявляем объект fft_t и обнуляем все поля
+int n = 64; // Размер БПФ
+int err;
+
+// создаем объект для 64-точечного БПФ
+err = fft_create(&pfft, n);
+
+// Вызов БПФ функции
+// Еще раз вызов БПФ функции
+// ...
+
+// очистить память объекта БПФ
+fft_free(&pfft);
+\endcode
+
+\note
+Важно отметить, что если объект `fft_t` был создан для размера БПФ равного `n`,
+то он может быть использован только для БПФ размера `n`. \n\n
+Также необходимо заметить, что функции БПФ самостоятельно контролируют размер,
+и самостоятельно выделяют память объекта БПФ при необходимости.
+Так если вызвать любую функцию использующую структуру `fft_t` с заполненными
+данными для длины БПФ `k` для расчета БПФ длины `n`,
+то массивы структуры будут автоматически пересозданы для длины `n`.
+
+\author
+Бахурин Сергей.
+www.dsplib.org
+***************************************************************************** */
+#endif
typedef struct
{
complex_t* w;
@@ -52,6 +236,7 @@ typedef struct
} fft_t;
+
#define RAND_TYPE_MRG32K3A 0x00000001
#define RAND_TYPE_MT19937 0x00000002
#define RAND_MT19937_NN 312
@@ -73,20 +258,194 @@ typedef struct
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup TYPES_GROUP
+\def RE(x)
+\brief Macro sets real part of the complex number.
+
+Example:
+\code{.cpp}
+ complex_t z;
+ RE(z) = 1.0;
+ IM(z) = -2.0;
+\endcode
+
+Variable `z = 1-2j`, here `j` - imaginary unit.
+
+This macro can be used to return
+real part of the complex number:
+
+\code{.cpp}
+ complex_t z = {3.0, -4.0};
+ double r;
+ r = RE(z);
+\endcode
+In this example `z = 3-4i`,
+but variable `r` will keep 3.
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup TYPES_GROUP
+\def RE(x)
+\brief Макрос определяющий реальную часть комплексного числа.
+
+Например:
+\code{.cpp}
+ complex_t z;
+ RE(z) = 1.0;
+ IM(z) = -2.0;
+\endcode
+
+Переменная `z = 1-2j`, где `j` --- мнимая единица.
+
+Аналогично, макрос можно использовать для получения
+реальной части комплексного числа:
+
+\code{.cpp}
+ complex_t z = {3.0, -4.0};
+ double r;
+ r = RE(z);
+\endcode
+В данном примере переменная `z = 3-4i`, а в переменой `r`
+будет храниться число 3.
+***************************************************************************** */
+#endif
+#define RE(x) (x[0])
+
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup TYPES_GROUP
+\def IM(x)
+\brief Macro sets imaginary part of the complex number.
+
+Example:
+\code{.cpp}
+ complex_t z;
+ RE(z) = 1.0;
+ IM(z) = -2.0;
+\endcode
+
+Variable `z = 1-2j`, here `j` - imaginary unit.
+
+This macro can be used to return
+imaginary part of the complex number:
+\code{.cpp}
+ complex_t z = {3.0, -4.0};
+ double r;
+ r = IM(z);
+\endcode
+In this example `z = 3-4i`,
+but variable `r` will keep -4.
+***************************************************************************** */
+
+
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup TYPES_GROUP
+\def IM(x)
+\brief Макрос определяющий мнимую часть комплексного числа.
+
+Например:
+\code{.cpp}
+ complex_t z;
+ RE(z) = 1.0;
+ IM(z) = -2.0;
+\endcode
+
+Переменная `z = 1-2j`, где `j` - мнимая единица.
+
+Аналогично, макрос можно использовать для получения
+мнимой части комплексного числа:
+\code{.cpp}
+ complex_t z = {3.0, -4.0};
+ double r;
+ r = IM(z);
+\endcode
+В данном примере переменная `z = 3-4i`,
+а в переменой `r` будет храниться число -4.
+***************************************************************************** */
+#endif
+#define IM(x) (x[1])
+
+
+
+#define SQR(x) ((x) * (x))
+
+
+#ifdef DOXYGEN_ENGLISH
+/*! ****************************************************************************
+\ingroup TYPES_GROUP
+\def ABSSQR(x)
+\brief
+The macro returns the square of the modulus of a complex number `x`.
+
+Square of the modulus of a complex number \f$ x = a + j b \f$ equals:
+
+\f[
+ |x|^2 = x x^* = a^2 + b^2.
+\f]
+
+Example:
+\code{.cpp}
+ complex_t z;
+ double y;
+ RE(z) = 1.0;
+ IM(z) = -2.0;
+ y = ABSSQR(z);
+\endcode
+
+Variable `z = 1-2j`, here `j` - imaginary unit, but variable `y = 5`.
+***************************************************************************** */
+#endif
+#ifdef DOXYGEN_RUSSIAN
+/*! ****************************************************************************
+\ingroup TYPES_GROUP
+\def ABSSQR(x)
+\brief Макрос возвращает квадрат модуля комплексного числа `x`.
+
+Квадрат модуля комплексного числа \f$ x = a + j b \f$ равен:
+
+\f[
+ |x|^2 = x x^* = a^2 + b^2.
+\f]
+
+Например:
+\code{.cpp}
+ complex_t z;
+ double y;
+ RE(z) = 1.0;
+ IM(z) = -2.0;
+ y = ABSSQR(z);
+\endcode
+
+Переменная `z = 1-2j`, где `j` - мнимая единица, а переменная `y = 5`.
+***************************************************************************** */
+#endif
+#define ABSSQR(x) ((SQR(RE(x))) + (SQR(IM(x))))
+
-#define RE(x) (x[0])
-#define IM(x) (x[1])
-#define SQR(x) ((x) * (x))
-#define ABSSQR(x) ((SQR(RE(x))) + (SQR(IM(x))))
#define ABS(x) sqrt((ABSSQR(x)))
+
+
#define ARG(x) atan2(IM(x), RE(x))
+
#define CMRE(a,b) ((RE(a)) * (RE(b)) - (IM(a)) * (IM(b)))
+
+
#define CMIM(a,b) ((RE(a)) * (IM(b)) + (IM(a)) * (RE(b)))
+
#define CMCONJRE(a, b) ((RE(a)) * (RE(b)) + (IM(a)) * (IM(b)))
+
+
#define CMCONJIM(a, b) ((IM(a)) * (RE(b)) - (RE(a)) * (IM(b)))
@@ -247,14 +606,14 @@ typedef struct
#ifdef BUILD_LIB
- #define DECLARE_FUNC(type, fn, param)\
- type DSPL_API fn(param);
+ #define DECLARE_FUNC(type, fn, param)\
+ type DSPL_API fn(param);
#endif
#ifndef BUILD_LIB
- #define DECLARE_FUNC( type, fn, param)\
- typedef type (*p_##fn)(param);\
- extern p_##fn fn;
+ #define DECLARE_FUNC( type, fn, param)\
+ typedef type (*p_##fn)(param);\
+ extern p_##fn fn;
#endif