МСС ресурс Freeware Open source Кафедра МСС Факультет  

Пакет
"Матричні операції"
v3.0

           

Клас matrix

Мова:
С++ (ISO/IEC 14882, Standard for the C++ Programming Language)
Платформа:
мультиплатформений

 


Клас для маніпуляцій із матрицями та векторами. Використовуються оптимізовані для наукових обчислень контейнери елементів valarray, апарат винятків при спробі виконати некоректні операції, подвійний спосіб звернення до елементів для збереження сумісності (у стилі FORTRAN: A(i,j) та у стилі C++: A[i][j]), ефективні алгоритми для роботи із стрічками (стовпчиками), блоками та інші особливості. Взагалі, головне в такій справі – знайти баланс між ефективністю та універсальністю. Частіше у такого сорту проектах ця рівновага порушується у бік універсальності (інколи доведеної до абсурду). Набагато рідше – у бік ефективності, що теж погано, оскільки крім ефективності обчислень існує поняття прозорості програми. Ну який смисл в економії 3 секунд машинного часу, якщо програміст вимушений тратити зайві тижні на розшифровку зарозумілого коду?

Важливим доповненням до класу матриць є набір додаткових функцій: обчислення детермінанту, оберненої матриці, векторного добутку, матричної експоненти, розв'язування системи лінійних алгебраїчних рівнянь тощо.

Базовi матричнi операцiї (такi як сумування, множення, обчислення детермiнантiв тощо) у режимi вiдладки (Debug) проводять перевiрку допустимостi виконання цих операцiй (перевiрка розмiрностей та границь допустимого iндексування). Але iз мiркувань швидкодiї цi перевiрки автоматичо вiдключаються при фiнальнiй компiляцiї (Release).

Пакет містить файли: matrix.h (необхідно підключити до проекту - містить основний шаблон, константи та сервісні функції), matrix_op.h (перевантажені оператори), slice_matrix.h (робота з рядками та стовпчиками), mask_matrix.h (робота з блоками), util.h (додаткові утиліти), pseudoinverse.h (алгоритми пошуку псевдооберненої матриці), matrix_error.h (виняткі), matrix_assert.h (відладчик), matrix_spec.h (специфікації).

Зауваження для користувачів компілятора gnu c++ v.2.96. Бібліотека стандартних шаблонів (STL) має помилку у файлі std_valarray.h, яка виправлена у наступних версіях. Для коректної роботи версії 2.96 необхідно користуватися файлом gnu_std_valarray.h (для чого треба розкоментарити стрічку #include "gnu_std_valarray.h" у файлі matrix.h).


Оновлення.


(c) 1999-2002 Щетенюк С.П. (sergweb@hotmail.com)
(c) 2002-2004
Башняков О.М. (bash@unicyb.kiev.ua)
(c) 2002-2004 Пічкур В.В. (pichkur@unicyb.kiev.ua)
(c) 2003-2004 Поліщук О.А. (zagamuf@ua.fm)


 

Члени класу
private valarray<T> _val
           Контейнер елементів типу T.
private size_t   _row
           Кількість рядків.
private size_t   _col
           Кількість стовпчиків.

 

Конструктори
matrix()
             Формальний: row = col = 0.
explicit matrix(size_t m,size_t n = 1)
             Тільки резервування пам'яті (m стрічок, n стовпчиків).
matrix(const valarray<T>& arg,size_t m,size_t n = 1)
             Створення матриці (m стрічок, n стовпчиків) та заповнення її елементами із arg (по стрічках, за порядком читання книжки).
explicit matrix(const valarray<T>& arg)
             Створення матриці (arg.size() стрічок, 1 стовпчик) та заповнення її елементами із arg.
matrix(const T* arg, size_t m,size_t n = 1)
             Створення матриці (m стрічок, n стовпчиків) та заповнення її елементами із arg (по стрічках, за порядком читання книжки).
matrix(const T& diag, const T& fill, size_t m, size_t n = 1)
             Створення діагональної матриці (з діагональними елементами diag) та заповнення решти елементів значенням fill. Якщо m != n, то значення diag набувають елементи з індексами (i,i).
matrix(T fn(size_t i, size_t j), size_t m, size_t n = 1)
             Створення матриці (m стрічок, n стовпчиків) з елементами a(i,j) = fn(i,j).
explicit matrix(const basic_slice_matrix& src)
             Створення матриці з рядка або стовпчика (з відповідною розмірністю).
explicit matrix(const basic_mask_matrix& src)
             Створення матриці з підматриці (з відповідною розмірністю).
matrix(const matrix& src)
             Створення матриці-копії.

 

Функції-члени класу

          Оператори

T& operator () (size_t i, size_t j = 0)
           Доступ до елементу матриці (нумерація - з нуля, перший індекс вказує рядок, другий - стовпчик). Другий аргумент не обов'язковий, що зручно при роботі з вектор-стовпчиками.
T operator () (size_t i, size_t j = 0) const
           Читання елементу сталої матриці (нумерація - з нуля, перший індекс вказує рядок, другий - стовпчик). Другий аргумент не обов'язковий, що зручно при роботі з вектор-стовпчиками.
mask_matrix operator () (const matrix<bool>& M)
           Повертає підматрицю, що відповідає true-елементам матриці M для читання та запису.
mask_matrix_const operator () (const matrix<bool>& M) const
           Повертає підматрицю, що відповідає true-елементам матриці M для читання.
slice_matrix operator [] (size_t i)
           Повертає рядок i для читання та запису.
slice_matrix_const operator [] (size_t i) const
           Повертає рядок i для читання.
matrix& operator = (const matrix& X)
           Присвоювання (розмірність лівого операнда приймає розмірність правого).
matrix& operator = (const T& src)
           Присвоювання всім елементам матриці значення src.
matrix&
operator @= (const matrix& X)
           Набір операторів, де "@" може бути "+" (приріст), "-" (від'ємний приріст), "*" (матричний добуток), "^" (поелементний матричний добуток), "/" (поелементна матрична частка).
matrix&
operator @= (const T& src)
           Набір операторів, де "@" може бути "+" (зсув), "-" (від'ємний зсув), "*" (добуток), "^" (добуток), "/" (частка). Операції проводяться з усіма елементами матриці, які змінюються відповідним чином на величіну src.
matrix
operator @ (const matrix& X)
           Набір операторів, де "@" може бути "+" (приріст), "-" (від'ємний приріст), "*" (матричний добуток), "^" (поелементний матричний добуток), "/" (поелементна матрична частка).
matrix
operator @ (const T& src)
           Набір операторів, де "@" може бути "+" (зсув), "-" (від'ємний зсув), "*" (добуток), "^" (добуток), "/" (частка). Операції проводяться з усіма елементами матриці, які змінюються відповідним чином на величіну src.
matrix <bool>
operator @ (const matrix& Y)
           Набір логічних порівнянь, де "@" може бути "==", "!=", ">", ">=", "<", "<=", "&&", "||", "!". Повертає матрицю, кожен елемент якої є результатом порівняння відповідних елементів.

          Стовпчикі та рядкі

size_t row() const
           Повертає кількість рядків.
size_t col() const
           Повертає кількість стовпчиків.
slice_matrix row(size_t k)
           Повертає рядок k (нумерація з нуля) для читання та запису.
slice_matrix col(size_t k)
           Повертає стовпчик k (нумерація з нуля) для читання та запису.
slice_matrix_const row(size_t k) const
           Повертає рядок k (нумерація з нуля) для читання.
slice_matrix_const col(size_t k) const
           Повертає стовпчик k (нумерація з нуля) для читання.
valarray<T> vrow(size_t k) const
           Повертає valarray, утворений рядком k (нумерація з нуля).
valarray<T> vcol(size_t k) const
           Повертає valarray, утворений стовпчиком k (нумерація з нуля).
matrix mrow(size_t k) const
           Повертає матрицю, утворену рядком k (нумерація з нуля).
matrix mcol(size_t k) const
           Повертає матрицю, утворену стовпчиком k (нумерація з нуля).

          Підматриці (блоки)

mask_matrix block(size_t rstr, size_t rfin, size_t cstr = 0, size_t cfin = 1)
           Повертає прямокутну підматрицю, складену з перетину рядків [rstr,rfin) та стовпчиків [cstr,cfin) (нумерація з нуля) для читання та запису.
mask_matrix_const block(size_t rstr, size_t rfin, size_t cstr = 0, size_t cfin = 1) const
           Повертає прямокутну підматрицю, складену з перетину рядків [rstr,rfin) та стовпчиків [cstr,cfin) (нумерація з нуля) для читання.
valarray<T> vblock(size_t rstr, size_t rfin, size_t cstr = 0, size_t cfin = 1)
           Повертає valarray, що містить елементи прямокутної підматриці, складеної з перетину рядків [rstr,rfin) та стовпчиків [cstr,cfin) (нумерація з нуля).
mask_matrix mblock(size_t rstr, size_t rfin, size_t cstr = 0, size_t cfin = 1)
           Повертає матрицю, що відповідає прямокутній підматриці, складеній з перетину рядків [rstr,rfin) та стовпчиків [cstr,cfin) (нумерація з нуля).

          Вставка, видалення, перестановка

matrix& insert_rows(const mtrx& X, size_t k)
           Вставляє, починаючи з рядка k, рядкі матриці X. Кількість рядків збільшується відповідно на кількість рядків X. Передбачається, що кількість стовпчиків співпадає (також допускаються матриці нульової розмірності, яка корегується автоматично при необхідності). Аргумент X може бути матрицею, підматрицею або рядком. Повертає зсилку на себе.
matrix insert_rows_copy(const mtrx& X, size_t k)
           Повертає нову матрицю, що є результатом вставки, починаючи з рядка k, рядків матриці X. Передбачається, що кількість стовпчиків співпадає (також допускаються матриці нульової розмірності, яка корегується автоматично при необхідності). Аргумент X може бути матрицею, підматрицею або рядком.
matrix& insert_cols(const mtrx& X, size_t k)
           Вставляє, починаючи з стовпчика k, стовпчикі матриці X. Кількість стовпчиків збільшується відповідно на кількість стовпчиків X. Передбачається, що кількість рядків співпадає (також допускаються матриці нульової розмірності, яка корегується автоматично при необхідності). Аргумент X може бути матрицею, підматрицею або стовпчиком. Повертає зсилку на себе.
matrix insert_cols_copy(const mtrx& X, size_t k)
           Повертає нову матрицю, що є результатом вставки, починаючи з стовпчика k, стовпчиків матриці X. Передбачається, що кількість рядків співпадає (також допускаються матриці нульової розмірності, яка корегується автоматично при необхідності). Аргумент X може бути матрицею, підматрицею або стовпчиком.
matrix& swap_rows(size_t k, size_t p)
           Переставляє рядки k та p. Повертає зсилку на себе.
matrix swap_rows_copy(size_t k, size_t p)
           Повертає нову матрицю, що є результатом перестановки рядків k та p.
matrix& swap_cols(size_t k, size_t p)
           Переставляє стовпчики k та p. Повертає зсилку на себе.
matrix swap_cols_copy(size_t k, size_t p)
           Повертає нову матрицю, що є результатом перестановки стовпчиків k та p.
matrix& erase_rows(size_t k [, size_t p])
           Видаляє рядки [k, p). Передбачається, що k<=p. Якщо другий аргумент не заданий, видаляє тільки рядок k. Повертає зсилку на себе.
matrix erase_rows_copy(size_t k [, size_t p])
           Повертає нову матрицю, що є результатом видалення рядків [k, p). Передбачається, що k<=p. Якщо другий аргумент не заданий, видаляє тільки рядок k.
matrix& erase_cols(size_t k [, size_t p])
           Видаляє стовпчики [k, p). Передбачається, що k<=p. Якщо другий аргумент не заданий, видаляє тільки стовпчик k. Повертає зсилку на себе.
matrix erase_cols_copy(size_t k [, size_t p])
           Повертає нову матрицю, що є результатом видалення стовпчиків [k, p). Передбачається, що k<=p. Якщо другий аргумент не заданий, видаляє тільки стовпчик k.

          Конвертація

valarray<T>& output(valarray<T>& dest) const
           Поміщає елементи матриці у буфер dest (порядок розміщення елементів - за правилами читання книжки), який повинен мати достатню розмірність. Повертає зсилку на dest. Може бути застосована також до рядків (стовпчиків) та блоків.
T* output(T* dest) const
           Поміщає елементи матриці у масив (порядок розміщення елементів - за правилами читання книжки). Може бути застосована також до рядків (стовпчиків) та блоків.
matrix <newT, newEXCEPTION, newSPEC>& output(matrix<newT, newEXCEPTION, newSPEC>& X) const
           Перевід матриці у інший тип та запис результату у X (розмірність корегується при необхідності). Може бути застосована також до рядків (стовпчиків) та блоків. Повертає зсилку на аргумент.

          Сервісні функції (без зміни елементів матриці)

const valarray<T>& val()
           Повертає контейнер (для читання) у вигляді valarray.
size_t size() const
           Повертає розмір контейнера (фактично добуток кількості стрічок на кількість стовпчиків).
matrix zero_matrix(size_t Row, size_t Col)
           Повертає нову матрицю розмірності Row (кількість рядків) на Col (кількість стовпчиків), заповнену нульовими елементами (згідно специфікації).
matrix unity_matrix(size_t Row, size_t Col)
           Повертає нову матрицю розмірності Row (кількість рядків) на Col (кількість стовпчиків), заповнену нульовими елементами та одиничною головною діагоналлю (згідно специфікації).
matrix transpose()
           Повертає транспоновану матрицю.
matrix& resize(size_t newRow, size_t newCol)
           Змінює розмірність матриці згідно newRow (нова кількість рядків) та newCol (нова кількість стовпчиків). Старі значення елементів втрачаються. Повертає зсилку на себе.
int compare(const matrix& X) const
           Порівняння матриць. Повертає константу MATRIX_SAME у випадку рівності. Інакше повертає константу MATRIX_DIFF. Може бути застосована також до рядків (стовпчиків) та блоків (аргумент функції має бути одного типу з тим об'єктом, для якого вона застосовується: рядки порівнюються з рядками, блоки з блоками і т.д.).
T tr() const
           Повертає слід матриці, тобто суму елементів з однаковими індексами (навіть у випадку неквадратних матриць). Може бути застосована також до блоків.
T norm() const
           Повертає евклідову норму матриці. Може бути застосована також до рядків (стовпчиків) та блоків.
T norm2() const
           Повертає евклідову норму матриці у квадраті. Може бути застосована також до рядків (стовпчиків) та блоків.
T normr() const
           Повертає max{(|A(1,1)|+...+|A(1,n)|),...,(|A(m,1)|+...+|A(m,n)|)}. Може бути застосована також до блоків.
T normc() const
           Повертає max{(|A(1,1)|+...+|A(m,1)|),...,(|A(1,n)|+...+|A(m,n)|)}. Може бути застосована також до блоків.
T norml() const
           Повертає максимальний по модулю елемент матриці. Може бути застосована також до рядків (стовпчиків) та блоків.
T min([fn]) const
           Повертає мінімальний елемент матриці, перетвореної функцією fn (якщо така задана). Аргумент може бути типу T fn(T) або T fn(const T&). Може бути застосована також до рядків (стовпчиків) та блоків.
T findmin([fn,] size_t& p, size_t& q, size_t k = 0, size_t l = 0) const
           Повертає мінімальний елемент матриці, перетвореної функцією fn (якщо така задана). Аргумент fn може бути типу T fn(T) або T fn(const T&). Змінні p та q отримують значення відповідно рядка та стовпчика, які відповідають знайденому елементу. Необов'язкові останні аргументи звужують пошук, який проводиться з рядка k (вправо) та стовпчика l (вниз). Може бути застосована також до блоків. Для рядків (стовпчиків) та узагальнених блоків передбачено аналогічну функцію з відсутніми аргументами q та l: findmin([fn,] size_t& p, size_t k = 0).
T max([fn]) const
           Повертає максимальний елемент матриці, перетвореної функцією fn (якщо така задана). Аргумент може бути типу T fn(T) або T fn(const T&). Може бути застосована також до рядків (стовпчиків) та блоків.
T findmax([fn,] size_t& p, size_t& q, size_t k = 0, size_t l = 0) const
           Повертає максимальний елемент матриці, перетвореної функцією fn (якщо така задана). Аргумент fn може бути типу T fn(T) або T fn(const T&). Змінні p та q отримують значення відповідно рядка та стовпчика, які відповідають знайденому елементу. Необов'язкові останні аргументи звужують пошук, який проводиться з рядка k (вправо) та стовпчика l (вниз). Може бути застосована також до блоків. Для рядків (стовпчиків) та узагальнених блоків передбачено аналогічну функцію з відсутніми аргументами q та l: findmin([fn,] size_t& p, size_t k = 0).
T sum() const
           Повертає суму елементів матриці. Може бути застосована також до рядків (стовпчиків) та блоків.
T prod() const
           Повертає добуток елементів матриці. Може бути застосована також до рядків (стовпчиків) та блоків.
size_t rank() const
           Повертає ранг матриці. Може бути застосована також до блоків.
matrix pseudoinverse(int alg = 0) const
           Повертає псевдоінверсну матрицю, обчислену за алгоритмом alg (MATRIX_PSEUDO_GREVILLE - метод Гревіля - за замовчуванням). Якщо alg = 0, використовується поточний режим.
matrix apply(fn) const
           Застосовує функцію fn до всіх елементів матриці та повертає результат. Аргумент може бути типу T fn(T) або T fn(const T&). Може бути застосована також до рядків (стовпчиків) та блоків.

          Сервісні функції (зі зміною елементів матриці)

const valarray<T>& val(const valarray<T>& v)
           Заповнює контейнер елементів значеннями з v. Передбачається рівність розмірностей. Повертає зсилку на аргумент.
matrix& modify(fn)
           Змінює всі елементи матриці згідно функції fn. Аргумент може бути типу T fn(T) або T fn(const T&). Повертає зсилку на себе. Може бути застосована також до рядків (стовпчиків) та блоків.
matrix& clear()
           Очистка матриці, розмірність якої стає 0х0. Повертає зсилку на себе.
matrix& fill(const T& n)
           Заповнює матрицю елементами n. Повертає зсилку на себе. Може бути застосована також до рядків (стовпчиків) та блоків.

          Ввід / вивід

istream& input(istream& is = cin, int mode = 0)
           Зчитує матрицю з потоку is (по замовчуванню cin) у режимі mode. Режим: MATRIX_NO_HEAD - без шапки, MATRIX_FULL_HEAD - повна шапка ("_row  _col"), при якому два перших значення трактуються як розмірності матриці. Якщо mode = 0, то ввід відбувається згідно поточних параметрів. Може бути застосована також до рядків (стовпчиків) та блоків, але для рядків (стовпчиків) неможливо вказати режим шапки (оскільки їхня розмірність визначається розмірністю матриці).
istream& operator >> (istream& is, matrix& X)
           Зчитує матрицю з потоку is згідно поточного режиму. Може бути застосована також до рядків (стовпчиків) та блоків.
ostream& output(ostream& os = cout, int mode = 0) const
           Поміщає форматовану матрицю у потік os (по замовчуванню cout) у режимі mode. Режим виводу шапки: MATRIX_NO_HEAD - без шапки, MATRIX_FULL_HEAD - повна шапка("_row  _col"). Режим розміщення елементів: MATRIX_BODY_TABLE - згідно розмірностей, MATRIX_BODY_COL - у стовпчик, MATRIX_BODY_ROW - у стрічку. Допускаються логічні комбінації режиму виводу шапки та режиму розміщення елементів з '|' (наприклад, MATRIX_FULL_HEAD | MATRIX_BODY_ROW). Якщо mode = 0, то вивід відбувається згідно поточних параметрів. Може бути застосована також до рядків (стовпчиків) та блоків, але для рядків (стовпчиків) неможливо вказати режим шапки.
ostream& operator << (ostream& os, const matrix& X)
           Поміщає форматовану матрицю у потік os згідно поточного режиму. Може бути застосована також до рядків (стовпчиків) та блоків.

 

Додаткові функції (не є членами класу матриць)
T  matrix_det(const matrix& X, int alg = 0)
           Обчислює детермінант квадратної матриці X за алгоритмом alg (MATRIX_DET_RECURSIVE - точний рекурсивний метод зведення до визначників 3-го порядку - за замовчуванням, MATRIX_DET_GAUSS - метод Гауса). Якщо alg = 0, використовується поточний режим. Викликає функції det_recursive(), det_gauss().
T  det_recursive(const matrix& X)
           Обчислює детермінант квадратної матриці X точним рекурсивним методом зведення до визначників 3-го порядку.
T  det_gauss(const matrix& X)
           Обчислює детермінант квадратної матриці X методом Гауса.
matrix matrix_inverse(const matrix& X, int alg = 0)
           Повертає обернену до квадратної матриці X, обчислену за алгоритмом alg (MATRIX_INVERSE_GAUSS - метод Гауса - за замовчуванням, MATRIX_INVERSE_DET - метод визначників). Якщо alg = 0, використовується поточний режим. Викликає функції inverse_gauss(), inverse_det().
matrix inverse_gauss(const matrix& X)
           Повертає обернену до квадратної матриці X, обчислену методом Гауса.
matrix inverse_det(const matrix& X)
           Повертає обернену до квадратної матриці X, обчислену методом визначників.
matrix matrix_slae(const matrix& X, int alg = 0)
           Розв'язує систему лінійних алгебраїчних рівнянь, які задаються розширеною матрицею X (останній стовпчик - права частина) за алгоритмом alg (MATRIX_SLAE_GAUSS - метод Гауса - за замовченням, MATRIX_SLAE_DET - метод визначників). Якщо alg = 0, використовується поточний режим. Викликає функції slae_gauss(), slae_det().
matrix slae_gauss(const matrix& X)
           Розв'язує систему лінійних алгебраїчних рівнянь, які задаються розширеною матрицею X (останній стовпчик - права частина) методом Гауса.
matrix slae_det(const matrix& X)
           Розв'язує систему лінійних алгебраїчних рівнянь, які задаються розширеною матрицею X (останній стовпчик - права частина) методом визначників.
matrix vector_product(const matrix& a, const matrix& b)
           Повертає векторний добуток 3-вимірних вектор-стовпчиків a та b.
T scalar_product(const matrix& a, const matrix& b)
           Повертає скалярний добуток вектор-стовпчиків a та b.
matrix matrix_pow(const matrix& a, size_t k)
           Повертає степінь k квадратної матриці a. Якщо k<0, то повертає степінь (-k) оберненої матриці (обчисленої згідно поточного режиму), при k=0 повертає одиничну матрицю.
matrix matrix_exp(const matrix& a, size_t iter)
           Повертає матричну експоненту, обчислену для iter ітерацій.
matrix operator ^ (const matrix& A, char op)
           Символічний запис: A^'+' - пседообернена (обчислена згідно поточного режиму), A^'-' - обернена (обчислена згідно поточного режиму), A^'T' - транспонована матриці.
matrix <resT, resEXCEPTION, resSPEC>& matrix_function(matrix<resT, resEXCEPTION, resSPEC>& Res, matrix<fT, fEXCEPTION, fSPEC>& F, const argT& Arg)
           Якщо матриця складається з покажчиків на функції, то у Res буде записано значення кожної функції з F для аргументу Arg. Повертає зсилку на Res. Розмірність Res корегується при необхідності.

 

Функції поточних режимів (не є членами класу матриць)
int  matrix_stream_format(int format = 0)
           Задає поточний режим вводу / виводу. Аргумент (допускається об'єднання через '|'): MATRIX_HEAD_NONE (без шапки), MATRIX_HEAD_FULL (шапка - кількість рядків та кількість стовпчиків, розділених пробілом), MATRIX_BODY_ROW (вивід всіх елементів у стовпчик), MATRIX_BODY_COL (вивід всіх елементів у стрічку), MATRIX_BODY_TABLE (вивід елементів згідно заданої розмірності). Функція без аргументів повертає поточний режим.
int  matrix_pseudoinverse_alg(int format = 0)
           Задає поточний режим розрахунку псевдоінверсної матриці. Аргумент: MATRIX_PSEUDO_GREVILLE (метод Гревіля). Функція без аргументів повертає поточний режим.
int  matrix_det_alg(int format = 0)
           Задає поточний режим розрахунку детермінанту квадратної матриці. Аргумент: MATRIX_DET_RECURSIVE (точний рекурсивний метод зведення до визначників 3-го порядку), MATRIX_DET_GAUSS (метод Гауса). Функція без аргументів повертає поточний режим.
int  matrix_inverse_alg(int format = 0)
           Задає поточний режим розрахунку оберненої квадратної матриці. Аргумент: MATRIX_INVERSE_GAUSS (метод Гауса), MATRIX_INVERSE_DET (метод визначників). Функція без аргументів повертає поточний режим.
int  matrix_slae_alg(int format = 0)
           Задає поточний режим розрахунку системи лінійних алгебраїчних рівнянь. Аргумент: MATRIX_SLAE_GAUSS (метод Гауса), MATRIX_SLAE_DET (метод визначників). Функція без аргументів повертає поточний режим.

 


 

Опис

I. Об'явлення та ініціалізація. Для роботи з матрицями необхідно приєднати файл "matrix.h". Об'явлення передбачає визначення типу елементів матриці та, за бажанням, типу винятків та типу специфікацій:

#include "matrix/matrix.h"; // вкажіть при необхідності шлях
matrix<double> M(10, 15); // елементи типу double, розмірність 10 рядків на 15 стовпчиків.
matrix<int> v(3); // елементи типу int, вектор-стовпчик розмірності 3.
matrixd A(2, 3); // matrixd = matrix<double>
double src[]={1,2,3,  4,5,6};
matrixd B(src, 2, 3);
matrixd C(B), D;

Передбачено також можливість ініціалізації матриці за допомогою valarray, стрічки (стовпчика), блока, пари елементів та функції. Див. також повний список конструкторів.

Вектор є частинним випадком матриці, друга розмірність якої дорівнює одиниці. Тому при ініціалізації та зверненні до елементів вектора можна використовувати тільки один індекс. Індексація елементів матриці - з нуля, але ініціалізація передбачає задання фактичної кількості рядків та стовпців (так само як в стандартних масивах С++).

Визначено наступні матричні типи (в усіх випадках текст винятків виводиться на консоль):
matrixd - елементи типу double
matrixld - .. long double
matrixf - .. float
matrixs - .. short
matrixus - .. unsigned short
matrixi
- .. int
matrixui - .. unsigned int
matrixl - .. long
matrixul - .. unsigned long
matrixc - .. char
matrixuc - .. unsigned char

Зауваження для користувачів компілятора gnu c++ v.2.96. Бібліотека стандартних шаблонів (STL) має помилку у файлі std_valarray.h, яка виправлена у наступних версіях. Для коректної роботи версії 2.96 необхідно користуватися файлом gnu_std_valarray.h (для чого треба розкоментарити стрічку #include "gnu_std_valarray.h" у файлі matrix.h).

II. Доступ до елементів. Доступ до елементів здійснюється за допомогою двох індексів (або ж допускається один індекс для векторів-стовпчиків). Індексація - з нуля, перший індекс є номером рядка, другий - номером стовпчика. Допускається два типи індексації:

C(0,0) = 3.14; // FORTRAN style
A[0][2] = B(1,0); // C++ style

У режимі відладки проводиться перевірка допустимості індексів. Можна також отримати копію контейнера (у вигляді valarray), який містить всі елементи матриці, або ж задати значення цього контейнера. Див. також Стовпчиики та рядки, Підматриці (блоки), Маски.

III. Матричні операції. Надається стандартний набір матричних операцій:

A = B; // присвоювання
A += B;
// аналогічно -=, *= (матричне множення), ^= (поелементне множення), /= (поелементне ділення)
A += n; // збільшення на число того самого типу, що і елементи матриці
// аналогічно -=, *=, ^= (множення), /=

A = B + 2*С;

При присвоюванні розмірність лівого операнда приймає розмірність правого. В інших випадках передбачається узгодженість розмірностей. У режимі відладки проводиться перевірка розмірностей.

IV. Стовпчики та рядки. Передбачено можливість роботи з рядками та стовчиками, доступ до яких здійснюється наступним чином:

C.row(0) = B.row(1); // копіювання рядка матриці B у рядок матриці C
// тут і далі зправа може також бути valarray, масив або число відповідного типу
A.col(1) += B.col(2); // збільшення стовпчика матриці A на стовпчик матриці B
// аналогічно -=, ^= (поелементне множення), /= (поелементне ділення)
A.col(1) += n; // збільшення стовпчика на число того самого типу, що і елементи матриці
// аналогічно -=, *=, ^= (множення), /=

Індексація - з нуля. У режимі відладки проводиться перевірка допустимості індексів. Рядки (стовпчики) можна порівнювати по аналогії з порівнянням матриць, також є допустимими функції обчислень норм, екстремальних елементів тощо. Неможливо створити об'єкт типу "рядок (стовпчик) матриці", тому наступна конструкція помилкова:

A.col(1) = B.col(2) + С.col(1); // помилка!
A.col(1) = B.col(2); // двокрокова альтернатива
A.col(1) += С.col(1);
(A.col(1) = B.col(2)) += С.col(1); // також ок!

Для перетворення рядків / стовпчиків у матриці відповідної розмірності передбачено функції mrow() / mcol().

Можна вставляти, вилучати та змінювати місцями рядки (стовпчики). При цьому є можливість змінювати саму матрицю або ж повертати результат дії, не змінюючи саму матрицю (набір функцій, які завершуються "_copy").

V. Підматриці (блоки). Передбачено можливість роботи з прямокутними підматрицями (блоками), доступ до яких здійснюється наступним чином:

C.block(0,2,0,3) = B.block(1,3,0,3); // копіювання блока матриці B у блок матриці C
A.block(0,2,0,3) += B.block(1,3,0,3); // збільшення блока матриці A на блок матриці B
// аналогічно -=, ^= (поелементне множення), /= (поелементне ділення)
A.block(0,2,0,3) += n; // збільшення на число того самого типу, що і елементи матриці
// аналогічно -=, *=, ^= (множення), /=

Індексація - з нуля, перші два аргументи вказують діапазон рядків [початковий, кінцевий), два останніх - стовпчиків. Якщо два останніх не вказано будуть вибрано елементи лише першого стовпчика (зручно при роботі з векторами-стовпчиками), якщо аргументи не вказано, повертається вся матриця як блок. У режимі відладки проводиться перевірка допустимості індексів. Блоки можна порівнювати по аналогії з порівнянням матриць, також є допустимими функції обчислень норм, екстремальних елементів тощо. Неможливо створити об'єкт типу "блок матриці", тому наступна конструкція помилкова:

A.block(0,2,0,3) = B.block(1,3,0,3) + С.block(1,3,0,3); // помилка!
A.block(0,2,0,3) = B.block(1,3,0,3); // двокрокова альтернатива
A.block(0,2,0,3) += С.block(1,3,0,3);
(A.block(0,2,0,3) = B.block(1,3,0,3)) += С.block(1,3,0,3); // також ок!

Для перетворення блоків у матриці відповідної розмірності передбачено функції mblock().

VI. Маски (узагальнені блоки). Передбачено можливість роботи з масками, які утворюють узагальнені (тобто непрямокутні) блоки. Маска будується як матриця булевського типу відповідної розмірності, у якої на місці елементів, що підлягають обробці стоїть true. Напрпиклад для роботи з головною діагоналлю 2х2-матриці С можна скористатися маскою:

matrix<bool> mask(2,2);
mask(0,0) = mask(1,1) = true; // обробляється
mask(0,1) = mask(1,0) = false; // не обробляється
C(M) *= 2.0; // збільшення діагоналі матриці C вдвічі

Робота з узагальненими блоками аналогічна роботі з блоками з тою різницею, що узагальнені блоки не можуть формувати прямокутні матриці, замість яких використовуються вектор-стовпчики відповідної розмірності (наприклад при порівнянні, виводі, конструюванні матриць з узагальнених блоків).

VII. Утілити. Надаються сервісні функції для обчислення детермінанту квадратних матриць, оберненої та псевдооберненої матриці, рангу, розв'язування системи лінійних алгебраїчних рівнянь та пошуку екстремальних значень тощо.

VIII. Ввід / вивід. Матриці можна поміщати у потік з урахуванням двох режимів: режим виводу шапки (вказується або не вказується розмірність через пробіл - кількість рядків та стовпчиків) та режим виводу самої матриці (фактичне, або все у стрічку через пробіл, або все у стовпчик). Режими можна задавати, об'єднуючи їх логічним '|'.

A.output(cout, MATRIX_HEAD_FULL | MATRIX_BODY_TABLE); // вивід на консоль з заданим форматом
A.output(cout); // вивід на консоль з поточним форматом
matrix_stream_format(MATRIX_HEAD_FULL | MATRIX_BODY_TABLE); // зміна поточного режиму вводу/виводу
cout << A; // вивід на консоль з поточним форматом

Рядки та стрічки виводяться у потік аналогічно, але для них неможливо вказати режим шапки (якої у них просто нема).

Ввід матриці з потоку залежить від режиму шапки: якщо встановлено MATRIX_HEAD_FULL, то перші два введені значення трактуватимуться як розмірність (перше - рядки, друге - стовпчики). Інакше ввід здійснюється згідно тої розмірності, яка була у матриці на момент вводу.

A.input(cin, MATRIX_HEAD_FULL); // ввід з клавіатури з заданим форматом
A.input(cin); // ввід з клавіатури з поточним форматом
matrix_stream_format(MATRIX_HEAD_FULL); // зміна поточного режиму вводу/виводу
cin >> A; // ввід з клавіатури з поточним форматом

Рядки та стрічки вводяться аналогічно, але для них неможливо вказати режим шапки (оскільки їхня розмірність визначається розмірністю матриці).

Зміна формату вводу / виводу за допомогою matrix_stream_format() розповсюджується на всі матриці, скомпільовані в даній одиніці компіляції.

IX. Вектор-функції. Для задання вектор-функції необхідно, щоб елементами матриці (вектора) були покажчики на функції:

matrix<double(*)(double)> F(2); // 2-вимірна вектор функція double->double
F(0) = sin; F(0) = cos;
matrix<double> Res(2); // 2-вимірний вектор значень функції F
matrix_function(Res, F, 3.14); // У Res 2-вимірне значення F(3.14)

Розмірність першого аргумента (результата) автоматично корегується при необхідності.

X. Відладка. У режимі відладки здійснюються різноманітні перевірки коректності обчислень: допустимість індексування, взаємоузгодженість розмірностей, коректність аргументів. Для включення режиму відладки при компіляції необхідно визначити стандартний макрос "_DEBUG" (gcc: у командній стрічці вказати -D_DEBUG; Visual C++, C++Builder:: скомпілювати у конфігурації "Debug"). При компіляції релізу ці перевірки відключаються з міркувань швидкодії. У режимі відладки при виникненні помилки генерується виняткі (exception), тип якого вказується (за бажанням) як другий аргумент шаблону при об'явленні матриці. За замовчуванням: matrix_exception. Він наслідується від стандартного exception, а отже такі виняткі перехоплюються catch(exception &ex). Певна річ, вони також можуть бути оброблені catch(matrix_exception &ex) та catch(...). Повідомлення про помилку можна проглянути за допомогою стандартної функції what(). Крім того, matrix_exception_message, незалежно від того, чи був виняток перехоплений, виведе відповідне повідомлення на консоль. При створенні нових класів винятків, необхідно наслідувати їх від одного з наведених, наприклад, для виводу повідомлень у Ms Windows, можна створити виняток вигляду:

#include "windows.h"
struct matrix_exception_win : matrix_exception
{
     matrix_exception_win(const char* msg = "") : matrix_exception(msg)
     {
          MessageBox(0, msg, "matrix exception", MB_ICONERROR);
     }
};

matrix<double, matrix_exception_win> M;
M.row(5); // помилка (немає такого рядка) - буде згенеровано MessageBox

XI. Точність обчислень. Оператори порівняння, функції compare(), rank(), det_gauss(), inversion_gauss(), slae_gauss(), проводять обчислення із деякою наперед заданною точністю. Точність задається за допомогою необов'язкового третього параметра шаблона при об'явленні матриці (точніше за допомогою функції-члена significant()). Функція significant() повертає true, якщо її аргумент вважається значущим, або false, якщо аргументом можна знехтувати в процесі обчислень. За замовчуванням знехтувати можна числом, модуль якого не перевищує 1e-15 (точність, що достатня для обчислень з типом double). Таким чином, можна задавати довільну точність обчислень:

class NewSpec : public matrix_spec<double> // наслідування не обов'язкове (лише для збереження решти параметрів)
{
     
public:
     static bool significant(const double& x) // синтаксис шапки не може бути змінений, крім типу double
    
{
           if (x > 0.1 || x < -0.1) return true;
           return false;
     }
};

matrix <double, matrix_exception, NewSpec> M; // обчислення вищезазначених функцій проводитемуться з точністю 0.1

Див. також інші специфікації, які можна задати за допомогою необов'язкового третього параметра шаблона при об'явленні матриці.

XII. Специфікації типу елементів. Специфічні типи. Специфікації типу елементів матриці задаються за допомогою необов'язкового третього параметра шаблона при об'явленні матриці. За замовченням використовується клас matrix_spec (файл matrix_spec.h), що коректно працює зі стандартними числовими типами та забезпечує операції порівняння (менше ніж) lt(), значущості significant(), а також повертає одиничний unity_element() та нульвий zero_element() елементи. При заданні матриць із нестандартними елементами для забезпечення коректної роботи деяких функцій (наприклад, порівняння) необхідно задати відповідний клас (перевантаживши функції-члени з matrix_spec зі збереженням синтаксису назв) та підставити його третім параметром шаблона при об'явленні матриці. Див., наприклад, задання нестандартної точності обчислень.


Будь-ласка, надсилайте пропозиції, питання, зауваження: soft@unicyb.kiev.ua
Запрошуємо також до участі у самому проекті: надсилайте свої матеріали, які, по-можливості, будуть виставлені на сайті (див. Для авторів).

Кафедра Моделювання складних систем факультету кібернетики Київського університету імені Тараса Шевченка
03127, Україна, Київ, просп. Глушкова 2, корп. 6, кафедра МСС тел.: (044) 259-05-31, (044) 259-02-37, e-mail: garash@unicyb.kiev.ua
Всі права застережено.