Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекции по С++.doc
Скачиваний:
34
Добавлен:
15.12.2018
Размер:
2.31 Mб
Скачать

1.3. Метод касательных (Ньютона)

Метод основывается на утверждении, что если на отрезке [a;b] содержится корень уравнения, то значения f(a) и f(b) имеют разные знаки, т.е. f(a)·f(b)<0. Точность вычислений зависит от выбора точки, с которой начинаются вычисления. Выбор начальной точки x0 вычислений определяет условие . Схема метода аналогична предыдущим. Разница заключается в поиске значения точки c. Для этого в методе касательных используется уравнение касательной к графику функции: . Пусть первая координата т.С(сi;0) – корень уравнения f(x)=0. Подставим координаты точки C в полученное уравнение. В итоге получаем уравнение для получения значений точек сi при вычислении корня исходного уравнения:

.

Если |ci-ci-1|>=eps, то вычисления продолжаются. Если |ci-ci-1|<eps, то вычисления можно прекратить, а за значение корня взять одно из этих значений, т.е. корень уравнения вычислен с заданной точность eps. Если нет, то вычисляется новое значение сi и т.д. Графически этот метод изображен на рис.16.

Опишем алгоритм и соответствующую программу для нахождения корней уравнения ln(x-3)=0 на отрезке [3.5;5] с помощью этого метода:

Алгоритм

Программа

объявление вещ: f_2p, fa, fb, a, b, c, c1, eps

ввод а

ввод b

fa=ln(a-3)

fb=ln(b-3)

если fa*fb<0

ввод eps

f_2p=-1/(a-3)2

если fa*f_2p>0

c1=a

иначе

c1=b

все_если

c=c1-ln(c1-3)/(1/(c1-3))

пока (|c-c1|>=eps )

c1=c

c=c1-ln(c1-3)/(1/(c1-3))

всё_цикл

печать c

печать ln(c-3)

иначе

печать “на отрезке нет корня”

все_если

#include "stdio.h"

#include "math.h"

#include "iostream.h"

#include "iomanip.h"

int main()

{

float f_2p, fa, fb, a, b, c, c1, eps;

cout<<"a="; cin>>a;

cout<<"b="; cin>>b;

fa=log(a-3); fb=log(b-3);

if(fa*fb<0)

{ cout<<"eps="; cin>>eps;

f_2p=-1/pow(a-3,2);

if(fa*f_2p>0)

c1=a;

else

c1=b;

c=c1-log(c1-3)/(1/(c1-3));

while(fabs(c-c1)>=eps)

{ c1=c;

c= c1-log(c1-3)/(1/(c1-3));

}

cout<<"корень уравнения х*=";

cout<<c<<endl;

cout<<"значение f(x*)="<<log(c-3)<<endl;

}

else

cout<<"неверно введены концы"

<<"отрезка"<<endl;

return 1;}

Лекция 21

Нахождение приближенного значения определенного интеграла

Цели:

  • познакомиться с алгоритмами нахождения приближенного значения определенного интеграла (с заданной точностью);

  • методику написания и перевода таких алгоритмов на язык программирования С++ и разработки соответствующего проекта в среде Visual C++ 6.0.

1. Нахождение приближенного значения определенного интеграла

с заданной точностью

Существует несколько методов приближенного вычисления определенных интегралов . Численно определенный интеграл равен площади фигуры, ограниченной кривой y=f(x), осью Ox и прямыми x=a и x=b. Такую фигуру называют криволинейной трапецией (рис.17). Рассмотрим методы левых, правых и центральных прямоугольников, а также метод трапеций и метод Симпсона. Суть их в том, что отрезок [a;b] разбивается на n равных частей и находится длина каждого частичного отрезка по формуле . Следовательно, криво-линейная трапеция разбивается на множество элементарных трапеций, и её площадь считается как сумма площадей элементарных трапеций. Площадь же элементарной трапеции приблизительно равна площади элементарного прямоугольника или трапеции и вычисляется по соответствующей формуле.

Для формул прямоугольников площадь каждой элементарной трапеции заменяется площадью прямоугольника и вычисляется как произведение значения функции, аргументом которой будет левая или правая граница каждого частичного отрезка (для формул левых и правых прямоугольников соответственно) или центр каждого частичного отрезка (для формулы центральных прямоугольников) на шаг разбиения h.

В методе трапеций площадь каждой элементарной криволинейной трапеции находится по формуле площади обычной трапеции, известной из школьного курса математики.

В методе Симпсона берутся три ближайшие точки разбиения и по ним строится парабола, график которой приближенно описывает график функции на двух близлежащих частичных отрезках. Ищутся приближенно площади криволинейных трапеций на всех участках и складываются. Это и будет приближенное вычисление определенного интеграла по методу Симпсона. Для нахождения приближенного значения интеграла по методу Симпсона необходимо, чтобы количество частичных отрезков было четным.

В программировании для вычисления интеграла используется цикл, который продолжает свою работу до тех пор, пока ближайшие значения интегралов различаются не более чем на заданную точность eps.

Математические формулы для всех описанных методов приведены в табл.13.

Таблица 13

Название метода

Формула

Метод левых прямоугольников

Метод центральных прямоугольников

Метод правых прямоугольников

Метод трапеций

Метод Симпсона

Общая схема вычисления интегралов с точностью eps:

ввод a

ввод b

ввод количества разбиений n

вычислить шаг h

ввод eps

вычисление интеграла i0

I1=0

пока |I0-I1|>=eps

I1=I0

увеличение количества разбиений n

вычислить новый шаг h

вычисление интеграла I0

все_пока

печать I0

Далее приведены примеры алгоритмов и соответствующих программ для вычисления приближенного значения определенного интеграла.

Вычислить интеграл с точностью eps методом левых прямоугольников:

Алгоритм

Программа

объявление вещ: a,b,h,eps,I0,I1,x; цел: i, n;

ввод a,b,n,eps

h=(b-a)/n

x=a

I0=ln(a-3)

для i=1 до n-1 шаг 1

x=x+h

I0=I0+ln(x-3)

все_для i

I0=I0*h

I1=0

пока |I1-I0|>=eps

I1=I0

n=2*n

h=(b-a)/n

x=a

I0=ln(a-3)

для i=1 до n-1 шаг 1

x=x+h

I0=I0+ln(x-3)

все_для i

I0=I0*h

все_цикл

печать I0

#include “stdio.h”

#include “math.h”

int main ( )

{

int i,n;

float a,b,h,x,I0,I1,eps;

printf(“a=”);

scanf(“%f”,&a);

printf(“b=”);

scanf(“%f”,&b);

printf(“n=”);

scanf(“%i”,&n);

h=(b-a)/n;

printf(“eps=”);

scanf(“%f”,&eps);

x=a;

I0=log(a-3);

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

{

x=x+h;

I0=I0+log(x-3);

}

I0=I0*h;

I1=0;

while (fabs(I0-I1)>=eps)

{

I1=I0;

n=2*n;

h=(b-a)/n;

x=a;

I0=log(a-3);

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

{

x=x+h;

I0=I0+log(x-3);

}

I0=I0*h;

}

printf(“integral=%f \n”,I0);

return 1;

}

Вычислить интеграл с точностью eps методом центральных прямоугольников:

Алгоритм

Программа

объявление вещ: a,b,h,eps,I0,I1,x; цел: i, n;

ввод a,b,n,eps;

h=(b-a)/n;

x=a+h/2;

I0=ln(a-3);

для i=1 до n-1 шаг 1

x=x+h;

I0=I0+ln(x-3);

все_для i

I0=I0*h

I1=0

пока |I1-I0|>=eps

I1=I0

n=2*n

h=(b-a)/n

x=a+h/2

I0=ln(a-3)

для i=1 до n-1 шаг 1

x=x+h

I0=I0+ln(x-3)

все_для i

I0=I0*h

все_цикл

печать I0

#include “stdio.h”

#include “math.h”

int main ( )

{

int i,n;

float a,b,h,x,I0,I1,eps;

printf(“a=”);

scanf(“%f”,&a);

printf(“b=”);

scanf(“%f”,&b);

printf(“n=”);

scanf(“%i”,&n);

h=(b-a)/n;

printf(“eps=”);

scanf(“%f”,&eps);

x=a+h/2;

I0=log(a-3);

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

{

x=x+h;

I0=I0+log(x-3);

}

I0=I0*h;

I1=0;

while (fabs(I0-I1)>=eps)

{

I1=I0;

n=2*n;

h=(b-a)/n;

x=a+h/2;

I0=log(a-3);

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

{

x=x+h;

I0=I0+log(x-3);

}

I0=I0*h;

}

printf(“integral=%f \n”,I0);

return 1;

}

Вычислить интеграл с точностью eps методом правых прямоугольников:

Алгоритм

Программа

объявление вещ: a,b,h,eps,I0,I1,x; цел: i, n;

ввод a,b,n,eps

h=(b-a)/n

x=a+h

I0=ln(a-3)

для i=2 до n шаг 1

x=x+h

I0=I0+ln(x-3);

все_для i

I0=I0*h

I1=0

пока |I1-I0|>=eps

I1=I0

n=2*n

h=(b-a)/n

x=a+h

I0=ln(a-3)

для i=2 до n шаг 1

x=x+h

I0=I0+ln(x-3)

все_для i

I0=I0*h;

все_цикл

печать I0

#include “stdio.h”

#include “math.h”

int main ( )

{

int i,n;

float a,b,h,x,I0,I1,eps;

printf(“a=”);

scanf(“%f”,&a);

printf(“b=”);

scanf(“%f”,&b);

printf(“n=”);

scanf(“%i”,&n);

h=(b-a)/n;

printf(“eps=”);

scanf(“%f”,&eps);

x=a+h;

I0=log(a-3);

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

{

x=x+h;

I0=I0+log(x-3);

}

I0=I0*h;

I1=0;

while (fabs(I0-I1)>=eps)

{

I1=I0;

n=2*n;

h=(b-a)/n;

x=a+h;

I0=log(a-3);

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

{

x=x+h;

I0=I0+log(x-3);

}

I0=I0*h;

}

printf(“integral=%f \n”,I0);

return 1;

}

Вычислить интеграл с точностью eps методом трапеций

Алгоритм

Программа

объявление вещ: a,b,h,eps,I0,I1,x; цел: i, n;

ввод a,b,n,eps

h=(b-a)/n

x=a

I0=0

для i=1 до n-1 шаг 1

x=x+h

I0=I0+ln(x-3)

все_для i

I0= h*((log(a-3)+log(b-3))/2+I0)

I1=0

пока |I1-I0|>=eps

I1=I0

n=2*n

h=(b-a)/n

x=a

I0=0

для i=1 до n шаг 1

x=x+h

I0=I0+ln(x-3)

все_для i

I0= h*( (log(a-3)+log(b-3))/2+I0)

все_цикл

печать I0

#include "stdio.h"

#include "math.h"

int main()

{

int i,n;

float x,a,b,h,eps,I0,I1;

printf("a = ");

scanf("%f",&a);

printf("b = ");

scanf("%f",&b);

printf("n = ");

scanf("%i",&n);

h=(b-a)/n;

printf(“eps=”);

scanf(“%f”,&eps);

x=a;

I0=0;

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

{

I0=I0+log(x-3);

x=x+h;

}

I0=h*((log(a-3)+log(b-3))/2+I0);

I1=0;

while(fabs(I0-I1)>eps)

{

I1=I0;

n=n*2;

h=(b-a)/n;

x=a;

I0=0;

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

{

I0=I0+log(x-3);

x=x+h;

}

I0=h*((log(a-3)+log(b-3))/2+I0);

}

printf("I=%f\n",I0);

return 1;

}

Вычислить интеграл с точностью eps методом Симпсона:

Алгоритм

Программа

объявление вещ: a,b,h,eps,I0,I1,x,f2i_1,f2i; цел: i, n

ввод a,b,n,eps;

//если n – нечетное, то умножаем на 2

если n%2= =1

n=n*2

h=(b-a)/n

f2i_1=0; //для «нечетных» точек

f2i=0; //для «четных» точек

x=a+h;

для i=1 до (n-1)/2 шаг 1

f2i_1=f2i_1+log(x-3);

x=x+h;

f2i=f2i+log(x-3);

x=x+h;

все_для i

f2i_1=f2i_1+log(x-3);

I0=h*(log(a-3)+log(b-3)+4*f2i_1

+2*f2i)/3;

I1=0

пока |I1-I0|>=eps

I1=I0

n=2*n

h=(b-a)/n

x=a

I0=0

для i=1 до (n-1)/2 шаг 1

f2i_1=f2i_1+log(x-3);

x=x+h;

f2i=f2i+log(x-3);

x=x+h;

все_для i

f2i_1=f2i_1+log(x-3);

I0=h*(log(a-3)+log(b-3)+4*f2i_1+

2*f2i)/3;

все_цикл

печать I0

#include "stdio.h"

#include "math.h"

int main()

{

int i,n;

float x,a,b,h, I0,I1,f2i_1,f2i,eps;

printf("a = "); scanf("%f",&a);

printf("b = "); scanf("%f",&b);

printf("n = "); scanf("%i",&n);

//если n – нечетное, то умножаем на 2

if(n%2==1)

n=n*2;

printf(“eps=”); scanf(“%f”,&eps);

f2i_1=0; //для «нечетных» точек

f2i=0; //для «четных» точек

h=(b-a)/n; x=a+h;

for(i=1;i<=(n-1)/2;i++)

{

f2i_1=f2i_1+log(x-3); x=x+h;

f2i=f2i+log(x-3); x=x+h;

}

f2i_1=f2i_1+log(x-3);

I0=h*(log(a-3)+log(b-3)+4*f2i_1+2*f2i)/3;

I1=0;

while(fabs(I0-I1)>=eps)

{ I1=I0;

n=n*2;

f2i_1=0; //для «нечетных» точек

f2i=0; //для «четных» точек

h=(b-a)/n; x=a+h;

for(i=1;i<=(n-1)/2;i++)

{

f2i_1=f2i_1+log(x-3); x=x+h;

f2i=f2i+log(x-3); x=x+h;

}

f2i_1=f2i_1+log(x-3);

I0=h*(log(a-3)+log(b-3)+4*f2i_1+2*f2i)/3;

}

printf("I=%f\n",I0);

return 1;

}

Примечание. Если сравнить результаты вычислений интегралов с точным значением определенного интеграла, то можно сделать вывод о том, что наиболее точным методом является метод Симпсона.