From 1bdc307d5fc0f0d22d1f4b43b130106ab937e553 Mon Sep 17 00:00:00 2001 From: Dsplib Date: Thu, 27 Sep 2018 00:05:39 +0300 Subject: [PATCH] added matrix_t and basic matrix functions --- dox/header.html | 13 ---- dox/ru/groups_define.dox | 91 +++++++++++++------------- dspl/dox/ru/matrix.dox | 115 ++++++++++++++++++++++++++++++++ dspl/src/matrix.c | 126 +++++++++++++++++++++++++++++++++++- include/dspl.c | 8 +++ include/dspl.h | 13 ++++ release/include/dspl.c | 8 +++ release/include/dspl.h | 13 ++++ test/src/matrix_print.c | 33 ++++++++++ test/src/matrix_transpose.c | 50 ++++++++++++++ 10 files changed, 410 insertions(+), 60 deletions(-) create mode 100644 dspl/dox/ru/matrix.dox create mode 100644 test/src/matrix_print.c create mode 100644 test/src/matrix_transpose.c diff --git a/dox/header.html b/dox/header.html index a3ea01f..5c2246a 100644 --- a/dox/header.html +++ b/dox/header.html @@ -78,19 +78,6 @@ $extrastylesheet
-
- - - - - - -
diff --git a/dox/ru/groups_define.dox b/dox/ru/groups_define.dox index 1eb0ecf..9e58b00 100755 --- a/dox/ru/groups_define.dox +++ b/dox/ru/groups_define.dox @@ -1,74 +1,74 @@ /*! - \defgroup MAIN_GROUP Библиотека DSPL - + \defgroup MAIN_GROUP Библиотека DSPL + \defgroup GETTING_START Быстрый старт использования библиотеки DSPL \ingroup MAIN_GROUP - - \defgroup TYPES_GROUP Типы данных DSPL - \ingroup MAIN_GROUP - В данной группе описаны типы данных библиотеки DSPL и методы их преобразования. - + \defgroup TYPES_GROUP Типы данных DSPL + \ingroup MAIN_GROUP + В данной группе описаны типы данных библиотеки DSPL и методы их преобразования. + + \defgroup SPECTRAL_GROUP Спектральный анализ - \ingroup MAIN_GROUP + \ingroup MAIN_GROUP В данной группе собраны функции реализующие алгоритмы дискретного преобразования Фурье (ДПФ), - быстрого преобразования Фурье (БПФ), функции оконного взвешивания, расчета спектральной плотности мощности. - + быстрого преобразования Фурье (БПФ), функции оконного взвешивания, расчета спектральной плотности мощности. + \defgroup DFT_GROUP Алгоритмы дискретного и быстрого преобразования Фурье \ingroup SPECTRAL_GROUP - + Алгоритмы дискретного и быстрого преобразования Фурье. \defgroup WIN_GROUP Функции оконного взвешивания - \ingroup SPECTRAL_GROUP - - + \ingroup SPECTRAL_GROUP + + \defgroup HILBERT_GROUP Преобразование Гильберта \ingroup MAIN_GROUP - - В данной группе собраны функции реализующие алгоритмы преобразования Гильберта. - - + В данной группе собраны функции реализующие алгоритмы преобразования Гильберта. + + + \defgroup FILTER_GROUP Цифровая фильтрация. Синтез и анализ цифровых фильтров. \ingroup MAIN_GROUP - - + + \defgroup FILTER_CONV_GROUP Свертка и цифровая фильтрация \ingroup FILTER_GROUP - - Функции для расчета циклической и линейной сверток, а также цифровой КИХ и БИХ фильтрации. - - + + Функции для расчета циклической и линейной сверток, а также цифровой КИХ и БИХ фильтрации. + + \defgroup IIR_FILTER_DESIGN_GROUP Расчет БИХ-фильтров - \ingroup FILTER_GROUP - Функции расчета цифровых БИХ-фильтров. - - + \ingroup FILTER_GROUP + Функции расчета цифровых БИХ-фильтров. + + \defgroup FIR_FILTER_DESIGN_GROUP Расчет КИХ-фильтров - \ingroup FILTER_GROUP + \ingroup FILTER_GROUP Функции расчета цифровых КИХ-фильтров. \defgroup FILTER_ANALYSIS_GROUP Функции анализа аналоговых и цифровых фильтров - \ingroup FILTER_GROUP + \ingroup FILTER_GROUP Функции анализа аналоговых и цифровых фильтров - + \defgroup RESAMPLING_GROUP Цифровая передискретизация сигналов \ingroup MAIN_GROUP - - + + \defgroup SPEC_MATH_GROUP Специальные математические функции \ingroup MAIN_GROUP - + \defgroup SPEC_MATH_COMMON_GROUP Базовые математические функции. \ingroup SPEC_MATH_GROUP - - \defgroup SPEC_MATH_TRIG_GROUP Тригонометрические и гиперболические функции + + \defgroup SPEC_MATH_TRIG_GROUP Тригонометрические и гиперболические функции вещественного и комплексного аргумента. \ingroup SPEC_MATH_GROUP - + \defgroup SPEC_MATH_ELLIP_GROUP Эллиптические функции вещественного и комплексного аргумента. \ingroup SPEC_MATH_GROUP @@ -77,19 +77,22 @@ \defgroup SPEC_MATH_STAT_GROUP Функции математической статистики \ingroup SPEC_MATH_GROUP - - + + \defgroup SPEC_MATH_LINALG_GROUP Линейная алгебра и матричные операции + \ingroup SPEC_MATH_GROUP + + \defgroup IN_OUT_GROUP Функции ввода - вывода данных \ingroup MAIN_GROUP Функции ввода и вывода данных. Запись и считывание данных в бинарные и текстовые файлы. - + \defgroup MACRO_DEFINE_GROUP Макросы и константы \ingroup MAIN_GROUP - + \defgroup ERROR_CODE_GROUP Коды ошибок при вызове функций - \ingroup MACRO_DEFINE_GROUP - В данной группе приведены возможные коды ошибок, возвращаемые функциями библиотеки в процессе - работы. + \ingroup MACRO_DEFINE_GROUP + В данной группе приведены возможные коды ошибок, возвращаемые функциями библиотеки в процессе + работы. */ diff --git a/dspl/dox/ru/matrix.dox b/dspl/dox/ru/matrix.dox new file mode 100644 index 0000000..066b530 --- /dev/null +++ b/dspl/dox/ru/matrix.dox @@ -0,0 +1,115 @@ +/*! **************************************************************************** +\ingroup SPEC_MATH_LINALG_GROUP +\struct matrix_t +\brief Структура данных объекта матриц и векторов + +Структура описывает вещественные и комплексные матрицы и векторы. + +\param dat Указатель на область памяти, которая + хранит матрицу или вектор

+ +\param n Количество строк матрицы.

+ +\param m Количество столбцов матрицы.

+ +\param type Тип матрицы.

+ + +Параметр `dat` преставляет собой указатель типа `void*` ввиду того, что матрица +может содержать как вещественные, так и комплексные значения. Если матрица +вещественная, то перед обращением к элементам матрицы необходимо указатель +`dat` привести к типу `double*`. Аналогично, указатель `dat` необходимо привести +к типу `complex_t*`, если матрица комплексная. + +Матрицу заданного размера и типа можно создать функцией \ref matrix_create. +Например +\code + + matrix_t a, b; // объявляем объекты матриц + + // обнуляем все поля и указатели. + // Данные шаг рекомендуется ввиду того, что некоторые компиляторы + // при создании переменной не инициализируют ее нулем. + memset(&a, 0, sizeof(matrix_t)); + memset(&b, 0, sizeof(matrix_t)); + + //создаем вещественную матрицу a размерности [3 x 4] + err = matrix_create(&a, 3, 4, DAT_DOUBLE); + + // создаем комплексную матрицу b размерности [3 x 2] + err = matrix_create(&b, 3, 2, DAT_COMPLEX); + + // .... + // работа с матрицами a и b + // .... + + //очистить память перед выходом + matrix_free(&a); + matrix_free(&b); + +\endcode + + +Двумереные матрицы размером `n` на `m` расположены в памяти в виде линейного +вектора, который организован по строкам. Так некий элемент матрицы \f$a_{ij}\f$ +матрицы размерности `n` на `m` будет иметь индекс `j*n+i` (индексация матриц +начинается с нуля). Например: + +\code + + matrix_t a; // объявляем объекты матриц + + // обнуляем все поля и указатели. + // Данные шаг рекомендуется ввиду того, что некоторые компиляторы + // при создании переменной не инициализируют ее нулем. + memset(&a, 0, sizeof(matrix_t)); + + + // создаем вещественную матрицу a размерности [3 x 4] + err = matrix_create(&a, 3, 4, DAT_DOUBLE); + + // приводим указатель к double* + double* x = (double*)(a.dat); + + // присваиваем элемент a[2,3] = 3.0 + x[3 * a.n + 2] = 3.0; + + //очистить память перед выходом + matrix_free(&a); + +\endcode + +Если требуется изменить размер матрицы, то можно повторно вызывать функцию +\ref matrix_create. Например: + +\code + + matrix_t a; // объявляем объекты матриц + + // обнуляем все поля и указатели. + // Данные шаг рекомендуется ввиду того, что некоторые компиляторы + // при создании переменной не инициализируют ее нулем. + memset(&a, 0, sizeof(matrix_t)); + + + // создаем вещественную матрицу a размерности [3 x 4] + err = matrix_create(&a, 3, 4, DAT_DOUBLE); + + // ..... + + // изменяем размер матрицы а на [6 x 7] + err = matrix_create(&a, 6, 7, DAT_DOUBLE); + + + // очистить память перед выходом + matrix_free(&a); + +\endcode + + +\author + Бахурин Сергей. + www.dsplib.org + +***************************************************************************** */ + diff --git a/dspl/src/matrix.c b/dspl/src/matrix.c index 2cbd03c..14a32a7 100644 --- a/dspl/src/matrix.c +++ b/dspl/src/matrix.c @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Foobar. If not, see . */ - +#include #include #include #include "dspl.h" @@ -30,8 +30,9 @@ void transpose_hermite(complex_t* a, int n, int m, complex_t* b); + /******************************************************************************* -Real matrx transpose +matrix_create *******************************************************************************/ int DSPL_API matrix_create(matrix_t* a, int n, int m, int type) { @@ -65,6 +66,123 @@ int DSPL_API matrix_create(matrix_t* a, int n, int m, int type) +/******************************************************************************* +matrix_free +*******************************************************************************/ +void DSPL_API matrix_free(matrix_t* a) +{ + if(!a) + return; + if(a->dat) + free(a->dat); + a->n = a->m = a->type = 0; +} + + + + + + +/******************************************************************************* +matrix transposition +*******************************************************************************/ +int DSPL_API matrix_print(matrix_t* a, const char* name, const char* format) +{ + int n,m; + if(!a) + return ERROR_PTR; + if(!a->dat) + return ERROR_PTR; + + if((a->type & DAT_MASK) == DAT_DOUBLE) + { + printf("\nMatrix %s size [%d x %d] type: real\n", + name, a->n, a->m); + double* p = (double*)(a->dat); + for(n = 0; n < a->n; n++) + { + for(m = 0; m < a->m; m++) + { + printf(format, p[m*a->n + n]); + } + printf("\n"); + } + } + + + if((a->type & DAT_MASK) == DAT_COMPLEX) + { + printf("\nMatrix %s size [%d x %d] type: complex\n", + name, a->n, a->m); + complex_t* p = (complex_t*)(a->dat); + for(n = 0; n < a->n; n++) + { + for(m = 0; m < a->m; m++) + { + printf(format, RE(p[m*a->n + n]), + IM(p[m*a->n + n])); + } + printf("\n"); + } + } + return RES_OK; +} + + + + + + + +/******************************************************************************* +matrix transposition +*******************************************************************************/ +int DSPL_API matrix_transpose(matrix_t* a, matrix_t* b) +{ + int err; + if(!a || !b) + return ERROR_PTR; + + err = matrix_create(b, a->m, a->n, a->type); + if(err != RES_OK) + return err; + + if((a->type & DAT_MASK) == DAT_DOUBLE) + transpose((double*)(a->dat), a->n, a->m, (double*)(b->dat)); + if((a->type & DAT_MASK) == DAT_COMPLEX) + transpose_cmplx((complex_t*)(a->dat), a->n, a->m, + (complex_t*)(b->dat)); + + return RES_OK; +} + + + + + +/******************************************************************************* +matrix Hermite transposition +*******************************************************************************/ +int DSPL_API matrix_transpose_hermite(matrix_t* a, matrix_t* b) +{ + int err; + if(!a || !b) + return ERROR_PTR; + + err = matrix_create(b, a->m, a->n, a->type); + if(err != RES_OK) + return err; + + if((a->type & DAT_MASK) == DAT_DOUBLE) + transpose((double*)(a->dat), a->n, a->m, (double*)(b->dat)); + if((a->type & DAT_MASK) == DAT_COMPLEX) + transpose_hermite((complex_t*)(a->dat), a->n, a->m, + (complex_t*)(b->dat)); + + return RES_OK; +} + + @@ -105,6 +223,7 @@ void transpose(double* a, int n, int m, double* b) + /******************************************************************************* Complex matrx transpose *******************************************************************************/ @@ -150,6 +269,7 @@ void transpose_cmplx(complex_t* a, int n, int m, complex_t* b) + /******************************************************************************* Hermite matrx transpose *******************************************************************************/ @@ -178,7 +298,7 @@ void transpose_hermite(complex_t* a, int n, int m, complex_t* b) for(j = 0; j < m; j++) { RE(b[i*m + j]) = RE(a[j*n+i]); - IM(b[i*m + j]) = IM(a[j*n+i]); + IM(b[i*m + j]) = -IM(a[j*n+i]); } } diff --git a/include/dspl.c b/include/dspl.c index ef249ed..99d028e 100755 --- a/include/dspl.c +++ b/include/dspl.c @@ -98,6 +98,10 @@ p_low2bp low2bp ; p_low2high low2high ; p_low2low low2low ; p_matrix_create matrix_create ; +p_matrix_free matrix_free ; +p_matrix_print matrix_print ; +p_matrix_transpose matrix_transpose ; +p_matrix_transpose_hermite matrix_transpose_hermite ; p_poly_z2a_cmplx poly_z2a_cmplx ; p_polyval polyval ; p_polyval_cmplx polyval_cmplx ; @@ -231,6 +235,10 @@ void* dspl_load() LOAD_FUNC(low2high); LOAD_FUNC(low2low); LOAD_FUNC(matrix_create); + LOAD_FUNC(matrix_free); + LOAD_FUNC(matrix_print); + LOAD_FUNC(matrix_transpose); + LOAD_FUNC(matrix_transpose_hermite); LOAD_FUNC(poly_z2a_cmplx); LOAD_FUNC(polyval); LOAD_FUNC(polyval_cmplx); diff --git a/include/dspl.h b/include/dspl.h index 42d1a3f..ff77582 100755 --- a/include/dspl.h +++ b/include/dspl.h @@ -560,6 +560,19 @@ DECLARE_FUNC(int, matrix_create, matrix_t* a COMMA int n COMMA int m COMMA int type); + +//------------------------------------------------------------------------------ +DECLARE_FUNC(void, matrix_free, matrix_t* a); +//------------------------------------------------------------------------------ +DECLARE_FUNC(int, matrix_print, matrix_t* a + COMMA const char* name + COMMA const char* format); +//------------------------------------------------------------------------------ +DECLARE_FUNC(int, matrix_transpose, matrix_t* a + COMMA matrix_t* b); +//------------------------------------------------------------------------------ +DECLARE_FUNC(int, matrix_transpose_hermite, matrix_t* a + COMMA matrix_t* b); //------------------------------------------------------------------------------ DECLARE_FUNC(int, poly_z2a_cmplx, complex_t* COMMA int diff --git a/release/include/dspl.c b/release/include/dspl.c index ef249ed..99d028e 100755 --- a/release/include/dspl.c +++ b/release/include/dspl.c @@ -98,6 +98,10 @@ p_low2bp low2bp ; p_low2high low2high ; p_low2low low2low ; p_matrix_create matrix_create ; +p_matrix_free matrix_free ; +p_matrix_print matrix_print ; +p_matrix_transpose matrix_transpose ; +p_matrix_transpose_hermite matrix_transpose_hermite ; p_poly_z2a_cmplx poly_z2a_cmplx ; p_polyval polyval ; p_polyval_cmplx polyval_cmplx ; @@ -231,6 +235,10 @@ void* dspl_load() LOAD_FUNC(low2high); LOAD_FUNC(low2low); LOAD_FUNC(matrix_create); + LOAD_FUNC(matrix_free); + LOAD_FUNC(matrix_print); + LOAD_FUNC(matrix_transpose); + LOAD_FUNC(matrix_transpose_hermite); LOAD_FUNC(poly_z2a_cmplx); LOAD_FUNC(polyval); LOAD_FUNC(polyval_cmplx); diff --git a/release/include/dspl.h b/release/include/dspl.h index 42d1a3f..ff77582 100755 --- a/release/include/dspl.h +++ b/release/include/dspl.h @@ -560,6 +560,19 @@ DECLARE_FUNC(int, matrix_create, matrix_t* a COMMA int n COMMA int m COMMA int type); + +//------------------------------------------------------------------------------ +DECLARE_FUNC(void, matrix_free, matrix_t* a); +//------------------------------------------------------------------------------ +DECLARE_FUNC(int, matrix_print, matrix_t* a + COMMA const char* name + COMMA const char* format); +//------------------------------------------------------------------------------ +DECLARE_FUNC(int, matrix_transpose, matrix_t* a + COMMA matrix_t* b); +//------------------------------------------------------------------------------ +DECLARE_FUNC(int, matrix_transpose_hermite, matrix_t* a + COMMA matrix_t* b); //------------------------------------------------------------------------------ DECLARE_FUNC(int, poly_z2a_cmplx, complex_t* COMMA int diff --git a/test/src/matrix_print.c b/test/src/matrix_print.c new file mode 100644 index 0000000..5df607f --- /dev/null +++ b/test/src/matrix_print.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include "dspl.h" + +int main() +{ + void* handle; // DSPL handle + handle = dspl_load(); // Load DSPL function + + matrix_t r, c; + + memset(&r, 0, sizeof(matrix_t)); + memset(&c, 0, sizeof(matrix_t)); + + matrix_create(&r, 4, 3, DAT_DOUBLE); + linspace(0, 12, 12, DSPL_PERIODIC, (double*)r.dat); + matrix_print(&r, "R", "%8.2f"); + + matrix_create(&c, 2, 3, DAT_COMPLEX); + linspace(0, 12, 12, DSPL_PERIODIC, (double*)c.dat); + matrix_print(&c, "C", "%8.2f%+8.2fj "); + + + matrix_free(&r); + matrix_free(&c); + dspl_free(handle); // free dspl handle + + // выполнить скрипт GNUPLOT для построения графиков + // по рассчитанным данным + return system("gnuplot gnuplot/sinc_test.plt");; +} + diff --git a/test/src/matrix_transpose.c b/test/src/matrix_transpose.c new file mode 100644 index 0000000..29c4bb8 --- /dev/null +++ b/test/src/matrix_transpose.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include "dspl.h" + +int main() +{ + void* handle; // DSPL handle + handle = dspl_load(); // Load DSPL function + + matrix_t a, b, c; + + memset(&a, 0, sizeof(matrix_t)); + memset(&b, 0, sizeof(matrix_t)); + memset(&c, 0, sizeof(matrix_t)); + + matrix_create(&a, 4, 3, DAT_DOUBLE); + linspace(0, 12, 12, DSPL_PERIODIC, (double*)a.dat); + matrix_print(&a, "A", "%8.2f"); + + matrix_transpose(&a, &b); + matrix_print(&b, "B=A^T", "%8.2f"); + + matrix_transpose_hermite(&a, &b); + matrix_print(&b, "B=A^H", "%8.2f"); + + + + matrix_create(&c, 2, 3, DAT_COMPLEX); + linspace(0, 12, 12, DSPL_PERIODIC, (double*)c.dat); + matrix_print(&c, "C", "%8.2f%+8.2fj "); + + matrix_transpose(&c, &b); + matrix_print(&b, "B=C^T", "%8.2f%+8.2fj "); + + + matrix_transpose_hermite(&c, &b); + matrix_print(&b, "B=C^H", "%8.2f%+8.2fj "); + + + matrix_free(&a); + matrix_free(&b); + matrix_free(&c); + dspl_free(handle); // free dspl handle + + // выполнить скрипт GNUPLOT для построения графиков + // по рассчитанным данным + return system("gnuplot gnuplot/sinc_test.plt");; +} +