/*! ****************************************************************************
\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
****************************************************************************** */