Числові методи
МІНІСТЕРСТВО ОСВІТИ УКРАЇНИ ЧЕРНІВЕЦЬКИЙ ДЕРЖАВНИЙ УНІВЕРСИТЕТ ІМ. Ю. ФЕДЬКОВИЧА КОНТРОЛЬНА РОБОТА з дисципліни " Числові методи " Варіант 16. Виконав студент 2-го курсу кафедри ЕОМ Перевірив м. Чернівці Завдання 1 Задана СЛАР а) розв'язати цю систему методом Гауса за схемою з частковим вибором головного елементу; б)розв'язати цю систему за формулою . - вектор невідомих, - вектор вільних членів, - обернена матриця до матриці з коєфіцієнтів при невідомих. Обернену матрицю знай ти методом Гауса - Жордана за схемою з частковим вибором головного елемента. Рішення. а) Прямий хід методу Гауса. () Запишемо матрицю . 1-й крок. Серед елементів першого стовпчика шукаємо максимальний: Перше і друге рівняння міняємо місцями. Розділимо рівняння (1) на 2.5 (1) Від рівняння (2) віднімемо 1.7Р1 . (2) (3) Таким чином в кінці першого кроку отримуємо систему 2-й крок. Порядок рівнянь зберігається. (2) (3) Після другого кроку система рівнянь стала такою: Зворотній хід. З рівняння (3) ; з рівняння (2) ; з рівняння (1) ; Для рішення системи лінійних рівнянь методом Гауса призначена програма Work1_1. //------------------------------------------------------------ // Work1_1.cpp //------------------------------------------------------------ // "Числові методи" // Завдання 1 // Рішення системи лінійних рівнянь методом Гауса #include <stdio.h> #include <iostream.h> #include <conio.h> const int nMax=5; // максимальна кількість рівнянь const float ZERO=.0000001; int fGaus(float A[nMax][nMax],float B[nMax],int n,float X[nMax]) /* Функція розв'язує систему лінійних рівнянь методом Гауса за схемою з частковим вибором головного елементу. Вхідні дані: A- масив з коефіцієнтами при невідомих; В- масив з вільними членами СЛАР; n- порядок матриці А(кількість рівнянь системи); Вихідні дані: Х- масив з коренями системи; функція повертає код помилки: 0- сисетма успішно розв'язана; 1- матриця А вироджена. */ {float aMax,t; // максимальний елемент , тимчасова змінна int i,j,k,l; for(k=0; k<n; k++) // шукаємо головний елемент, мах за модулем {aMax=A[k][k]; l=k; for (i=k+1; i<n; i++) if (fabs(A[i][k])>fabs(aMax)) {aMax=A[i][k]; l=i;} // якщо модуль головного елементу aMax менший за програмний 0 (ZERO) if ( fabs(aMax)<ZERO ) return 1; // якщо потрібно, міняємо місцями рівняння Pk i Pl if ( l!=k) {for( j=0; j<n; j++) { t=A[l][j]; A[l][j]=A[k][j]; A[k][j]=t; } t=B[l]; B[l]=B[k]; B[k]=t;} // ділимо k-те рівняння на головний елемент for (j=0; j<n; j++) A[k][j]/=aMax; B[k]/=aMax; // обчислюємо коефіцієнти A[i][j] та вільні члени решти рівнянь for (i=k+1; i<n; i++) {t=A[i][k]; B[i]-=t*B[k]; for (j=0; j<n; j++) A[i][j]-=t*A[k][j];} } // for (k) // Зворотній хід for ( k=n-1; k>=0; k--) {X[k]=0; for (l=k+1; l<n; l++) X[k]+=A[k][l]*X[l]; X[k]=B[k]-X[k];} return 0; } // fGaus() void main() {float A[nMax][nMax]; float B[nMax]; float X[nMax]; int n,i,j; char *strError="\n Error of file !"; FILE *FileIn,*FileOut; FileIn=fopen("data_in.txt","r"); // відкриваємо файл для читання if (FileIn==NULL) {cout << " \"Data_in.txt\": Error open file or file not found !!!\n"; goto exit;} FileOut=fopen("data_out.txt","w"); // відкриваємо файл для запису if (FileOut==NULL) {cout << " \"Data_out.txt\": Error open file !!!\n"; goto exit;} if(fscanf(FileIn,"%d",&n)==NULL) { cout << strError; goto exit;}; for (i=0; i<n; i++) for(j=0; j<n; j++) fscanf(FileIn,"%f",&(A[i][j])); for (i=0; i<n;i++) if(fscanf(FileIn,"%f",&(B[i]))==NULL) { cout << strError; goto exit;} if(fGaus(A,B,n,X)!=0) =0 !"; goto exit; // Вивід результатів for (i=0; i<n; i++) {printf(" x[%d]= %f ",i+1,X[i]); fprintf(FileOut," x[%d]= %f ",i+1,X[i]);} fclose(FileIn); fclose(FileOut); exit: cout << "\n Press any key ..."; getch();} Результат роботи програми: x[1]= 3.017808 x[2]= 0.356946 x[3]= -0.302131 б) Знайдемо обернену матрицю . 0-й крок. А Е 1-й крок. ; 2-й крок. ; 3-й крок. ; ; . Даний алгоритм рішення системи лінійних рівнянь реалізований в програмі Work1_2. //------------------------------------------------------------ // Work1_2.cpp //------------------------------------------------------------ // "Числові методи" // Завдання 1 // Рішення системи лінійних рівнянь методом Гауса-Жордана #include <stdio.h> #include <iostream.h> #include <conio.h> const int nMax=5; // максимальна кількість рівнянь const float ZERO=.0000001; int fGausJordan(int n,float A[nMax][nMax],float Ainv[nMax][nMax]) /* Функція знаходить обернену матрицю Вхідні дані: A- масив з коефіцієнтами при невідомих; n- порядок матриці А(кількість рівнянь системи); Вихідні дані: Ainv- матриця обернена до матриці А; функція повертає код помилки: 0- помилки немає; 1- матриця А вироджена. */ {float aMax,t; // максимальний елемент , тимчасова змінна int i,j,k,l; // формуємо одиничну матрицю for(i=0; i<n; i++) for (j=0; j<n; j++) Ainv[i][j] = (i==j)? 1. : 0.; for (k=0; k<n; k++) {// знаходимо мах по модулю елемент aMax=A[k][k]; l=k; for (i=k+1; i<n; i++) if (fabs(A[i][k])>fabs(aMax)) { aMax=A[i][k]; l=i; } // якщо модуль головного елементу aMax менший за програмний 0 (ZERO) if ( fabs(aMax)<ZERO ) return 1; // якщо потрібно, міняємо місцями рівняння Pk i Pl if ( l!=k) for( j=0; j<n; j++) {t=A[l][j]; A[l][j]=A[k][j]; A[k][j]=t; t=Ainv[l][j]; Ainv[l][j]=Ainv[k][j]; Ainv[k][j]=t;} // ділимо k-й рядок на головний елемент for (j=0; j<n; j++) { A[k][j]/=aMax; Ainv[k][j]/=aMax; } // обчислюємо елементи решти рядків for (i=0; i<n; i++) if( i!=k ) {t=A[i][k]; for (j=0; j<n; j++) {A[i][j]-=t*A[k][j]; Ainv[i][j]-=t*Ainv[k][j];}}} return 0; } // fGausJordana() void fDobMatr(int n, float A[nMax][nMax], float B[nMax],float X[nMax]) // функція знаходить добуток матриці А на вектор В і результат повертає в // векторі Х {int i,j; float summa; for (i=0; i<n; i++) {summa=0; for (j=0; j<n; j++) {summa+=A[i][j]*B[j]; X[i]=summa;}} } // fDobMatr void main() {float A[nMax][nMax],Ainv[nMax][nMax]; float B[nMax]; float X[nMax]; int n,i,j; char *strError="\n Error of file !"; FILE *FileIn,*FileOut; FileIn=fopen("data_in.txt","r"); // відкриваємо файл для читання if (FileIn==NULL) {cout << " \"Data_in.txt\": Error open file or file not found !!!\n"; goto exit;} FileOut=fopen("data_out.txt","w"); // відкриваємо файл для запису if (FileOut==NULL) {cout << " \"Data_out.txt\": Error open file !!!\n"; goto exit;} if(fscanf(FileIn,"%d",&n)==NULL) { cout << strError; goto exit;}; for (i=0; i<n; i++) for(j=0; j<n; j++) fscanf(FileIn,"%f",&(A[i][j])); for (i=0; i<n;i++) if(fscanf(FileIn,"%f",&(B[i]))==NULL) { cout << strError; goto exit;} if(fGausJordan(n,A,Ainv)!=0) =0 !"; goto exit; fDobMatr(n,Ainv,B,X); // Вивід результатів for (i=0; i<n; i++) {printf(" x[%d]= %f ",i+1,X[i]); fprintf(FileOut," x[%d]= %f ",i+1,X[i]);} fclose(FileIn); fclose(FileOut); exit: cout << "\n Press any key ..."; getch();} Результат роботи програми: x[1]= 3.017808 x[2]= 0.356946 x[3]= -0.302131 Завдання 2 Задана задача Коші , а) Знайти розв'язок в табличній формі методом Рунге-Кутта: , , . б) Інтерполювати цю функцію кубічним сплайном. Систему рівнянь для моментів кубічного сплайну розв'язати методом прогонки. Вибрати крайові умови для кубічного сплайну у вигляді . в) Використовуючи кубічний сплайн з пункту б) обчислити методом Сімпсона . Взяти (- кількість відрізків розбиття). Рішення. а) Метод Рунге-Кутта Розрахунок будемо проводити за наступними формулами : ; ; ; ; ; . Цей алгоритм реалізовується в програмі Work2_1. //------------------------------------------------------------ // Work2_1.cpp //------------------------------------------------------------ // "Числові методи" // Завдання 2 // Рішення задачі Коші методом Рунге-Кутта #include <stdio.h> #include <iostream.h> #include <conio.h> typedef float (*pfunc)(float,float); // pfunc - вказівник на функцію const int nMax=5; // максимальна кількість відрізків розбиття void fRunge_Kutta(pfunc f, float x0, float y0,float h, int n, float Y[nMax]) /* Функція знаходить табличне значення функції методом Рунге-Кутта Вхідні дані: f - функція f(x,y) x0,y0 - початкова точка; h - крок; n- кількість точок розбиття; Вихідні дані: Y- вектор значень функції*/ {float k1,k2,k3,k4,x; // максимальний елемент , тимчасова змінна
Страницы: 1, 2, 3
|