Выполнение процесса решения СЛАУ двумя методами – Гаусса и LU-разложения

Страницы работы

Фрагмент текста работы

Лабораторная работа №1       

Решение СЛАУ

Студент                     Кохно

Группа                       РМС7-71

Преподаватель         Лобач

Задача 2

2. Выполнить процесс решения СЛАУ, заданной преподавателем, двумя методами – Гаусса и LU-разложения (с выводом промежуточных данных в файлы). Проанализировать ход решения и сравнить с описанием алгоритмов.

Текст программы (метод Гаусса):

// Программа для решения СЛАУ с помощью LinGauss или LinDecomp и LinSolve

#include <iostream.h>

#include <stdio.h>

#include <conio.h>

#include "linsys.h"

void main()

{

// описание данных

int i,j,n,keyDemo,Err1=0,Err2=0;

Matrix A,L,U;

Vector B,X;

// задание входных данных

keyDemo=3;

n=4;

A[1][1]= 2.2; A[1][2]= 3.1; A[1][3]= 1.1; A[1][4]=-1.2;

A[2][1]= 0.3; A[2][2]= 1.7; A[2][3]= 2.9; A[2][4]=-0.5;

A[3][1]= 3.1; A[3][2]= 0.1; A[3][3]=-5.1; A[3][4]= 2.1;

A[4][1]=-3.0; A[4][2]= 2.5; A[4][3]= 1.6; A[4][4]= 8.1;

B[1]= 6.9; B[2]= 10.4; B[3]=-3.6; B[4]=39.2;

// решение СЛАУ

Err1=LinGauss(n,A,B,X,keyDemo);

//    Err1=LinDecomp(n,A,L,U,keyDemo);

//    Err2=LinSolve(n,L,U,B,X,keyDemo);

// вывод результата

clrscr();

cout<<"Err1 = "<<Err1<<endl;

cout<<"Err2 = "<<Err2<<endl;

cout<<endl;

cout<<"Vector X:"<<endl;

for (i=1; i<=n; i++)

printf("%6.3f  ",X[i]);

cout<<endl;

getch();

}

Пример работы программы в файле LINGAUSS.DAT

Блок-схема:

 - исходная система.

Метод Гаусса основан на замене исходной системы на эквивалентную (т.е. имеющую то же решение ), но с матрицей  верхней треугольной формы:

Матрица  получается путем преобразования исходной матрицы , а вектор  - из вектора . Так как матрица  - треугольная, все компоненты вектора , начиная с , легко находятся последовательно.

Алгоритм метода Гаусса состоит из двух этапов:

Преобразование и . - прямой ход;

Последовательное  вычисление  – обратный ход.


                                                          Прямой ход                               Обратный ход

Текст программы (метод LU-разложения):

// Программа для решения СЛАУ с помощью LinGauss или LinDecomp и LinSolve

#include <iostream.h>

#include <stdio.h>

#include <conio.h>

#include "linsys.h"

void main()

{

// описание данных

int i,j,n,keyDemo,Err1=0,Err2=0;

Matrix A,L,U;

Vector B,X;

// задание входных данных

keyDemo=3;

n=4;

A[1][1]= 2.2; A[1][2]= 3.1; A[1][3]= 1.1; A[1][4]=-1.2;

A[2][1]= 0.3; A[2][2]= 1.7; A[2][3]= 2.9; A[2][4]=-0.5;

A[3][1]= 3.1; A[3][2]= 0.1; A[3][3]=-5.1; A[3][4]= 2.1;

A[4][1]=-3.0; A[4][2]= 2.5; A[4][3]= 1.6; A[4][4]= 8.1;

B[1]= 6.9; B[2]= 10.4; B[3]=-3.6; B[4]=39.2;

// решение СЛАУ

//    Err1=LinGauss(n,A,B,X,keyDemo);

Err1=LinDecomp(n,A,L,U,keyDemo);

Err2=LinSolve(n,L,U,B,X,keyDemo);

// вывод результата

clrscr();

cout<<"Err1 = "<<Err1<<endl;

cout<<"Err2 = "<<Err2<<endl;

cout<<endl;

cout<<"Vector X:"<<endl;

for (i=1; i<=n; i++)

printf("%6.3f  ",X[i]);

cout<<endl;

getch();

}

Пример работы программы в файле LINLU.DAT

i     Sum    X[i]

4    0.00    4.00

3    4.20    3.00

2    5.41    2.00

1    2.14    1.00

Блок-схема:

Метод LU-разложения основан на том, что матрица  может быть представлена в виде произведения двух матриц:

                                                                                      где       - нижняя треугольная матрица,

 - верхняя треугольная матрица с единичной  главной диагональю.

При этом разложении исходная система  разлагается на две, но с треугольными матрицами:

                                                                                     

                                                                                     которые легко решаются  последовательно,  т.е.  сначала из решения системы  находится вектор промежуточных неизвестных ,  а затем, используя найденный вектор  в качестве вектора свободных членов,  решается система  и находится искомый вектор неизвестных .

Прямой ход                                                     Обратный ход

                                   

Задача 3

3. Методами Гаусса и LU-разложения выполнить решение СЛАУ

, которая имеет решением значения ,  и , в чем легко убедиться умножением матрицы на этот вектор. Объяснить полученный результат.


Текст программы (метод Гаусса):

// Программа для решения СЛАУ с помощью LinGauss или LinDecomp и LinSolve

#include <iostream.h>

#include <stdio.h>

#include <conio.h>

#include "linsys.h"

void main()

{

// описание данных

int i,j,n,keyDemo,Err1=0,Err2=0;

Matrix A,L,U;

Vector B,X;

// задание входных данных

keyDemo=3;

n=3;

A[1][1]= 1.1; A[1][2]= 1.2; A[1][3]= 1.3;

A[2][1]= 2.1; A[2][2]= 2.2; A[2][3]= 2.3;

A[3][1]= 3.1; A[3][2]= 3.2; A[3][3]= 3.3;

B[1]=7; B[2]=13; B[3]=19;

// решение СЛАУ

Err1=LinGauss(n,A,B,X,keyDemo);

//    Err1=LinDecomp(n,A,L,U,keyDemo);

//    Err2=LinSolve(n,L,U,B,X,keyDemo);

// вывод результата

clrscr();

cout<<"Err1 = "<<Err1<<endl;

cout<<"Err2 = "<<Err2<<endl;

cout<<endl;

cout<<"Vector X:"<<endl;

for (i=1; i<=n; i++)

printf("%6.3f  ",X[i]);

cout<<endl;

getch();

}

Пример исполнения(метод LU-разложения):

Err1 = 0

Err2 = 0

Vector X:

2.000   4.000   0.000

Текст программы(метод гауса):

// Программа для решения СЛАУ с помощью LinGauss или LinDecomp и LinSolve

#include <iostream.h>

#include <stdio.h>

#include <conio.h>

#include "linsys.h"

#include "matrix.h"

void main()

{

// описание данных

int i,j,n,keyDemo,Err1=0,Err2=0;

Matrix A,L,U;

Vector B,X,N,Y;

// задание входных данных

keyDemo=3;

n=3;

A[1][1]= 1.1; A[1][2]= 1.2; A[1][3]= 1.3;

A[2][1]= 2.1; A[2][2]= 2.2; A[2][3]= 2.3;

A[3][1]= 3.1; A[3][2]= 3.2; A[3][3]= 3.3;

B[1]=7; B[2]=13; B[3]=19;

N[1]=3; N[2]=2; N[3]=1;

// решение СЛАУ

Err1=LinGauss(n,A,B,X,keyDemo);

//    Err1=LinDecomp(n,A,L,U,keyDemo);

//    Err2=LinSolve(n,L,U,B,X,keyDemo);

// вывод результата

clrscr();

cout<<"Err1 = "<<Err1<<endl;

cout<<"Err2 = "<<Err2<<endl;

cout<<endl;

cout<<"Vector X:"<<endl;

for (i=1; i<=n; i++)

printf("%6.3f  ",X[i]);

cout<<endl;

getch();

LinMxV(n,A,N,Y);

cout<<"Vector B:"<<endl;

printf("%6.3f  %6.3f  %6.3f",Y[1],Y[2],Y[3]);

getch();

}

Пример исполнения:

Err1 = 0

Err2 = 0

Vector X:

4.000   0.000   2.000

Vector B:

7.000  13.000  19.000

Вывод: решением данной матрицы являются несколько векторов. Это объясняется тем, что эта матрица вырожденная (ее определитель равен нулю) значит данная СЛАУ имеет бесконечное множество решений.

Задача 4

4. Выполнить решение СЛАУ из п. 2 с выводом промежуточных результатов с помощью функций LinGaussPro() или LinDecompPro() и LinSolvePro() (по указанию преподавателя). Проанализировать ход решения и сравнить с описанием алгоритмов.

Текст программы:

// Программа для решения СЛАУ с помощью LinGaussPro

// или LinDecompPro и LinSolvePro

#include <iostream.h>

#include <stdio.h>

#include <conio.h>

#include "linsys.h"

void main()

{

// описание данных

int i,j,n,keyDemo,Err1=0,Err2=0;

Matrix A;

Vector B,X;

iVector P;

// задание входных данных

keyDemo=3;

n=4;

A[1][1]= 2.2; A[1][2]= 3.1; A[1][3]= 1.1; A[1][4]=-1.2;

A[2][1]= 0.3; A[2][2]= 1.7; A[2][3]= 2.9; A[2][4]=-0.5;

A[3][1]= 3.1; A[3][2]= 0.1; A[3][3]=-5.1; A[3][4]= 2.1;

A[4][1]=-3.0; A[4][2]= 2.5; A[4][3]= 1.6; A[4][4]= 8.1;

B[1]=6.9; B[2]=10.4; B[3]=-3.6; B[4]=39.2;

// решение СЛАУ

Err1=LinGaussPro(n,A,B,X,keyDemo);

//    Err1=LinDecompPro(n,A,P,keyDemo);

//    Err2=LinSolvePro(n,A,P,B,X,keyDemo);

// вывод результата

clrscr();

cout<<"Err1 = "<<Err1<<endl;

cout<<"Err2 = "<<Err2<<endl;

cout<<endl;

cout<<"Vector X:"<<endl;

for (i=1; i<=n; i++)

printf("%6.3f  ",X[i]);

cout<<endl;

getch();

}

Пример исполнения: см. файл 4LINGAUSS.DAT

i     Sum    X[i]

4    0.00    4.00

3    4.20    3.00

2    5.41    2.00

1    2.14    1.00

Задача 5

5. Методом прогонки выполнить решение СЛАУ, имеющей трехдиагональную матрицу, (заданной преподавателем) с выводом промежуточных данных в файл. Проанализировать ход решения и сравнить с описанием алгоритмов.

Текст программы:

// Программа для решения СЛАУ методом прогонки

#include <iostream.h>

#include <stdio.h>

#include <conio.h>

#include "linsys.h"

void main()

{

// описание данных

int i,n,keyDemo,Err;

double Rmod;

Matrix A;

Vector R,P,Q,F,X,RR;

// задание входных данных

n=5;

P[1]=1; Q[1]=3;                           F[1]=7;

R[2]=2; P[2]=1; Q[2]=4;                   F[2]=16;

R[3]=2; P[3]=-1; Q[3]=2;           F[3]=9;

R[4]=4; P[4]=1; Q[4]=2;   F[4]=26;

R[5]=3; P[5]=1;   F[5]=17;

keyDemo=3;

// решение

Err=LinProgon(n,R,P,Q,F,X,keyDemo);

// вывод результата

clrscr();

cout<<"Err = "<<Err<<endl;

cout<<endl;

cout<<"Вектор X: ";

for (i=1; i<=n; i++)

printf("%7.3f ",X[i]);

cout<<endl;

getch();

Пример исполнения: 5LINPROGO.DAT

i     Sum    X[i]

4    0.00    4.00

3   -6.74    3.00

2    1.12    2.00

1   -2.16    1.00

Блок-схема:

Метод прогонки применяется для СЛАУ с трехдиагональной матрицей, в которой все элементы, не входящие в главную и прилегающие к ней диагонали, равны нулю:

коэффициенты СЛАУ хранятся и обрабатываются в виде трех одномерных массивов:  - массива элементов главной диагонали,  - массива элементов ниже главной диагонали и  - массива элементов выше главной диагонали. Индекс элемента массивов ,  или  соответствует индексу строки матрицы.

Идея метода прогонки основана на представлении каждой компоненты вектора неизвестных через следующую:

где и  - прогоночные коэффициенты, которые необходимо определить.

                                            

Задача 6

6. Выполнить решение системы из п. 5 с помощью метода Гаусса или LU-разложения (по указанию преподавателя).

Текст программы:

// Программа для решения СЛАУ с помощью LinGauss или LinDecomp и LinSolve

#include <iostream.h>

#include <stdio.h>

#include <conio.h>

#include "linsys.h"

void main()

{

// описание данных

int i,j,n,keyDemo,Err1=0,Err2=0;

Matrix A,L,U;

Vector B,X;

// задание входных данных

keyDemo=3;

n=5;

A[1][1]= 1; A[1][2]= 3; A[1][3]= 0; A[1][4]= 0; A[1][5]= 0;

A[2][1]= 2; A[2][2]= 1; A[2][3]= 4; A[2][4]= 0; A[2][5]= 0;

A[3][1]= 0; A[3][2]= 2; A[3][3]=-1; A[3][4]= 2; A[3][5]= 0;

A[4][1]= 0; A[4][2]= 0; A[4][3]= 4; A[4][4]= 1; A[4][5]= 2;

A[5][1]= 0; A[5][2]= 0; A[5][3]= 0; A[5][4]= 3; A[5][5]= 1;

B[1]=7; B[2]=16; B[3]=9; B[4]=26; B[5]=17;

// решение СЛАУ

//    Err1=LinGauss(n,A,B,X,keyDemo);

Err1=LinDecomp(n,A,L,U,keyDemo);

Err2=LinSolve(n,L,U,B,X,keyDemo);

// вывод результата

clrscr();

cout<<"Err1 = "<<Err1<<endl;

cout<<"Err2 = "<<Err2<<endl;

cout<<endl;

cout<<"Vector X:"<<endl;

for (i=1; i<=n; i++)

printf("%6.3f  ",X[i]);

cout<<endl;

getch();

}

Пример исполнения: файл  6LINLU.DAT

i     Sum    X[i]

4    0.00    4.00

3    4.20    3.00

2    5.41    2.00

1    2.14    1.00

Задача 7

7. Используя программу из файла cond.exe, рассчитать числа обусловленности матриц СЛАУ, решаемых при выполнении предыдущих пунктов задания. Сделать вывод о влиянии числа обусловленности на точность решения СЛАУ.

 Число обусловленности cond=1.626744e+17

Число обусловленности cond = 16.573734

 Число обусловленности cond = 18.175613

Вывод: Чем больше значение числа обусловленности, тем больше погрешность вычисления вектора неизвестных.

Задача 8

8. Проверить работу одной из функций (по указанию преподавателя

Похожие материалы

Информация о работе

Тип:
Отчеты по лабораторным работам
Размер файла:
324 Kb
Скачали:
0