

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

