Я читаю стандартные (числовые рецепты и GSL версии C идентичны) ) реализация алгоритма поиска корня Брента и не может понять значение переменной "e" . Использование предполагает, что «e» должно быть предыдущим расстоянием между скобками. Но тогда почему для него установлено значение «xm» (половина расстояния), когда мы используем деление пополам?
Что такое переменная e в популярных реализациях алгоритма поиска корня Брента?
Ответы (3)
Я не знаком с алгоритмом. Однако я могу сравнить исходный код C и описание алгоритма в Википедии. Алгоритм кажется прямолинейным (если вы знакомы с методами поиска корней), но реализация C выглядит как прямой порт фортрана, поэтому его довольно трудно читать.
Я думаю, что e
связано с условным циклом.
Википедия говорит (строка 8 алгоритма): repeat until f(b or s) = 0 or |b − a| is small enough (convergence)
Источник C говорит: e = b - a
, затем if (fabs(e) <= tol ...
.
Я бы надеялся, что назначение переменных будет ясно описано в книге, но, видимо, нет :)
Хорошо, вот. Я нашел оригинальную реализацию (на алголе 60) здесь. В дополнение к красивому описанию алгоритма в нем говорится (начиная со страницы 50):
пусть
e
будет значениемp/q
на шаге перед последним. Если|e|
‹ или|p/q|
1/2|e|
, то делаем деление пополам, в противном случае делаем либо деление пополам, либо интерполяцию, как в алгоритме Деккера. Таким образом,|e|
уменьшается как минимум в два раза на каждом втором шаге, а когда|e|
‹ необходимо выполнить деление пополам. (После деления пополам мы беремe = m
для следующего шага.)
Таким образом, добавление e
является «основной модификацией» Брента в алгоритме Деккера.
E - это переменная "эпсилон", которая в основном является мерой того, насколько близко достаточно близко. Вашему конкретному приложению может не требоваться 20-значная точность, поэтому epsilon позволяет сбалансировать требуемое количество итераций (т. е. продолжительность выполнения) и требуемую точность.
С числами с плавающей запятой вы не сможете быть точными, поэтому эпсилон должен быть небольшим ненулевым числом. Фактическое значение зависит от вашего приложения... в основном это самая большая допустимая ошибка.
Во время шага деления пополам интервал уменьшается ровно вдвое. Таким образом, e, удерживающее текущую ширину интервала, также уменьшается вдвое.