Реализации алгоритмов/Метод бисекции: различия между версиями
Содержимое удалено Содержимое добавлено
→На языке C: обновление данных |
→На языке C: обновление данных |
||
Строка 27: | Строка 27: | ||
xl = xm; // берём правую часть; |
xl = xm; // берём правую часть; |
||
} |
} |
||
printf (" |
printf ("Value of function: %.10lf\n", f(xm)); // выводим значение функции вблизи корня |
||
printf ("Left bound equal: %.10lf\n", xl ); // выводим xl |
printf ("Left bound equal: %.10lf\n", xl ); // выводим xl |
||
printf ("Middle of line segment: %.10lf\n", (xl + xr) / 2); // выводим результат вблизи корня |
|||
printf ("Right bound equal: %.10lf\n", xr ); // выводим xr |
printf ("Right bound equal: %.10lf\n", xr ); // выводим xr |
||
printf ("Numbers of iterations equal: %10i\n", n ); // выводим число проходов (делений на 2, итераций) n |
printf ("Numbers of iterations equal: %10i\n", n ); // выводим число проходов (делений на 2, итераций) n |
||
Строка 35: | Строка 36: | ||
В результате прогона программы на устройстве ввода-вывода должен получиться следующий вывод: |
В результате прогона программы на устройстве ввода-вывода должен получиться следующий вывод: |
||
<big><source lang="C"> |
<big><source lang="C"> |
||
Value of function: -0.0000000027 |
|||
Root equal: 1.1461932203 |
|||
Left bound equal: 1.1461932193 |
Left bound equal: 1.1461932193 |
||
Middle of line segment: 1.1461932203 |
|||
Right bound equal: 1.1461932212 |
Right bound equal: 1.1461932212 |
||
Numbers of iterations equal: 30 |
Numbers of iterations equal: 30 |
||
</source></big> |
</source></big> |
Версия от 12:15, 7 мая 2012
Численные методы.
Метод деления отрезка пополам (метод бисекции).
На языке C
#include <stdio.h> // подключаем к компилятору библиотеку stdio.h;
#include <math.h> // подключаем к компилятору библиотеку math.h;
#define EPS 1e-10 // задаём точность результата 1*10^(-10)
double f(double x) { // задаём вызываемой функции и аргументу - тип двойной точности;
return exp(x) - 2 - x; // задаём описание функции f(x);
}
int main ( ) { // главная часть программы;
double xl = 0, xr = 2, xm, xd, signfxl, signfxm; // задаём переменным тип двойной длины и начальные значения;
int n = 0; // задаём переменной тип целая и начальное значение;
xd = xr - xl; // вычисляем длину отрезка;
while ( abs(f(xl))>EPS || abs(f(xr)>EPS ) { // пока абсолютные значения функции больше заданной точности делаем;
n = n + 1; // прибавляем 1 в счётчик числа проходов (делений на 2, итераций);
xd = xd / 2; // вычисляем длину новых отрезков;
xm = xl + xd; // вычисляем значение x в середине отрезка;
signfxl = copysign(1, f(xl)); // придаём единице знак f(xm);
signfxm = copysign(1, f(xm)); // придаём единице знак f(xr);
if ( signfxl != signfxm ) // узнаём, находится ли искомый корень в левой части;
xr = xm; // берём левую часть;
else // иначе искомый корень находится в правой части;
xl = xm; // берём правую часть;
}
printf ("Value of function: %.10lf\n", f(xm)); // выводим значение функции вблизи корня
printf ("Left bound equal: %.10lf\n", xl ); // выводим xl
printf ("Middle of line segment: %.10lf\n", (xl + xr) / 2); // выводим результат вблизи корня
printf ("Right bound equal: %.10lf\n", xr ); // выводим xr
printf ("Numbers of iterations equal: %10i\n", n ); // выводим число проходов (делений на 2, итераций) n
}
В результате прогона программы на устройстве ввода-вывода должен получиться следующий вывод:
Value of function: -0.0000000027
Left bound equal: 1.1461932193
Middle of line segment: 1.1461932203
Right bound equal: 1.1461932212
Numbers of iterations equal: 30
На языке Matlab
Пример реализации алгоритма на языке Matlab:
clear;
%Интервал
x_L=1;
x_R=2;
length=x_R-x_L;
%Начальная ошибка
err=length;
%Итерационный цикл
while err>1e-3
%Деление отрезка пополам
x_M=(x_L+x_R)/2;
%Нахождение нового интервала
if tan(x_L)*tan(x_M)<0
x_R=x_M;
else
if tan(x_M)*tan(x_R)<0
x_L=x_M;
else
x_M
break;
end
end
%Пересчёт ошибки
err=(x_R-x_L)/length;
end
%Вывод результата
x_M
err
Результат выполнения вполне ожидаемый:
x_M =
1.5713
err =
9.7656e-004