Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Решение уравнений.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
480.48 Кб
Скачать

Входные аргументы 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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]