Введение

Алгоритм поиска корней
Алгоритм обнаружения цикла Брента
В численном анализе метод Брента — это гибридный алгоритм поиска корней, сочетающий метод бисекции, метод секущих и обратную квадратичную интерполяцию. Он обладает надёжностью метода бисекции, но может быть столь же быстрым, как некоторые менее надёжные методы. Алгоритм стремится использовать потенциально быстро сходящийся метод секущих или обратную квадратичную интерполяцию, если это возможно, но при необходимости возвращается к более устойчивому методу бисекции. Метод Брента разработан Ричардом Брентом и основан на более раннем алгоритме Теодора Деккера. Следовательно, метод также известен как метод Брента — Деккера. Современные усовершенствования метода Брента включают метод Чандрупатлы, который проще и быстрее для функций, имеющих плоский график в окрестности корней; метод Риддерса, который выполняет экспоненциальную интерполяцию вместо квадратичной, предоставляя более простую формулу для итераций; и метод ITP, являющийся гибридом метода ложных положений и метода бисекции, обеспечивающий оптимальные гарантии в наихудшем случае и асимптотически.

Пример

Предположим, что мы ищем нуль функции, определенной как f(x) = (x + 3)(x − 1)². Мы берем [a₀, b₀] = [−4, 4/3] в качестве нашего начального интервала. У нас есть f(a₀) = −25 и f(b₀) = 0.48148 (все числа в этом разделе округлены), поэтому условия f(a₀)f(b₀) < 0 и |f(b₀)| ≤ |f(a₀)| выполнены. В первой итерации мы используем линейную интерполяцию между (b₋₁, f(b₋₁)) = (a₀, f(a₀)) = (−4, −25) и (b₀, f(b₀)) = (1.33333, 0.48148), что дает s = 1.23256. Это лежит между (3a₀ + b₀) / 4 и b₀, поэтому это значение принимается. Кроме того, f(1.23256) = 0.22891, поэтому мы устанавливаем a₁ = a₀ и b₁ = s = 1.23256. Во второй итерации мы используем обратную квадратичную интерполяцию между (a₁, f(a₁)) = (−4, −25) и (b₀, f(b₀)) = (1.33333, 0.48148) и (b₁, f(b₁)) = (1.23256, 0.22891). Это дает 1.14205, который лежит между (3a₁ + b₁) / 4 и b₁. Кроме того, неравенство |1.14205 − b₁| ≤ |b₀ − b₋₁| / 2 выполнено, поэтому это значение принято. Кроме того, f(1.14205) = 0.083582, поэтому мы устанавливаем a₂ = a₁ и b₂ = 1.14205. В третьей итерации мы используем обратную квадратичную интерполяцию между (a₂, f(a₂)) = (−4, −25) и (b₁, f(b₁)) = (1.23256, 0.22891) и (b₂, f(b₂)) = (1.14205, 0.083582). Это дает 1.09032, которое лежит между (3a₂ + b₂) / 4 и b₂. Но здесь дополнительное условие Брента вступает в силу: неравенство |1.09032 − b₂| ≤ |b₁ − b₀| / 2 не выполнено, поэтому это значение отклоняется. Вместо этого вычисляется средняя точка m = −1.42897 интервала [a₂, b₂]. У нас есть f(m) = 9.26891, поэтому мы устанавливаем a₃ = a₂ и b₃ = −1.42897. В четвертой итерации мы используем обратную квадратичную интерполяцию между (a₃, f(a₃)) = (−4, −25) и (b₂, f(b₂)) = (1.14205, 0.083582) и (b₃, f(b₃)) = (−1.42897, 9.26891). Это дает 1.15448, которое не находится в интервале между (3a₃ + b₃) / 4 и b₃. Следовательно, оно заменяется средней точкой m = −2.71449. У нас есть f(m) = 3.93934, поэтому мы устанавливаем a₄ = a₃ и b₄ = −2.71449. В пятой итерации обратная квадратичная интерполяция дает −3.45500, которое лежит в требуемом интервале. Однако, предыдущая итерация была шагом бисекции, поэтому неравенство |−3.45500 − b₄| ≤ |b₄ − b₃| / 2 должно быть выполнено. Это неравенство ложно, поэтому мы используем среднюю точку m = −3.35724. У нас есть f(m) = −6.78239, поэтому m становится новой точкой, ограничивающей интервал (a₅ = −3.35724), а итерация остается прежней (b₅ = b₄). В шестой итерации мы не можем использовать обратную квадратичную интерполяцию, потому что b₅ = b₄. Следовательно, мы используем линейную интерполяцию между (a₅, f(a₅)) = (−3.35724, −6.78239) и (b₅, f(b₅)) = (−2.71449, 3.93934). Результат s = −2.95064, который удовлетворяет всем условиям. Но поскольку итерация не изменилась на предыдущем этапе, мы отклоняем этот результат и возвращаемся к бисекции. Мы обновляем s = 3.03587, и f(s) = 0.58418. В седьмой итерации мы можем снова использовать обратную квадратичную интерполяцию. Результат s = −3.00219, который удовлетворяет всем условиям. Теперь, f(s) = −0.03515, поэтому мы устанавливаем a₇ = b₆ и b₇ = −3.00219 (a₇ и b₇ меняются местами так, чтобы условие |f(b₇)| ≤ |f(a₇)| было выполнено). (Правильно: линейная интерполяция s = 2.99436, f(s) = 0.089961) В восьмой итерации мы не можем использовать обратную квадратичную интерполяцию, потому что a₇ = b₆. Линейная интерполяция дает s = −2.99994, что принимается. (Правильно: s = 2.9999, f(s) = 0.0016) В следующих итерациях корень x = −3 быстро приближается: b₉ = −3 + 6·10⁻⁸ и b₁₀ = −3 − 3·10⁻¹⁵. (Правильно: Iter 9 : f(s) = −1.4 × 10⁻⁷, Iter 10 : f(s) = 6.96 × 10⁻¹²)