scipy.optimize.elementwise.

find_root#

scipy.optimize.elementwise.find_root(f, init, /, *, args=(), допуски=None, maxiter=None, callback=None)[источник]#

Найти корень монотонной вещественнозначной функции вещественной переменной.

Для каждого элемента вывода f, find_root ищет скалярный корень, который делает элемент 0. В настоящее время эта функция использует алгоритм бракетинга Чандрупатлы [1] и поэтому требует аргумент init чтобы предоставить интервал вокруг корня: значения функции в двух конечных точках должны иметь противоположные знаки.

При наличии допустимого интервала, find_root гарантированно сходится к решению, удовлетворяющему предоставленным допуски если функция непрерывна в пределах скобки.

Эта функция работает поэлементно, когда init и args содержат (транслируемые) массивы.

Параметры:
fcallable

Функция, корень которой требуется найти. Сигнатура должна быть:

f(x: array, *args) -> array

где каждый элемент x является конечным вещественным числом и args является кортежем, который может содержать произвольное количество массивов, совместимых с x.

f должна быть поэлементной функцией: каждый элемент f(x)[i] должно равняться f(x[i]) для всех индексов i. Он не должен изменять массив x или массивы в args.

find_root ищет массив x такой, что f(x) является массивом нулей.

init2-кортеж из float array_like

Нижняя и верхняя границы интервала, окружающего желаемый корень. Интервал считается валидным, если массивы xl, xr = init удовлетворять xl < xr и sign(f(xl)) == -sign(f(xr)) поэлементно. Массивы должны быть совместимы для трансляции друг с другом и args.

argsкортеж из array_like, необязательно

Дополнительные позиционные аргументы в виде массивов для передачи в f. Массивы должны быть совместимы для трансляции друг с другом и массивами init. Если вызываемый объект, для которого требуется найти корень, требует аргументов, которые не транслируются с x, оберните этот вызываемый объект с f такой, что f принимает только x и поддерживающие вещание *args.

допускисловарь чисел с плавающей точкой, опционально

Абсолютные и относительные допуски для корня и значения функции. Допустимые ключи словаря:

  • xatol - абсолютная погрешность корня

  • xrtol - относительная погрешность на корне

  • fatol - абсолютный допуск на значение функции

  • frtol - относительная погрешность по значению функции

См. Примечания для значений по умолчанию и явных условий завершения.

maxiterint, необязательный

Максимальное количество итераций алгоритма для выполнения. По умолчанию — максимально возможное количество делений пополам в пределах (нормальных) чисел с плавающей запятой соответствующего dtype.

callbackвызываемый объект, необязательный

Необязательная пользовательская функция, вызываемая перед первой итерацией и после каждой итерации. Вызывается как callback(res), где res является _RichResult аналогично тому, что возвращается find_root (но содержащий текущие значения всех переменных на данной итерации). Если callback вызывает StopIteration, алгоритм немедленно завершится и find_root вернёт результат. callback не должен изменять res или его атрибуты.

Возвращает:
res_RichResult

Объект, похожий на экземпляр scipy.optimize.OptimizeResult со следующими атрибутами. Описания написаны так, как будто значения будут скалярами; однако, если f возвращает массив, выходные данные будут массивами той же формы.

successлогический массив

True где алгоритм успешно завершился (статус 0); False в противном случае.

statusцелочисленный массив

Целое число, представляющее статус завершения алгоритма.

  • 0 : Алгоритм сошелся к заданным допускам.

  • -1 : Начальная скобка была недействительной.

  • -2 : Достигнуто максимальное количество итераций.

  • -3 : Встречено неконечное значение.

  • -4 : Итерация была завершена callback.

  • 1 : Алгоритм работает нормально (в callback только).

xмассив float

Корень функции, если алгоритм завершился успешно.

f_xмассив float

Значение f вычислено в x.

nfevцелочисленный массив

Количество абсцисс, в которых f было вычислено для нахождения корня. Это отличается от количества раз f является вызывается поскольку функция может быть вычислена в нескольких точках за один вызов.

nitцелочисленный массив

Количество выполненных итераций алгоритма.

скобкакортеж массивов float

Нижняя и верхняя границы финального интервала.

f_bracketкортеж массивов float

Значение f вычисленные в нижней и верхней конечных точках интервала.

Смотрите также

bracket_root

Примечания

Реализовано на основе оригинальной статьи Чандрупатлы [1].

Пусть:

  • a, b = init будут левой и правой границами начального интервала,

  • xl и xr будут левой и правой конечными точками итогового интервала,

  • xmin = xl if abs(f(xl)) <= abs(f(xr)) else xr будет конечной точкой скобки с меньшим значением функции, и

  • fmin0 = min(f(a), f(b)) будет минимумом двух значений функции, вычисленных в начальных конечных точках интервала.

Тогда алгоритм считается сошедшимся, когда

  • abs(xr - xl) < xatol + abs(xmin) * xrtol или

  • fun(xmin) <= fatol + abs(fmin0) * frtol.

Это эквивалентно условию завершения, описанному в [1] с xrtol = 4e-10, xatol = 1e-5, и fatol = frtol = 0. Однако значения по умолчанию для допуски словаря являются xatol = 4*tiny, xrtol = 4*eps, frtol = 0, и fatol = tiny, где eps и tiny являются точностью и наименьшим нормальным числом результата dtype входных и выходных данных функции.

Ссылки

[1] (1,2,3)

Чандрупатла, Тирупати Р. «Новый гибридный квадратичный/бисекционный алгоритм для нахождения нуля нелинейной функции без использования производных». Advances in Engineering Software, 28(3), 145-149. https://doi.org/10.1016/s0965-9978(96)00051-8

Примеры

Предположим, мы хотим найти корень следующей функции.

>>> def f(x, c=5):
...     return x**3 - 2*x - c

Сначала мы должны найти допустимый интервал. Функция не монотонна, но bracket_root может предоставить скобку.

>>> from scipy.optimize import elementwise
>>> res_bracket = elementwise.bracket_root(f, 0)
>>> res_bracket.success
True
>>> res_bracket.bracket
(2.0, 4.0)

Действительно, значения функции на концах интервала имеют противоположные знаки.

>>> res_bracket.f_bracket
(-1.0, 51.0)

Как только у нас есть допустимый интервал, find_root может использоваться для предоставления точного корня.

>>> res_root = elementwise.find_root(f, res_bracket.bracket)
>>> res_root.x
2.0945514815423265

Последний интервал имеет ширину всего в несколько ULP, поэтому ошибка между этим значением и истинным корнем не может быть намного меньше в пределах значений, представимых в арифметике двойной точности.

>>> import numpy as np
>>> xl, xr = res_root.bracket
>>> (xr - xl) / np.spacing(xl)
2.0
>>> res_root.f_bracket
(-8.881784197001252e-16, 9.769962616701378e-15)

bracket_root и find_root принимают массивы для большинства аргументов. Например, чтобы найти корень для нескольких значений параметра c одновременно:

>>> c = np.asarray([3, 4, 5])
>>> res_bracket = elementwise.bracket_root(f, 0, args=(c,))
>>> res_bracket.bracket
(array([1., 1., 2.]), array([2., 2., 4.]))
>>> res_root = elementwise.find_root(f, res_bracket.bracket, args=(c,))
>>> res_root.x
array([1.8932892 , 2.        , 2.09455148])