This site is version 0.0.1. Most of the code on this site is drafted by an agent and needs review. I apologize for the AI-speak, we are working on rewriting it!
viv-lang.org

vp.optimize.root

Solve a square nonlinear system F(x) = 0 by Levenberg-Marquardt, as SciPy's root(method='lm').

Part of the distribution vipyr; it runs from a checkout of the repository. Planned on PyPI as pip install vipyr.

vp.optimize.root(fun, x0) minimizes for a system of n equations in n unknowns with the same compiled lmder as vp.optimize.least_squares, under leastsq's defaults; it is SciPy's root(method="lm"). The function forms, args and jac are those of least_squares.

SciPy's default method, "hybr", is Powell's hybrid method from MINPACK (hybrd without a Jacobian, hybrj with one); it is not ported, and method takes "lm" only. At a root the two find the same point; Levenberg-Marquardt also stops at a local minimum of that is not a root, which success alone does not reveal: check fun.

Signature

vp.optimize.root(fun, x0, *, args=(), jac=None, method='lm', xtol=1.49012e-08, ftol=1.49012e-08, gtol=0.0, maxfev=None, eps=None, diag=None, fast=False)

Parameters

fun : str | function, required
The system F(x, *args) = 0, n equations: 'file.viv:def', a def of a module from vp.load, or a Python function in py2viv's subset.
x0 : ndarray[float64], required
The starting point, length n.
args : tuple, default ()
Extra arguments of fun and jac, each a number or a 1-D array.
jac : str | function, default None
As for vp.optimize.least_squares.
method : str, default 'lm'
'lm' only: Levenberg-Marquardt on the square system, as SciPy's root(method='lm'); MINPACK's hybrd/hybrj (Powell's hybrid method, SciPy's default 'hybr') is not ported.
xtol : float, default 1.49012e-08
Leastsq's xtol.
ftol : float, default 1.49012e-08
Leastsq's ftol.
gtol : float, default 0.0
Leastsq's gtol.
maxfev : int, default None
As for vp.optimize.curve_fit.
eps : float, default None
With jac='fd', the relative step squared; None: eps.
diag : ndarray[float64], default None
MINPACK's variable scales; None: the Jacobian's column norms.
fast : bool, default False
Compile with the fast flags (fused multiply-add): faster, last bits may differ.

Returns

A frozen RootResult. Iterating it gives the fields below in order; it also has params, tests, log and check().

x : ndarray[float64]
The root.
fun : ndarray[float64]
F at x.
jac : ndarray[float64]
The n by n Jacobian at x.
success : bool
Status is 1 to 4.
status : int
MINPACK's info, 0 to 8.
message : str
Status in words.
nfev : int
Evaluations of F.
njev : int
Jacobian evaluations.

Raises

ValueError
A tolerance below machine epsilon, fewer residuals than variables, or an array of the wrong shape; vipyr._optimize.OptimizeProblemError (a ValueError) when the function or jac cannot be made into a Viv problem, or py2viv refuses a Python function.
vipyr.VivCompileError
A SyntaxError: the function's .viv file (or py2viv's translation) does not compile.
TypeError
An argument of the wrong type, or an unknown keyword.
vipyr.VivBuildError
An ImportError: no C compiler, or the program's C does not build.

See also

  • vp.optimize.least_squares : Minimize a sum of squares of nonlinear residuals by MINPACK's Levenberg-Marquardt, with the residuals in Viv.

References

  1. J. J. Moré, B. S. Garbow and K. E. Hillstrom, Testing unconstrained optimization software, ACM Trans. Math. Softw. 7, 17-41 (1981): the helical valley and the other square problems. doi:10.1145/355934.355936

Examples

import numpy as np
import vipyr as vp

def helical_valley(x):
    th = np.arctan(x[1] / x[0]) / (2.0 * np.pi)
    if x[0] < 0.0:
        th = th + 0.5
    return np.array([10.0 * (x[2] - 10.0 * th), 10.0 * (np.sqrt(x[0] ** 2 + x[1] ** 2) - 1.0), x[2]])

r = vp.optimize.root(helical_valley, [-1.0, 0.0, 0.0])
print(r.x, r.nfev, r.njev)
assert r.check()
[ 1.00000000e+00 -6.24330118e-18  0.00000000e+00] 11 8

Each example ran as written when these pages were generated, and the output shown is what it printed.

Checked against

Reference
SciPy 1.12's root(method='lm') on the square Moré-Garbow-Hillstrom problems (Rosenbrock, helical valley, Powell singular, Freudenstein-Roth) from their standard starts: same root and evaluation counts (lib/minpack/bench_optimize.py, python/tests/test_optimize.py).

Credits

  • A port of MINPACK (Argonne National Laboratory), under MINPACK's BSD-style copyright notice (1999, University of Chicago), which the port and the Fortran in lib/minpack/ref both carry. This product includes software developed by the University of Chicago, as Operator of Argonne National Laboratory.

Source