Лабы / ЧМ.Лабы.Лисовец / ЧМ.labs.by mice / lab02 / Отчёт по лабораторной работе
.docОтчёт по лабораторной работе №2
Решение уравнений вида . Методы дихотомии, Ньютона, простых итераций.
Решение данных уравнений подразумевает два этапа:
-
Локализация корней – выделение отрезков, на которых находится не более одного корня.
-
Поиск корня с заданной точностью.
Первый пункт решается следующим способом:
lx = left_bound;
rx = lx + rs_step;
while (rigth_bound >= rx)
ly = slv_func(lx);
ry = slv_func(rx);
if (0 > ry * ly)
disp(sprintf('root found in [%f, %f]', lx, rx));
nx = (rx + lx) / 2; % x0
[...]
end
lx = lx + rs_step;
rx = rx + rs_step;
end
Можно добавить проверку минимумов и максимумов функции.
Второй пункт выполняем тремя различными способами: дихотомия, метод Ньютона, метод простых итераций.
Дихотомия:
disp(sprintf('root found in [%f, %f]', lx, rx));
tlx = lx;
trx = rx;
mx = (trx + tlx) / 2;
sc = 1; % steps count
while (dich_precision <= trx - tlx)
my = slv_func(mx);
if (0 > my * ry)
tlx = mx;
elseif (0 > my * ly)
trx = mx;
end
mx = (trx + tlx) / 2;
ly = slv_func(tlx);
ry = slv_func(trx);
sc = sc + 1;
end
disp(sprintf('root approx value is: %f; %i steps used\n', mx, sc));
Метод Ньютона:
disp(sprintf('root found in [%f, %f]', lx, rx));
nx = (rx + lx) / 2; % x0 for newton
px = nx + 2*newt_precision;
sc = 1;
while(newt_precision < abs(px-nx))
drv = slv_func(nx+newt_deriv_acc/2) / newt_deriv_acc;
drv = drv - (slv_func(nx-newt_deriv_acc/2)) / newt_deriv_acc;
% drv = slv_func1(nx);
px = nx;
nx = nx - slv_func(nx) / drv;
sc = sc + 1;
end
disp(sprintf('root approx value is: %f; %i steps used\n', nx, sc));
Метод простых итераций:
disp(sprintf('root found in [%f, %f]', lx, rx));
nx = (rx + lx) / 2; % x0 for simp_iter
px = nx + 2*newt_precision;
sc = 1;
while(newt_precision < abs(px-nx))
px = nx;
nx = slv_funcp(px);
sc = sc + 1;
end
disp(sprintf('root approx value is: %f; %i steps used\n', nx, sc));
Программа целиком:
clc;
clear;
left_bound = -10;
rigth_bound = 10;
rs_step = 0.001; % roots search step
dich_precision = 0.0000001;
newt_precision = 0.0000001;
newt_deriv_acc = 0.0000001;
sitr_precision = 0.0000001;
if (left_bound > rigth_bound)
disp('Bound check error: (left_bound > rigth_bound)');
return;
end
if (0 >= rs_step)
disp('Invalid roots search step: (0 >= rs_step)');
return;
end
if (0 >= dich_precision)
disp('Invalid precision for [dichotomy]: (0 >= dich_precision)');
return;
end
if (0 >= newt_precision)
disp('Invalid precision for [newton]: (0 >= newt_precision)');
return;
end
if (0 >= newt_deriv_acc)
disp('Invalid derivative accuracy for [newton]: (0 >= newt_deriv_acc)');
return;
end
if (0 >= sitr_precision)
disp('Invalid precision for [simp_iter]: (0 >= sitr_precision)');
return;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% метод дихотомии
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp(sprintf('Searching for roots using [dichotomy]...\n'));
lx = left_bound;
rx = lx + rs_step;
while (rigth_bound >= rx)
ly = slv_func(lx);
ry = slv_func(rx);
if (0 > ry * ly)
disp(sprintf('root found in [%f, %f]', lx, rx));
tlx = lx;
trx = rx;
mx = (trx + tlx) / 2;
sc = 1; % steps count
while (dich_precision <= trx - tlx)
my = slv_func(mx);
if (0 > my * ry)
tlx = mx;
elseif (0 > my * ly)
trx = mx;
end
mx = (trx + tlx) / 2;
ly = slv_func(tlx);
ry = slv_func(trx);
sc = sc + 1;
end
disp(sprintf('root approx value is: %f; %i steps used\n', mx, sc));
end
lx = lx + rs_step;
rx = rx + rs_step;
end
disp(sprintf('[dichotomy] complete.\n\n'));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% метод Ньютона
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp(sprintf('Searching for roots using [newton]...\n'));
lx = left_bound;
rx = lx + rs_step;
while (rigth_bound >= rx)
ly = slv_func(lx);
ry = slv_func(rx);
if (0 > ry * ly)
disp(sprintf('root found in [%f, %f]', lx, rx));
nx = (rx + lx) / 2; % x0 for newton
px = nx + 2*newt_precision;
sc = 1;
while(newt_precision < abs(px-nx))
drv = slv_func(nx+newt_deriv_acc/2) / newt_deriv_acc;
drv = drv - (slv_func(nx-newt_deriv_acc/2)) / newt_deriv_acc;
% drv = slv_func1(nx);
px = nx;
nx = nx - slv_func(nx) / drv;
sc = sc + 1;
end
disp(sprintf('root approx value is: %f; %i steps used\n', nx, sc));
end
lx = lx + rs_step;
rx = rx + rs_step;
end
disp(sprintf('[newton] complete.\n\n'));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% метод простых итераций
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp(sprintf('Searching for roots using [simp_iter]...\n'));
lx = left_bound;
rx = lx + rs_step;
while (rigth_bound >= rx)
ly = slv_func(lx);
ry = slv_func(rx);
if (0 > ry * ly)
disp(sprintf('root found in [%f, %f]', lx, rx));
nx = (rx + lx) / 2; % x0 for simp_iter
px = nx + 2*sitr_precision;
sc = 1;
while(sitr_precision < abs(px-nx))
px = nx;
nx = slv_funcp(px);
sc = sc + 1;
end
disp(sprintf('root approx value is: %f; %i steps used\n', nx, sc));
end
lx = lx + rs_step;
rx = rx + rs_step;
end
disp(sprintf('[simp_iter] complete.\n\n'));
disp(sprintf('program complete.\n\n'));