// Copyright 2018-2025 RnD Center "ELVEES", JSC

/*! \file
 *  \brief Заголовочный файл c референсными функциями библиотеки
 *  \author Фролов Андрей
 */

#ifndef _REFERENCE_H
#define _REFERENCE_H

#include <float.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DBL_EPS 0.0000001

/*!
 *  \fn void ref_adds16(const int16_t *src0, const int16_t *src1, int16_t *dst, const int32_t size)
 *  \brief Сумма элементов типа int16
 *  \param[in] src0 входные данные типа int16
 *  \param[in] src1 входные данные типа int16
 *  \param[out] dst выходные данные типа int16
 *  \param[in] size размер входных данных
 */
void ref_adds16(const int16_t *src0, const int16_t *src1, int16_t *dst, const int32_t size);

/*!
 *  \fn void ref_adds32(const int32_t *src0, const int32_t *src1, int32_t *dst, const int32_t size)
 *  \brief Сумма элементов типа int32
 *  \param[in] src0 входные данные типа int32
 *  \param[in] src1 входные данные типа int32
 *  \param[out] dst выходные данные типа int32
 *  \param[in] size размер входных данных
 */
void ref_adds32(const int32_t *src0, const int32_t *src1, int32_t *dst, const int32_t size);

/*!
 *  \fn void ref_add_fl(const float *src0, const float *src1, float *dst, const int32_t size)
 *  \brief Сумма элементов типа float
 *  \param[in] src0 входные данные типа float
 *  \param[in] src1 входные данные типа float
 *  \param[out] dst выходные данные типа float
 *  \param[in] size размер входных данных
 */
void ref_add_fl(const float *src0, const float *src1, float *dst, const int32_t size);

/*!
 *  \fn void ref_add_db(const double *src0, const double *src1, double *dst, const int32_t size)
 *  \brief Сумма элементов типа double
 *  \param[in] src0 входные данные типа double
 *  \param[in] src1 входные данные типа double
 *  \param[out] dst выходные данные типа double
 *  \param[in] size размер входных данных
 */
void ref_add_db(const double *src0, const double *src1, double *dst, const int32_t size);

/*!
 *  \fn int32_t ref_dotprod(const int16_t *src0, const int16_t *src1, const int32_t size)
 *  \brief Скалярное произведение векторов типа int16
 *  \param[in] src0 входные данные типа int16
 *  \param[in] src1 входные данные типа int16
 *  \param[in] size размер входных данных
 *  \return
 *      - \b int32 результат скалярного произведения
 */
int32_t ref_dotprod(const int16_t *src0, const int16_t *src1, const int32_t size);

/*!
 *  \fn int64_t ref_dotprod32(const int32_t *src0, const int32_t *src1, const int32_t size)
 *  \brief Скалярное произведение векторов типа int32
 *  \param[in] src0 входные данные типа int32
 *  \param[in] src1 входные данные типа int32
 *  \param[in] size размер входных данных
 *  \return
 *      - \b int64 результат скалярного произведения
 */
int64_t ref_dotprod32(const int32_t *src0, const int32_t *src1, const int32_t size);

/*!
 *  \fn float ref_dotprod_fl(const float *src0, const float *src1, const int32_t size)
 *  \brief Скалярное произведение векторов типа float
 *  \param[in] src0 входные данные типа float
 *  \param[in] src1 входные данные типа float
 *  \param[in] size размер входных данных
 *  \return
 *      - \b float результат скалярного произведения
 */
float ref_dotprod_fl(const float *src0, const float *src1, const int32_t size);

/*!
 *  \fn double ref_dotprod_db(const double *src0, const double *src1, const int32_t size)
 *  \brief Скалярное произведение векторов типа double
 *  \param[in] src0 входные данные типа double
 *  \param[in] src1 входные данные типа double
 *  \param[in] size размер входных данных
 *  \return
 *      - \b double результат скалярного произведения
 */
double ref_dotprod_db(const double *src0, const double *src1, const int32_t size);

/*!
 *  \fn int32_t ref_vecsumsq(const int16_t *src0, const int32_t size)
 *  \brief Корень из суммы элементов вектора типа int16
 *  \param[in] src0 входные данные типа int16
 *  \param[in] size размер входных данных
 *  \return
 *      - \b int32 корень из суммы элементов вектора
 */
int32_t ref_vecsumsq(const int16_t *src0, const int32_t size);

/*!
 *  \fn int64_t ref_vecsumsq32(const int32_t *src0, const int32_t size)
 *  \brief Корень из суммы элементов вектора типа int32
 *  \param[in] src0 входные данные типа int32
 *  \param[in] size размер входных данных
 *  \return
 *      - \b int64 корень из суммы элементов вектора
 */
int64_t ref_vecsumsq32(const int32_t *src0, const int32_t size);

/*!
 *  \fn float ref_vecsumsq_fl(const float *src0, const int32_t size)
 *  \brief Корень из суммы элементов вектора типа float
 *  \param[in] src0 входные данные типа float
 *  \param[in] size размер входных данных
 *  \return
 *      - \b float корень из суммы элементов вектора
 */
float ref_vecsumsq_fl(const float *src0, const int32_t size);

/*!
 *  \fn double ref_vecsumsq_db(const double *src0, const int32_t size)
 *  \brief Корень из суммы элементов вектора типа double
 *  \param[in] src0 входные данные типа double
 *  \param[in] size размер входных данных
 *  \return
 *      - \b double корень из суммы элементов вектора
 */
double ref_vecsumsq_db(const double *src0, const int32_t size);

/*!
 *  \fn void ref_neg32(const int32_t *src0, int32_t *dst, const int32_t size)
 *  \brief Отрицание элементов вектора типа int32
 *  \param[in] src0 входные данные типа int32
 *  \param[out] dst выходные данные типа int32
 *  \param[in] size размер входных данных
 */
void ref_neg32(const int32_t *src0, int32_t *dst, const int32_t size);

/*!
 *  \fn void ref_neg16(const int16_t *src0, int16_t *dst, const int32_t size)
 *  \brief Отрицание элементов вектора типа int16
 *  \param[in] src0 входные данные типа int16
 *  \param[out] dst выходные данные типа int16
 *  \param[in] size размер входных данных
 */
void ref_neg16(const int16_t *src0, int16_t *dst, const int32_t size);

/*!
 *  \fn void ref_neg_fl(const float *src0, float *dst, const int32_t size)
 *  \brief Отрицание элементов вектора типа float
 *  \param[in] src0 входные данные типа float
 *  \param[out] dst выходные данные типа float
 *  \param[in] size размер входных данных
 */
void ref_neg_fl(const float *src0, float *dst, const int32_t size);

/*!
 *  \fn void ref_neg_db(const double *src0, double *dst, const int32_t size)
 *  \brief Отрицание элементов вектора типа double
 *  \param[in] src0 входные данные типа double
 *  \param[out] dst выходные данные типа double
 *  \param[in] size размер входных данных
 */
void ref_neg_db(const double *src0, double *dst, const int32_t size);

/*!
 *  \fn void ref_w_vec(const int16_t *src0, const int16_t *src1, const int16_t w, int16_t *dst, const int32_t size)
 *  \brief Сложение элементов вектора с взвешенными элементами другого вектора для типа int16
 *  \param[in] src0 входные данные типа int16
 *  \param[in] src1 входные данные типа int16
 *  \param[in] w весовой коэффициент
 *  \param[out] dst выходные данные типа int16
 *  \param[in] size размер входных данных
 */
void ref_w_vec(const int16_t *src0, const int16_t *src1, const int16_t w, int16_t *dst, const int32_t size);

/*!
 *  \fn void ref_w_vec32(const int32_t *src0, const int32_t *src1, const int32_t w, int32_t *dst, const int32_t size)
 *  \brief Сложение элементов вектора с взвешенными элементами другого вектора для типа int32
 *  \param[in] src0 входные данные типа int32
 *  \param[in] src1 входные данные типа int32
 *  \param[in] w весовой коэффициент
 *  \param[out] dst выходные данные типа int32
 *  \param[in] size размер входных данных
 */
void ref_w_vec32(const int32_t *src0, const int32_t *src1, const int32_t w, int32_t *dst, const int32_t size);

/*!
 *  \fn void ref_w_vec_fl(const float *src0, const float *src1, const float w, float *dst, const int32_t size)
 *  \brief Сложение элементов вектора с взвешенными элементами другого вектора для типа float
 *  \param[in] src0 входные данные типа float
 *  \param[in] src1 входные данные типа float
 *  \param[in] w весовой коэффициент
 *  \param[out] dst выходные данные типа float
 *  \param[in] size размер входных данных
 */
void ref_w_vec_fl(const float *src0, const float *src1, const float w, float *dst, const int32_t size);

/*!
 *  \fn void ref_w_vec_db(const double *src0, const double *src1, const double w, double *dst, const int32_t size)
 *  \brief Сложение элементов вектора с взвешенными элементами другого вектора для типа double
 *  \param[in] src0 входные данные типа double
 *  \param[in] src1 входные данные типа double
 *  \param[in] w весовой коэффициент
 *  \param[out] dst выходные данные типа double
 *  \param[in] size размер входных данных
 */
void ref_w_vec_db(const double *src0, const double *src1, const double w, double *dst, const int32_t size);

/*!
 *  \fn int32_t ref_dotp_sqr(const int32_t G, const int16_t *src0, const int16_t *src1, int32_t *r, const int32_t size)
 *  \brief Подсчет суммы квадратов элементов второго вектора, вычисление скалярного произведения векторов типа int16
 *  \param[in] G коэффициент, который суммируется с результатом суммы квадратов
 *  \param[in] src0 входные данные типа int16
 *  \param[in] src1 входные данные типа int16
 *  \param[in] r скалярное произведение векторов
 *  \param[in] size размер входных данных
 *  \return
 *      - \b int32_t сумма квадратов элементов второго вектора
 */
int32_t ref_dotp_sqr(const int32_t G, const int16_t *src0, const int16_t *src1, int32_t *r, const int32_t size);

/*!
 *  \fn int64_t ref_dotp_sqr32(const int64_t G, const int32_t *src0, const int32_t *src1, int64_t *r, const int32_t
 * size)
 *  \brief Подсчет суммы квадратов элементов второго вектора, вычисление скалярного произведения векторов типа int32
 *  \param[in] G коэффициент, который суммируется с результатом суммы квадратов
 *  \param[in] src0 входные данные типа int32
 *  \param[in] src1 входные данные типа int32
 *  \param[in] r скалярное произведение векторов
 *  \param[in] size размер входных данных
 *  \return
 *      - \b int64_t сумма квадратов элементов второго вектора
 */
int64_t ref_dotp_sqr32(const int64_t G, const int32_t *src0, const int32_t *src1, int64_t *r, const int32_t size);

/*!
 *  \fn float ref_dotp_sqr_fl(const float G, const float *src0, const float *src1, float *r, const int32_t size)
 *  \brief Подсчет суммы квадратов элементов второго вектора, вычисление скалярного произведения векторов типа float
 *  \param[in] G коэффициент, который суммируется с результатом суммы квадратов
 *  \param[in] src0 входные данные типа float
 *  \param[in] src1 входные данные типа float
 *  \param[in] r скалярное произведение векторов
 *  \param[in] size размер входных данных
 *  \return
 *      - \b float сумма квадратов элементов второго вектора
 */
float ref_dotp_sqr_fl(const float G, const float *src0, const float *src1, float *r, const int32_t size);

/*!
 *  \fn double ref_dotp_sqr_db(const double G, const double *src0, const double *src1, double *r, const int32_t size)
 *  \brief Подсчет суммы квадратов элементов второго вектора, вычисление скалярного произведения векторов типа double
 *  \param[in] G коэффициент, который суммируется с результатом суммы квадратов
 *  \param[in] src0 входные данные типа double
 *  \param[in] src1 входные данные типа double
 *  \param[in] r скалярное произведение векторов
 *  \param[in] size размер входных данных
 *  \return
 *      - \b double сумма квадратов элементов второго вектора
 */
double ref_dotp_sqr_db(const double G, const double *src0, const double *src1, double *r, const int32_t size);

/*!
 *  \fn int32_t ref_maxval(const int16_t *src0, const int32_t size)
 *  \brief Поиск значения максимального элемента в векторе типа int16
 *  \param[in] src0 входные данные типа int16
 *  \param[in] size размер входных данных
 *  \return
 *      - \b int32 значение максимума
 */
int32_t ref_maxval(const int16_t *src0, const int32_t size);

/*!
 *  \fn int32_t ref_maxval32(const int32_t *src0, const int32_t size)
 *  \brief Поиск значения максимального элемента в векторе типа int32
 *  \param[in] src0 входные данные типа int32
 *  \param[in] size размер входных данных
 *  \return
 *      - \b int32 значение максимума
 */
int32_t ref_maxval32(const int32_t *src0, const int32_t size);

/*!
 *  \fn float ref_maxval_fl(const float *src0, const int32_t size)
 *  \brief Поиск значения максимального элемента в векторе типа float
 *  \param[in] src0 входные данные типа float
 *  \param[in] size размер входных данных
 *  \return
 *      - \b float значение максимума
 */
float ref_maxval_fl(const float *src0, const int32_t size);

/*!
 *  \fn double ref_maxval_db(const double *src0, const int32_t size)
 *  \brief Поиск значения максимального элемента в векторе типа double
 *  \param[in] src0 входные данные типа double
 *  \param[in] size размер входных данных
 *  \return
 *      - \b double значение максимума
 */
double ref_maxval_db(const double *src0, const int32_t size);

/*!
 *  \fn int32_t ref_minval(const int16_t *src0, const int32_t size)
 *  \brief Поиск значения минимального элемента в векторе типа int16
 *  \param[in] src0 входные данные типа int16
 *  \param[in] size размер входных данных
 *  \return
 *      - \b int32 значение максимума
 */
int32_t ref_minval(const int16_t *src0, const int32_t size);

/*!
 *  \fn int32_t ref_minval32(const int32_t *src0, const int32_t size)
 *  \brief Поиск значения минимального элемента в векторе типа int32
 *  \param[in] src0 входные данные типа int32
 *  \param[in] size размер входных данных
 *  \return
 *      - \b int32 значение максимума
 */
int32_t ref_minval32(const int32_t *src0, const int32_t size);

/*!
 *  \fn float ref_minval_fl(const float *src0, const int32_t size)
 *  \brief Поиск значения минимального элемента в векторе типа float
 *  \param[in] src0 входные данные типа float
 *  \param[in] size размер входных данных
 *  \return
 *      - \b float значение максимума
 */
float ref_minval_fl(const float *src0, const int32_t size);

/*!
 *  \fn double ref_minval_db(const double *src0, const int32_t size)
 *  \brief Поиск значения минимального элемента в векторе типа double
 *  \param[in] src0 входные данные типа double
 *  \param[in] size размер входных данных
 *  \return
 *      - \b double значение максимума
 */
double ref_minval_db(const double *src0, const int32_t size);

/*!
 *  \fn void ref_mat_trans(const int16_t *src0, const int32_t rows, const int32_t columns, int16_t *dst)
 *  \brief Транспонирование матрицы типы int16
 *  \param[in] src0 входные данные типа int16
 *  \param[in] rows количество строк матрицы
 *  \param[in] columns количество столбцов матрицы
 *  \param[out] dst выходные данные типа int16
 */
void ref_mat_trans(const int16_t *src0, const int32_t rows, const int32_t columns, int16_t *dst);

/*!
 *  \fn void ref_mat_trans_fl(const float *src0, const int32_t rows, const int32_t columns, float *dst)
 *  \brief Транспонирование матрицы типы float
 *  \param[in] src0 входные данные типа float
 *  \param[in] rows количество строк матрицы
 *  \param[in] columns количество столбцов матрицы
 *  \param[out] dst выходные данные типа float
 */
void ref_mat_trans_fl(const float *src0, const int32_t rows, const int32_t columns, float *dst);

/*!
 *  \fn void ref_mat_trans_s32(const int32_t *src0, const int32_t rows, const int32_t columns, int32_t *dst)
 *  \brief Транспонирование матрицы типы int32
 *  \param[in] src0 входные данные типа int32
 *  \param[in] rows количество строк матрицы
 *  \param[in] columns количество столбцов матрицы
 *  \param[out] dst выходные данные типа int32
 */
void ref_mat_trans_s32(const int32_t *src0, const int32_t rows, const int32_t columns, int32_t *dst);

/*!
 *  \fn void ref_mat_trans_db(const double *src0, const int32_t rows, const int32_t columns, double *dst)
 *  \brief Транспонирование матрицы типы double
 *  \param[in] src0 входные данные типа double
 *  \param[in] rows количество строк матрицы
 *  \param[in] columns количество столбцов матрицы
 *  \param[out] dst выходные данные типа double
 */
void ref_mat_trans_db(const double *src0, const int32_t rows, const int32_t columns, double *dst);

/*!
 *  \fn void ref_mat_trans_cplx_fl(float *src0, int32_t rows, int32_t columns, float *dst)
 *  \brief Транспонирование комплексной матрицы типы float
 *  \param[in] src0 входные данные типа float
 *  \param[in] rows количество строк матрицы
 *  \param[in] columns количество столбцов матрицы
 *  \param[out] dst выходные данные типа float
 */
void ref_mat_trans_cplx_fl(float *src0, int32_t rows, int32_t columns, float *dst);

/*!
 *  \fn void ref_mat_mul(const int16_t *src0, const int32_t rows0, const int32_t columns0, const int16_t *src1, const
 * int32_t columns1, int16_t *dst, const int32_t shift)
 *  \brief Умножение матриц типа int16
 *  \param[in] src0 входные данные типа int16
 *  \param[in] rows0 количество строк первой матрицы
 *  \param[in] columns0 количество столбцов первой матрицы
 *  \param[in] src1 входные данные типа int16
 *  \param[in] columns1 количество столбцов второй матрицы
 *  \param[out] dst выходные данные типа int16
 *  \param[in] shift сдвиг результата
 */
void ref_mat_mul(const int16_t *src0, const int32_t rows0, const int32_t columns0, const int16_t *src1,
                 const int32_t columns1, int16_t *dst, const int32_t shift);

/*!
 *  \fn void ref_mat_mul32(const int32_t *src0, const int32_t rows0, const int32_t columns0, const int32_t *src1, const
 * int32_t columns1, int32_t *dst, const int32_t shift)
 *  \brief Умножение матриц типа int32
 *  \param[in] src0 входные данные типа int32
 *  \param[in] rows0 количество строк первой матрицы
 *  \param[in] columns0 количество столбцов первой матрицы
 *  \param[in] src1 входные данные типа int32
 *  \param[in] columns1 количество столбцов второй матрицы
 *  \param[out] dst выходные данные типа int32
 *  \param[in] shift сдвиг результата
 */
void ref_mat_mul32(const int32_t *src0, const int32_t rows0, const int32_t columns0, const int32_t *src1,
                   const int32_t columns1, int32_t *dst, const int32_t shift);

/*!
 *  \fn void ref_mat_mul_fl(const float *src0, const int32_t rows0, const int32_t columns0, const float *src1, const
 * int32_t columns1, float *dst)
 *  \brief Умножение матриц типа float
 *  \param[in] src0 входные данные типа float
 *  \param[in] rows0 количество строк первой матрицы
 *  \param[in] columns0 количество столбцов первой матрицы
 *  \param[in] src1 входные данные типа float
 *  \param[in] columns1 количество столбцов второй матрицы
 *  \param[out] dst выходные данные типа float
 */
void ref_mat_mul_fl(const float *src0, const int32_t rows0, const int32_t columns0, const float *src1,
                    const int32_t columns1, float *dst);

/*!
 *  \fn void ref_mat_mul_db(const double *src0, const int32_t rows0, const int32_t columns0, const double *src1, const
 * int32_t columns1, double *dst)
 *  \brief Умножение матриц типа double
 *  \param[in] src0 входные данные типа double
 *  \param[in] rows0 количество строк первой матрицы
 *  \param[in] columns0 количество столбцов первой матрицы
 *  \param[in] src1 входные данные типа double
 *  \param[in] columns1 количество столбцов второй матрицы
 *  \param[out] dst выходные данные типа double
 */
void ref_mat_mul_db(const double *src0, const int32_t rows0, const int32_t columns0, const double *src1,
                    const int32_t columns1, double *dst);

/*!
 *  \fn void ref_mat_mul_cplx(const int16_t *src0, const int32_t rows0, const int32_t columns0, const int16_t *src1,
 * const int32_t columns1, int16_t *dst, const int32_t shift)
 *  \brief Комплексное умножение матриц типа int16 (cint16)
 *  \param[in] src0 входные данные типа int16 (cint16)
 *  \param[in] rows0 количество строк первой матрицы
 *  \param[in] columns0 количество столбцов первой матрицы
 *  \param[in] src1 входные данные типа int16 (cint16)
 *  \param[in] columns1 количество столбцов второй матрицы
 *  \param[out] dst выходные данные типа int16 (cint16) референсной функции
 *  \param[in] shift сдвиг результата
 */
void ref_mat_mul_cplx(const int16_t *src0, const int32_t rows0, const int32_t columns0, const int16_t *src1,
                      const int32_t columns1, int16_t *dst, const int32_t shift);

/*!
 *  \fn void ref_mat_mul_cplx32(const int32_t *src0, const int32_t rows0, const int32_t columns0, const int32_t *src1,
 * const int32_t columns1, int32_t *dst, const int32_t shift)
 *  \brief Комплексное умножение матриц типа int32 (cint32)
 *  \param[in] src0 входные данные типа int32 (cint32)
 *  \param[in] rows0 количество строк первой матрицы
 *  \param[in] columns0 количество столбцов первой матрицы
 *  \param[in] src1 входные данные типа int32 (cint32)
 *  \param[in] columns1 количество столбцов второй матрицы
 *  \param[out] dst выходные данные типа int32 (cint32) референсной функции
 *  \param[in] shift сдвиг результата
 */
void ref_mat_mul_cplx32(const int32_t *src0, const int32_t rows0, const int32_t columns0, const int32_t *src1,
                        const int32_t columns1, int32_t *dst, const int32_t shift);

/*!
 *  \fn void ref_mat_mul_cplx_fl(const float *src0, const int32_t rows0, const int32_t columns0, const float *src1,
 * const int32_t columns1, float *dst)
 *  \brief Комплексное умножение матриц типа float (cfloat)
 *  \param[in] src0 входные данные типа float (cfloat)
 *  \param[in] rows0 количество строк первой матрицы
 *  \param[in] columns0 количество столбцов первой матрицы
 *  \param[in] src1 входные данные типа float (cfloat)
 *  \param[in] columns1 количество столбцов второй матрицы
 *  \param[out] dst выходные данные типа float (cfloat) референсной функции
 */
void ref_mat_mul_cplx_fl(const float *src0, const int32_t rows0, const int32_t columns0, const float *src1,
                         const int32_t columns1, float *dst);

/*!
 *  \fn void ref_mat_mul_cplx_db(const double *src0, const int32_t rows0, const int32_t columns0, const double *src1,
 * const int32_t columns1, double *dst)
 *  \brief Комплексное умножение матриц типа double (cdouble)
 *  \param[in] src0 входные данные типа double (cdouble)
 *  \param[in] rows0 количество строк первой матрицы
 *  \param[in] columns0 количество столбцов первой матрицы
 *  \param[in] src1 входные данные типа double (cdouble)
 *  \param[in] columns1 количество столбцов второй матрицы
 *  \param[out] dst выходные данные типа double (cdouble) референсной функции
 */
void ref_mat_mul_cplx_db(const double *src0, const int32_t rows0, const int32_t columns0, const double *src1,
                         const int32_t columns1, double *dst);

/*!
 *  \fn void ref_recip16(const int16_t *x, int16_t *rfrac, int16_t* rexp, const int32_t size)
 *  \brief Обратная величина для чисел с фиксированной точкой типа int16
 *  \param[in] x входные данные типа int16
 *  \param[out] rfrac выходные данные типа int16, нормализованное значение
 *  \param[out] rexp выходные данные типа int16, значение степени экспоненты
 *  \param[in] size размер входных массивов
 */
void ref_recip16(const int16_t *x, int16_t *rfrac, int16_t *rexp, const int32_t size);

/// Для операций с фиксированной точкой числа записываются в int32,
/// Младшие 16 бит - дробная часть, старшие - целая.
/// Порядок следования байтов little-endian.

/// Умножение чисел с фиксированной точкой (i=16,f=16)
void ref_mul16i16f(const int32_t *x,   ///< [in]  входные данные для первого массива
                   const int32_t *y,   ///< [in]  входные данные для второго массива
                   int32_t *r,         ///< [out] выходные данные
                   const int32_t size  ///< [in]  количество элементов массивов
);

/*!
 *  \fn void ref_autocor(int16_t* dst, const int16_t* src, const int size_autocor, const int size_dst)
 *  \brief Функция автокорреляции
 *  \param[out] dst выходные данные типа int16
 *  \param[in] src входные данные типа int16
 *  \param[in] size_autocor размер автокорреляции
 *  \param[in] size_dst размер выходных данных
 */
void ref_autocor(int16_t *dst, const int16_t *src, const int size_autocor, const int size_dst);

/*!
 *  \fn void ref_autocor_fl(float* dst, const float* src, const int size_autocor, const int size_dst)
 *  \brief Функция автокорреляции
 *  \param[out] dst выходные данные типа float
 *  \param[in] src входные данные типа float
 *  \param[in] size_autocor размер автокорреляции
 *  \param[in] size_dst размер выходных данных
 */
void ref_autocor_fl(float *dst, const float *src, const int size_autocor, const int size_dst);

/*!
 *  \fn void ref_blk_move(const int16_t* src, int16_t* dst, const int size)
 *  \brief Копирование данных
 *  \param[in] src входные данные типа int16
 *  \param[out] dst выходные данные типа int16
 *  \param[in] size размер входных данных
 */
void ref_blk_move(const int16_t *src, int16_t *dst, const int size);

/*!
 *  \fn void ref_blk_eswap16(void* src, void* dst, const int size)
 *  \brief Перестановка байт внутри 16-ти битных слов
 *  \param[in] src входные данные
 *  \param[out] dst выходные данные
 *  \param[in] size размер входных данных
 */
void ref_blk_eswap16(void *src, void *dst, const int size);

/*!
 *  \fn void ref_blk_eswap32(void* src, void* dst, const int size)
 *  \brief Перестановка байт внутри 32-х битных слов
 *  \param[in] src входные данные
 *  \param[out] dst выходные данные
 *  \param[in] size размер входных данных
 */
void ref_blk_eswap32(void *src, void *dst, const int size);

/*!
 *  \fn void ref_blk_eswap64(void* src, void* dst, const int size)
 *  \brief Перестановка байт внутри 64-х битных слов
 *  \param[in] src входные данные
 *  \param[out] dst выходные данные
 *  \param[in] size размер входных данных
 */
void ref_blk_eswap64(void *src, void *dst, const int size);

/*!
 *  \fn int ref_maxidx(const int16_t* src0, const int size)
 *  \brief Поиск индекса максимального элемента в векторе типа int16_t
 *  \param[in] src0 входные данные типа int16_t
 *  \param[in] size размер входных данных
 *  \return
 *      - \b int индекс первого минимума
 */
int ref_maxidx(const int16_t *src0, const int size);

/*!
 *  \fn int ref_maxidx_fl(const float* src0, const int size)
 *  \brief Поиск индекса максимального элемента в векторе типа float
 *  \param[in] src0 входные данные типа float
 *  \param[in] size размер входных данных
 *  \return
 *      - \b int индекс первого минимума
 */
int ref_maxidx_fl(const float *src0, const int size);

/*!
 *  \fn void ref_q15tofl(const int16_t* src0, float* dst, const int size)
 *  \brief Преобразование данных из Q15 во float
 *  \param[in] src0 входные данные типа Q15
 *  \param[out] dst выходные данные типа float
 *  \param[in] size размер входных данных
 */
void ref_q15tofl(const int16_t *src0, float *dst, const int size);

/*!
 *  \fn int ref_minerror(const int16_t* src0, const int16_t* src1, int* max_idx)
 *  \brief Вычисление скалярного произведения между парами входных векторов src0 и коэффицентами src1, поиск индекса
 * вектора, дающего максимальное значение.
 *  \param[in] src0 входные данные типа int16_t
 *  \param[in] src1 входные данные типа int16_t
 *  \param[out] max_idx индекс дающий максимальное значение
 *  \return
 *      - \b int максимальное значение скалярного произведения
 */
int ref_minerror(const int16_t *src0, const int16_t *src1, int *max_idx);

/*!
 *  \fn float ref_minerror_fl(const float* src0, const float* src1, float* max_idx)
 *  \brief Вычисление скалярного произведения между парами входных векторов src0 и коэффицентами src1, поиск индекса
 * вектора, дающего максимальное значение.
 *  \param[in] src0 входные данные типа float
 *  \param[in] src1 входные данные типа float
 *  \param[out] max_idx индекс дающий максимальное значение
 *  \return
 *      - \b float максимальное значение скалярного произведения
 */
float ref_minerror_fl(const float *src0, const float *src1, float *max_idx);

/*!
 *  \fn int ref_bexp(const int32_t* src, const int size)
 *  \brief Поиск максимальной степени двойки в массиве
 *  \param[in] src входные данные типа int32_t
 *  \param[in] size размер входных данных
 *  \return
 *      - \b int максимальная степень
 */
int ref_bexp(const int32_t *src, const int size);

/*!
 *  \fn void ref_iir(int16_t* dst0, const int16_t* src0, int16_t* dst1, const int16_t* coef0, const int16_t* coef1,
 * const int size)
 *  \brief Реализация iir фильтра
 *  \param[out] dst0 выходные данные типа int16_t
 *  \param[in] src входные данные типа int16_t
 *  \param[out] dst1 выходные данные типа int16_t
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[in] coef1 коэффициенты фильтра
 *  \param[in] size размер выходных данных
 */
void ref_iir(int16_t *dst0, const int16_t *src0, int16_t *dst1, const int16_t *coef0, const int16_t *coef1,
             const int size);

/*!
 *  \fn void ref_iir_fl(float* dst0, const float* src0, float* dst1, const float* coef0, const float* coef1, int size)
 *  \brief Реализация iir фильтра
 *  \param[out] dst0 выходные данные типа float
 *  \param[in] src входные данные типа float
 *  \param[out] dst1 выходные данные типа float
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[in] coef1 коэффициенты фильтра
 *  \param[in] size размер выходных данных
 */
void ref_iir_fl(float *dst0, const float *src0, float *dst1, const float *coef0, const float *coef1, int size);

/*!
 *  \fn void ref_fir_r4(const short* src0, const short* coef0, short* dst, const int coef0_size, const int size)
 *  \brief Реализация fir фильтра
 *  \param[in] src0 входные данные типа int16_t
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[out] dst выходные данные типа int16_t
 *  \param[in] coef0_size количество коэффициентов
 *  \param[in] size размер выходных данных
 */
void ref_fir_r4(const short *src0, const short *coef0, short *dst, const int coef0_size, const int size);

/*!
 *  \fn void ref_fir_r2_fl(const float* src0, const float* coef0, float* dst, const int coef0_size, const int size)
 *  \brief Реализация fir фильтра
 *  \param[in] src0 входные данные типа float
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[out] dst выходные данные типа float
 *  \param[in] coef0_size количество коэффициентов
 *  \param[in] size размер выходных данных
 */
void ref_fir_r2_fl(const float *src0, const float *coef0, float *dst, const int coef0_size, const int size);

/*!
 *  \fn void ref_fir_r8(const int16_t* src0, const int16_t* coef0, int16_t* dst, const int coef0_size, const int size)
 *  \brief Реализация fir фильтра
 *  \param[in] src0 входные данные типа int16_t
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[out] dst выходные данные типа int16_t
 *  \param[in] coef0_size количество коэффициентов
 *  \param[in] size размер выходных данных
 */
void ref_fir_r8(const int16_t *src0, const int16_t *coef0, int16_t *dst, const int coef0_size, const int size);

/*!
 *  \fn void ref_fir_r8_h8(const int16_t* src0, const int16_t* coef0, int16_t* dst, const int size)
 *  \brief Реализация fir фильтра
 *  \param[in] src0 входные данные типа int16_t
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[out] dst выходные данные типа int16_t
 *  \param[in] size размер выходных данных
 */
void ref_fir_r8_h8(const int16_t *src0, const int16_t *coef0, int16_t *dst, const int size);

/*!
 *  \fn void ref_fir_r8_h16(const int16_t* src0, const int16_t* coef0, int16_t* dst, const int size)
 *  \brief Реализация fir фильтра
 *  \param[in] src0 входные данные типа int16_t
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[out] dst выходные данные типа int16_t
 *  \param[in] size размер выходных данных
 */
void ref_fir_r8_h16(const int16_t *src0, const int16_t *coef0, int16_t *dst, const int size);

/*!
 *  \fn void ref_fir_r8_h24(const int16_t* src0, const int16_t* coef0, int16_t* dst, const int size)
 *  \brief Реализация fir фильтра
 *  \param[in] src0 входные данные типа int16_t
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[out] dst выходные данные типа int16_t
 *  \param[in] size размер выходных данных
 */
void ref_fir_r8_h24(const int16_t *src0, const int16_t *coef0, int16_t *dst, const int size);

/*!
 *  \fn void ref_fir_cplx(const int16_t* src0, const int16_t* coef0, int16_t* dst, const int coef0_size, const int
 * size)
 *  \brief Реализация комплексного fir фильтра
 *  \param[in] src0 входные данные типа int16_t
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[out] ds1 выходные данные типа int16_t
 *  \param[in] coef0_size количество коэффициентов
 *  \param[in] size размер выходных данных
 */
void ref_fir_cplx(const int16_t *src0, const int16_t *coef0, int16_t *dst, const int coef0_size, const int size);

/*!
 *  \fn void ref_fir_r8_hM16_rM8A8X8(const short* src0, const short* coef0, short* dst, const int coef0_size, const int
 * size)
 *  \brief Реализация fir фильтра
 *  \param[in] src0 входные данные типа int16_t
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[out] dst выходные данные типа int16_t
 *  \param[in] coef0_size количество коэффициентов
 *  \param[in] size размер выходных данных
 */
void ref_fir_r8_hM16_rM8A8X8(const short *src0, const short *coef0, short *dst, const int coef0_size, const int size);

/*!
 *  \fn void ref_fir_cplx_hM4X4(const short* src0, const short* coef0, short* dst, const int coef0_size, const int
 * size)
 *  \brief Реализация комплексного fir фильтра
 *  \param[in] src0 входные данные типа int16_t
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[out] dst выходные данные типа int16_t
 *  \param[in] coef0_size количество коэффициентов
 *  \param[in] size размер выходных данных
 */
void ref_fir_cplx_hM4X4(const short *src0, const short *coef0, short *dst, const int coef0_size, const int size);

/*!
 *  \fn void ref_fir_cplx_fl(const float* src0, const float* coef0, float* dst, int coef0_size, int size)
 *  \brief Реализация комплексного fir фильтра
 *  \param[in] src0 входные данные типа float
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[out] dst выходные данные типа float
 *  \param[in] coef0_size количество коэффициентов
 *  \param[in] size размер выходных данных
 */
void ref_fir_cplx_fl(const float *src0, const float *coef0, float *dst, int coef0_size, int size);

/*!
 *  \fn void ref_fir_gen(const int16_t* src0, const int16_t* coef0, int16_t* dst, const int coef0_size, const int size)
 *  \brief Реализация fir фильтра
 *  \param[in] src0 входные данные типа int16_t
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[out] dst выходные данные типа int16_t
 *  \param[in] coef0_size количество коэффициентов
 *  \param[in] size размер выходных данных
 */
void ref_fir_gen(const int16_t *src0, const int16_t *coef0, int16_t *dst, const int coef0_size, const int size);

/*!
 *  \fn void ref_fir_gen_fl(const float* src0, const float* coef0, float* dst, int coef0_size, int size)
 *  \brief Реализация fir фильтра
 *  \param[in] src0 входные данные типа float
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[out] dst выходные данные типа float
 *  \param[in] coef0_size количество коэффициентов
 *  \param[in] size размер выходных данных
 */
void ref_fir_gen_fl(const float *src0, const float *coef0, float *dst, int coef0_size, int size);

/*!
 *  \fn void ref_fir_gen_hM17_rA8X8(const int16_t* src0, const int16_t* coef0, int16_t* dst, const int coef0_size,
 * const int size)
 *  \brief Реализация fir фильтра
 *  \param[in] src0 входные данные типа int16_t
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[out] dst выходные данные типа int16_t
 *  \param[in] coef0_size количество коэффициентов
 *  \param[in] size размер выходных данных
 */
void ref_fir_gen_hM17_rA8X8(const int16_t *src0, const int16_t *coef0, int16_t *dst, const int coef0_size,
                            const int size);

/*!
 *  \fn int ref_firlms2(int16_t* coef0, const int16_t* src0, int16_t err, const int coef0_size)
 *  \brief Реализация firlms фильтра
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[in] src0 входные данные типа int16_t
 *  \param[in] err указатель на ошибку
 *  \param[in] coef0_size количество коэффициентов
 *      - \b int результат работы фильтра
 */
int ref_firlms2(int16_t *coef0, const int16_t *src0, int16_t err, const int coef0_size);

/*!
 *  \fn void ref_fir_sym(const int16_t* src, const int16_t* coef0, int16_t* dst, const int coef0_size, const int size,
 * const int shift)
 *  \brief Реализация симметричного fir фильтра
 *  \param[in] src входные данные типа int16_t
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[out] dst выходные данные типа int16_t
 *  \param[in] coef0_size количество коэффициентов
 *  \param[in] shift сдвиг результата
 */
void ref_fir_sym(const int16_t *src, const int16_t *coef0, int16_t *dst, const int coef0_size, const int size,
                 const int shift);

/*!
 *  \fn void ref_iir_lat(const int16_t* src, const int size, const int16_t* coef0, const int coef0_size, int* delay,
 * int16_t* dst)
 *  \brief Реализация решеточного iir фильтра
 *  \param[in] src входные данные типа int16_t
 *  \param[in] size размер выходных данных
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[in] coef0_size количество коэффициентов
 *  \param[in] delay данные задержки, нулевые при первом вызове
 *  \param[out] dst выходные данные типа int16_t
 */
void ref_iir_lat(const int16_t *src, const int size, const int16_t *coef0, const int coef0_size, int *delay,
                 int16_t *dst);

/*!
 *  \fn void ref_iir_lat_fl(const float* src, const int size, const float* coef0, const int coef0_size, float* delay,
 * float* dst)
 *  \brief Реализация решеточного iir фильтра
 *  \param[in] src входные данные типа float
 *  \param[in] size размер выходных данных
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[in] coef0_size количество коэффициентов
 *  \param[in] delay данные задержки, нулевые при первом вызове
 *  \param[out] dst выходные данные типа float
 */
void ref_iir_lat_fl(const float *src, const int size, const float *coef0, const int coef0_size, float *delay,
                    float *dst);

/*!
 *  \fn int16_t ref_iir_ss(const int16_t src, const int16_t* coef0, const int coef0_size, int16_t* state)
 *  \brief Реализация биквадратного iir фильтра
 *  \param[in] src входные данные типа int16_t
 *  \param[in] coef0 коэффициенты фильтра
 *  \param[in] coef0_size количество коэффициентов
 *  \param[in] state указатель на состояние
 *      - \b int результат работы фильтра
 */
int16_t ref_iir_ss(const int16_t src, const int16_t *coef0, const int coef0_size, int16_t *state);

/*!
 *  \fn void ref_fltoq15(const float *src, int16_t* dst, const int size)
 *  \brief Преобразование данных из float в Q15
 *  \param[in] src0 входные данные типа float
 *  \param[out] dst выходные данные типа Q15
 *  \param[in] size размер входных данных
 */
void ref_fltoq15(const float *src, int16_t *dst, const int size);

/*!
 *  \fn void ref_fft16x16(const int16_t* ptr_w, const int npoints, int16_t* ptr_x, int16_t* ptr_y)
 *  \brief Реализация fft для типов int16_t
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[in] npoints количество точек
 *  \param[out] ptr_x выходные данные типа int16_t
 *  \param[out] ptr_y выходные данные типа int16_t
 */
void ref_fft16x16(const int16_t *ptr_w, const int npoints, int16_t *ptr_x, int16_t *ptr_y);

/*!
 *  \fn void ref_fft16x16_imre(const int16_t* ptr_w, const int npoints, int16_t* ptr_x, int16_t* ptr_y)
 *  \brief Реализация fft для типов int16_t, порядок следования данных: мнимая, действительная части
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[in] npoints количество точек
 *  \param[out] ptr_x выходные данные типа int16_t
 *  \param[out] ptr_y выходные данные типа int16_t
 */
void ref_fft16x16_imre(const int16_t *ptr_w, const int npoints, int16_t *ptr_x, int16_t *ptr_y);

/*!
 *  \fn void ref_fft16x16r(const int n, int16_t* ptr_x, const int16_t* ptr_w, int16_t* ptr_y, int radix, int offset,
 * int nmax)
 *  \brief Реализация fft для типов int16_t
 *  \param[in] n размер fft
 *  \param[out] ptr_x выходные данные типа int16_t
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[out] ptr_y выходные данные типа int16_t
 *  \param[in] radix размер "бабочки" преобразования
 *  \param[in] offset смещение
 *  \param[in] nmax размер основного преобразования
 */
void ref_fft16x16r(const int n, int16_t *ptr_x, const int16_t *ptr_w, int16_t *ptr_y, int radix, int offset, int nmax);

/*!
 *  \fn void ref_fft16x32(const int16_t* ptr_w, const int npoints, int* ptr_x, int* ptr_y)
 *  \brief Реализация fft для типов int16_t и int32_t
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[in] npoints количество точек
 *  \param[out] ptr_x выходные данные типа int
 *  \param[out] ptr_y выходные данные типа int
 */
void ref_fft16x32(const int16_t *ptr_w, const int npoints, int *ptr_x, int *ptr_y);

/*!
 *  \fn void ref_fft32x32(const int* ptr_w, const int npoints, int* ptr_x, int* ptr_y)
 *  \brief Реализация fft для типов int32_t
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[in] npoints количество точек
 *  \param[out] ptr_x выходные данные типа int
 *  \param[out] ptr_y выходные данные типа int
 */
void ref_fft32x32(const int *ptr_w, const int npoints, int *ptr_x, int *ptr_y);

/*!
 *  \fn void ref_fft32x32s(const int* ptr_w, const int npoints, int* ptr_x, int* ptr_y)
 *  \brief Реализация fft для типов int32_t
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[in] npoints количество точек
 *  \param[out] ptr_x выходные данные типа int
 *  \param[out] ptr_y выходные данные типа int
 */
void ref_fft32x32s(const int *ptr_w, const int npoints, int *ptr_x, int *ptr_y);

/*!
 *  \fn void ref_ifft16x16(const int16_t* ptr_w, int npoints, int16_t* ptr_x, int16_t* ptr_y)
 *  \brief Реализация ifft для типов int16_t
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[in] npoints количество точек
 *  \param[in] ptr_x входные данные типа int16_t
 *  \param[out] ptr_y выходные данные типа int16_t
 */
void ref_ifft16x16(const int16_t *ptr_w, int npoints, int16_t *ptr_x, int16_t *ptr_y);

/*!
 *  \fn void ref_ifft16x16_imre(const int16_t* ptr_w, int npoints, int16_t* ptr_x, int16_t* ptr_y)
 *  \brief Реализация ifft для типов int16_t, порядок следования данных: мнимая, действительная части
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[in] npoints количество точек
 *  \param[in] ptr_x входные данные типа int16_t
 *  \param[out] ptr_y выходные данные типа int16_t
 */
void ref_ifft16x16_imre(const int16_t *ptr_w, int npoints, int16_t *ptr_x, int16_t *ptr_y);

/*!
 *  \fn void ref_ifft16x32(const int16_t* ptr_w, int npoints, int* ptr_x, int* ptr_y)
 *  \brief Реализация ifft для типов int16_t и int32_t
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[in] npoints количество точек
 *  \param[in] ptr_x входные данные типа int
 *  \param[out] ptr_y выходные данные типа int
 */
void ref_ifft16x32(const int16_t *ptr_w, int npoints, int *ptr_x, int *ptr_y);

/*!
 *  \fn void ref_ifft32x32(const int* ptr_w, int npoints, int* ptr_x, int* ptr_y)
 *  \brief Реализация ifft для типов int32_t
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[in] npoints количество точек
 *  \param[in] ptr_x входные данные типа int
 *  \param[out] ptr_y выходные данные типа int
 */
void ref_ifft32x32(const int *ptr_w, int npoints, int *ptr_x, int *ptr_y);

/*!
 *  \fn void ref_vecmul_fl(const float *src0, const float *src1, float *dst, const int size)
 *  \brief Умножение массивов типа float
 *  \param[in] src0 входной массив типа float
 *  \param[in] src1 входной массив типа float
 *  \param[out] dst выходные данные типа float
 *  \param[in] size размер входных данных
 */
void ref_vecmul_fl(const float *src0, const float *src1, float *dst, const int size);

/*!
 *  \fn void ref_urand16(uint16_t* src, const int size, void* dst)
 *  \brief Заполнение массива случайными числами
 *  \param[in] src входной массив типа uint16_t
 *  \param[in] size размер выходных данных
 *  \param[out] dst выходные данные
 */
void ref_urand16(uint16_t *src, const int size, void *dst);

/*!
 *  \fn void ref_mat_mul_gemm_fl(const float *src0, const float a, const int32_t rows0, const int32_t columns0, const
 * float *src1, const int32_t columns1, float *dst)
 *  \brief Умножение матриц типа float, первая матрица домножается на коэф. а, результат суммируется со значениями из
 * dst
 *  \param[in] src0 входные данные типа float
 *  \param[in] a коэффициент
 *  \param[in] rows0 количество строк первой матрицы
 *  \param[in] columns0 количество столбцов первой матрицы
 *  \param[in] src1 входные данные типа float
 *  \param[in] columns1 количество столбцов второй матрицы
 *  \param[in/out] dst выходные данные типа float
 */
void ref_mat_mul_gemm_fl(const float *src0, const float a, const int32_t rows0, const int32_t columns0,
                         const float *src1, const int32_t columns1, float *dst);

/*!
 *  \fn void ref_mat_mul_gemm_db(double *src0, const double a, const int32_t rows0, const int32_t columns0, double
 * *src1, const int32_t columns1, double *dst)
 *  \brief Умножение матриц типа double, первая матрица домножается на коэф. а, результат суммируется со значениями из
 * dst
 *  \param[in] src0 входные данные типа double
 *  \param[in] a коэффициент
 *  \param[in] rows0 количество строк первой матрицы
 *  \param[in] columns0 количество столбцов первой матрицы
 *  \param[in] src1 входные данные типа double
 *  \param[in] columns1 количество столбцов второй матрицы
 *  \param[in/out] dst выходные данные типа double
 */
void ref_mat_mul_gemm_db(double *src0, const double a, const int32_t rows0, const int32_t columns0, double *src1,
                         const int32_t columns1, double *dst);

/*!
 *  \fn int ref_lud_fl(const int size, float* src, float* L, float* U, uint16_t* P)
 *  \brief Получение нижней и верхней треугольных матриц
 *  \param[in] size количество строк/столбцов матрицы
 *  \param[in] src указатель на исходную матрицу типа float
 *  \param[out] L указатель на нижнюю треугольную матрицу
 *  \param[out] U указатель на верхнюю треугольную матрицу
 *  \param[out] P указатель на матрицу перестановок
 *      - \b int 0 в случае успешной работы
 */
int ref_lud_fl(const int size, float *src, float *L, float *U, uint16_t *P);

/*!
 *  \fn int ref_lud_cplx_fl(const int size, float* src, float* L, float* U, uint16_t* P)
 *  \brief Получение нижней и верхней треугольных комплексных матриц
 *  \param[in] size количество строк/столбцов матрицы
 *  \param[in] src указатель на исходную матрицу типа float
 *  \param[out] L указатель на нижнюю треугольную матрицу
 *  \param[out] U указатель на верхнюю треугольную матрицу
 *  \param[out] P указатель на матрицу перестановок
 *      - \b int 0 в случае успешной работы
 */
int ref_lud_cplx_fl(const int size, float *src, float *L, float *U, uint16_t *P);

/*!
 *  \fn int ref_lud_db(const int size, double* src, double* L, double* U, uint16_t* P)
 *  \brief Получение нижней и верхней треугольных матриц
 *  \param[in] size количество строк/столбцов матрицы
 *  \param[in] src указатель на исходную матрицу типа double
 *  \param[out] L указатель на нижнюю треугольную матрицу
 *  \param[out] U указатель на верхнюю треугольную матрицу
 *  \param[out] P указатель на матрицу перестановок
 *      - \b int 0 в случае успешной работы
 */
int ref_lud_db(const int size, double *src, double *L, double *U, uint16_t *P);

/*!
 *  \fn int ref_lud_cplx_db(const int size, double* src, double* L, double* U, uint16_t* P)
 *  \brief Получение нижней и верхней треугольных комплексных матриц
 *  \param[in] size количество строк/столбцов матрицы
 *  \param[in] src указатель на исходную матрицу типа double
 *  \param[out] L указатель на нижнюю треугольную матрицу
 *  \param[out] U указатель на верхнюю треугольную матрицу
 *  \param[out] P указатель на матрицу перестановок
 *      - \b int 0 в случае успешной работы
 */
int ref_lud_cplx_db(const int size, double *src, double *L, double *U, uint16_t *P);

/*!
 *  \fn int ref_lud_inverse_fl(const int size, uint16_t* P, float* L, float* U, float* inv_A)
 *  \brief Получение нижней и верхней треугольных матриц, матрицы перестановок и обратной матрицы
 * (inv_A=inv(U)*inv(L)).
 *  \param[in] size количество строк/столбцов матрицы
 *  \param[out] P указатель на матрицу перестановок
 *  \param[out] L указатель на нижнюю треугольную матрицу
 *  \param[out] U указатель на верхнюю треугольную матрицу
 *  \param[out] inv_A указатель на обратную матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_lud_inverse_fl(const int size, uint16_t *P, float *L, float *U, float *inv_A);

/*!
 *  \fn int ref_lud_inverse_cplx_fl(const int size, uint16_t* P, float* L, float* U, float* inv_A)
 *  \brief Получение нижней и верхней треугольных матриц, матрицы перестановок и обратной матрицы
 * (inv_A=inv(U)*inv(L)), комплексные числа.
 *  \param[in] size количество строк/столбцов матрицы
 *  \param[out] P указатель на матрицу перестановок
 *  \param[out] L указатель на нижнюю треугольную матрицу
 *  \param[out] U указатель на верхнюю треугольную матрицу
 *  \param[out] inv_A указатель на обратную матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_lud_inverse_cplx_fl(const int size, uint16_t *P, float *L, float *U, float *inv_A);

/*!
 *  \fn int ref_lud_inverse_db(const int size, uint16_t* P, double* L, double* U, double* inv_A)
 *  \brief Получение нижней и верхней треугольных матриц, матрицы перестановок и обратной матрицы
 * (inv_A=inv(U)*inv(L)).
 *  \param[in] size количество строк/столбцов матрицы
 *  \param[out] P указатель на матрицу перестановок
 *  \param[out] L указатель на нижнюю треугольную матрицу
 *  \param[out] U указатель на верхнюю треугольную матрицу
 *  \param[out] inv_A указатель на обратную матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_lud_inverse_db(const int size, uint16_t *P, double *L, double *U, double *inv_A);

/*!
 *  \fn int ref_lud_inverse_cplx_db(const int size, uint16_t* P, double* L, double* U, double* inv_A)
 *  \brief Получение нижней и верхней треугольных матриц, матрицы перестановок и обратной матрицы
 * (inv_A=inv(U)*inv(L)), комплексные числа.
 *  \param[in] size количество строк/столбцов матрицы
 *  \param[out] P указатель на матрицу перестановок
 *  \param[out] L указатель на нижнюю треугольную матрицу
 *  \param[out] U указатель на верхнюю треугольную матрицу
 *  \param[out] inv_A указатель на обратную матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_lud_inverse_cplx_db(const int size, uint16_t *P, double *L, double *U, double *inv_A);

/*!
 *  \fn int ref_lud_solver_fl(const int size, uint16_t* P, float* L, float* U, float* b, float* b_mod, float* y, float*
 * x)
 *  \brief Поиск решений системы линейных уравнений A * x = b с использование данных функции ref_lud_fl.
 *  \param[in] size количество строк/столбцов матрицы
 *  \param[in] P указатель на матрицу перестановок
 *  \param[in] L указатель на нижнюю треугольную матрицу
 *  \param[in] U указатель на верхнюю треугольную матрицу
 *  \param[in] b указатель на вектор коэффициентов
 *  \param[in] b_mod указатель на измененный вектор коэффициентов
 *  \param[in] y указатель на временный вектор
 *  \param[out] x указатель на решения системы
 *      - \b int 0 в случае успешной работы
 */
int ref_lud_solver_fl(const int size, uint16_t *P, float *L, float *U, float *b, float *b_mod, float *y, float *x);

/*!
 *  \fn int ref_lud_solver_cplx_fl(const int size, uint16_t* P, float* L, float* U, float* b, float* b_mod, float* y,
 * float* x)
 *  \brief Поиск решений системы линейных уравнений A * x = b с использование данных функции ref_lud_cplx_fl,
 * комплексные числа
 *  \param[in] size количество строк/столбцов матрицы
 *  \param[in] P указатель на матрицу перестановок
 *  \param[in] L указатель на нижнюю треугольную матрицу
 *  \param[in] U указатель на верхнюю треугольную матрицу
 *  \param[in] b указатель на вектор коэффициентов
 *  \param[in] b_mod указатель на измененный вектор коэффициентов
 *  \param[in] y указатель на временный вектор
 *  \param[out] x указатель на решения системы
 *      - \b int 0 в случае успешной работы
 */
int ref_lud_solver_cplx_fl(const int size, uint16_t *P, float *L, float *U, float *b, float *b_mod, float *y,
                           float *x);

/*!
 *  \fn int ref_lud_solver_db(const int size, uint16_t* P, double* L, double* U, double* b, double* b_mod, double* y,
 * double* x)
 *  \brief Поиск решений системы линейных уравнений A * x = b с использование данных функции ref_lud_cplx_db
 *  \param[in] size количество строк/столбцов матрицы
 *  \param[in] P указатель на матрицу перестановок
 *  \param[in] L указатель на нижнюю треугольную матрицу
 *  \param[in] U указатель на верхнюю треугольную матрицу
 *  \param[in] b указатель на вектор коэффициентов
 *  \param[in] b_mod указатель на измененный вектор коэффициентов
 *  \param[in] y указатель на временный вектор
 *  \param[out] x указатель на решения системы
 *      - \b int 0 в случае успешной работы
 */
int ref_lud_solver_db(const int size, uint16_t *P, double *L, double *U, double *b, double *b_mod, double *y,
                      double *x);

/*!
 *  \fn int ref_lud_solver_cplx_db(const int size, uint16_t* P, double* L, double* U, double* b, double* b_mod, double*
 * y, double* x)
 *  \brief Поиск решений системы линейных уравнений A * x = b с использование данных функции ref_lud_cplx_db,
 * комплексные числа
 *  \param[in] size количество строк/столбцов матрицы
 *  \param[in] P указатель на матрицу перестановок
 *  \param[in] L указатель на нижнюю треугольную матрицу
 *  \param[in] U указатель на верхнюю треугольную матрицу
 *  \param[in] b указатель на вектор коэффициентов
 *  \param[in] b_mod указатель на измененный вектор коэффициентов
 *  \param[in] y указатель на временный вектор
 *  \param[out] x указатель на решения системы
 *      - \b int 0 в случае успешной работы
 */
int ref_lud_solver_cplx_db(const int size, uint16_t *P, double *L, double *U, double *b, double *b_mod, double *y,
                           double *x);

/*!
 *  \fn void ref_mat_submat_copy_fl(float* x, const int rows, const int cols, const int start, const int n, float* y,
 * const int dir)
 *  \brief Копирование части данных одной матрицы в другую типов float
 *  \param[in/out] x указатель на первую матрицу
 *  \param[in] rows количество строк
 *  \param[in] cols количество столбцов
 *  \param[in] start стартовый индекс строки для копирования
 *  \param[in] n количество строк для копирования
 *  \param[in/out] y указатель на вторую матрицу
 *  \param[in] dir направление копирования
 */
void ref_mat_submat_copy_fl(float *x, const int rows, const int cols, const int start, const int n, float *y,
                            const int dir);

/*!
 *  \fn void ref_mat_submat_copy_db(double* x, const int rows, const int cols, const int start, const int n, double* y,
 * const int dir)
 *  \brief Копирование части данных одной матрицы в другую типов double
 *  \param[in/out] x указатель на первую матрицу
 *  \param[in] rows количество строк
 *  \param[in] cols количество столбцов
 *  \param[in] start стартовый индекс строки для копирования
 *  \param[in] n количество строк для копирования
 *  \param[in/out] y указатель на вторую матрицу
 *  \param[in] dir направление копирования
 */
void ref_mat_submat_copy_db(double *x, const int rows, const int cols, const int start, const int n, double *y,
                            const int dir);

/*!
 *  \fn void ref_vecrecip_fl(const float* src, float* dst, const int size)
 *  \brief Поиск обратных значений элементов массива
 *  \param[in] src указатель на входной массив
 *  \param[out] dst указатель на выходной массив
 *  \param[in] size количество массивов
 */
void ref_vecrecip_fl(const float *src, float *dst, const int size);

/*!
 *  \fn void ref_mat_mul_gemm_cplx_fl(const float *src0, const float a, const int32_t rows0, const int32_t columns0,
 * const float *src1, const int32_t columns1, float *dst)
 *  \brief Умножение комплексных матриц типа float, первая матрица домножается на коэф. а, результат суммируется со
 * значениями из dst
 *  \param[in] src0 входные данные типа float
 *  \param[in] a коэффициент
 *  \param[in] rows0 количество строк первой матрицы
 *  \param[in] columns0 количество столбцов первой матрицы
 *  \param[in] src1 входные данные типа float
 *  \param[in] columns1 количество столбцов второй матрицы
 *  \param[in/out] dst выходные данные типа float
 */
void ref_mat_mul_gemm_cplx_fl(const float *src0, const float a, const int32_t rows0, const int32_t columns0,
                              const float *src1, const int32_t columns1, float *dst);

/*!
 *  \fn void ref_urand_fl(const uint32_t size, float* vector, void* state)
 *  \brief Генерация случайных чисел типа float
 *  \param[in] size размер выходного массива
 *  \param[out] vector указатель на выходной массив
 *  \param[in/out] state параметр генерации
 */
void ref_urand_fl(const uint32_t size, float *vector, void *state);

/*!
 *  \fn void ref_biquad_fl(float* x, float* b, float* a, float* delay, float* y, const int size)
 *  \brief Биквадратный фильтр
 *  \param[in] x указатель на входной массив
 *  \param[in] b указатель на коэффициенты
 *  \param[in] a указатель на коэффициенты
 *  \param[in] delay задержка фильтра
 *  \param[out] y указатель на выхожной массив
 *  \param[in] size размер массивов
 */
void ref_biquad_fl(float *x, float *b, float *a, float *delay, float *y, const int size);

/*!
 *  \fn ref_bitrev_cplx_fl(double* src, int16_t* index, int size)
 *  \brief Поразрядно обратная перестановка
 *  \param[in] src указатель на входной массив
 *  \param[out] index указатель на выхожной массив
 *  \param[in] size размер входного массива
 */
void ref_bitrev_cplx_fl(double *src, int16_t *index, int size);

/*!
 *  \fn int ref_qrd_fl(const int Nrows, const int Ncols, float *A, float *Q, float *R, float *u)
 *  \brief Поиск ортогональной и верхней правой треугольной матриц
 *  \param[in] Nrows количество строк входной матрицы
 *  \param[in] Ncols количество столбцов входной матрицы
 *  \param[in] A указатель на входную матрицу
 *  \param[out] Q указатель на ортогональную матрицу
 *  \param[out] R указатель на верхнюю правую треугольную матрицу
 *  \param[out] u указатель на вектор временных значений
 *      - \b int 0 в случае успешной работы
 */
int ref_qrd_fl(const int Nrows, const int Ncols, float *A, float *Q, float *R, float *u);

/*!
 *  \fn int ref_qrd_solver_fl(const int Nrows, const int Ncols, float *Q, float *R, float *b, float *y, float *x)
 *  \brief Поиск решений системы линейных уравнений A * x = b с использование данных функции ref_qrd_fl
 *  \param[in] Nrows количество строк входной матрицы
 *  \param[in] Ncols количество столбцов входной матрицы
 *  \param[in] Q указатель на ортогональную матрицу
 *  \param[in] R указатель на верхнюю правую треугольную матрицу
 *  \param[in] b указатель на вектор коэффициентов
 *  \param[in] y указатель на временный вектор
 *  \param[out] x указатель на решения системы
 *      - \b int 0 в случае успешной работы
 */
int ref_qrd_solver_fl(const int Nrows, const int Ncols, float *Q, float *R, float *b, float *y, float *x);

/*!
 *  \fn int ref_qrd_inverse_fl(const int Nrows, const int Ncols, float *Q, float *R, float *inv_A)
 *  \brief Поиск обратной матрицы
 *  \param[in] Nrows количество строк входной матрицы
 *  \param[in] Ncols количество столбцов входной матрицы
 *  \param[in] Q указатель на ортогональную матрицу
 *  \param[in] R указатель на верхнюю правую треугольную матрицу
 *  \param[out] inv_A указатель на обратную матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_qrd_inverse_fl(const int Nrows, const int Ncols, float *Q, float *R, float *inv_A);

/*!
 *  \fn int ref_qrd_db(const int Nrows, const int Ncols, double *A, double *Q, double *R, double *u)
 *  \brief Поиск ортогональной и верхней правой треугольной матриц
 *  \param[in] Nrows количество строк входной матрицы
 *  \param[in] Ncols количество столбцов входной матрицы
 *  \param[in] A указатель на входную матрицу
 *  \param[out] Q указатель на ортогональную матрицу
 *  \param[out] R указатель на верхнюю правую треугольную матрицу
 *  \param[out] u указатель на вектор временных значений
 *      - \b int 0 в случае успешной работы
 */
int ref_qrd_db(const int Nrows, const int Ncols, double *A, double *Q, double *R, double *u);

/*!
 *  \fn int ref_qrd_solver_db(const int Nrows,const int Ncols,double *Q,double *R,double *b,double *y,double *x)
 *  \brief Поиск решений системы линейных уравнений A * x = b с использование данных функции ref_qrd_db
 *  \param[in] Nrows количество строк входной матрицы
 *  \param[in] Ncols количество столбцов входной матрицы
 *  \param[in] Q указатель на ортогональную матрицу
 *  \param[in] R указатель на верхнюю правую треугольную матрицу
 *  \param[in] b указатель на вектор коэффициентов
 *  \param[in] y указатель на временный вектор
 *  \param[out] x указатель на решения системы
 *      - \b int 0 в случае успешной работы
 */
int ref_qrd_solver_db(const int Nrows, const int Ncols, double *Q, double *R, double *b, double *y, double *x);

/*!
 *  \fn int ref_qrd_inverse_db(const int Nrows, const int Ncols, double *Q, double *R, double *inv_A)
 *  \brief Поиск обратной матрицы
 *  \param[in] Nrows количество строк входной матрицы
 *  \param[in] Ncols количество столбцов входной матрицы
 *  \param[in] Q указатель на ортогональную матрицу
 *  \param[in] R указатель на верхнюю правую треугольную матрицу
 *  \param[out] inv_A указатель на обратную матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_qrd_inverse_db(const int Nrows, const int Ncols, double *Q, double *R, double *inv_A);

/*!
 *  \fn int ref_qrd_cplx_fl(const int Nrows, const int Ncols, float *A, float *Q, float *R, float *u)
 *  \brief Поиск ортогональной и верхней правой треугольной матриц, комплексные числа
 *  \param[in] Nrows количество строк входной матрицы
 *  \param[in] Ncols количество столбцов входной матрицы
 *  \param[in] A указатель на входную матрицу
 *  \param[out] Q указатель на ортогональную матрицу
 *  \param[out] R указатель на верхнюю правую треугольную матрицу
 *  \param[out] u указатель на вектор временных значений
 *      - \b int 0 в случае успешной работы
 */
int ref_qrd_cplx_fl(const int Nrows, const int Ncols, float *A, float *Q, float *R, float *u);

/*!
 *  \fn int ref_qrd_solver_cplx_fl(const int Nrows, const int Ncols, float *Q, float *R, float *b, float *y, float *x)
 *  \brief Поиск решений системы линейных уравнений A * x = b с использование данных функции ref_qrd_cplx_fl,
 * комплексные числа
 *  \param[in] Nrows количество строк входной матрицы
 *  \param[in] Ncols количество столбцов входной матрицы
 *  \param[in] Q указатель на ортогональную матрицу
 *  \param[in] R указатель на верхнюю правую треугольную матрицу
 *  \param[in] b указатель на вектор коэффициентов
 *  \param[in] y указатель на временный вектор
 *  \param[out] x указатель на решения системы
 *      - \b int 0 в случае успешной работы
 */
int ref_qrd_solver_cplx_fl(const int Nrows, const int Ncols, float *Q, float *R, float *b, float *y, float *x);

/*!
 *  \fn int ref_qrd_inverse_cplx_fl(const int Nrows, const int Ncols, float *Q, float *R, float *inv_A)
 *  \brief Поиск обратной матрицы, комплексные числа
 *  \param[in] Nrows количество строк входной матрицы
 *  \param[in] Ncols количество столбцов входной матрицы
 *  \param[in] Q указатель на ортогональную матрицу
 *  \param[in] R указатель на верхнюю правую треугольную матрицу
 *  \param[out] inv_A указатель на обратную матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_qrd_inverse_cplx_fl(const int Nrows, const int Ncols, float *Q, float *R, float *inv_A);

/*!
 *  \fn int ref_qrd_cplx_db(const int Nrows, const int Ncols, double *A, double *Q, double *R, double *u)
 *  \brief Поиск ортогональной и верхней правой треугольной матриц, комплексные числа
 *  \param[in] Nrows количество строк входной матрицы
 *  \param[in] Ncols количество столбцов входной матрицы
 *  \param[in] A указатель на входную матрицу
 *  \param[out] Q указатель на ортогональную матрицу
 *  \param[out] R указатель на верхнюю правую треугольную матрицу
 *  \param[out] u указатель на вектор временных значений
 *      - \b int 0 в случае успешной работы
 */
int ref_qrd_cplx_db(const int Nrows, const int Ncols, double *A, double *Q, double *R, double *u);

/*!
 *  \fn int ref_qrd_solver_cplx_db(const int Nrows, const int Ncols, double *Q, double *R, double *b, double *y, double
 * *x)
 *  \brief Поиск решений системы линейных уравнений A * x = b с использование данных функции ref_qrd_cplx_db,
 * комплексные числа
 *  \param[in] Nrows количество строк входной матрицы
 *  \param[in] Ncols количество столбцов входной матрицы
 *  \param[in] Q указатель на ортогональную матрицу
 *  \param[in] R указатель на верхнюю правую треугольную матрицу
 *  \param[in] b указатель на вектор коэффициентов
 *  \param[in] y указатель на временный вектор
 *  \param[out] x указатель на решения системы
 *      - \b int 0 в случае успешной работы
 */
int ref_qrd_solver_cplx_db(const int Nrows, const int Ncols, double *Q, double *R, double *b, double *y, double *x);

/*!
 *  \fn int ref_qrd_inverse_cplx_db(const int Nrows, const int Ncols, double *Q, double *R, double *inv_A)
 *  \brief Поиск обратной матрицы, комплексные числа
 *  \param[in] Nrows количество строк входной матрицы
 *  \param[in] Ncols количество столбцов входной матрицы
 *  \param[in] Q указатель на ортогональную матрицу
 *  \param[in] R указатель на верхнюю правую треугольную матрицу
 *  \param[out] inv_A указатель на обратную матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_qrd_inverse_cplx_db(const int Nrows, const int Ncols, double *Q, double *R, double *inv_A);

/*!
 *  \fn void ref_fft_fl(const int N, float *ptr_x, const float *ptr_w, float *ptr_y, uint8_t *brev, int n_min, int
 * offset, int n_max)
 *  \brief fft преобразование
 *  \param[in] N размер преобразования
 *  \param[in] ptr_x указатель на входные данные
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[out] ptr_y указатель на выходные данные
 *  \param[in] brev указатель на таблицу преобразования битов (не используется)
 *  \param[in] n_min параметр преобразования, 4 если N является степенью 4, иначе 2
 *  \param[in] offset смещение
 *  \param[in] n_max размер основного преобразования
 */
void ref_fft_fl(const int N, float *ptr_x, const float *ptr_w, float *ptr_y, uint8_t *brev, int n_min, int offset,
                int n_max);

/*!
 *  void ref_fft_db(const int N, double *ptr_x, const double *ptr_w, double *ptr_y, int n_min, int offset, int n_max)
 *  \brief fft преобразование
 *  \param[in] N размер преобразования
 *  \param[in] ptr_x указатель на входные данные
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[out] ptr_y указатель на выходные данные
 *  \param[in] n_min параметр преобразования, 4 если N является степенью 4, иначе 2
 *  \param[in] offset смещение
 *  \param[in] n_max размер основного преобразования
 */
void ref_fft_db(const int N, double *ptr_x, const double *ptr_w, double *ptr_y, int n_min, int offset, int n_max);

/*!
 *  void ref_fft_c2r_fl (const int N, float *ptr_x, const float *ptr_w, float *ptr_y, uint8_t *brev, int n_min, int
 * offset, int n_max)
 *  \brief fft преобразование
 *  \param[in] N размер преобразования
 *  \param[in] ptr_x указатель на входные данные
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[out] ptr_y указатель на выходные данные
 *  \param[in] brev указатель на таблицу преобразования битов (не используется)
 *  \param[in] n_min параметр преобразования, 4 если N является степенью 4, иначе 2
 *  \param[in] offset смещение
 *  \param[in] n_max размер основного преобразования
 */
void ref_fft_c2r_fl(const int N, float *ptr_x, const float *ptr_w, float *ptr_y, uint8_t *brev, int n_min, int offset,
                    int n_max);

/*!
 *  void ref_ifft_c2r_fl(const int N, float *ptr_x, const float *ptr_w, float *ptr_y, uint8_t *brev, int n_min, int
 * offset, int n_max)
 *  \brief ifft преобразование
 *  \param[in] N размер преобразования
 *  \param[in] ptr_x указатель на входные данные
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[out] ptr_y указатель на выходные данные
 *  \param[in] brev указатель на таблицу преобразования битов (не используется)
 *  \param[in] n_min параметр преобразования, 4 если N является степенью 4, иначе 2
 *  \param[in] offset смещение
 *  \param[in] n_max размер основного преобразования
 */
void ref_ifft_c2r_fl(const int N, float *ptr_x, const float *ptr_w, float *ptr_y, uint8_t *brev, int n_min, int offset,
                     int n_max);

/*!
 *  void ref_ifft_db(const int N, double *ptr_x, const double *ptr_w, double *ptr_y, int n_min, int offset, int n_max)
 *  \brief ifft преобразование
 *  \param[in] N размер преобразования
 *  \param[in] ptr_x указатель на входные данные
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[out] ptr_y указатель на выходные данные
 *  \param[in] n_min параметр преобразования, 4 если N является степенью 4, иначе 2
 *  \param[in] offset смещение
 *  \param[in] n_max размер основного преобразования
 */
void ref_ifft_db(const int N, double *ptr_x, const double *ptr_w, double *ptr_y, int n_min, int offset, int n_max);

/*!
 *  void ref_ifft_fl(const int N, float *ptr_x, const float *ptr_w, float *ptr_y, uint8_t *brev, int n_min, int offset,
 * int n_max)
 *  \brief ifft преобразование
 *  \param[in] N размер преобразования
 *  \param[in] ptr_x указатель на входные данные
 *  \param[in] ptr_w указатель на коэффициенты
 *  \param[out] ptr_y указатель на выходные данные
 *  \param[in] brev указатель на таблицу преобразования битов (не используется)
 *  \param[in] n_min параметр преобразования, 4 если N является степенью 4, иначе 2
 *  \param[in] offset смещение
 *  \param[in] n_max размер основного преобразования
 */
void ref_ifft_fl(const int N, float *ptr_x, const float *ptr_w, float *ptr_y, uint8_t *brev, int n_min, int offset,
                 int n_max);

/*!
 *  \fn void ref_urand32(const uint32_t size, void* vector, void* state)
 *  \brief Генерация случайных чисел типа int32
 *  \param[in] size размер выходного массива
 *  \param[out] vector указатель на выходной массив
 *  \param[in/out] state параметр генерации
 */
void ref_urand32(const uint32_t size, void *vector, void *state);

/*!
 *  \fn void ref_nrand_fl(const int size, float *vector, void *state)
 *  \brief Генерация случайных чисел типа float, нормальное распределение
 *  \param[in] size размер выходного массива
 *  \param[out] vector указатель на выходной массив
 *  \param[in/out] state параметр генерации
 */
void ref_nrand_fl(const int size, float *vector, void *state);

/*!
 *  \fn void ref_erand_fl(const int size, void *vector, void *state)
 *  \brief Генерация случайных чисел типа float, экспоненциальное распределение
 *  \param[in] size размер выходного массива
 *  \param[out] vector указатель на выходной массив
 *  \param[in/out] state параметр генерации
 */
void ref_erand_fl(const int size, void *vector, void *state);

/*!
 *  \fn int ref_svd_fl(const int Nrows, const int Ncols, float *A, float *U, float *V, float *U1, float *diag, float
 * *superdiag)
 *  \brief Сингулярное разложение матрицы
 *  \param[in] Nrows количество строк
 *  \param[in] Ncols количество столбцов
 *  \param[in] A указатель на входную матрицу
 *  \param[out] U указатель на выходную матрицу U
 *  \param[out] V указатель на выходную матрицу V
 *  \param[out] U1 указатель на выходной массив U1
 *  \param[out] diag указатель на выходной массив
 *  \param[out] superdiag указатель на выходной массив
 *      - \b int 0 в случае успешной работы
 */
int ref_svd_fl(const int Nrows, const int Ncols, float *A, float *U, float *V, float *U1, float *diag,
               float *superdiag);

/*!
 *  \fn int ref_svd_cplx_fl(const int Nrows, const int Ncols, float *A, float *U, float *V, float *U1, float *diag,
 * float *superdiag)
 *  \brief Сингулярное разложение матрицы, комплексные числа
 *  \param[in] Nrows количество строк
 *  \param[in] Ncols количество столбцов
 *  \param[in] A указатель на входную матрицу
 *  \param[out] U указатель на выходную матрицу U
 *  \param[out] V указатель на выходную матрицу V
 *  \param[out] U1 указатель на выходной массив U1
 *  \param[out] diag указатель на выходной массив
 *  \param[out] superdiag указатель на выходной массив
 *      - \b int 0 в случае успешной работы
 */
int ref_svd_cplx_fl(const int Nrows, const int Ncols, float *A, float *U, float *V, float *U1, float *diag,
                    float *superdiag);

/*!
 *  \fn int ref_svd_db(const int Nrows, const int Ncols, double *A, double *U, double *V, double *U1, double *diag,
 * double *superdiag)
 *  \brief Сингулярное разложение матрицы
 *  \param[in] Nrows количество строк
 *  \param[in] Ncols количество столбцов
 *  \param[in] A указатель на входную матрицу
 *  \param[out] U указатель на выходную матрицу U
 *  \param[out] V указатель на выходную матрицу V
 *  \param[out] U1 указатель на выходной массив U1
 *  \param[out] diag указатель на выходной массив
 *  \param[out] superdiag указатель на выходной массив
 *      - \b int 0 в случае успешной работы
 */
int ref_svd_db(const int Nrows, const int Ncols, double *A, double *U, double *V, double *U1, double *diag,
               double *superdiag);

/*!
 *  \fn int ref_svd_cplx_db(const int Nrows, const int Ncols, double *A, double *U, double *V, double *U1, double
 * *diag, double *superdiag)
 *  \brief Сингулярное разложение матрицы, комплексные числа
 *  \param[in] Nrows количество строк
 *  \param[in] Ncols количество столбцов
 *  \param[in] A указатель на входную матрицу
 *  \param[out] U указатель на выходную матрицу U
 *  \param[out] V указатель на выходную матрицу V
 *  \param[out] U1 указатель на выходной массив U1
 *  \param[out] diag указатель на выходной массив
 *  \param[out] superdiag указатель на выходной массив
 *      - \b int 0 в случае успешной работы
 */
int ref_svd_cplx_db(const int Nrows, const int Ncols, double *A, double *U, double *V, double *U1, double *diag,
                    double *superdiag);

/*!
 *  \fn int ref_cholesky_db(const int enable_test, const int order, double * A, double * L)
 *  \brief Поиск нижней треугольной матрицы, проверка является ли матрица положительно определенной
 *  \param[in] enable_test параметр проверки на положительную определенность
 *  \param[in] order размер матрицы
 *  \param[in] A указатель на входную матрицу
 *  \param[out] L указатель на нижнюю треугольную матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_cholesky_db(const int enable_test, const int order, double *A, double *L);

/*!
 *  \fn int ref_cholesky_in_place_db(const int enable_test, const int order, double * A)
 *  \brief Поиск нижней треугольной матрицы, проверка является ли матрица положительно определенной
 *  \param[in] enable_test параметр проверки на положительную определенность
 *  \param[in] order размер матрицы
 *  \param[in/out] A указатель на матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_cholesky_in_place_db(const int enable_test, const int order, double *A);

/*!
 *  \fn int ref_cholesky_solver_db(const int order, double * L, double * y, double * b, double * x)
 *  \brief Поиск решений системы линейных уравнений A * x = b с использование данных функции ref_cholesky_db
 *  \param[in] order размер матрицы
 *  \param[in] L указатель на нижнюю треугольную матрицу
 *  \param[in] b указатель на вектор коэффициентов
 *  \param[out] y указатель на вектор промежуточного результата
 *  \param[out] x указатель на решения системы
 *      - \b int 0 в случае успешной работы
 */
int ref_cholesky_solver_db(const int order, double *L, double *y, double *b, double *x);

/*!
 *  \fn int ref_cholesky_cplx_db(const int enable_test, const int Nrows, double *A, double *L)
 *  \brief Поиск нижней треугольной матрицы, проверка является ли матрица положительно определенной, комплексные числа
 *  \param[in] enable_test параметр проверки на положительную определенность
 *  \param[in] order размер матрицы
 *  \param[in] A указатель на входную матрицу
 *  \param[out] L указатель на нижнюю треугольную матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_cholesky_cplx_db(const int enable_test, const int Nrows, double *A, double *L);

/*!
 *  \fn int ref_cholesky_in_place_cmplx_db(const int enable_test, const int Nrows, double *A)
 *  \brief Поиск нижней треугольной матрицы, проверка является ли матрица положительно определенной, комплексные числа
 *  \param[in] enable_test параметр проверки на положительную определенность
 *  \param[in] order размер матрицы
 *  \param[in/out] A указатель на матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_cholesky_in_place_cmplx_db(const int enable_test, const int Nrows, double *A);

/*!
 *  \fn int ref_cholesky_solver_cmplx_db(const int Nrows, double *L, double *y, double *b, double *x)
 *  \brief Поиск решений системы линейных уравнений A * x = b с использование данных функции ref_cholesky_cplx_db,
 * комплексные числа
 *  \param[in] order размер матрицы
 *  \param[in] L указатель на нижнюю треугольную матрицу
 *  \param[in] b указатель на вектор коэффициентов
 *  \param[out] y указатель на вектор промежуточного результата
 *  \param[out] x указатель на решения системы
 *      - \b int 0 в случае успешной работы
 */
int ref_cholesky_solver_cmplx_db(const int Nrows, double *L, double *y, double *b, double *x);

/*!
 *  \fn int ref_cholesky_fl(const int enable_test, const int order, float *A, float *L)
 *  \brief Поиск нижней треугольной матрицы, проверка является ли матрица положительно определенной
 *  \param[in] enable_test параметр проверки на положительную определенность
 *  \param[in] order размер матрицы
 *  \param[in] A указатель на входную матрицу
 *  \param[out] L указатель на нижнюю треугольную матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_cholesky_fl(const int enable_test, const int order, float *A, float *L);

/*!
 *  \fn int ref_cholesky_in_place_fl(const int enable_test, const int order, float *A)
 *  \brief Поиск нижней треугольной матрицы, проверка является ли матрица положительно определенной
 *  \param[in] enable_test параметр проверки на положительную определенность
 *  \param[in] order размер матрицы
 *  \param[in/out] A указатель на матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_cholesky_in_place_fl(const int enable_test, const int order, float *A);

/*!
 *  \fn int ref_cholesky_solver_fl(const int order, float *L, float *y, float *b, float *x)
 *  \brief Поиск решений системы линейных уравнений A * x = b с использование данных функции ref_cholesky_fl
 *  \param[in] order размер матрицы
 *  \param[in] L указатель на нижнюю треугольную матрицу
 *  \param[in] b указатель на вектор коэффициентов
 *  \param[out] y указатель на вектор промежуточного результата
 *  \param[out] x указатель на решения системы
 *      - \b int 0 в случае успешной работы
 */
int ref_cholesky_solver_fl(const int order, float *L, float *y, float *b, float *x);

/*!
 *  \fn int ref_cholesky_cplx_fl(const int enable_test, const int Nrows, float *A, float *L)
 *  \brief Поиск нижней треугольной матрицы, проверка является ли матрица положительно определенной, комплексные числа
 *  \param[in] enable_test параметр проверки на положительную определенность
 *  \param[in] order размер матрицы
 *  \param[in] A указатель на входную матрицу
 *  \param[out] L указатель на нижнюю треугольную матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_cholesky_cplx_fl(const int enable_test, const int Nrows, float *A, float *L);

/*!
 *  \fn int ref_cholesky_in_place_cmplx_fl(const int enable_test, const int Nrows, float *A)
 *  \brief Поиск нижней треугольной матрицы, проверка является ли матрица положительно определенной, комплексные числа
 *  \param[in] enable_test параметр проверки на положительную определенность
 *  \param[in] order размер матрицы
 *  \param[in/out] A указатель на матрицу
 *      - \b int 0 в случае успешной работы
 */
int ref_cholesky_in_place_cmplx_fl(const int enable_test, const int Nrows, float *A);

/*!
 *  \fn int ref_cholesky_solver_cmplx_fl(const int Nrows, float *L, float *y, float *b, float *x)
 *  \brief Поиск решений системы линейных уравнений A * x = b с использование данных функции ref_cholesky_cplx_fl,
 * комплексные числа
 *  \param[in] order размер матрицы
 *  \param[in] L указатель на нижнюю треугольную матрицу
 *  \param[in] b указатель на вектор коэффициентов
 *  \param[out] y указатель на вектор промежуточного результата
 *  \param[out] x указатель на решения системы
 *      - \b int 0 в случае успешной работы
 */
int ref_cholesky_solver_cmplx_fl(const int Nrows, float *L, float *y, float *b, float *x);

/*!
 *  \fn void ref_convol_fl(const float* src, const float* src1, float* dst, const int16_t size_src1, const int16_t
 * size)
 *  \brief Свертка
 *  \param[in] src указатель на первый входной массив
 *  \param[in] src1 указатель на второй входной массив
 *  \param[out] dst указатель на выходной массив
 *  \param[in] size_src1 размер второго массива
 *  \param[in] size размер первого массива
 */
void ref_convol_fl(const float *src, const float *src1, float *dst, const int16_t size_src1, const int16_t size);

/*!
 *  \fn void ref_dotp_cplx_fl(const float* src0, const float* src1, const int size, float* dst_real, float* dst_imag)
 *  \brief Скалярное произведение комплексных векторов типа float
 *  \param[in] src0 комплексные входные данные типа float
 *  \param[in] src1 комплексные входные данные типа float
 *  \param[in] size размер входных данных
 *  \param[in] dst_real выходные данные, действительная часть
 *  \param[in] dst_imag выходные данные, мнимая часть
 */
void ref_dotp_cplx_fl(const float *src0, const float *src1, const int size, float *dst_real, float *dst_imag);

/*!
 *  \fn void ref_fircirc_fl(const float* src, float *coef, float* dst, int index, int csize, int coef_size, int size)
 *  \brief Реализация fir-фильтра
 *  \param[in] src входные данные типа float
 *  \param[in] coef указатель на коэффициенты фильтра
 *  \param[out] dst выходные данные
 *  \param[in] index смещение на чтение
 *  \param[in] csize размер буфера
 *  \param[in] coef_size размер массива коэффициентов
 *  \param[in] size размер входного массива
 */
void ref_fircirc_fl(const float *src, float *coef, float *dst, int index, int csize, int coef_size, int size);

/*!
 *  \fn float ref_lms_fl(const float *input, float *coef, float *d_output, float *output, const float coef1, float err,
 * const int coef_size, const int size)
 *  \brief Реализация firlms фильтра
 *  \param[in] input входные данные
 *  \param[in] coef коэффициенты фильтра
 *  \param[in] d_output желаемый выход
 *  \output[out] output выходные данные
 *  \param[in] coef1 адаптационный коэффициент
 *  \param[in] err указатель на ошибку
 *  \param[in] coef_size количество коэффициентов
 *  \param[in] size размер выходных данных
 *      - \b float результат работы фильтра
 */
float ref_lms_fl(const float *src, float *coef, const float *dst_i, float *dst_o, const float ar, float error,
                 const int coef_size, const int size);

/*!
 *  \fn ref_add_cplx32(const int32_t *src0, const int32_t *src1, int size, int32_t *dst)
 *  \brief Сложение комплексных чисел
 *  \param[in] src0 входные данные типа int32
 *  \param[in] src1 входные данные типа int32
 *  \param[in] size количество комплексных элементов входных массивов
 *  \param[out] dst выходные данные типа int32
 */
void ref_add_cplx32(const int32_t *src0, const int32_t *src1, int size, int32_t *dst);
/*!
 *  \fn void ref_acc_cplx32(int32_t *dst, const int32_t *src0, int size)
 *  \brief Комплексное векторное сложение с накоплением
 *  \param[in/out] dst входные/выходные данные типа int32
 *  \param[in] src0 входные данные типа int32
 *  \param[in] size количество комплексных элементов входных массивов
 */
void ref_acc_cplx32(int32_t *dst, const int32_t *src0, int size);

/*!
 *  \fn void ref_sub_cplx32(const int32_t *src0, const int32_t *src1, int size, int32_t *dst)
 *  \brief Комплексное векторное вычитание
 *  \param[in] src0 входные данные типа int32
 *  \param[in] src1 входные данные типа int32
 *  \param[in] size количество комплексных элементов входных массивов
 *  \param[out] dst выходные данные типа int32
 */
void ref_sub_cplx32(const int32_t *src0, const int32_t *src1, int size, int32_t *dst);

/// Поэлементное умножение двух векторов комплексных чисел для типа int32_t
void ref_mul_cplx32(const int32_t *src0,  ///< [in]  входные данные для первого массива
                    const int32_t *src1,  ///< [in]  входные данные для второго массива
                    int size,             ///< [in]  количество комплексных элементов входных массивов
                    int32_t *dst          ///< [out] выходные данные
);

/// Поэлементное умножение двух векторов комплексных чисел порядок следования Re, Im для типа int16_t
void ref_mul_cplx16_re_im(const int16_t *src0,  ///< [in]  входные данные для первого массива
                          const int16_t *src1,  ///< [in]  входные данные для второго массива
                          int size,             ///< [in]  количество комплексных элементов входных массивов
                          int16_t *dst          ///< [out] выходные данные
);

/// Поэлементное умножение двух векторов комплексных чисел порядок следования Re, Im для типа int32_t
void ref_mul_cplx32_re_im(const int32_t *src0,  ///< [in]  входные данные для первого массива
                          const int32_t *src1,  ///< [in]  входные данные для второго массива
                          int size,             ///< [in]  количество комплексных элементов входных массивов
                          int32_t *dst          ///< [out] выходные данные
);

/// Поэлементное умножение двух векторов комплексных чисел порядок следования Re, Im для типа float
void ref_mul_cplx_fl_re_im(const float *src0,  ///< [in]  входные данные для первого массива
                           const float *src1,  ///< [in]  входные данные для второго массива
                           int size,           ///< [in]  количество комплексных элементов входных массивов
                           float *dst          ///< [out] выходные данные
);

/// Поэлементное умножение двух векторов комплексных чисел порядок следования Re, Im для типа double
void ref_mul_cplx_db_re_im(const double *src0,  ///< [in]  входные данные для первого массива
                           const double *src1,  ///< [in]  входные данные для второго массива
                           int size,            ///< [in]  количество комплексных элементов входных массивов
                           double *dst          ///< [out] выходные данные
);

/// Поэлементное умножение двух векторов комплексных чисел c комплексным сопряжением второго вектора.
/// Порядок следования Re, Im для типа int16_t
void ref_mul_conj_cplx16_re_im(const int16_t *src0,  ///< [in]  входные данные для первого массива
                               const int16_t *src1,  ///< [in]  входные данные для второго массива
                               int size,             ///< [in]  количество комплексных элементов входных массивов
                               int16_t *dst          ///< [out] выходные данные
);

/// Поэлементное умножение двух векторов комплексных чисел c комплексным сопряжением второго вектора.
/// Порядок следования Re, Im для типа int32_t
void ref_mul_conj_cplx32_re_im(const int32_t *src0,  ///< [in]  входные данные для первого массива
                               const int32_t *src1,  ///< [in]  входные данные для второго массива
                               int size,             ///< [in]  количество комплексных элементов входных массивов
                               int32_t *dst          ///< [out] выходные данные
);

/// Поэлементное умножение двух векторов комплексных чисел c комплексным сопряжением второго вектора.
/// Порядок следования Re, Im для типа float
void ref_mul_conj_cplx_fl_re_im(const float *src0,  ///< [in]  входные данные для первого массива
                                const float *src1,  ///< [in]  входные данные для второго массива
                                int size,           ///< [in]  количество комплексных элементов входных массивов
                                float *dst          ///< [out] выходные данные
);

/// Поэлементное умножение двух векторов комплексных чисел c комплексным сопряжением второго вектора.
/// Порядок следования Re, Im для типа double
void ref_mul_conj_cplx_db_re_im(const double *src0,  ///< [in]  входные данные для первого массива
                                const double *src1,  ///< [in]  входные данные для второго массива
                                int size,            ///< [in]  количество комплексных элементов входных массивов
                                double *dst          ///< [out] выходные данные
);

/// Поэлементное умножение двух векторов комплексных чисел c комплексным сопряжением второго вектора для типа int32
void ref_mul_conj_cplx32(const int32_t *src0,  ///< [in]  входные данные для первого массива
                         const int32_t *src1,  ///< [in]  входные данные для второго массива
                         int size,             ///< [in]  количество комплексных элементов входных массивов
                         int32_t *dst          ///< [out] выходные данные
);

/*!
 *  \fn void ref_add_rconst_cplx32(int32_t *dst, int32_t size, int32_t value)
 *  \brief Добавление числа к каждому элементу вектора
 *  \param[in/out] dst входные данные типа int32
 *  \param[in] size количество комплексных элементов входных массивов
 *  \param[in] value коэффициент типа int32
 */
void ref_add_rconst_cplx32(int32_t *vec, int vec_size, int32_t a);

/*!
 *  \fn void ref_mul_rconst_cplx32(int32_t *dst, int32_t size, int32_t value)
 *  \brief Умножение вектора на реальное число
 *  \param[in/out] dst входные данные типа int32
 *  \param[in] size количество комплексных элементов входных массивов
 *  \param[in] value коэффициент типа int32
 */
void ref_mul_rconst_cplx32(int32_t *vec, int vec_size, int32_t a);

/*!
 *  \fn void ref_scale_cplx32(int32_t *dst, int32_t size, int32_t value)
 *  \brief Масштабирование вектора на степень двойки
 *  \param[in/out] dst входные данные типа int32
 *  \param[in] size количество комплексных элементов входных массивов
 *  \param[in] value коэффициент типа int32
 */
void ref_scale_cplx32(int32_t *vec, int vec_size, int32_t scale);

/*!
 *  \fn void ref_div_rconst_cplx32(int32_t *dst, int32_t size, int32_t value)
 *  \brief Деление вектора на реальное число
 *  \param[in/out] dst входные данные типа int32
 *  \param[in] size количество комплексных элементов входных массивов
 *  \param[in] value коэффициент типа int32
 */
void ref_div_rconst_cplx32(int32_t *vec, int vec_size, int32_t a);

/*!
 *  \fn void ref_sum_cplx32(int32_t *dst, int32_t size, int32_t* res)
 *  \brief Сумма всех элементов вектора
 *  \param[in/out] dst входные данные типа int32
 *  \param[in] size количество комплексных элементов входных массивов
 *  \param[in] res указатель на результат int32
 */
void ref_sum_cplx32(int32_t *vec, int size, int32_t *res);

/*!
 *  \fn void ref_abs_cplx32(int32_t *src, int32_t size, int32_t* res)
 *  \brief Расчет модуля
 *  \param[in] src входные данные типа int32
 *  \param[in] size количество комплексных элементов входных массивов
 *  \param[in] res указатель на результат int32
 */
void ref_abs_cplx32(int32_t *vec, int size, int32_t *out);

/// Вычисление свертки для одномерного массива, тип обработки границ valid, размер результата input_size - ker_size + 1
void ref_conv_cplx32(const int32_t *src,  ///< [in]  входные данные типа
                     const int32_t *ker,  ///< [in]  входные данные ядра
                     int size,            ///< [in]  количество комплексных элементов входных массивов
                     int size_ker,        ///< [in]  размер ядра свертки
                     int32_t *dst         ///< [out] указатель на результат
);

/// Вычисление свертки для одномерного массива, тип обработки границ valid, размер результата input_size - ker_size + 1
/// Порядок следования Re, Im. Тип данных int32.
void ref_conv_cplx32_re_im(const int32_t *src,  ///< [in]  входные данные типа
                           const int32_t *ker,  ///< [in]  входные данные ядра
                           int size,            ///< [in]  количество комплексных элементов входных массивов
                           int size_ker,        ///< [in]  размер ядра свертки
                           int32_t *dst         ///< [out] указатель на результат
);

/// Вычисление свертки для одномерного массива, тип обработки границ valid, размер результата input_size - ker_size + 1
/// Порядок следования Re, Im. Тип данных float.
void ref_conv_cplx_fl_re_im(const float *src,  ///< [in]  входные данные типа
                            const float *ker,  ///< [in]  входные данные ядра
                            int size,          ///< [in]  количество комплексных элементов входных массивов
                            int size_ker,      ///< [in]  размер ядра свертки
                            float *dst         ///< [out] указатель на результат
);

/// Поэлементное перемножение двух массивов типа int16
void ref_muls16(const int16_t *src0,  ///< [in]  входные данные первого массива
                const int16_t *src1,  ///< [in]  входные данные второго массива
                int16_t *dst,         ///< [out] выходные данные массива
                const int32_t size    ///< [in]  количество элементов выходного массива
);

/// Поэлементное перемножение двух массивов типа int32
void ref_muls32(const int32_t *src0,  ///< [in]  входные данные первого массива
                const int32_t *src1,  ///< [in]  входные данные второго массива
                int32_t *dst,         ///< [out] выходные данные массива
                const int32_t size    ///< [in]  количество элементов выходного массива
);

/// Поэлементное перемножение двух массивов типа float
void ref_mul_fl(const float *src0,  ///< [in]  входные данные первого массива
                const float *src1,  ///< [in]  входные данные второго массива
                float *dst,         ///< [out] выходные данные массива
                const int32_t size  ///< [in]  количество элементов выходного массива
);

/// Поэлементное перемножение двух массивов типа double
void ref_mul_db(const double *src0,  ///< [in]  входные данные первого массива
                const double *src1,  ///< [in]  входные данные второго массива
                double *dst,         ///< [out] выходные данные массива
                const int32_t size   ///< [in]  количество элементов выходного массива
);

#endif
