Министерство образования и науки РФ Федеральное государственное бюджетное образовательное учреждение Высшего профессионального образования Решение СЛАУ методом Гаусса с LU-разложением матрицы А Выполнил: студент гр.1-2 . Проверил: . ,2013 год. Задание: составить программу для вычисления корней системы линейных алгебраических уравнений методом Гаусса с LU-разложением матрицы А.При этом матрицы L и U должны хранится на месте матрицы А, необходим выбор ведущего элемента. Программа должна решать матрицы любой размерности. LU-разложение-представление матрицы А в виде произведения матриц L и U,где Lнижняя треугольная, а U-верхняя треугольная.LU-разложение ещё называют LUфакторизацией. После проведения разложения на месте исходной матрицы А записаны элементы нижней L и верхней U треугольных матриц разложения A=LU. Прямой ход LU-разложения представляет собой прямой ход метода Гаусса, но в отличие от него, столбец b не участвует в треугольном разложении матрицы А, так как от него не зависят L и U. Обратный ход метода предполагает вычисление двух уравнений: 1. Ly=b 2. Ux=y Из последнего уравнения получаем ответ. Спецификация Входные данные: n – размерность матрицы (количество линейных уравнений), aij – коэффициенты системы, bi – свободные члены. Выходные данные: xi – корни системы. Таблица разработки Шаги разработки max → begin ввод входных данных вычисление корней СЛАУ вывод результата end. Ввод данных → begin read (n); for i :=1 to n do begin for j :=1 to n do begin read(a[i,j]); end; read(b[i]); Примечания end; Вычисляем машинный эпсилон: macheps:=1; repeat macheps:=macheps/2; until (1+macheps)=1; macheps:=macheps*2; После окончания масштабирования в массиве А0 хранятся масштабные коэффициенты. Матрица А нормализуется таким образом, что каждый элемент столбца не превышает по модулю 1. Полученные треугольные матрицы L и U в Составляем процедуру разложения матрицы совокупности с массивом целых чисел int позволяют найти решение СЛУ Ax = b для А на верхнюю и нижнюю треугольные: заданных значений правых чисел b,используя уравнение LUx = b, которое сводится к Формируем вектор A0-A0[i]=max(aj,i): последовательному решению уравнений Ly = b, for i:=1 to n do Ux=y. begin Если в какой-то момент времени алгоритм A0[i]:=A[1,i]; определит, что А является вырожденной for j:=2 to n do матрицей, то разложение прекращается с begin выдачей retcode = 1. if abs (A[j,i]) > A0[i] then A0[i]:=abs(A[j,i]); end; Нормализуем матрицу А: for j:=1 to n do A[j,i]:=A[j,i]/A0[i]; end; for i:=1 to n do int [i]:=i; Вычисление элементов к-го столбца: for k:=1 to n-1 do begin Выбор наибольшего элемента к-го столбца: amax:=abs (A[int[k],i]); for i:=k+1 to n do begin if abs (A[int[k],i])> amax then amax:=abs (A[int[k],i]); imax:=i; end; if imax <>k then begin j:=int [k]; int[k]:=int[imax]; int[imax]:=j; end; Проверка на вырожденность: if abs(A[int[k],k]) < n*macheps then retcode:=1; i,j,n,k,imax:integer; amax:real; Вычисление элементов к-й строки: for j:=k+1 to n do A[int[k],j]:=A[int[k],j]/A[int[k],k]; Вычисление элементов строк k+1…n: for i:=k+1 to n do for j:=k+1 to n do A[int[i],j]:=A[int[i],j]-A[int[k],j]*A[int[i],k]; end; Составим процедуру для непосредственного решения заданной СЛАУ: for i:=1 to n do Перестановка компонентов правой части b: x[i]:=b[i]; for i:=1 to n do begin if int[i] <>i then z:=x[i]; x[i]:=x[int[i]]; x[int[i]]:=z; end; Решение системы Ly=b: for i:=1 to n do begin summa:=0; for j:=1 to i-1 do summa:=summa+A[i,j]*x[j]; x[i]:=(x[i]-summa)/A[i,i]; end; Решение системы Ux=y: for i:=n downto 1 do begin summa:=0; for j:=n downto i+1 do summa:=summa+A[i,j]*x[j]; x[i]:=x[i]-summa; end; Переход к реальному масштабу измерений: for i:=1 to n do x[i]:=x[i]/A0[i]; Вывод решения и выход из программы: Если retcode=1, то выводим сообщение о вырожденности. В противном случае обращаемся к процедуре решения и выводим решение: write('Корни системы: '); for i:=1 to n do writeln('x[',i, ']= ',x[i], ''); end. i,j,n:integer; z,summa:real; Текст программы program max; type matrica=array[1..100,1..100]of real; vector=array[1..100]of real; vector1=array[1..100]of integer; var A:matrica; x,b,A0:vector; i,j,n,retcode:integer; macheps:real; Procedure triangul(var A:matrica ); var i,j,n,k,imax:integer; amax:real; int:vector1; BEGIN //формирование вектора A0-A0[i]=max(aj,i) for i:=1 to n do begin A0[i]:=A[1,i]; for j:=2 to n do begin if abs(A[j,i])>A0[i]then A0[i]:=abs(A[j,i]); end; //нормализация матрицы A for j:=1 to n do A[j,i]:=A[j,i]/A0[i]; end; for i:=1 to n do int[i]:=i; //вычисление элементов к-го столбца for k:=1 to n-1 do begin //выбор наибольшего элемента к-го столбца amax:=abs(A[int[k],i]); for i:=k+1 to n do begin if abs(A[int[k],i])>amax then amax:=abs(A[int[k],i]); imax:=i; end; if imax <>k then begin //переставить строки k и imax j:=int[k]; int[k]:=int[imax]; int[imax]:=j; end; //проверка на вырожденность if abs(A[int[k],k])<n*macheps then retcode:=1; //вычисление элементов к-й строки for j:=k+1 to n do A[int[k],j]:=A[int[k],j]/A[int[k],k]; //вычисление элементов строк k+1...n for i:=k+1 to n do for j:=k+1 to n do A[int[i],j]:=A[int[i],j]-A[int[k],j]*A[int[i],k]; end; END; Procedure reshenie(A:matrica;var x:vector); var i,j,n:integer; z,summa:real; int:vector1; b:vector; BEGIN for i:=1 to n do //перестановка компонентов правой части b x[i]:=b[i]; for i:=1 to n do begin if int[i] <>i then z:=x[i]; x[i]:=x[int[i]]; x[int[i]]:=z; end; //решение системы Ly=b for i:=1 to n do begin summa:=0; for j:=1 to i-1 do summa:=summa+A[i,j]*x[j]; x[i]:=(x[i]-summa)/A[i,i]; end; //решение системы Ux=y for i:=n downto 1 do begin summa:=0; for j:=n downto i+1 do summa:=summa+A[i,j]*x[j]; x[i]:=x[i]-summa; end; //переход к реальному масштабу измерений for i:=1 to n do x[i]:=x[i]/A0[i]; END; begin write('Введите количество уравнений системы:'); read(n); for i:=1 to n do begin for j:=1 to n do begin write('a[',i,',',j,']='); read(a[i,j]); end; write('b[',i,']='); read(b[i]); end; //вычисление машинного эпсилон macheps:=1; repeat macheps:=macheps/2; until(1+macheps)=1; macheps:=macheps*2; retcode:=0; triangul(A ); if retcode=1 then writeln('Нет решения.Матрица вырожденная')else begin reshenie(A,x); write('корни СЛАУ:'); writeln; for i:=1 to n do writeln('x[',i,']=',x[i]); end; end. Экспериментальная часть Пример1. Введите количество уравнений системы:5 a[1,1]=1 a[1,2]=5 a[1,3]=6 a[1,4]=9 a[1,5]=84 b[1]=26 a[2,1]=58 a[2,2]=27.7 a[2,3]=89 a[2,4]=6 a[2,5]=5 b[2]=23 a[3,1]=69 a[3,2]=21 a[3,3]=26 a[3,4]=36 a[3,5]=59 b[3]=57 a[4,1]=28 a[4,2]=54 a[4,3]=19 a[4,4]=36 a[4,5]=34 b[4]=98 a[5,1]=67 a[5,2]=46 a[5,3]=58 a[5,4]=32 a[5,5]=16 b[5]=23 корни СЛАУ: x[1]=-2897.30143315118 x[2]=295.513916190974 x[3]=-1975.46345689773 x[4]=671.024457943531 x[5]=243.760689931734 Пример 2. Введите количество уравнений системы:2 a[1,1]=2 a[1,2]=4 b[1]=6 a[2,1]=4 a[2,2]=8 b[2]=12 Нет решения. Пример 3. Введите число уравнений:4 a[1,1]=2 a[1,2]=3 a[1,3]=6 a[1,4]=5 b[1]=4 a[2,1]=1 a[2,2]=2 a[2,3]=3 a[2,4]=-9 b[2]=7.5 a[3,1]=-8.23 a[3,2]=5 a[3,3]=9 a[3,4]=4 b[3]=6 a[4,1]=4 a[4,2]=6 a[4,3]=7 a[4,4]=6 b[4]=12 Корни системы: x[1]=0.23577887724 x[2]=2.7999157752 x[3]=-0.5147796791 x[4]=-0.35652540107 Экспериментальная часть заключалась в рассмотрении трёх примеров СЛАУ разных видов. В первом и в третьем примерах рассматривались невырожденные СЛАУ.В результате работы программы мы получили значения корней СЛАУ. Во втором примере было рассмотрено решение линейно зависимых СЛАУ. Результатом работы программы стал вывод ответа о том, что СЛАУ не имеет решения, так как определитель матрицы будет равен 0. Таким образом, программа работает. Из примеров видно, что программа решает матрицы любой размерности.