Курсовик / VMKUR_6.DOC
Cанкт-Петербургский Государственный Электротехнический Университет.
КАФЕДРА МОЭВМ
Отчет по курсовой работе
Преподаватель : Титов М.С.
Студент : Виноградо К.Ю.
Санкт-Петербург
д/ММ/гг
Задание на курсовую работу :
Используя программы - функции BISECT , NEWTON , HORDA , ITER, Round из файла metods.cpp найти корень уравнения f(x)=0 с заданной точностью методом бисекции , Ньютона , хорд и итераций соответственно .
Исследуйте обусловленность методов и зависимость числа итераций от точности результата Eps при изменении Eps от 0.1 до 0.000001 .
Порядок выполнения работы :
- Графически или аналитически отделить корень уравнения (т.е. найти отрезки [Left, Right], на которых функция удовлетворяет условиям применимости методов).
- Составить подпрограмму- функцию вычисления функции и ее производной (при необходимости), предусмотрев округление их значений с заданной точностью Delta с использованием библиотечной функции Round.
- Составить головную программу, содержащую ввод исходных данных, обращение к подпрограммам BISECT, NEWTON, HORDA, ITER вывод результатов.
- Выполнить вычисления по программе. Построить графики зависимости числа итераций, необходимых для достижения заданной точности Eps, от величины Eps, а также достижимой точности результатов от точности Delta задания функции .
- Теоретически и экспериментально сравнить методы бисекции, Ньютона, хорд и итераций по скорости сходимости и степени обусловленности.
- Результаты оформить в виде отчета, содержащего постановку задачи, тексты разработанных программ, результаты теоретического и экспериментального анализа в виде таблиц и графиков, выводы.
F(x)=tg(x)-1/x
Oai?aoeaneia aaaaaiea :
A aaiiie ?aaioa enneaao?ony aou?a iaoiaa iaoi?aaiey ei?iy iaeeiaeiiai o?aaiaiey.
- Iaoia Aenaeoee iniiaai ia iieiaeiiii aaeaiee io?acea, ia eiioao eioi?iai ooieoey i?eieiaao ciaaiey ?aciuo ciaeia. Yoi naiue iaaeaiiue iaoia ec aaiiuo, iaiaei ii naiue oiiue.
- Iaoia Iu?oiia aaiiao?eanee yeaeaaeaioai caiaia iaaieuoie aoae e?eaie y=f(x) eanaoaeuiie, i?iaaaaiiie a iaeioi?ie oiea e?eaie. Yoi iaei ec naiuo auno?uo iaoiaia o.e. iaeaaaao eaaa?aoeiie nei?inou? noiaeiinoe. Ii oiiinoe onooiaao iaoiao Aenaeoee.
- Iaoia Oi?a iniiaai ia i?iii?oeiiaeuiii aaeaiee io?acea.Yoi iioe naiue auno?ue iaoia, iaiaei ii oiiinoe ii onooiaao iaoiao Aenaeoee.
- Iaoia I?inouo Eoa?aoee iniiaai ia caiaia aaiiie ooieoee a?oaie ooieoeae. Yoi iaei ec auno?uo iaoiaia, i?eai ai iaiuoa ia?aiao? q, oai auno?aa iieoaaony ?acoeuoao.
Niaa??aiea ?aaiou :
- Eieaeecoai ei?ie o?aaiaiey. A aaiiii o?aaiaiee ei?aiae iiiai. Auaa?aai io?acie, ia eioi?ii ooieoey, ia?aay e aoi?ay i?iecaiaiua iiiioiiiu ( ni. a?aoeee ) , yoi iaiaoiaeiua oneiaey iaoiaia iaoi?aaiey ei?iy. A aaiiii neoaa auaa?ai io?acie [0.5;1.2] i?e ei?ia o?aaiaiey 0.8.
- Aey iaoiaa i?inouo eoa?aoee aaiaei iiao? ooieoe? (x)=x-*f(x) I?iaa?yai auiieieiinou oneiaey iiiioiiiinoe (x) = (ci. a?aoee) . Ii a?aoeeo aeaii, oi f(x)>0 ia enneaaoaiii io?acea. f(x): 0<m=f1(0.5)f(x)f2(1.2)=M; m=5.29844, M=8.310040, q0.362432, =0.120331. Auae?aai iaaeuiia i?eaee?aiea ?aaiia eaaie a?aieoa (0.5).
- Aey iaoiaa Iu?oiia auae?aai iaaeuiia i?eaee?aiea, ioaaa?uaa oneiae? f(x0)*f( x0)>0, ii a?aoeeai aeaii, oi i?aaay a?aieoa oaiaeaoai?yao yoiio oneiae?, iiyoiio a eaanoaa iaaeuiiai i?eaee?aiey aa?ai eaao? a?aieoo, ?aaio? 0.5 .
- Enneaaoai aaiiua iaoiau ii nei?inoe noiaeiinoe , eciaiyy Eps io 0.1 ai 0.000001 i?e Delta =0. Aaiiua e ?acoeuoaou i?eaaaaiu a oaaeeoa e ioia?a?aiu ia a?aoeeao.
- Enneaaoai aaiiua iaoiau ii noaiaie iaoneiaeaiiinoe , eciaiyy Delta io 0.1 ai 0.000001 i?e ciaaieyo Eps=0.000001 e Eps=0.01. Aaiiua e ?acoeuoaou i?eaaaaiu a oaaeeoa e ioia?a?aiu ia a?aoeeao.
- Aueneyai iaoneiaeaiiinoe f(x) == 0,276040 e (x)==2,29400
Oекст программы :
#include <conio.h>
#include <iostreams.h>
#include methods.h
double delta[18]={0,0,0,0,0,0,0,
0.1,0.01,0.001,0.0001,0.00001,0.000001,
0.1,0.01,0.001,0.0001,0.00001,0.000001};
double a=0.120331
int c2;
//----------------------------------
void main()
{
int i,c1;
double left=0.5,
right=1.2,
x;
double eps[18]={0.1,0.01,0.001,0.0001,0.00001,0.000001,
0.000001,0.000001,0.000001,0.000001,0.000001,0.000001,
0.01,0.01,0.01,0.01,0.01,0.01};
cout<<endl;
for (c1=1;c1<5;c1++)
{
for (c2=0;c2<18;c2++)
{
switch (c1)
{
case 1:
cout<<Метод бисекции.........;
x=BISECT(left,right,eps[c2],i);
cout<<endl<<Delta=<<delta[c2]<< Eps=<<eps[c2]<<endl;
cout<<X=<<x<< число интерации=<<i<<endl;
break;
case 2:
cout<<Метод Ньютона..........;
x=NEWTON(3.6,eps[c2],i);
cout<<endl<<Delta=<<delta[c2]<< Eps=<<eps[c2]<<endl;
cout<<X=<<x<< число интерации=<<i<<endl;
break;
case 3:
cout<<Метод Хорд.............;
x=HORDA(left,right,eps[c2],i);
cout<<endl<<Delta=<<delta[c2]<< Eps=<<eps[c2]<<endl;
cout<<X=<<x<< число интерации=<<i<<endl;
break;
case 4:
cout<<Метод простых итераций.;
x=ITER(3.6,eps[c2],i);
cout<<endl<<Delta=<<delta[c2]<< Eps=<<eps[c2]<<endl;
cout<<X=<<x<< число интерации=<<i<<endl;
break;
}
getch();
}
cout<<endl;
}
getch();
}//main
double F(double x)
{
double f;
f=tan(x)-1/x;
f=Round(f,delta[c2]);
return f;
}
double F1 (double x)
{
double f;
f=tan(x)*tan(x)+1/(x*x)+1;
f=Round(f,delta[c2]);
return f;
}
double func (double x)
{
double f;
f=x-a*(tan(x)+1/x);
f=Round(f,delta[c2]);
return f;
}
Текст модулей :
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
extern double F (double);
//extern double c,d;
extern double func (double);
double BISECT(double Left,double Right,double Eps,int &N)
{
double E = fabs(Eps)*2.0;
double FLeft = F(Left);
double FRight = F(Right);
double X = (Left+Right)/2.0;
double Y;
if (FLeft*FRight>0.0) {puts(Неверное задание интервала );exit(1);}
if (Eps<=0.0) {puts(Неверное задание точности );exit(1);}
N=0;
if (FLeft==0.0) return Left;
if (FRight==0.0) return Right;
while ((Right-Left)>=E)
{
X = 0.5*(Right + Left); /* вычисление середины отрезка */
Y = F(X);
if (Y == 0.0) return (X);
if (Y*FLeft < 0.0)
Right=X;
else
{ Left=X; FLeft=Y; }
N++;
};
return(X);
}
double Round (double X,double Delta)
{
if (Delta<=1E-9) {puts(Неверное задание точности округления );exit(1);}
if (X>0.0) return (Delta*(long((X/Delta)+0.5)));
else return (Delta*(long((X/Delta)-0.5)));
}
double ITER(double X0,double Eps,int &N)
{
if (Eps<=0.0) {puts(Неверное задание точности );exit (1);}
double X1=func(X0);
double X2=func(X1);
N = 2;
while( (X1 - X2)*(X1 - X2) > fabs((2*X1-X0-X2)*Eps) )
{
X0 = X1;
X1 = X2;
X2 = func(X1);
N++;
}
return(X2);
}
double NEWTON (double X,double Eps,int &N)
{
extern double F1 (double);
double Y,Y1,DX;
N=0;
do
{
Y = F(X);
if (Y==0.0) return (X);
Y1 = F1(X);
if (Y1==0.0) {puts(Производная обратилась в ноль );exit(1);}
DX=Y/Y1; X=X-DX; N++;
}
while (fabs(DX)>Eps);
return (X);
}
double HORDA(double Left,double Right,double Eps,int &N)
{
double FLeft = F(Left);
double FRight = F(Right);
double X,Y;
if (FLeft*FRight>0.0) {puts(Неверное задание интервала );exit(1);}
if (Eps<=0.0) {puts(Неверное задание точности );exit(1);}
N=0;
if (FLeft==0.0) return Left;
if (FRight==0.0) return Right;
do
{
X = Left-(Right-Left)*FLeft/(FRight-FLeft);
Y = F(X);
if (Y == 0.0) return (X);
if (Y*FLeft < 0.0)
{ Right=X; FRight=Y; }
else
{ Left=X; FLeft=Y; }
N++;
}
while ( fabs(Y) >= Eps );
return(X);
}
Выводы :
В ходе выполнения курсовой работы была исследована работа четырех методов вычисления и уточнения корней нелинейного уравнения . Для этого был выбран отрезок ,на котором сама функция, ее первая и вторая производные монотонны, что является необходимым условием при вычислении корня функции методом хорд и Ньютона.
Так-же в работе необходимо было оценить обусловленность методов , для этого был выбран большой ряд пар чисел Eps и Delta , для обьективной оценки методов .
Скорость сходимости и точность результатов :
Если проанализировать графики iter(Eps) для всех четырех методов то можно сразу заметить что лучшим по скорости сходимости являются методы Ньютона, Хорд и Простых Итераций.
Это подтверждается теорией :
-метод Хорд обладает линейной сходимостью;
-метод Ньютона обладает квадратичной скоростью сходимости:
-метод Простых Итераций сходится тем быстрее, чем меньше окажется q, в данном случае q0,362432, что подтверждает быструю сходимость метода ( всего 18 итерации при высокой точности для данного уравнения ).
Самым медленным оказался метод Бисекции , это подтверждается теорией, что метод сходится по геометрической прогрессии со знаменателем q=0.5. Однако этот метод является самым точным для заданного Eps.
По графикам видно, что при изменении Delta от 0.1 до 0.000001 при постоянных значениях Eps=0.01 и Eps=0.000001 точные результаты получаются при Delta < 0.001.
Обусловленность задачи :
Данная задача являеться не очень хорошо обусловленной т.к коэффициент обусловленности в данной задаче равен 0,276040. В данной задаче метод Итераций являеться хорошо обусловленным так как в нем используеться другая функция ( x=f(x) ) имеющая коэффициент обусловенности примерно равный 2,29400.
