Числові методи

МІНІСТЕРСТВО ОСВІТИ УКРАЇНИ

ЧЕРНІВЕЦЬКИЙ ДЕРЖАВНИЙ УНІВЕРСИТЕТ

ІМ. Ю. ФЕДЬКОВИЧА


КОНТРОЛЬНА РОБОТА

з дисципліни " Числові методи "

Варіант 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)

{ cout << "n det|A|=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)

{ cout << "n det|A|=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; // максимальний елемент , тимчасова змінна

int i;

x=x0; Y[0]=y0;

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

{k1=f(x,Y[i]);

k2=f(x+h/2, Y[i]+k1*h/2);

k3=f(x+h/2, Y[i]+k2*h/2);

k4=f(x+h, Y[i]+h*k3);

Y[i+1]=Y[i]+(h/6)*(k1+2*k2+2*k3+k4);

x+=h;}}

float Myfunc(float x,float y)

{return log10(cos(x+y)*cos(x+y)+2)/log10(5);}

void main()

{float Y[nMax],h,x0,y0;

int n,i;

char *strError="n Error of file !";

FILE *FileIn,*FileOut, *FileOut2;

FileIn=fopen("data2_in.txt","r"); // відкриваємо файл для читання

if (FileIn==NULL)

{cout << " "Data2_in.txt": Error open file or file not found !!!n";

goto exit;}

FileOut=fopen("data2_out.txt","w"); // відкриваємо файл для запису

if (FileOut==NULL)

{cout << " "Data2_out.txt": Error open file !!!n";

goto exit;}

FileOut2=fopen("data2_2in.txt","w"); // відкриваємо файл для запису

if (FileOut==NULL)

{cout << " "Data2_2in.txt": Error open file !!!n";

goto exit;}

if(fscanf(FileIn,"%d%f%f%f,",&n,&h,&x0,&y0)==NULL)

{ cout << strError; goto exit;};

fRunge_Kutta(Myfunc,x0,y0,h,n,Y);

// Вивід результатів

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

{printf(" x[%d]= %4.2f ",i,Y[i]);

fprintf(FileOut," x[%d]= %4.2f ",i,Y[i]);

fprintf(FileOut2,"%4.2f ",Y[i]);}

fclose(FileIn);

fclose(FileOut);

exit: cout << "n Press any key ...";

getch();}

Результат роботи програми (файл "data2_out.txt"):


x[0]= 1.00 x[1]= 1.05 x[2]= 1.10 x[3]= 1.14 x[4]= 1.18


б) В загальному вигляді кубічний сплайн виглядає наступним чином:


Числові методи,Числові методиЧислові методи


Параметри кубічного сплайну будемо обчислювати , використовуючи формули:


Числові методи; Числові методи;

Числові методи; Числові методи, де

Числові методи– моменти кубічного сплайну.


Моменти мають задовольняти такій системі рівнянь:


Числові методи Числові методи.

Для Числові методи Числові методи; Числові методи; Числові методи.


Якщо прийняти до уваги граничні умови Числові методи, то систему можна записати так Числові методи


Числові методи Числові методи .


В даному випадку матриця з коефіцієнтів при невідомих є тридіагональною


Числові методи ,


тому для знаходження моментів кубічних сплайнів застосуємо метод прогонки.

На прямому ході обчислюємо такі коефіцієнти.


Числові методи ; Числові методи;


На зворотньому ході обчислюємо значення моментів кубічного сплайну.


Числові методи; Числові методи.


Для знаходження коефіцієнті вкубічного сплайну призначена програма Work2_2.

//------------------------------------------------------------

// Work2_2.cpp

//------------------------------------------------------------

// "Числові методи"

// Завдання 2

// Інтерполювання функції кубічним сплайном

#include <stdio.h>

#include <iostream.h>

#include <conio.h>

const int nMax=4; // максимальна кількість відрізків розбиття

const float x0=0.;// початкова точка сітки

const float h=0.1;// крок розбиття

// вектори матриці А

float a[]={0., 0.5, 0.5};

float b[]={2., 2., 2.};

float c[]={0.5, 0.5, 0.};

//void fMetodProgonku( int n,float a[nMax],float b[nMax],float c[nMax],float d[nMax], float M[nMax+1])

/* Функція знаходить моменти кубічного сплайну методом прогонки

Вхідні дані:

a,b,c -вектори матриці А ;

d - вектор вільних членів;

n- степінь матриці А;

Вихідні дані:

М- вектор моментів кубічного сплайну.*/

{float k[nMax],fi[nMax];

int i;

// прямий хід

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

{k[i] = (i==0)? -c[i]/b[i] : -c[i]/(b[i]+a[i]*k[i-1]);

fi[i] = (i==0)? d[i]/b[i] : (-a[i]*fi[i-1]+d[i])/(b[i]+a[i]*k[i-1]);}

//зворотній хід

for (i=n; i>0; i--)

M[i] = (i==n)? fi[i-1] : k[i-1]*M[i+1]+fi[i-1];}

void fSplain( int n,float h,float Y[nMax+1],float M[nMax+1],float Ak[nMax][4])

/* Функція обчислює коефіцієнти кубічного сплайну

Вхідні дані:

n- кількість відрізків розбиття;

H - крок розбиття відрізку [X0; Xn]]

М- вектор моментів кубічного сплайну.

Y- вектор значень функції f(x,y) в точках x[0],x[1],...x[n].

Вихідні дані:

Ak- матриця коефіцієнтів кубічного сплайну.*/

{int i;

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

{Ak[i][0] = Y[i];

Ak[i][1] = (Y[i+1]-Y[i])/h-h/6*(2.*M[i]+M[i+1]);

Ak[i][2] = M[i]/2;

Ak[i][3] = (M[i+1]-M[i])/6*h;}}

void main()

{float Y[nMax+1],d[nMax],M[nMax+1],Ak[nMax][4];

int n,i,j;

n=nMax;

M[0]=0; M[n]=0; //крайові умови

char *strError="n Error of file !";

FILE *FileIn,*FileOut,*FileOut2;

FileIn=fopen("data2_2in.txt","r"); // відкриваємо файл для читання

if (FileIn==NULL)

{ cout << " "Data2_2in.txt": Error open file or file not found !!!n";

goto exit; }

FileOut=fopen("data2_2ou.txt","w"); // відкриваємо файл для запису

if (FileOut==NULL)

{ cout << " "Data2_2ou.txt": Error open file !!!n";

goto exit; }

FileOut2=fopen("data2_3in.txt","w"); // відкриваємо файл для запису

if (FileOut2==NULL)

{ cout << " "Data2_3in.txt": Error open file !!!n";

goto exit; }

// читаємо вектор Y

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

if(fscanf(FileIn,"%f,",&(Y[i]))==NULL)

{ cout << strError; goto exit;};

// обчислюємо вектор d

for (i=1; i<n; i++) d[i-1]=3/(h*h)*(Y[i+1]-2*Y[i]+Y[i-1]);

//fMetodProgonku(n-1,a,b,c,d,M);

fSplain( n,h,Y,M,Ak);

// Вивід результатів в тому числі і для наступного завдання

fprintf(FileOut2,"%dn",n); // n - кількість відрізків

// координати точок сітки по Х

for(float xi=x0,i=0; i<n; i++) fprintf(FileOut2,"%2.2f ",xi+h*i);

fprintf(FileOut2,"n");

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

{for (j=0; j<4; j++)

{printf("a[%d,%d]= %4.4f ",i,j,Ak[i][j]);

fprintf(FileOut,"a[%d,%d]= %4.4f ",i,j,Ak[i][j]);

fprintf(FileOut2,"%4.4f ",Ak[i][j]);}

cout << endl;

fprintf(FileOut,"n");

fprintf(FileOut2,"n");}

fclose(FileIn);

fclose(FileOut);

exit: cout << "n Press any key ...";

getch();}

Результат роботи програми (" data2_2uo.txt"):

a[0,0]= 1.0000 a[0,1]= 0.5104 a[0,2]= 0.0000 a[0,3]= -0.0104

a[1,0]= 1.0500 a[1,1]= 0.4793 a[1,2]= -0.3107 a[1,3]= 0.0118

a[2,0]= 1.0960 a[2,1]= 0.4525 a[2,2]= 0.0429 a[2,3]= -0.0068

a[3,0]= 1.1410 a[3,1]= 0.4407 a[3,2]= -0.1607 a[3,3]= 0.0054

в) Розіб’ємо відрізок Числові методи на Числові
    <div class=

Если Вам нужна помощь с академической работой (курсовая, контрольная, диплом, реферат и т.д.), обратитесь к нашим специалистам. Более 90000 специалистов готовы Вам помочь.
Бесплатные корректировки и доработки. Бесплатная оценка стоимости работы.
Подробнее

Поможем написать работу на аналогичную тему

Получить выполненную работу или консультацию специалиста по вашему учебному проекту
Нужна помощь в написании работы?
Мы - биржа профессиональных авторов (преподавателей и доцентов вузов). Пишем статьи РИНЦ, ВАК, Scopus. Помогаем в публикации. Правки вносим бесплатно.

Похожие рефераты: