kopia lustrzana https://github.com/Dsplib/libdspl-2.0
Changed doxygen structure. Documntation is integrated in source code
Changes to be committed: modified: dspl/dox/doxyfile_en modified: dspl/dox/doxyfile_ru deleted: dspl/dox/en/array.dox deleted: dspl/dox/en/cheby.dox deleted: dspl/dox/en/complex.dox deleted: dspl/dox/en/dft.dox deleted: dspl/dox/en/ellipj.dox deleted: dspl/dox/en/fft.dox deleted: dspl/dox/en/filter_an.dox modified: dspl/dox/en/filter_ap.dox modified: dspl/dox/en/groups_define.dox modified: dspl/dox/en/mainpage.dox modified: dspl/dox/en/math.dox deleted: dspl/dox/ru/array.dox deleted: dspl/dox/ru/cheby.dox deleted: dspl/dox/ru/complex.dox deleted: dspl/dox/ru/dft.dox deleted: dspl/dox/ru/ellipj.dox modified: dspl/dox/ru/error_list.dox deleted: dspl/dox/ru/fft.dox deleted: dspl/dox/ru/filter_an.dox modified: dspl/dox/ru/filter_ap.dox modified: dspl/dox/ru/groups_define.dox modified: dspl/dox/ru/mainpage.dox modified: dspl/src/array.c modified: dspl/src/cheby.c modified: dspl/src/complex.c modified: dspl/src/dft.c modified: dspl/src/ellipj.c modified: dspl/src/fft.c modified: dspl/src/filter_an.c modified: dspl/src/filter_ap.c modified: dspl/src/math.c modified: examples/src/bilinear_test.c modified: examples/src/cheby_poly1_test.c modified: examples/src/cheby_poly2_test.c modified: examples/src/complex_test.c modified: examples/src/conv_fft_cmplx_test.c modified: examples/src/conv_fft_test.c modified: examples/src/conv_test.c modified: examples/src/ellip_landen_test.c modified: include/dspl.hpull/6/merge
rodzic
d2dd42dea8
commit
f3fe75fa0e
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
****************************************************************************** */
|
|
@ -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
|
||||
|
||||
<pre>
|
||||
cheby_poly1_ord1.txt
|
||||
cheby_poly1_ord2.txt
|
||||
cheby_poly1_ord3.txt
|
||||
cheby_poly1_ord4.txt
|
||||
</pre>
|
||||
|
||||
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
|
||||
|
||||
<pre>
|
||||
cheby_poly2_ord1.txt
|
||||
cheby_poly2_ord2.txt
|
||||
cheby_poly2_ord3.txt
|
||||
cheby_poly2_ord4.txt
|
||||
</pre>
|
||||
|
||||
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
|
||||
****************************************************************************** */
|
|
@ -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
|
||||
****************************************************************************** */
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
<a href="http://en.dsplib.org/content/dft_freq/dft_freq.html">
|
||||
to move the frequency 0 to the center
|
||||
</a> 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
|
||||
***************************************************************************** */
|
|
@ -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
|
||||
***************************************************************************** */
|
|
@ -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
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -42,7 +42,9 @@ Dsplib toolchain includes GCC, GNUPLOT, CodeBlocks IDE, Far file manager and als
|
|||
|
||||
\subsection sec_doc_content Documentation content
|
||||
<b>Mathematical sections:</b> \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
|
||||
|
|
|
@ -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
|
||||
<a href = "https://www.sciencedirect.com/science/article/pii/S221313371500013X?via%3Dihub">
|
||||
Padé approximants of the convergent Taylor series.
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
\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
|
||||
***************************************************************************** */
|
||||
|
||||
|
|
|
@ -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
|
||||
**************************************************************************** */
|
||||
|
|
@ -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
|
||||
|
||||
<pre>
|
||||
cheby_poly1_ord1.txt
|
||||
cheby_poly1_ord2.txt
|
||||
cheby_poly1_ord3.txt
|
||||
cheby_poly1_ord4.txt
|
||||
</pre>
|
||||
|
||||
Кроме того программа 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
|
||||
|
||||
<pre>
|
||||
cheby_poly2_ord1.txt
|
||||
cheby_poly2_ord2.txt
|
||||
cheby_poly2_ord3.txt
|
||||
cheby_poly2_ord4.txt
|
||||
</pre>
|
||||
|
||||
Кроме того программа GNUPLOT произведет построение следующих графиков
|
||||
по сохраненным в файлах данным:
|
||||
|
||||
\image html cheby_poly2.png
|
||||
|
||||
\author Бахурин Сергей www.dsplib.org
|
||||
**************************************************************************** */
|
|
@ -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
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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 Перестановка спектральных отсчетов дискретного преобразования Фурье
|
||||
|
||||
Функция производит
|
||||
<a href="http://ru.dsplib.org/content/dft_freq/dft_freq.html">
|
||||
перестановку спектральных отсчетов ДПФ
|
||||
</a> и переносит нулевую частоту в центр вектора ДПФ. \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
|
||||
***************************************************************************** */
|
|
@ -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
|
||||
***************************************************************************** */
|
|
@ -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
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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 Тригонометрические и гиперболические функции
|
||||
Тригонометрические и гиперболические функции вещественного
|
||||
и комплексного аргумента.
|
||||
|
|
|
@ -35,7 +35,9 @@ DSPL-2.0 --- свободная библиотека алгоритмов циф
|
|||
|
||||
\subsection sec_doc_content Разделы документации
|
||||
<b>Математические функции:</b> \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
|
||||
|
|
1749
dspl/src/array.c
1749
dspl/src/array.c
Plik diff jest za duży
Load Diff
367
dspl/src/cheby.c
367
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 <http://www.gnu.org/licenses/>.
|
||||
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
551
dspl/src/dft.c
551
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 <http://www.gnu.org/licenses/>.
|
||||
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
1352
dspl/src/ellipj.c
1352
dspl/src/ellipj.c
Plik diff jest za duży
Load Diff
1440
dspl/src/fft.c
1440
dspl/src/fft.c
Plik diff jest za duży
Load Diff
1319
dspl/src/filter_an.c
1319
dspl/src/filter_an.c
Plik diff jest za duży
Load Diff
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
|
1034
dspl/src/math.c
1034
dspl/src/math.c
Plik diff jest za duży
Load Diff
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
381
include/dspl.h
381
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
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue