Осуществление алгоритмов линейной алгебры
Отчет по практике, 21 Ноября 2013, автор: пользователь скрыл имя
Краткое описание
Моя отчетная работа посвящена вычислительной практике. Цель данной практики – ознакомление студентов с базовыми понятиями вычислительной математики, проверка полученных знаний студентом за 1 курс в области программирования, а также умение использовать их на практике. В течении двух недель мы изучали алгоритмы: их историю, оптимизация алгоритма и так далее. По-моему учебная практика была достаточно сложной, но в то же время полезной, так как мы наглядно увидели применение языка Си в математических задачах, а точнее в линейной алгебре.
Содержание
Введение
1.Основные алгоритмы
1.1.История алгоритмов
1.2.Реализация на С
1.3.Быстродействие
Вывод
Вложенные файлы: 1 файл
отчет по практике.docx
— 250.35 Кб (Скачать файл)Сначала мы находим ту строку где первый элемент является максимальным в первом столбце. После переставляем ее на первое место, разделив на первый элемент. Далее отнимаем первую строку из всех остальных умноженную на соответствующий коэффициент.
Далее делаем тоже самое с остальными столбцами, начиная с диагональных элементов, т.е. мы как бы уменьшаем размер матрицы.
Достоинства метода
• Для матриц ограниченного размера менее трудоёмкий по сравнению с другими методами.
• Позволяет однозначно установить, совместна система или нет, и если совместна, найти её решение.
• Позволяет найти максимальное
число линейно независимых
Неоптимальность метода Гаусса. В 1969 году Штрассен доказал, что большие матрицы можно перемножить за время Θ(nlog2 7) = Θ(n2.81). Отсюда вытекает, что обращение матриц и решение СЛАУ можно осуществлять алгоритмами асимптотически более быстрыми, чем метод Гаусса. Таким образом, для больших СЛАУ метод Гаусса не оптимален по скорости.
4.Нахождение обратной матрицы.
Обра́тная ма́трица — такая матрица A−1, при умножении на которую, исходная матрица A даёт в результате единичную матрицу E:
Квадратная матрица обратима тогда и только тогда, когда она невырожденная, то есть её определитель не равен нулю. Для неквадратных матриц и вырожденных матриц обратных матриц не существует. Однако возможно обобщить это понятие и ввести псевдообратные матрицы, похожие на обратные по многим свойствам.
Ниже представлен пседокод программы на Си, осуществляющей нахождение обратной матрицы.
- for (i=0; i<n; i++)
- for (j=0; j<n; j++)
- if (j==i) b[i][j]=1; else b[i][j]=0;
- for(s=0; s<n; s++){
- max=a[s][s];
- k=s;
- for (i=s; i<n; i++){
- if (abs(a[i][s])>max){
- max=abs(a[i][s]);
- k=i;
- }
- }
- if (a[k][s]<0) max=-max;
- if(max!=0){
- if (k!=s) {
- for (j=s; j<n; j++){
- c=a[s][j];
- a[s][j]=a[k][j]/max;
- a[k][j]=c;
- }
- for (j=0; j<n; j++){
- m=b[s][j];
- b[s][j]=b[k][j]/max;
- b[k][j]=m;
- }
- }else{
- for(j=s; j<n; j++){
- a[k][j]=a[k][j]/max;
- }
- for (j=0; j<n; j++)
- b[k][j]=b[k][j]/max;
- }
- } else {
- printf ("matrica ne obratima\n");
- goto m10;
- }
- for (i=s+1; i<n; i++){
- c=a[i][s];
- for (j=s; j<n; j++)
- a[i][j]=a[i][j]-a[s][j]*c;
- for (j=0; j<n; j++)
- b[i][j]=b[i][j]-b[s][j]*c;
- }
- }
- for (s=n-1; s>-1; s--)
- for (i=s-1; i>-1; i--)
- for (j=0; j<n; j++)
- b[i][j]=b[i][j]-a[i][s]*b[
s][j]; - for (s=n-1; s>-1; s--){
- for (i=n-2; i>-1; i--){
- c=a[i][s];
- for (j=n-1; j>s; j--)
- a[i][j]=a[i][j]-a[s][j]*c;
- }
- }
- for (i=0; i<n; i++){
- for(j=0;j<n; j++)
- printf("%f ", a[i][j]);
- printf ("\n");
- }
- printf ("\n");
- for (i=0; i<n; i++){
- for(j=0;j<n; j++)
- printf("%f ", b[i][j]);
- printf("\n");
- }
- m10: return 0;
- }
Описание: Алгоритм весьма прост. Изначально матрица В – единичная матрица. После приводим матрицу А к ступенчатому виду как было показано в программе Метод Гаусса, также делая соответствующие преобразования в матрице В. Далее находим элементы массива х.
5.Решение СЛАУ.
АХ=В; Х=А-1В.
Приведем псевдо код программы на Си.
- for (i=0; i<n; i++)
- for (j=0; j<n; j++)
- if (j==i) b[i][j]=1; else b[i][j]=0;
- for(s=0; s<n; s++){
- max=a[s][s];
- k=s;
- for (i=s; i<n; i++){
- if (abs(a[i][s])>max){
- max=abs(a[i][s]);
- k=i;
- }
- }
- if (a[k][s]<0) max=-max;
- if(max!=0){
- if (k!=s) {
- for (j=s; j<n; j++){
- c=a[s][j];
- a[s][j]=a[k][j]/max;
- a[k][j]=c;
- }
- for (j=0; j<n; j++){
- m=b[s][j];
- b[s][j]=b[k][j]/max;
- b[k][j]=m;
- }
- }else{
- for(j=s; j<n; j++){
- a[k][j]=a[k][j]/max;
- }
- for (j=0; j<n; j++)
- b[k][j]=b[k][j]/max;
- }
- } else {
- printf ("matrica ne obratima\n");
- goto m10;
- }
- for (i=s+1; i<n; i++){
- c=a[i][s];
- for (j=s; j<n; j++)
- a[i][j]=a[i][j]-a[s][j]*c;
- for (j=0; j<n; j++)
- b[i][j]=b[i][j]-b[s][j]*c;
- }
- }
- for (s=n-1; s>-1; s--)
- for (i=s-1; i>-1; i--)
- for (j=0; j<n; j++)
- b[i][j]=b[i][j]-a[i][s]*b[
s][j]; - for (s=n-1; s>-1; s--){
- for (i=n-2; i>-1; i--){
- c=a[i][s];
- for (j=n-1; j>s; j--)
- a[i][j]=a[i][j]-a[s][j]*c;
- }
- }
- for (i=0; i<n; i++)
- for (j=0; j<h; j++)
- x[i][j]=0;
- for (k=0; k<n; k++)
- for (i=0; i<n; i++)
- for (j=0; j<h; j++)
- x[i][j]=x[i][j]+b[i][k]*d[
k][j]; - for (i=0; i<n; i++){
- for(j=0;j<h; j++)
- printf("%f ", x[i][j]);
- printf ("\n");
- }
- printf ("\n");
- for (i=0; i<n; i++){
- for(j=0;j<n; j++)
- printf("%f ", b[i][j]);
- printf("\n");
- }
Описание: Сначала находим обратную матрицу к А, после умножаем ее на вектор В и находим вектор Х.
6. LU – разложение.
LU- разложение — представление матрицы A в виде произведения двух матриц, , где L—нижняя треугольная матрица, а U— верхняя треугольная матрица. LU-разложение еще называют LU-факторизацией.
LU-разложение используется
Найти матрицы и можно следующим образом (выполнять шаги следует строго по порядку, так как следующие элементы находятся с использованием предыдущих):
1.
2.
Для
1.
2.
В итоге мы получим матрицы — L и U.
Вот псевдокод программы.
- for (i=0; i<n; i++)
- for (j=0; j<n; j++){
- l[i][j]=0;
- u[i][j]=0;
- }
- for (i=0; i<n; i++)
- L[i][i]=1;
- for (j=0; j<n; j++)
- u[0][j]=a[0][j];
- for (j=1; j<n; j++)
- L[j][0]=a[j][0]/u[0][0];
- for (i=1; i<n; i++)
- for (j=i; j<n; j++){
- s=0;
- for (k=0; k<i-1; k++)
- s=s+l[i][k]*u[k][j];
- u[i][j]=a[i][j]-s;
- }
- for (i=1; i<n; i++)
- for (j=i+1; j<n; j++){
- r=0;
- for (k=0; k<i-1; k++)
- r=r+l[j][k]*u[k][i];
- l[j][i]=(a[j][i]-r)/u[i][i]
; - }
7. LUX=B.
Решение систем линейных уравнений. LU-разложение может быть использовано для решения системы линейных уравнений
где A— матрица коэффициентов системы, x— вектор неизвестных величин системы, b — вектор правых частей системы.
Если известно LU-разложение матрицы , , исходная система может быть записана как
Эта система может быть решена в два шага. На первом шаге решается система
Поскольку L — нижняя треугольная матрица, эта система решается непосредственно прямой подстановкой.
На втором шаге решается система
Поскольку U — верхняя треугольная матрица, эта система решается непосредственно обратной подстановкой.
Ниже предоставлен псевдокод программы.
- for (i=0; i<n; i++)
- for (j=0; j<n; j++){
- l[i][j]=0;
- u[i][j]=0;
- }
- for (i=0; i<n; i++)
- L[i][i]=1;
- for (j=0; j<n; j++)
- u[0][j]=a[0][j];
- for (j=1; j<n; j++)
- L[j][0]=a[j][0]/u[0][0];
- for (i=1; i<n; i++)
- for (j=i; j<n; j++){
- s=0;
- for (k=0; k<i-1; k++)
- s=s+l[i][k]*u[k][j];
- u[i][j]=a[i][j]-s;
- }
- for (i=1; i<n; i++)
- for (j=i+1; j<n; j++){
- r=0;
- for (k=0; k<i-1; k++)
- r=r+l[j][k]*u[k][i];
- l[j][i]=(a[j][i]-r)/u[i][i]
; - }
- for (i=0; i<n; i++){
- z=0;
- for(j=0; j<i-1; j++)
- z=z+l[i][j]*y[j][0];
- y[i][0]=b[i][0]-z;
- }
- for (i=0; i<n; i++){
- c=u[i][i];
- for (j=0; j<n; j++)
- u[i][j]=u[i][j]/c;
- y[i][0]=y[i][0]/c;
- }
- for (i=0; i<n; i++){
- z=0;
- for(j=0; j<i-1; j++)
- z=z+u[i][j]*x[j][0];
- x[i][0]=y[i][0]-z;
- }
8. Применение метода Гаусса к
ленточно – диагональным
Если матрица А имеет ленточно – диагональный вид, то программа выглядит так:
- for (i=0; i<n; i++)
- for (j=0; j<n; j++)
- if ((i-j>k1)||(j-i>k2)) a[i][j]=0;
- for (s=0; s<n; s++){
- max=a[s][s];
- k=s;
- for (i=s; i<k1; i++){
- if (abs(a[i][s])>max){
- max=abs(a[i][j]);
- k=i;
- }
- }
- if (a[k][s]<0) max=-max;
- if(max!=0){
- if (k!=s) {
- for (j=s; j<k2; j++){
- c=a[s][j];
- a[s][j]=a[k][j]/max;
- a[k][j]=c;
- }
- m=b[s];
- b[s]=b[k]/max;
- b[k]=m;
- }else{
- for(j=s; j<k2; j++){
- a[k][j]=a[k][j]/max;
- }
- b[k]=b[k]/max;
- }
- } else {
- printf ("mn-vo reshenii\n");
- goto m10;
- }
- for (i=s+1; i<n; i++){
- c=a[i][s];
- for(j=s; j<n; j++)
- a[i][j]=a[i][j]-a[s][j]*c;
- b[i]=b[i]-b[s]*c;
- }
- }
- for (i=n-1; i>-1; i--){
- z=0;
- for(j=n-1; j>i-1; j--)
- z=z+a[i][j+1]*x[j+1];
- x[i]=b[i]-z;
- }
Как видно из программы, имея дополнительные сведения о матрице А, можно написать программу, которая будет работать гораздо быстрее, чем программа обычного Метода Гаусса.
Вывод:
Учебно – вычислительная практика позволила нам применить знания полученные в течении года по программированию при решении математических задач, в частности задач из линейной алгебры. Также на практике мы получали новые знания в области программирования.