- •Графики функций sin X и .
- •В чем заключается задача о численном решении уравнений
- •Задача о нахождении корня уравнения с заданной точностью.
- •Отделение корней
- •График функции
- •Графики, полученные при помощи plot (верхний) и fplot (нижний).
- •Различное число корней в зависимости от значения параметра .
- •Основные способы обращения к fzero
- •Графики функций
- •Способы задания уравнения для fzero
- •Решение уравнения, зависящего от параметров
- •Интерфейс fzero, получение информации о вычислениях, параметры вычислительного процесса
- •Выходные аргументы fzero
- •Входные аргументы fzero
- •Прерывание работы fzero, пример приложения с кнопкой Stop
Входные аргументы fzero
До сих пор (см., например Способы задания уравнения для fzero) мы рассматривали способ вызова fzero с двумя входными аргументами:
исследуемой функцией;
начальным приближением или отрезком, на котором отделен корень.
Функция fzero может быть вызвана и с третьим входным аргументом — структурой, для заполнения полей которой предназначена функция optimset. Назначение полей этой структуры следующее
Display — уровень отображаемой о ходе алгоритма информации. Значения: 'off' (не отображать), 'iter' (выводить информацию о каждой итерации), 'final' (выводить информацию о завершении), 'notify' (используется по умолчанию, предупреждать о получении расходящегося процесса).
FunValCheck — вывод сведений о значениях функции. Значения: 'on' (выводить предупреждение о получении комплексных значений или NaN), 'off' (по умолчанию сведения о значениях функции не выводятся).
OutputFcn — функция, вызываемая на каждом шаге алгоритма. Данную функцию следует запрограммировать отдельно (см. раздел Прерывание работы fzero, пример приложения с кнопкой Stop).
TolX — точность нахождения корня, которая оценивается по разности соседних приближений. Более подробно об этом написано в разделе Алгоритм, по которому работает fzero.
Для формирования структуры следует вызвать функцию optimset, указав в ее входных аргументах пары: НазваниеПоля, значение. Например, мы хотим найти корень уравнения x-cos x=0 с точностью 10 -4 . Для этого определяем inline-функцию, формируем структуру options (название структуры может быть и другим, например opt3) и вызываем fzero:
>> fun = inline('cos(x)-x');
>> options = optimset('TolX', 1e-4);
>> x = fzero(fun, 1, options)
x =
0.7391
Непосредственная проверка убеждает нас, что корень найден с требуемой точностью, т.к. в окрестности приближенного к корню значения исследуемая функция меняет знак:
>> fun(x-1e-4)*fun(x+1e-4)
ans =
-2.6884e-008
На самом деле способ проверки на достижение заданной точности, заложенный в алгоритме fzero, не всегда дает гарантированный результат. Например, если мы зададим точность 10-10 при решении уравнения x41=0, то мы не получим приближенное решение (точное здесь равно 0) с этой точностью:
>> options = optimset('TolX', 1e-10);
>> x = fzero('x^41', 1, options)
x =
-1.1706e-008
Почему так происходит, разобрано в разделе Отличие fzero от fsolve.
В
процессе нахождения корня иногда полезно
проследить, что происходит на каждом
шаге алгоритма. Для этого следует
установить Display в 'iter'. Обратимся снова
к рассмотренному выше
и
проследим за действиями fzero на каждом
шаге:
>> fun = inline('sqrt(x-pi)-x^2+10');
>> options = optimset('Display', 'iter');
>> x = fzero(fun, 5, options)
Search for an interval around 5 containing a sign change:
Func-count a f(a) b f(b) Procedure
1 5 -13.6368 5 -13.6368 initial interval
3 4.85858 -12.2954 5.14142 -15.0201 search
5 4.8 -11.7522 5.2 -15.6053 search
7 4.71716 -10.9964 5.28284 -16.4451 search
9 4.6 -9.95235 5.4 -17.6572 search
11 4.43431 -8.52617 5.56569 -19.4199 search
13 4.2 -6.61121 5.8 -22.0095 search
15 3.86863 -4.11363 6.13137 -25.8646 search
17 3.4 -1.05166 6.6 -31.7003 search
Exiting fzero: aborting search for an interval containing a sign change
because complex function value encountered during search.
(Function value at 2.73726 is 2.5074+0.63587i.)
Check function or try again with a different starting value.
Мы видим, что fzero начала искать отрезок, на границах которого исследуемая функция изменяет знаки, отступая все больше влево и вправо от начального приближения 5 (в выводимой таблице границы обозначены a и b). Процесс отделения закончился неудачно, потому что значение 3.4 было уменьшено до 2.73726 при котором значение исследуемой функции стало комплексным (это видно из сообщения, выведенного перед завершением работы fzero).
Проанализируем также, почему в случае поиска корня уравнения x41=0 с точностью 10-10 на самом деле находится корень с меньшей точностью.
>> options = optimset('Display', 'iter', 'TolX', 1e-10);
>> x = fzero('x^41', 1, options)
Сначала fzero отделяет корень и успешно справляется с этой задачей за 24 вычисления исследуемой функции, в результате находится отрезок [-0.28, 1.9051], на границах которого функция принимает значения разных знаков:
Search for an interval around 1 containing a sign change:
Func-count a f(a) b f(b) Procedure
1 1 1 1 1 initial interval
3 0.971716 0.308396 1.02828 3.13791 search
….
24 -0.28 -2.15516e-023 1.9051 2.99639e+011 search
Затем происходит уточнение корня
Search for a zero in the interval [-0.28, 1.9051]:
Func-count x f(x) Procedure
24 -0.28 -2.15516e-023 initial
25 -0.28 -2.15516e-023 interpolation
….
102 -1.34016e-008 -1.4822e-323 bisection
103 -1.1706e-008 0 interpolation
На 103-ей итерации значение функции оказывается точным нулем, т.к. вещественные числа типа double лежат в интервалах [-1.79769e+308, -2.22507e-308] и [2.22507e-308, 1.79769e+308]. Возведение же последнего полученного приближения -1.1706e-008 в 41-ую степень дает машинный ноль и вычисления прекращаются.
Примечание. Границы значений для вещественных типов double и single выводятся при помощи функций realmax, realmin:
>> realmax
ans =
1.7977e+308
>> realmin
ans =
2.2251e-308
>> realmax('single')
ans =
3.4028e+038
>> realmin('single')
ans =
1.1755e-038
