Міністерство освіти і науки України
Національний університет “Львівська політехніка”
Кафедра автоматизованих систем управління
Розрахункова робота
з дисципліни
«Проблемно-орієнтовані мови програмування»
на тему
ОБЧИСЛЕННЯ ОБЕРНЕНОЇ МАТРИЦІ МЕТОДОМ ГАУССА
Міністерство освіти і науки України
Національний університет “Львівська політехніка”
Кафедра автоматизованих систем управління
Завдання на розрахункову роботу
з дисципліни
«Проблемно-орієнтовані мови програмування»
Прізвище, ім’я студента Славич Юрій
Група КН-21
Тема курсової Екранні перетворення двовимірних об’єктів
Спеціальна частина завдання :
Провести огляд літератури по методах знаходження оберненої матриці.
Здійснити програмну реалізацію на мові Сі.
Реалізувати користувацький інтерфейс та редагування оголошень програмних елементів.
Середовище функціонування програми – MS DOS.
Завдання видано
Керівник
Студент
Зміст
Вступ 4
1. Огляд літератури 5
1.1. Деякі відомості з теорії ланцюгових дробів 5
1.1.1. Означення оберненої матриці та її властивості 5
1.1.2. Метод Гаусса для знаходження оберненої матриці 6
1.1.3. Прогонка 8
1.1.4. Нескінченні ланцюгові дроби Ошибка! Закладка не определена.
1.2. Порівняльний аналіз методів знаходження оберненої матриці 8
2. Постановка задачі 8
3. Алгоритм розв’язку 11
4. Програмні реалізації алгоритму 13
4.1. Опис програми на мові Turbo C 13
4.1. Опис програми на мові Turbo Pascal 14
5. Інструкція користувачеві 16
6. Контрольні приклади та аналіз їх реалізації 17
Висновки 19
Список використаної літератури 20
Додатки 20
Додаток 1. Текст програми на мові Турбо-Паскаль
Додаток 2. Текст програми на мові Турбо-Сі
Вступ
Актуальність даної роботи полягає втому, що
Метою даної роботи було доведення перваги методу Гаусса для обчислення оберненої матриці над іншими і написання на його основі програми, яка знаходить обернену матрицю для будь-якої заданої.
Для вирішення добре обумовлених лінійних систем загального виду та для обчислення обернених матриць метод Гаусса є одним з кращих. Також вагомою перевагою вибраного методу, окрім швидкодії, є порівняна нескладність алгоритму.
1. Огляд літератури
1.1. Деякі відомості про матриці.
1.1.1. Означення оберненої матриці та її властивості.
Знаходження матриці, оберненої матриці А, еквівалентне розв’язку матричного рівняння
АХ=XA=Е, (1)
де Е – одинична матриця, Х – шукана обернена квадратна матриця. Нехай А=[aij], X=[xij]. Рівняння (1) можна записати у вигляді системи m2 рівнянь
, i, j=1, 2, …, m, (2)
де δij=1 при i=j і δij=0 при i≠j.
Важливо зазначити, що система (2) розкладається на m незалежних систем рівнянь з однією і тією ж матрицею А, але з різними правими частинами. Ці системи мають вигляд
Ax(j)=δ(j), i, j=1, 2, …, m, (3)
де x(j)=(x1j, x2j, …, xmj)T, у вектора δ(j) рівна одиниці j-а компонента і рівні нулю всі інші компоненти.
Наприклад, для матриці другого порядку система (2) розкладається на дві незалежні системи
a11x11+a12x21=1, a11x12+a12x22=0,
і
a21x11+a22x21=0, a21x12+a22x22=1.
Означення 1. Квадратна матриця називається неособливою (невиродженою), якщо її визначник відмінний від нуля.
В протилежному випадку матриця називається особливою або сингулярною.
Теорема 1. Будь-яка особлива матриця має обернену матрицю. Зауваження 1. Для даної матриці А її обернена матриця А-1 єдина. Більше того, будь-яка права обернена (ліва обернена) матриця матриці А співпадає з її оберненою матрицею А-1 (якщо остання існує).
Дійсно, якщо
АВ=Е,
то, домноживши цю рівність зліва на А-1, отримаємо:
А-1АВ=А-1Е
або
В=А-1.
Зауваження 2. Особлива квадратна матриця оберненої не має. Дійсно, оскільки матриця А – особлива, то
det A=0.
З рівності (1) маємо:
det A · det A-1=det E=1,
тобто 0=1, що неможливо.
Також важливо вказати основні властивості оберненої матриці, які можна використовувати для перевірки правильності отриманої оберненої матриці.
1. Визначник оберненої матриці рівний оберненій величині визначника вхідної матриці.
det A-1=.
2. Обернена матриця добутку квадратних матриць рівна добутку обернених матриць співмножників, взятому в зворотньому порядку, тобто
(АВ)-1=В-1А-1.
3. Транспонована обернена матриця рівна оберненій від транспонованої даної матриці:
(А-1)´=(А´)-1. --------------(
1.1.2. Метод Гаусса для знаходження оберненої матриці.
Нехай нам дано невироджену матрицю
a11 a12 … a1n
a21 a22 … a2n
... … … …
an1 an2 … ann
Для обчислення елементів її оберненої матриці
x11 x12 … x1n
x21 x22 … x2n
... … … …
xn1 xn2 … xnn
використовуємо вже згадане відношення
АА-1=Е.
Перемноживши матрицю А на А-1 і прирівнявши кожен елемент добутку відповідному елементу матриці Е, отримуємо систему з n2 рівнянь з n2 невідомими xij (i, j=1, 2, …, n).
Домножуючи почленно кожен рядок матриці А на перший стовпець матриці А-1 і щоразу прирівнюючи отриманий добуток до відповідного елемента першого стовпця матриці Е, отримуємо систему
a11x11+a12x21+a13x31+…+a1nxn1=1,
a21x11+a22x21+a23x31+…+a2nxn1=0,
…………………………………………
an1x11+an2x21+an3x31+…+annxn1=0,
Аналогічно при почленному перемножуванні рядків матриці А на другий стовпець матриці А-1 утворюється ще одна система:
a11x12+a12x22+a13x32+…+a1nxn2=0,
a21x12+a22x22+a23x32+…+a2nxn2=1,
…………………………………………
an1x12+an2x22+an3x32+…+annxn2=0,
і так далі.
Таким чином, система з n2 рівнянь з n2 невідомими розпадається на n систем рівнянь з n невідомими. Всі ці системи мають одну і ту ж матрицю А і відрізняються тільки вільними членами.
1.1.3. Прогонка.
Нехай матриця А містить багато нульових елементів, розміщених в матриці не будь-як, а щільними масивами на попередньо відомих місцях.
( k = 1, 2, . . . ), де , називають k-підходящим дробом ланцюгового дробу (1). Згідно з Ейлером, звичайно вважають:
причому для визначеності вважають, що
зручно знаходити за допомогою схеми Горнера для ділення
Вказана послідовність дій легко програмується.
1.2. Порівняльний аналіз методів знаходження оберненої матриці.
Є дуже багато методів вирішення задач лінійної алгебри. Розглянемо формальні характеристики найбільш поширених методів.
Метод оптимального виключення має таку ж швидкість і потребує такого ж об’єму пам’яті, що і метод Гаусса. Але якщо матриця вводиться в оперативну пам’ять ЕОМ не вся відразу, а по рядках, то для методу Гаусса потрібно n2 комірок, а для методу оптимального виключення досить n2 комірок. Практична цінність цієї переваги невелика, бо порядкове введення викликає багато звернень до зовнішньої пам'яті, тобто значне збільшення часу обрахунку. Окрім того, при введенні по рядках неможливо вибрати головний елемент, що проявляється в помилках округлення.
Метод окаймлення мало відрізняється від методу оптимального виключення, тому має аналогічні характеристики.
Метод відображень потребує вдвічі більшої кількості дій, ніж метод Гаусса (при тому ж об'ємі оперативної пам’яті).
Метод ортогоналізації втричі повільніший за метод Гаусса. Ним зацікавились в надії на те, що він дозволить розв’язувати недостатньо обумовлені системи. Але виявилося, що при великих n сама ортогоналізація приводить до великої втрати точності, тому краще використовувати методи регуляризації.
Метод Жордана володіє такою ж швидкодією, як і метод Гаусса; при розв'язуванні лінійних систем він не дає жодних переваг. Але при обчисленні оберненої матриці він потребує менше оперативної пам'яті – всього n2 комірок.
Для вирішення добре обумовлених лінійних систем загального виду та для обчислення обернених матриць метод Гаусса є одним з кращих. Також вагомою перевагою вибраного методу, окрім швидкодії, є порівняна нескладність алгоритму.
2. Постановка задачі.
Як було сказано вище, для знаходження значення ланцюгового дробу доцільно використовувати схему Горнера для ділення
Вказана послідовність дій легко програмується. Але наперед невідомо порядок підходящого дробу, який дає потрібну точність. Тому чисельник та знаменник підходящого дробу k-го порядку знаходитимемо за формулами:
Якщо різниця k-го та k–1-го підходящих дробів є не більшою за потрібну точність та k-ий дріб є шуканим. Детально проблема знаходження підходящих дробів для будь-якого ланцюгового дробу розглянута в [1].
Ламберт отримав наступний розклад tg x в ланцюговий дріб:
Обчисливши за допомогою цієї формули tg x з певною точністю та помноживши його на cos x отримаємо потрібне значення синуса.
З метою запобігання виходу за межі розрядної сітки при проведенні обчислень значення синуса за допомогою степеневих рядів потрібно звести аргумент до вигляду , тобто відняти певну кількість повних обертів.
Розклад синуса в степеневий ряд виглядає:
Як сказано в [1], суму ряду зручно обчислювати процесом сумування
sin x = u1 + u2 + u3 + … + un + Rn ,
де доданки uk (k = 1, 2, …, n) послідовно знаходяться за допомогою рекурентного співвідношення
3. Алгоритм розв’язку.
Згідно з принципами структурного програмування, алгоритм розв’язку громіздкої задачі складається із алгоритмів розв’язку окремих простіших підзадач. Наслідуючи ці принципи я розробив окремі функції, кожна з яких обчислює значення синуса із заданою точністю певним методом. Функції викликаються з головної програми, яка передає в якості фактичних параметрів аргумент синуса та точність виконання обчислень. Розглянемо детальніше алгоритм роботи головної програми, блок-схема якого зображено на Рис 1.
Спочатку виводиться титульна сторінка, де зазначений автор курсової роботи. Нижче на екрані виведеться меню з трьома пунктами. Вибір режиму роботи відбувається за допомогою маніпулятора “миші”, який як і драйвер до нього обов”язково повинен бути встановлений на даному комп”ютері. Згідно з вибором користувача кодом відбувається одна з трьох дій:
у разі вибору пункту ‘1’ відбувається ручне введення вхідної матриці та обчислення оберненої до неї матриці;
у разі вибору пункту ‘2’ відбувається випадкова генерація вхідної матриці програмою та обчислення оберненої до неї матриці;
у разі вибору пункту ‘3’ відбувається закінчення роботи;
Обчислення та виведення оберненої матриці відбувається за методом Гауса на основі вказаної в програмі точності.
Блок-схема головної програми
4. Програмні реалізації алгоритму
4.1. Опис програми на мові Turbo C.
Програма написана на мові Turbo Pascal збережена у файлі KURSAK.PAS. Об’єм програми в байтах – 11733 байт. Це 423 рядки програмного коду.
Програма призначена для обчислення оберненої матриці за методом Гауса із заданою точністю.
В програмі використовуються наступні стандартні бібліотечні функції [3]:
clrscr() – очищує екран;
initgraph() – встановлення графічного режиму;
textcolor() – встановлює певний колір тексту;
textbackground() – встановлює певний колір фону;
cputs() – консольний вивід рядків символів;
getch() – повертає код натиснутої клавіші без еходруку на екрані;
cprintf() – консольний форматований вивід інформації;
cscanf() – консольний форматований ввід інформації;
readkey – повертає код натиснутої клавіші без еходруку на екрані;
closegraph() – завершення графічного режиму;
Список ідентифікаторів:
Ідентифікатори глобальних змінних
Оголошений новий тип matr.
A – тип matr, використовується для збереження вхідної матриці;
B - тип matr, використовується для збереження вихідної матриці;
a0 - тип matr, використовується для перевірки правильності обрахунку;
i – тип int, використовується для знаходження координат елементів матриці;
j – тип int, використовується для знаходження координат елементів матриці;
s0 –тип long, використовується для знаходження суми діагональних елементів матриці.
s1 - тип long, використовується для знаходження суми недіагональних елементів матриці.
Вхідною інформацією для програми є значення аргумента функції синус, яке зчитується з клавіатури і зберігається у змінній х та значення точності виконання обчислень, яке також зчитується з клавіатури, перевіряється на допустимість значення (0<e<1) і зберігається у змінній e.
Вихідна інформація виводиться на екран, як числове значення синуса, обчислене певним методом з певною точністю та кількість ітерацій, що була зроблена при виконанні обчислень.
4.1. Опис програми на мові Turbo Pascal.
Програма написана на мові Turbo Pascal збережена у файлі KURSAK.PAS. Об’єм програми в байтах – 11733 байт. Це 423 рядки програмного коду.
Програма призначена для обчислення оберненої матриці за методом Гауса із заданою точністю
В програмі використовуються наступні стандартні бібліотечні підпрограми [2]:
clrscr() – очищує екран;
initgraph() – встановлення графічного режиму;
textcolor() – встановлює певний колір тексту;
textbackground() – встановлює певний колір фону;
writeln() – вивід інформації з наступним переходом на новий рядок (write – без переходу на новий рядок);
read() – ввід інформації;
readkey – повертає код натиснутої клавіші без еходруку на екрані;
closegraph() – завершення графічного режиму;
Список ідентифікаторів змінних та їх характеристика (тип, розмір у байтах, призначення у програмі), аналогічні до характеристик ідентифікаторів змінних програми написаної на мові Turbo С. За винятком глобальної змінної grad – тип boolean, розмір 1 байти, містить спосіб інтерпретації аргумента функції.
Вхідна та вихідна інформація така ж, як і для програми написаної на мові Turbo С.
Програми на мовах Turbo C та Turbo Pascal є апаратно незалежними та працюють під керуванням операційних систем MS DOS, WINDOWS 95/98/XP. Для коректної роботи програми вимагається наявність клавіатури, для введення вхідної інформації та монітору, для виведення вихідної інформації.
5. Інструкція користувачеві.
Програму слід запускати без жодних параметрів (при наявності параметрів вони ігноруються). Після запуску на екран виводиться головне меню програми, в якому 5 пунктів (Рис. 2). Для активізації певного пункту меню слід навести мишку на цей пункт та натиснути її ліву клавішу.
Детальніше про кожен пункт:
при виборі першого пункту відбувається введення з клавіатури вхідної матриці; слід ввести саму матрицю;
при виборі другого пункту відбувається автоматична генерація матриці тобто вхідних данних;
при виборі третього пункту відбувається закінчення роботи програми.
Контрольні приклади та аналіз їх реалізації.
Для контрольного обчислення елементів оберненої матриці взято матрицю розміром 3 на 3 ( n=3 ).
1. Вхідна матриця:
1,0 2,0 3,0
3,0 2,0 1,0
7,0 8,0 0,0
Вхідна і обернена до неї обернена матриця:
1,000 2,000 3,000 -0,222 0,667 -0,111
3,000 2,000 1,000 0,194 -0,583 0,222
7,000 8,000 0,000 0,278 0,167 -0,111
Матриця для перевірки (Повинна вийти одинична матриця):
1,000 0,000 -0,000 1,000 0,000 -0,000
-0,000 1,000 0,000 -0,000 1,000 0,000
-0,000 0,000 1,000 -0,000 0,000 1,000
Сума модулів діагональних елементів: 3,0
Сума модулів недіагональних елементів: 9,777е-12
2. Вхідна матриця:
7,0 5,0 3,0
9,0 6,0 2,0
1,0 8,0 4,0
Вихідна обернена матриця:
7,000 5,000 3,000 0,095 0,048 -0,095
9,000 6,000 2,000 -0,405 0,298 0,155
1,000 8,000 4,000 0,786 -0,607 -0,036
Матриця для перевірки (Повинна вийти одинична матриця):
1,000 0,000 0,000 1,000 0,000 0,000
0,000 1,000 -0,000 0,000 1,000 -0,000
-0,000 0,000 1,000 -0,000 0,000 1,000
Сума модулів діагональних елементів: 3,0
Сума модулів недіагональних елементів: 1,062е-11
Для додаткової перевірки програма находить сума модулів діагональних та недіагональних елементів. Сума модулів діагональних елементів має бути рівна n, а сума модулів недіагональних елементів має бути рівна 0. Враховуючи дану точність обчислення (е=0,00001) можна сказати, що дана сума =0 в обох випадках.
Проаналізувавши отримані результати можна сказати, що програма коректно виконує усі обчислення в межах вказаної точності.
Висновки.
В ході виконання даної курсової роботи було опрацьовано літературу, список якої подано нижче та розроблено алгоритм розв’язку завдання курсової роботи. Також були створені програми на мовах Turbo C та Turbo Pascal, які обчислюють обернену матрицю певного рангу з певною точністю методом Гауса.
Проаналізувавши отримані результати можна сказати, що програма коректно виконує усі обчислення в межах вказаної точності.
Список використаної літератури.
Ахо А.Б. и др. Построение и анализ вьічислительньіх алгоритмов. – М.: Мир, 1979.
Демидович Б.М., Марон И.А. Основьі вьічислительной математики. – М.: Наука, 1970.
Калиткин Н.Н. Численньіе методьі. – М.: Наука, 1978.
Копченова Н.В., Марон И.А. Вьічислительная математика в примерах и задачах. – М.: Наука, 1972.
Подбельский В.В., Фомин С.С. Программирование на языке Си. – М.: Финансьі и статистика, 2002.
Прата С. Язьік программирования С – К.: ДиаСофт, 2000.
Самарский А.А., Гулинь А.Ф. Численньіе методьі. – М.: Наука, 1989.
Фаронов В.В. Turbo Pascal 7.0. Начальньій курс. – М.: Нолидж, 2002.
Додаток 1. Тексти програм на мові Турбо-Паскаль
Program Kursova;
uses crt, graph, dos, egamouse;
const n=5;
eps=0.00001; { vsi chysla menshi za eps rivni 0 }
type matr=array[1..n, 1..n] of real;
var a, b, a0: matr;
i, j, imx, np: integer;
s0, s1: real;
procedure TestMouse;
begin
if not Mouse_Installed then
begin
CloseGraph;
RestoreCrtMode;
WRITELN;
WRITELN('Mouse not installed');
Halt
end;
SetMousePosition(300,175);
ShowMouse;
end;
procedure PrintMatr(m, m1: matr; n, nz, nd, bool: integer);
var i, j, dx, dy, x, y: integer;
t: string;
begin
dx:=60; dy:=20;
x:=20;
if bool=0 then y:=110 else y:=240;
textcolor(red);
for i:=1 to n do
begin
for j:=1 to n do
begin
str(m[i, j]:nz:nd, t);
outtextxy(x, y, t);
x:=x+dx;
end;
for j:=1 to n do
begin
str(m1[i, j]:nz:nd, t);
outtextxy(x, y, t);
x:=x+dx;
end;
y:=y+dy;
x:=20;
end;
inc(np);
end;
procedure MultString(var a, b: matr; i1: integer; r: real);
var j: integer;
begin
for j:=1 to n do
begin
a[i1, j]:=a[i1, j]*r;
b[i1, j]:=b[i1, j]*r;
end;
end;
procedure AddStrings(var a, b: matr; i1, i2: integer; r: real);
{ Procedura dodaye do i1 ryadka matryci i2-yj pomnozhenyj na r}
var j: integer;
begin
for j:=1 to n do
begin
a[i1, j]:=a[i1, j]+r*a[i2, j];
b[i1, j]:=b[i1, j]+r*b[i2, j];
end;
end;
procedure MultMatr(a, b: matr; var c: matr);
var i, j, k: byte;
s: real;
begin
for i:=1 to n do
for j:=1 to n do
begin
s:=0;
for k:=1 to n do
s:=s+a[i, k]*b[k, j];
c[i, j]:=s;
end;
end;
function sign(r: real): shortint;
begin
if (r>=0) then sign:=1 else sign:=-1;
end;
procedure Button(ox, oy, oxt, oyt: integer; message: string);
begin
setfillstyle(1, LIGHTGRAY);
bar(ox, oy, ox+300, oy+30);
setcolor(LIGHTBLUE);
line(ox, oy-1, ox+300, oy-1);
line(ox+301, oy, ox+301, oy+30);
line(ox+300, oy+31, ox, oy+31);
line(ox-1, oy+30, ox-1, oy);
setcolor(WHITE);
line(ox, oy, ox+300, oy);
line(ox+300, oy, ox+297, oy+3);
line(ox+297, oy+3, ox+3, oy+3);
line(ox+3, oy+3, ox+3, oy+27);
line(ox+3, oy+27, ox, oy+30);
line(ox, oy+30, ox, oy);
setfillstyle(1, WHITE);
floodfill(ox+150, oy+1, WHITE);
setcolor(DARKGRAY);
line(ox, oy+30, ox+3, oy+27);
line(ox+3, oy+27, ox+297, oy+27);
line(ox+297, oy+27, ox+297, oy+3);
line(ox+297, oy+3, ox+300, oy);
line(ox+300, oy , ox+300, oy+30);
line(ox+300, oy+30, ox, oy+30);
setfillstyle(1, DARKGRAY);
floodfill(ox+150, oy+29, DARKGRAY);
setcolor(BLUE);
settextstyle(6, HORIZDIR, 3);
outtextxy(oxt, oyt, message);
end;
procedure window;
begin
setfillstyle(SOLIDFILL, WHITE);
bar(0, 0, getmaxx, getmaxy);
setcolor(DARKGRAY);
line(0, getmaxy, getmaxx, 0);
setfillstyle(SOLIDFILL, DARKGRAY);
floodfill(getmaxx, getmaxy, DARKGRAY);
setfillstyle(SOLIDFILL, LIGHTGRAY);
bar(4, 4, getmaxx-4, getmaxy-4);
setfillstyle(SOLIDFILL, DARKGRAY);
bar(8, 8, getmaxx-8, getmaxy-8);
setcolor(WHITE);
line(8, getmaxy-8, getmaxx-8, 8);
line(8, getmaxy-8, getmaxx-8, getmaxy-8);
line(getmaxx-8, getmaxy-8, getmaxx-8, 8);
setfillstyle(SOLIDFILL, WHITE);
floodfill(getmaxx-9, getmaxy-9, WHITE);
setfillstyle(SOLIDFILL, LIGHTGRAY);
bar(12, 12, getmaxx-12, getmaxy-12);
bar(8, getmaxy-100, getmaxx-8, getmaxy-96);
setcolor(DARKGRAY);
line(8, getmaxy-96, getmaxx-8, getmaxy-96);
line(getmaxx-8, getmaxy-96, getmaxx-15, getmaxy-93);
line(getmaxx-12, getmaxy-93, 12, getmaxy-93);
setfillstyle(SOLIDFILL, DARKGRAY);
floodfill(getmaxx div 2, getmaxy-94, DARKGRAY);
setcolor(WHITE);
line(8, getmaxy-101, 12, getmaxy-105);
line(12, getmaxy-104, getmaxx-12, getmaxy-104);
line(8, getmaxy-101, getmaxx-8, getmaxy-101);
setfillstyle(SOLIDFILL, WHITE);
floodfill(getmaxx div 2, getmaxy-102, WHITE);
setfillstyle(SOLIDFILL, LIGHTGRAY);
bar(8, 70, getmaxx-8, 66);
setcolor(WHITE);
line(8, 66, getmaxx-8, 66);
line(8, 66, 12, 63);
line(getmaxx-12, 63, 12, 63);
setfillstyle(1, WHITE);
floodfill(getmaxx div 2, 64, WHITE);
setcolor(DARKGRAY);
line(getmaxx-8, 71, getmaxx-12, 75);
line(12, 74, getmaxx-12, 74);
line(8, 71, getmaxx-8, 71);
setfillstyle(1, DARKGRAY);
floodfill(getmaxx div 2, 72, DARKGRAY);
setbkcolor(LIGHTGRAY);
setfillstyle(10, LIGHTBLUE);
bar(12, 12, getmaxx-12, 62);
setcolor(DARKGRAY);
settextstyle(8, HORIZDIR, 4);
outtextxy(getmaxx div 2-152, 13, 'Make your choice');
setcolor(RED);
outtextxy(getmaxx div 2-155, 10, 'Make your choice');
setbkcolor(LIGHTGRAY);
end;
procedure GenMatr;
var grdr, grmode: integer;
a, b, a0: matr;
Stat, X, Y: Word;
t: string;
begin
closegraph;
grdr:=DETECT;
initgraph(grdr, grmode, '');
cleardevice;
testmouse;
window;
for i:=1 to n do
begin
for j:=1 to n do
begin
b[i, j]:=0;
a[i, j]:=1.0*random(8)-4;
end;
b[i, i]:=1;
end;
for i:=1 to n do
for j:=1 to n do
a0[i, j]:=a[i, j];
settextstyle(2, 0, 5);
textcolor(red);
outtextxy(30, 90, 'Starting matrix:');
PrintMatr(a, b, n, 6, 1, 0);
button(getmaxx div 2-150, 410, getmaxx div 2-60, 406, 'CALCULATE');
repeat
Stat := MousePosition(X,Y);
if ((X>getmaxx div 2-150) and (X<getmaxx div 2+150)) and ((Y>410) and (Y<440)) then
CursorShape(PointingHand)
else
CursorShape(Standard);
if Stat=1 then {if left pressed}
if ((X>getmaxx div 2-150) and (X<getmaxx div 2+150)) and ((Y>410) and (Y<440)) then
begin
setfillstyle(SolidFill, Lightgray);
bar(15, 77, 625, 372);
settextstyle(2, 0, 5);
for i:=1 to n do
begin
for j:=i+1 to n do
AddStrings(a, b, i, j, sign(a[i, i])*sign(a[j, i]));
if (abs(a[i, i])>eps) then
begin
MultString(a, b, i, 1/a[i, i]);
for j:=i+1 to n do
AddStrings(a, b, j, i, -a[j, i]);
end
else
begin
closegraph;
writeln('No inverse matrix.');
readkey;
halt;
end
end;
if (a[n,n]>eps) then
begin
for i:=n downto 1 do
for j:=1 to i-1 do
begin
AddStrings(a, b, j, i, -a[j, i]);
end;
end
else outtextxy(30, 90, 'No inverse matrix.');
MultMatr(a0, b, a);
outtextxy(30, 90, 'Starting matrix; inverse matrix:');
PrintMatr(a0, b, n, 7, 3, 0);
outtextxy(30, 220, 'Check (must be E-matrix):');
PrintMatr(a, a, n, 7, 3, 1);
s0:=0; s1:=0;
for i:=1 to n do
for j:=1 to n do
if (i=j) then s1:=s1+abs(a[i, j])
else s0:=s0+abs(a[i, j]);
str(s1, t);
outtextxy(30, 350, 'Diagonal elements sum: '+t);
str(s0, t);
outtextxy(30, 360, 'Not-diagonal elements sum: '+t);
end;
until keypressed;
readkey;
closegraph;
end;
procedure EnterMatr;
var grdr, grmode: integer;
a, b, a0: matr;
Stat, X, Y: Word;
t: string;
begin