РЕФЕРАТ
ПЗ: стор
МЕТА РОБОТИ: розробити бібліотечні засоби рішення задач лінійної алгебри.
ОБ'ЄКТ ДОСЛІДЖЕННЯ: класові типи - чисельна квадратна матриця і одновимірний динамічний масив із змінними розмірами.
МЕТОД ДОСЛІДЖЕННЯ: розробка алгоритмів і написання класів функцій на мові Borland С + +.
У курсовому проекті розроблені алгоритми для вирішення основних задач лінійної алгебри. За цим алгоритмам на мові Borland C + + написані два класи функцій, орієнтованих на об'єкти типу чисельна квадратна матриця і одновимірний масив (вектор). У класи включені арифметичні операції, операції вводу-виводу, функції обчислення визначника матриці, довжини вектора, а також рішення системи лінійних алгебраїчних рівнянь. Для наочності отриманих результатів розроблена демонстраційно-Тестуюча програма.
Результати курсового проекту можуть бути використані на практиці для розв'язання систем лінійних рівнянь та інших задач лінійної алгебри.
Список ключових слів:
Лінійна алгебра, МАТРИЦЯ, ВЕКТОР, системи лінійних рівнянь, визначник, ФУНКЦІЯ, КЛАС ФУНКЦІЙ, Об'єкт, ОПЕРАЦІЯ, ШАБЛОН, Об'єктно-орієнтоване програмування.
ВСТУП
Об'єктно-орієнтоване програмування - це новий спосіб підходу до програмування. Таке програмування, взявши кращі риси структурного програмування, доповнює його новими ідеями, які переводять в нову якість підхід до створення програм.
Найбільш важливе поняття мов об'єктно-орієнтованого програмування - це поняття об'єкта (object). Об'єкт - це логічна одиниця, яка містить дані і правила (методи) обробки цих даних. У мові С + + в якості таких правил обробки виступають функції, тобто об'єкт у Borland C + + поєднує в собі характеристики та функції, що обробляють ці дані.
Одним з найголовніших понять мови С + + є поняття класу (class). У мові С + + для того, щоб визначити об'єкт, треба спочатку визначити його форму за допомогою ключового слова class [1].
Найближчою аналогією класу є структура. Пам'ять виділяється об'єкту тільки тоді, коли клас використовується для його створення. Цей процес називається створенням екземпляра класу (class instance).
Будь-який об'єкт мови С + + має однакові атрибути і функціональність з іншими об'єктами того ж класу. За створення своїх класів і поведінку об'єктів цих класів повну відповідальність несе сам програміст. Працюючи в деякому середовищі, програміст дістає доступ до великих бібліотек стандартних класів.
Зазвичай, об'єкт знаходиться в деякому унікальному стані, що визначається поточними значеннями його атрибутів. Функціональність об'єктного класу визначається можливими операціями над екземпляром цього класу.
Шаблони, або параметризрвані типи, дозволяють конструювати сімейство пов'язаних функцій або класів. Узагальнений синтаксис визначення шаблону має вигляд
template (оголошення);
Розрізняють шаблони функцій і шаблони класів.
Шаблон класів задає зразок визначень сімейства класів. Над типізований елементами цього класу виконуються однакові базові операції незалежно від конкретного типу елементів [2].
ВСТУП У Об'єктно-орієнтоване програмування
Об'єктно-орієнтоване програмування являє собою трохи більше автоматизований спосіб програмування. Об'єктно-орієнтовані програми - це не просто процедурні програми, переведені на новий синтаксис. Вони повинні будується на новій філософії розробки. Для них потрібна нова стратегія програмування, яку часто буває важко освоїти [3].
Основна ідея ООП: програма складається з групи об'єктів, часто пов'язаних між собою. У С + + об'єкти описуються за допомогою нового типу даних class. Клас включає в себе набір змінних (даних) і операцій (методів або функцій-членів), які діють на ці змінні. Отриманими об'єктами можна керувати за допомогою повідомлень.
У ООП об'єкти включають в себе не тільки дані (дані-члени), а й методи (функції-члени) впливу на ці дані. Ці дві частини в поєднанні утворюють функціональну одиницю програми. Іншими словами, об'єкти містять дані та методи роботи з цими даними. Нижче наведено три основні переваги об'єктно-орієнтованих програм в порівнянні з еквівалентними програмами, розробленими зверху вниз.
* Супровід програми. Програми простіше читати і розуміти, ООП дозволяє керувати складністю програми, залишаючи видимими програмісту тільки істотні деталі.
* Модифікація програми (додавання або виключення можливостей). Ви можете часто робити доповнення або виключення в програмі, наприклад, при роботі з базою даних, просто додаючи і виключаючи об'єкти. Нові об'єкти можуть наслідувати всі властивості базових об'єктів, необхідно тільки додати або прибрати що відрізняються властивості.
* Повторне використання. Можна зберегти грамотно розроблений об'єкт в наборі корисних програм і потім вставити його в нову програму з невеликими змінами або без змін.
ООП повністю належить до світу С + +, оскільки в С немає основного ядра - абстрактного типу даних class [5]. Тому переписати процедурно-орієнтовану програму як об'єктно-орієнтовану набагато складніше, ніж просто підставити замість одного ключового слова іншого.
ООП представляє собою техніку програмування, яка дозволяє розглядати основні ідеї як безліч об'єктів. Використовуючи об'єкти, можна уявити завдання, які необхідно виконати, їх взаємодія і будь-які поставлені умови, які повинні бути дотримані. Структура даних часто утворює основи об'єктів; таким чином у С або С + + тип struct може утворювати елементарний об'єкт. Зв'язок з об'єктом можна організувати за допомогою повідомлень. Використання повідомлень схоже на виклик функцій у процедурно-орієнтованої програми. Коли об'єкт отримує повідомлення, вступають в дію методи, що містяться в об'єкті. Методи (їх іноді називають Функція-членами) аналогічні функціям процедурно-орієнтованого програмування. Проте метод є частиною об'єкта, а не чимось окремим, як було б у процедурному аналогу.
Основні терміни та положення ООП
Інкапсуляція даних
Цей термін включає в себе логічне зв'язування даних з конкретною операцією. Вона так само означає, що вони є не-глобальними доступними всій програмі, а локальними - доступними тільки малої її частини. Інкапсуляція також автоматично передбачає захист даних. Саме для цього призначена структура class в С + +. У класі керування функціональними деталями об'єкта здійснюється за допомогою специфікатор private, public, protected.
Ієрархія класів
У загальному випадку можна уявити собі ієрархію класів як родовід в генеалогічному дереві, де клас С + + представляє собою шаблон для створення класів-нащадків. Об'єкти, отримані з опису класу, називають примірниками цього класу. Можна створити ієрархію класів з класом-батьком і декількома класами-нащадками. Основою для цього є похідні класи.
Спадкування
Спадкування в ООП дозволяє класу отримувати совйства іншого класу об'єктів. Батьківський клас є шаблоном для похідного класу; цей шаблон можна змінювати різними способами. Спадкування є важливим положенням, оскільки воно дозволяє повторно використовувати визначення класу без значних змін в коді.
Поліморфізм
Будується на описаної вище концепції наслідування. Програма посилає одне і теж повідомлення як об'єкту батьківського класу, так і всіх об'єктах похідних класів. І батьківський клас, і класи-нащадки дадуть відповідь на повідомлення відповідним чином. Поліморфізм дає можливість доповнювати вже існуючі частини програми.
Віртуальні функції
Віртуальні функції визначаються в батьківському класі, а в похідних класах відбувається довизначення цих функцій і для них створюються нові реалізації. Під час роботи з віртуальними функціями повідомлення передаються як покажчики, які вказують на об'єкт замість прямої передачі об'єкту. Віртуальні функції використовують таблицю для адресної інформації. Ця таблиця ініціалізується під час виконання за допомогою конструктора.
Конструктор викликається кожного разу, коли створюється об'єкт його класу. Завдання конструктора в даному випадку полягає в зв'язуванні віртуальної функції з таблицею адресної інформації. Під час компіляції адреса віртуальної функції невідомий; натомість їй відводиться позиція в таблиці адрес. Ця позиція буде містити адресу функції [5].
Глава 2. Задачі лінійної алгебри
2.1. Обчислення визначників
Нехай маємо квадратну матрицю розміром n? N:
. (2.1.1)
Потрібно обчислити визначник матриці det (A).
Еквівалентним перетворенням матриці називають перетворення матриці, що не змінюють величину визначника матриці. Еквівалентним є наступне перетворення: будь-яку її рядок можна замінити сумою вихідної рядки і будь-який інший, помноженої на будь-яке число, не рівне нулю.
Використовуючи такого роду перетворення можна спробувати привести ис-Ходна матрицю до Трикутному увазі:
,
при цьому det (A) = det (A?).
Формула для перерахунку елементів матриці має вигляд:
, (2.1.2)
де i - номер стовпця, в якому елементи, що лежать нижче головною
діагоналі, перетворюються на нулі;
j - номер елемента в оброблюваному стовпці (тобто номер рядка);
k - номер елемента в поточному рядку.
Алгоритм приведення матриці до Трикутному увазі включає в себе 3 вкладених циклу:
- Зовнішній цикл, i = 1 .. n-1;
- Середній цикл, j = i +1 .. n;
- Внутрішній цикл, k = i +1 .. n.
Тепер шуканий визначник обчислюється як добуток діагональ-них елементів:
.
Описаний вище алгоритм дає результат не завжди. Якщо при виконанні-ванні i-того кроку зовнішнього циклу діагональний елемент aii виявляється рав-ним нуля, а серед елементів i-того стовпця з номерами від i +1 до n є хоча б одна не нульовий, алгоритм завершується безрезультатно (через невозмож -ності обчислень за формулою (2.1.2). Для того, щоб це не відбувалося, використовується прийом, який називається «вибір головного елементу».
При виконанні чергового кроку циклу по i попередньо виконують-ся наступні операції:
1) знаходиться максимальний по модулю елемент серед елементів i-то-го стовпця від aii до ani;
2) якщо знайдений елемент ali дорівнює нулю, процес обчислення завер-щує з видачею результату det (A) = 0;
3) якщо l? I, тоді рядки вихідної матриці з номерами i, l поміняти місцями.
Після завершення перетворення матриці, визначник обчислюється за формулою:
,
де p - кількість виконаних операцій зміни рядків місцями.
2.2 Звернення матриць
Зворотній до матриці A називається матриця A-1, яка має властивість:
A? A-1 = A-1? A = I,
де I - одинична діагональна матриця. Опишемо один з універсальних та ефективних методів розрахунку оберненої матриці (метод Жордана-Гаусса, у книзі [4-218] описаний як «метод винятків»). В [5-22] наведено більш ефективних по пам'яті алгоритм звернення матриці.
Нехай маємо матрицю A виду (2.1.1) і хай B - одинична діагональна матриця такого ж розміру. Створимо робочу матрицю R розміром N? 2N просто приєднавши матрицю B справа до матриці A:
.
Над рядками такої розширеної матриці будемо виробляти перетворень-тання, аналогічні тим, які були описані в п.2.1. Ліву частину мат-Ріци R будемо називати подматріцей A, праву - подматріцей B. Весь про-процес перетворення матриці R розіб'ємо на 3 етапи.
1 етап. Виконаємо перетворення рядків матриці так, щоб всі елементом ти, що лежать нижче діагональних елементів подматріци A, звернулися до ну-ли. При цьому може використовуватися вибір головного елемента.
2 етап. Виконаємо перетворення так, щоб всі елементи, що лежать ви-ше діагональних елементів подматріци A, звернулися в нулі. Перетворять-вання треба виконувати у зворотному порядку: з стовпця номер n і до стовпця номер 2.
3 етап. Кожну рядок розширеної матриці R з номером i ділимо на ді-агональну елемент aii.
Після завершення процедури подматріца A перетворюється на одиничну діагональну матрицю, а подматріца B дорівнюватиме шуканої зворотного мат-ріце A-1. Алгоритм має порядок O (n3).
2.3. Методи рішення систем лінійних рівнянь
Завдання пошуку рішень системи лінійних рівнянь має не тільки са-мостоятельное значення, але часто є складовою частиною алгоритму ре-ності багатьох нелінійних задач. Основні методи вирішення СЛР:
- Метод Гауса;
- Метод звернення матриці;
- Ітераційні методи.
2.4. Метод Гаусса
Нехай маємо систему лінійних рівнянь:
Простий метод Гауса полягає в наступному.
Складемо розширену матрицю, приписав до матриці коефіцієнтів СЛР додатковий стовпець - праві частини рівняння:
.
Виконаємо над рядками розширеної матриці перетворення, аналогічних тим, які були описані в п. 2.1:
,
,
і приведемо її до Трикутному увазі:
.
Тепер можна обчислити шукані величини xi, починаючи з останнього, тобто спочатку знаходиться xn, потім xn-1, xn-2, ..., x1. Формула для обчислень має вигляд:
.
Для розширення можливостей і підвищення стійкості наведеного алгоритму використовується вибір головного елемента. Порядок методу Гаусса дорівнює O (n3).
2.5. Метод звернення матриці
Уявімо систему лінійних рівнянь в матричній формі:
.
Помножимо останнє рівність зліва на A-1:
.
Враховуючи, що A-1? A = I, формально отримуємо шукане рішення:
Таким чином, рішення системи виконується в два етапи:
1) обчислення оберненої матриці;
2) множення оберненої матриці на вектор правих частин СЛР.
Незважаючи на те, що метод звернення матриці має такий же порядок, як і метод Гауса - O (n3), за обсягом обчислень він програє йому в ніс-колько раз. Однак, якщо СЛР необхідно вирішувати багато разів і при цьому змінюється лише вектор правих частин, метод звернення матриці становит-ся все ж вигідним.
ПРАКТИЧНА ЧАСТИНА
Опис класу Matrix для вирішення задач лінійної алгебри
Клас має приватні і загальнодоступні члени-дані та члени-функції (методи). Для зберігання компонентів матриці використовується одновимірний динамічний масив елементів типу параметр шаблону. Для створення об'єкта передбачені три конструктори: конструктор за умовчанням, конструктор з параметрами, конструктор копіювання і деструктор. Для виконання безлічі матричних операцій створені перевантажені операції: присвоювання (=), додавання (+), віднімання (-), множення (*) і т.п. На базі операторів введення/виведення С + + розроблені функції введення матриць з потоку та виведення їх у потік, що передбачають у випадку файлового введення/виводу як текстову форму зберігання, так і бінарну.
Доступ до членів-даними класу - числу рядків і стовпців матриці здійснюється за допомогою методів size_row () і size_col (). Для доступу до елементів матриці створений перевантажений оператор виклику функції operator () (dim x, dim x), де dim - перевизначених тип unsigned char. Виклик функції використовується як оператор індексування, що приймає два аргументи. Аналогічно створений оператор виклику функції з одним аргументом operator () (dim x). Для даного класу - це дуже важливі перевантажені оператори, тому що вони використовуються у всіх функціях і операторів, в яких відбувається звертання до елементів матриці.
Опис функцій, конструкторів і деструкторів класу:
1. Конструктор за умовчанням Matrix ():
Конструктор за умовчанням створює матрицю нульового розміру. Надалі розмір цієї матриці можна змінити за допомогою функції newsize (i, j).
2. Конструктор з параметрами Matrix (dim, dim = 1):
Це звичайний конструктор з параметрами, який приймає в якості параметрів розміри матриці і створює одновимірний динамічний масив розміром m * n, де m - число рядків, а n - число стовпців матриці. З метою можливості використовувати його для створення векторів, другий параметр конструктора заданий як замовчуваних із значенням 1. Для первісної «ініціалізації» елементів матриці нулями використовується функція setmem ().
3. Конструктор копіювання Matrix (const Matrix &):
Конструктор приймає як параметр посилання на об'єкт класу (на існуючу матрицю), визначає її розмір, виділяє для неї пам'ять і копіює в цю пам'ять вміст матриці, що приймається за посиланням. Таким чином, створюється точна копія матриці з поточними значеннями її елементів.
4. Деструктор ~ Matrix ():
Деструктор вивільняє пам'ять, виділену конструкторами для елементів матриці.
5. Функція операції присвоювання "=" Matrix & operator = (Matrix &):
Ця функція порівнює адреса переданого за посиланням об'єкта з адресою власного класу, щоб не зробив спроби присвоїть об'єкт самому собі. Після цього створюється новий масив з числом елементів, що дорівнює кількості елементів масиву що приймається за посиланням, і в цей масив заноситься вміст прийнятого масиву. Повертається разименованний покажчик this (return * this;).
6. Опції операцій додавання, віднімання, множення матриць і множення матриці на число:
Ці функції реалізовані як дружні функції і алгоритми цих функцій аналогічні за своїм складом. Загальний вигляд прототипу цих функцій: friend Matrix operator @ (const Matrix &, const Matrix &). Застосування дружніх функцій у даному випадку доцільно для того, щоб мати можливість надавати у оператор функцію об'єкти в будь-якій послідовності. У цих операторах-функціях спочатку створюється тимчасовий об'єкт типу матриця (за допомогою конструктора копіювання), до якого копіюється перша матриця і який при виході з функції є що повертається об'єктом. Потім ця матриця підсумовується (віднімається, множиться) з матрицею, що стоїть після символу оператора за відповідними правилами матричних операцій. При цьому для доступу до елементів матриці та індексування використовуються перевантажені оператори виклику функції operator () (dim x, dim x) і operator () (dim x).
7. Функція - оператор Matrix operator ^ (int):
Цей оператор-функція реалізований як член класу і призначений для зведення матриці до степеня. У випадку, коли значення вхідного параметра дорівнює мінус одиниці здійснюється виклик функції обчислення оберненої матриці методом Гаусса перетворень, для чого розроблена окрема функція Matrix & Gauss (dim, dim). Таким чином, використання цього оператора дозволяє вирішувати систему лінійних алгебраїчних рівнянь в поданні X = (A ^ -1) & B, де X і B-вектора невідомих і правих частин відповідно.
8. Функція - оператор Matrix operator! ():
Оператор для визначення транспонований матриці.
9. Функція - оператор friend VARTYPE operator% (const Matrix &, const Matrix &):
Функція обчислення скалярного добутку векторів. У ній на початку перевіряється, чи є що передаються об'єкти векторами, а потім обчислюється скалярний добуток.
10. Функції-члени VARTYPE determ () і VARTYPE vmodule ():
Перша функція обчислює визначник власного об'єкту (матриці). При цьому використовуються функція Matrix & Gauss (dim, dim). Функція VARTYPE vmodule () обчислює довжину (модуль) вектора
11. Функція операції виводу friend ostream & operator (istream &, Matrix &):
Так само як і попередня, ця функція не може бути членом класу, а тому для доступу до приватних елементів класу оголошена "дружньої" функцією класу. Вона так само має два параметри: посилання на потік, який знаходиться ліворуч від знаку>>, і посилання об'єкт, який знаходиться ліворуч від знаку операції, у нього і будуть вводитися дані з потоку. Потім слід введення даних з потоку в елементи масиву і повертається потік. Для введення даних з файлу, треба відкрити його приєднанням до потоку ifstream.
13. Функції-члени dim write (ofstream &) і dim read (ifstream &):
Опції призначені для виведення у файл і введення з файлу матриць в з довічним поданні. Для цього необхідно передати у них відповідне посилання на відкритий файл.
14. Функція void ERROR_MATRIX (dim):
Це функція-член, яка викликається для фіксації деяких помилок при створенні матриць і роботі з ними, таких як відсутність пам'яті, неузгодженість розмірів матриць при операції множення, спроби обчислити негативну ступінь матриці і т.п.
Лістинг модуля з визначенням і реалізацією класу матриць
//Фото tmatr.cpp
# include
# include// для setmem ()
# include
# include
typedef unsigned char dim;
template class Matrix (
typedef Matrix Vector;
private:
VARTYPE * matr;// вказівник на масив матриці
dim m, n;// розміри матриці
public:
//Конструктори і деструктори:
Matrix () (matr = (VARTYPE *) 0; m = n = 0;)
Matrix (dim, dim = 1);// Звичайний конструктор
Matrix (const Matrix &);// Конструктор копіювання
~ Matrix () (delete [] matr;)
//Доступ до елементів матриці
dim size_row () (return m;)// число рядків
dim size_col () (return n;)// число стовпців
VARTYPE & operator () (dim x) const (return (* this) (x, 0);)// елементу
//Перевантажені операції та функції:
Matrix & operator = (const Matrix &);
Matrix & operator = (const VARTYPE &);
Matrix operator ^ (int);// піднесення до степеня
Matrix operator! ();// Транспонування
VARTYPE determ ();// визначник матриці
VARTYPE vmodul ();// модуль вектора
Matrix & Gauss (dim, dim);// перетворення по Гаусу
//(Для получ. Зворотної та одиничної матриці)
//(Для получ. Верхнетреугольной матриці)
Matrix minor (dim, dim);// повертає указ. мінор матриці
Vector line (dim i)// повертає вектор-рядок матриці
(Return extract (1, n, i, 0);)
Vector column (dim j)// повертає вектор-стовпець матриці
(Return extract (m, 1,0, j);)
VARTYPE & operator () (dim, dim) const;// доступ до
Matrix & operator (istream &, Matrix &);
//Потоковий введення істот. матриці
//0 - без. помилок, 1 - була помилка
dim read (ifstream &);// файлове читання і запис матриці
dim write (ofstream &);// в її внутрішньому, двійковому поданні.
friend VARTYPE operator% (const Matrix &, const Matrix &);
//Функція помилок
void ERROR_MATRIX (dim) const;
);
//Реалізація класу матриць
template
Matrix:: Matrix (dim M, dim N)
(
m = M;
n = N;
matr = new VARTYPE [m * n];
if (! matr) ERROR_MATRIX (1);
setmem (matr, sizeof (VARTYPE) * m * n, 0);
)
template
Matrix:: Matrix (const Matrix & M_Obj)// Конструктор копіювання
(
m = M_Obj.m;
n = M_Obj.n;
matr = new VARTYPE [m * n];
if (! matr) ERROR_MATRIX (1);
movmem (M_Obj.matr, matr, sizeof (VARTYPE) * m * n);
)
template
Matrix & Matrix:: operator = (const Matrix & M_Obj)
(
m = M_Obj.m;
n = M_Obj.n;
matr = new VARTYPE [m * n];
if (! matr) ERROR_MATRIX (1);
movmem (M_Obj.matr, matr, sizeof (VARTYPE) * m * n);
return * this;
)
//Диагональ?
template
Matrix & Matrix:: operator = (const VARTYPE & f)
(
for (int i = 0, j; i0)
(
for (Matrix M =* this; q> 1; q -)
M = M * (* this);
return M;
)
if (q! =- 1) ERROR_MATRIX (3);
//Обчислення оберненої метoдом перетворень Гаусса
if (n! = m) ERROR_MATRIX (4);
Matrix M (m, 2 * n);
M.insert (* this);
for (int i = 0; i
M (i, i + M.m) = 1;
for (i = 0; i
M. Gauss (i, i);
return M.extract (M.m, M.m, 0, M.m);
)
template
Matrix Matrix:: operator! ()// Транспозиція
(Matrix A (n, m);
for (int i = 0, j; i
for (j = 0; j
A (j, i) = (* this) (i, j);
return A;
)
template
VARTYPE Matrix:: determ ()// рекурсивно знаходить визначник матриці
(
if (n! = m) ERROR_MATRIX (4);
if (n == 1)
return (* this) (0,0);
for (int i = 0; i
if ((* this) (i, 0))
(
static Matrix M;
M n) ERROR_MATRIX (6);
for (int i = 0, j; i
for (j = 0; j
(* this) (i + M, j + N) = A (i, j);
return * this;
)
template// витяг
Matrix Matrix:: extract (dim LM, dim LN, dim M, dim N)
(
if (M + LM> m | | N + LN> n) ERROR_MATRIX (7);
Matrix A (LM, LN);
for (int i = 0, j; i
for (j = 0; j
A (i, j) = (* this) (i + M, j + N);
return A;
)
template
VARTYPE & Matrix:: operator () (dim M, dim N) const
(Return * (matr + n * M + N);)
template
Matrix operator + (const Matrix & A, const Matrix & B)
(
Matrix C = A;
for (int i = 0, j; i
for (j = 0; j
C (i, j) + = B (i, j);
return C;
)
template
Matrix operator-(const Matrix & A, const Matrix & B)
(
Matrix C = A;
for (int i = 0, j; i
for (j = 0; j
C (i, j) -= B (i, j);
return C;
)
template
Matrix operator * (const Matrix & A, const Matrix & B)
(
Matrix C (A.m, B.n);
if (A.n! = B.m)
(
if (A.m == 3 & & A.n == 1 & & B.m == 3 & & B.n == 1)
(
C (0) = A (1) * B (2)-A (2) * B (1);
C (1) = A (2) * B (0)-A (0) * B (2);
C (2) = A (0) * B (1)-A (1) * B (0);
)
else
A. ERROR_MATRIX (2);
)
else
(
for (int i = 0, j, k; i
for (j = 0; j
for (k = 0; k
C (i, j) + = A (i, k) * B (k, j);
)
return C;
)
template// множення числа на матрицю
Matrix operator * (const double f &, const Matrix & A)
(
Matrix B = A;
for (int i = 0, j; i
for (j = 0; j
B (i, j) *= f;
return B;
)
template// множення матриці на число
Matrix operator * (const Matrix & A, const double & f)
(
Matrix B = A;
for (int i = 0, j; i
for (j = 0; j
B (i, j) *= f;
return B;
)
template
Matrix & Matrix:: newsize (dim M, dim N)
(Delete [] matr;
m = M;
n = N;
if (N & & M) (matr = new VARTYPE [m * n];
if (! matr) ERROR_MATRIX (1);
setmem (matr, sizeof (VARTYPE) * m * n, 0);)
else (m = n = 0; matr = (VARTYPE *) 0;)
return * this;
)
template
ostream & operatorA (i, j))) return 1;
return 0;
)
template
void Matrix:: swap_line (dim L1, dim L2)
(
if (L1 == L2)
return;
double b;
for (int j = 0; j
(
b = (* this) (L1, j);
(* this) (L1, j) = (* this) (L2, j);
(* this) (L2, j) = b;
)
)
template
void Matrix:: swap_column (dim C1, dim C2)
(
if (C1 == C2)
return;
double b;
for (int i = 0; i
(
b = (* this) (i, C1);
(* this) (i, C1) = (* this) (i, C2);
(* this) (i, C2) = b;
)
)
template
dim Matrix:: read (ifstream & finp)
((Finp.get (m)). Get (n); delete [] matr; matr = new VARTYPE [m * n];
if (! matr) ERROR_MATRIX (1);
setmem (matr, sizeof (VARTYPE) * m * n, 0);
finp.read ((char *) matr, sizeof (VARTYPE) * m * n); return finp.fail ();
)
template
dim Matrix:: write (ofstream & fout)
((Fout.put (m)). Put (n);
(fout.write ((char *) matr, sizeof (VARTYPE) * m * n))