Глава 1. Численные методы алгебры
высокой степени, то, хотя сходимость метода не доказана
[Касаткин, 1978] при произвольном начальном приближе-
нии, на практике итерации всегда сходятся к какому-либо
корню. По теореме Горнера для алгебраического много-
члена частное F(х)/(х - х
n
) будет тоже многочленом, но
меньшей степени. Поэтому, последовательно удаляя найден-
ные корни, можно найти все корни многочлена.
Один из лучших имеющихся машинных алгоритмов
для нахождения действительного нуля функции сочетает в
себе безотказность метода бисекции с асимптотической
скоростью метода парабол в случае гладких функций. Он
называется ZEROIN и был изобретен в 1960-х гг. в Матема-
тическом центре Амстердама Ван Вейнгарденом, Декке-
ром и др. Описание алгоритма и его анализ даны в публи-
кации Уилкинсона (1967, с. 8-12). Сам алгоритм впервые
был опубликован в 1969 г. Деккером, а в 1973 г. улучшен
Брентом. Реализация программы на языке FORTRAN была
предложена Форсайтом в 1980 г. по алгоритму Деккера в
версии Брента. Здесь же предлагается реализация алго-
ритма на языке PASCAL, выполненная авторами пособия.
Подрограмма оформлена как процедура-функция ZE-
ROIN. Все названия переменных по сравнению с фортран-
ной версией сохранены. Обращение к процедуре-функции
имеет простой вид:
zz := zeroin (a, b, tol).
Здесь а и b (тип real) - точки интервала, на котором
ищется нуль, tol (тип real) - граница погрешности вычис-
ления результата. Процедура ZEROIN обращается также к
процедуре-функции FUNC(x) (тип real), которая воз-
вращает значение функции в заданной точке. Без проверки
в ZEROIN предполагается, что FUNC(a) и FUNC(b) имеют
разные знаки.
В процедуре ZEROIN выполняется итерационный
процесс, в котором на каждом шаге присутствуют три абс-
циссы a, b и c. Обычно абcцисса a - предыдущее прибли-
жение (х
n-1
); b - последнее и наилучшее приближение х
n
; c
- предыдущее, но еще более раннее приближение, причем
sign( FUNC(b) ) = sign( FUNC(c) ). Таким образом, b и с
ограничивают нуль. При этом |FUNC(b)|< |FUNC(c)|. Если
|b - c| уменьшилось настолько, что выполняется условие
|b - c| < tol + 4.0 ⋅ eps
⋅
abs(b),
то b выдается как найденное значение процедуры-функ-
ции ZEROIN. Кроме параметра tоl в проверке сходимости
участвует еще один параметр - ерs, "машинный нуль",
чтобы подстраховаться на случай, если tol задано слишком
маленьким, например равным нулю.
На каждой очередной итерации в ZEROIN выбирается
очередное приближение к корню из двух - один получен
алгоритмом бисекции, а другой - интерполяцией. Если a, b
и c различны, то используется квадратичная интерполяция
(метод парабол), если нет, то метод секущих (линейная
интерполяция). Если полученное x
n+1
находится в "ра-
зумных" пределах, то выбирают его, в противном случае
выбирают точку бисекции. Определение "разумности"
означает, что x
n+1
∈ [b, c], т.е. лежит внутри интервала и не
совпадает с его концами. Таким образом, длина интервала
гарантированно убывает с каждой итерацией, а если функ-
ция еще к тому же ведет себя хорошо, то и достаточно
быстро. Более подробно об алгоритме, программе и
описании метода можно посмотреть в книге Брента (1973).
Еще несколько важных замечаний по поводу алгорит-
ма. Для того чтобы точка бисекции всегда лежала внутри
расчетного интервала и желаемая величина получалась как
малая поправка к найденному приближению, ее вычисля-
ют по формуле xm := b + 0.5*(c - b).
Большое внимание в алгоритме уделяется проблеме ма-
шинных нулей. Это выражается в необычной проверке
знаков FUNC(b) и FUNC(c) (см. соответствующие подпро-
граммы).
Итоговая точка, получаемая алгоритмом, записывается
в виде b + p/q, но деление не выполняется до тех пор, пока
оно не станет безопасным и действительно необходимым,
так как если будет выбрана точка по методу бисекций, то
деление вообще не нужно.
Версия алгоритма Брента, во-первых, всегда сходится,
даже при плавающей арифметике. Во-вторых, количество
итераций не может стать больше числа
log
2
2
1
BA
tol
−
⎛
⎝
⎜
⎞
⎠
⎟
⎡
⎣
⎢
⎤
⎦
⎥
,
где tol1 := 0.5*tol + 2.0*eps*abs(B). В-третьих, нуль R, по-
лучаемый алгоритмом, таков, что FUNC гарантированно
меняет знак в определенном интервале, приблизительно
совпадающим с
[R - exp(tol*ln2), R + exp(tol*ln2)].
В-четвертых, сам Брент тщательно проверял свой алго-
ритм на самых разнообразных функциях и установил, что
в типичном случае для гладкой функции требуется не
более 10 итераций. В общем случае Брент ни разу не
встретил функции, для которой количество итераций было
больше трехзначного числа. Более подробно смотрите
работу Брента (1973).
Формальные параметры процедуры. Входные: ax, bx
(тип real) - определяют отрезок, на котором ищется корень
уравнения; tol (тип real) - точность, с которой должен
быть определен корень уравнения. Выходные: процедура-
функция возвращает найденное с заданной точностью
значение корня на отрезке [ax, bx].
Описанная процедура выглядит:
F
UNCTION ZEROIN (AX, BX, TOL : REAL) : REAL;
L
ABEL 20, 30;
VAR A,B,C,D,E,EPS,FA,FB,FC,TOL1,XM,P,Q,R,S:REAL;
DN : BOOLEAN;
BEGIN EPS := 1.0;
DN := FALSE;
REPEAT
EPS := EPS / 2.0;
TOL1 := 1.0 + EPS;
UNTIL TOL1 <= 1.0;
26