Beispiel #1
0
def _root_leastsq(func,
                  x0,
                  args=(),
                  jac=None,
                  col_deriv=0,
                  xtol=1.49012e-08,
                  ftol=1.49012e-08,
                  gtol=0.0,
                  maxiter=0,
                  eps=0.0,
                  factor=100,
                  diag=None,
                  **unknown_options):
    _check_unknown_options(unknown_options)
    x, cov_x, info, msg, ier = leastsq(func,
                                       x0,
                                       args=args,
                                       Dfun=jac,
                                       full_output=True,
                                       col_deriv=col_deriv,
                                       xtol=xtol,
                                       ftol=ftol,
                                       gtol=gtol,
                                       maxfev=maxiter,
                                       epsfcn=eps,
                                       factor=factor,
                                       diag=diag)
    sol = Result(x=x,
                 message=msg,
                 status=ier,
                 success=ier in (1, 2, 3, 4),
                 cov_x=cov_x,
                 fun=info.pop('fvec'))
    sol.update(info)
    return sol
Beispiel #2
0
Datei: _root.py Projekt: 87/scipy
def _root_leastsq(func, x0, args=(), jac=None,
                  col_deriv=0, xtol=1.49012e-08, ftol=1.49012e-08,
                  gtol=0.0, maxiter=0, eps=0.0, factor=100, diag=None,
                  **unknown_options):
    _check_unknown_options(unknown_options)
    x, cov_x, info, msg, ier = leastsq(func, x0, args=args, Dfun=jac,
                                       full_output=True,
                                       col_deriv=col_deriv, xtol=xtol,
                                       ftol=ftol, gtol=gtol,
                                       maxfev=maxiter, epsfcn=eps,
                                       factor=factor, diag=diag)
    sol = Result(x=x, message=msg, status=ier,
                 success=ier in (1, 2, 3, 4), cov_x=cov_x,
                 fun=info.pop('fvec'))
    sol.update(info)
    return sol
Beispiel #3
0
Datei: _root.py Projekt: 87/scipy
def _root_nonlin_solve(func, x0, args=(), jac=None,
                       _callback=None, _method=None,
                       nit=None, disp=False, maxiter=None,
                       ftol=None, fatol=None, xtol=None, xatol=None,
                       tol_norm=None, line_search='armijo', jac_options=None,
                       **unknown_options):
    _check_unknown_options(unknown_options)

    f_tol = fatol
    f_rtol = ftol
    x_tol = xatol
    x_rtol = xtol
    verbose = disp
    if jac_options is None:
        jac_options = dict()

    jacobian = {'broyden1': nonlin.BroydenFirst,
                'broyden2': nonlin.BroydenSecond,
                'anderson': nonlin.Anderson,
                'linearmixing': nonlin.LinearMixing,
                'diagbroyden': nonlin.DiagBroyden,
                'excitingmixing': nonlin.ExcitingMixing,
                'krylov': nonlin.KrylovJacobian
               }[_method]

    if args:
        if jac == True:
            def f(x):
                return func(x, *args)[0]
        else:
            def f(x):
                return func(x, *args)
    else:
        f = func

    x, info = nonlin.nonlin_solve(f, x0, jacobian=jacobian(**jac_options),
                                  iter=nit, verbose=verbose,
                                  maxiter=maxiter, f_tol=f_tol,
                                  f_rtol=f_rtol, x_tol=x_tol,
                                  x_rtol=x_rtol, tol_norm=tol_norm,
                                  line_search=line_search,
                                  callback=_callback, full_output=True,
                                  raise_exception=False)
    sol = Result(x=x)
    sol.update(info)
    return sol
Beispiel #4
0
def _root_nonlin_solve(func,
                       x0,
                       args=(),
                       jac=None,
                       _callback=None,
                       _method=None,
                       nit=None,
                       disp=False,
                       maxiter=None,
                       ftol=None,
                       fatol=None,
                       xtol=None,
                       xatol=None,
                       tol_norm=None,
                       line_search='armijo',
                       jac_options=None,
                       **unknown_options):
    _check_unknown_options(unknown_options)

    f_tol = fatol
    f_rtol = ftol
    x_tol = xatol
    x_rtol = xtol
    verbose = disp
    if jac_options is None:
        jac_options = dict()

    jacobian = {
        'broyden1': nonlin.BroydenFirst,
        'broyden2': nonlin.BroydenSecond,
        'anderson': nonlin.Anderson,
        'linearmixing': nonlin.LinearMixing,
        'diagbroyden': nonlin.DiagBroyden,
        'excitingmixing': nonlin.ExcitingMixing,
        'krylov': nonlin.KrylovJacobian
    }[_method]

    if args:
        if jac == True:

            def f(x):
                return func(x, *args)[0]
        else:

            def f(x):
                return func(x, *args)
    else:
        f = func

    x, info = nonlin.nonlin_solve(f,
                                  x0,
                                  jacobian=jacobian(**jac_options),
                                  iter=nit,
                                  verbose=verbose,
                                  maxiter=maxiter,
                                  f_tol=f_tol,
                                  f_rtol=f_rtol,
                                  x_tol=x_tol,
                                  x_rtol=x_rtol,
                                  tol_norm=tol_norm,
                                  line_search=line_search,
                                  callback=_callback,
                                  full_output=True,
                                  raise_exception=False)
    sol = Result(x=x)
    sol.update(info)
    return sol
Beispiel #5
0
def _root_hybr(func, x0, args=(), jac=None,
               col_deriv=0, xtol=1.49012e-08, maxfev=0, band=None, eps=0.0,
               factor=100, diag=None, full_output=0, **unknown_options):
    """
    Find the roots of a multivariate function using MINPACK's hybrd and
    hybrj routines (modified Powell method).

    Options for the hybrd algorithm are:
        col_deriv : bool
            Specify whether the Jacobian function computes derivatives down
            the columns (faster, because there is no transpose operation).
        xtol : float
            The calculation will terminate if the relative error between two
            consecutive iterates is at most `xtol`.
        maxfev : int
            The maximum number of calls to the function. If zero, then
            ``100*(N+1)`` is the maximum where N is the number of elements
            in `x0`.
        band : tuple
            If set to a two-sequence containing the number of sub- and
            super-diagonals within the band of the Jacobi matrix, the
            Jacobi matrix is considered banded (only for ``fprime=None``).
        eps : float
            A suitable step length for the forward-difference
            approximation of the Jacobian (for ``fprime=None``). If
            `eps` is less than the machine precision, it is assumed
            that the relative errors in the functions are of the order of
            the machine precision.
        factor : float
            A parameter determining the initial step bound
            (``factor * || diag * x||``).  Should be in the interval
            ``(0.1, 100)``.
        diag : sequence
            N positive entries that serve as a scale factors for the
            variables.

    This function is called by the `root` function with `method=hybr`. It
    is not supposed to be called directly.
    """
    _check_unknown_options(unknown_options)
    epsfcn = eps

    x0 = array(x0, ndmin=1)
    n = len(x0)
    if type(args) != type(()):
        args = (args,)
    _check_func('fsolve', 'func', func, x0, args, n, (n,))
    Dfun = jac
    if Dfun is None:
        if band is None:
            ml, mu = -10,-10
        else:
            ml, mu = band[:2]
        if (maxfev == 0):
            maxfev = 200*(n + 1)
        retval = _minpack._hybrd(func, x0, args, 1, xtol, maxfev,
                                 ml, mu, epsfcn, factor, diag)
    else:
        _check_func('fsolve', 'fprime', Dfun, x0, args, n, (n,n))
        if (maxfev == 0):
            maxfev = 100*(n + 1)
        retval = _minpack._hybrj(func, Dfun, x0, args, 1,
                                 col_deriv, xtol, maxfev, factor,diag)

    x, status = retval[0], retval[-1]

    errors = {0:["Improper input parameters were entered.",TypeError],
              1:["The solution converged.", None],
              2:["The number of calls to function has "
                 "reached maxfev = %d." % maxfev, ValueError],
              3:["xtol=%f is too small, no further improvement "
                 "in the approximate\n  solution "
                 "is possible." % xtol, ValueError],
              4:["The iteration is not making good progress, as measured "
                 "by the \n  improvement from the last five "
                 "Jacobian evaluations.", ValueError],
              5:["The iteration is not making good progress, "
                 "as measured by the \n  improvement from the last "
                 "ten iterations.", ValueError],
              'unknown': ["An error occurred.", TypeError]}

    if status != 1 and not full_output:
        if status in [2,3,4,5]:
            msg = errors[status][0]
            warnings.warn(msg, RuntimeWarning)
        else:
            try:
                raise errors[status][1](errors[status][0])
            except KeyError:
                raise errors['unknown'][1](errors['unknown'][0])

    info = retval[1]
    info['fun'] = info.pop('fvec')
    sol = Result(x=x, success=(status==1), status=status)
    sol.update(info)
    try:
        sol['message'] = errors[status][0]
    except KeyError:
        info['message'] = errors['unknown'][0]

    return sol
Beispiel #6
0
def _root_hybr(func,
               x0,
               args=(),
               jac=None,
               col_deriv=0,
               xtol=1.49012e-08,
               maxfev=0,
               band=None,
               eps=0.0,
               factor=100,
               diag=None,
               full_output=0,
               **unknown_options):
    """
    Find the roots of a multivariate function using MINPACK's hybrd and
    hybrj routines (modified Powell method).

    Options for the hybrd algorithm are:
        col_deriv : bool
            Specify whether the Jacobian function computes derivatives down
            the columns (faster, because there is no transpose operation).
        xtol : float
            The calculation will terminate if the relative error between two
            consecutive iterates is at most `xtol`.
        maxfev : int
            The maximum number of calls to the function. If zero, then
            ``100*(N+1)`` is the maximum where N is the number of elements
            in `x0`.
        band : tuple
            If set to a two-sequence containing the number of sub- and
            super-diagonals within the band of the Jacobi matrix, the
            Jacobi matrix is considered banded (only for ``fprime=None``).
        eps : float
            A suitable step length for the forward-difference
            approximation of the Jacobian (for ``fprime=None``). If
            `eps` is less than the machine precision, it is assumed
            that the relative errors in the functions are of the order of
            the machine precision.
        factor : float
            A parameter determining the initial step bound
            (``factor * || diag * x||``).  Should be in the interval
            ``(0.1, 100)``.
        diag : sequence
            N positive entries that serve as a scale factors for the
            variables.

    This function is called by the `root` function with `method=hybr`. It
    is not supposed to be called directly.
    """
    _check_unknown_options(unknown_options)
    epsfcn = eps

    x0 = array(x0, ndmin=1)
    n = len(x0)
    if type(args) != type(()):
        args = (args, )
    _check_func('fsolve', 'func', func, x0, args, n, (n, ))
    Dfun = jac
    if Dfun is None:
        if band is None:
            ml, mu = -10, -10
        else:
            ml, mu = band[:2]
        if (maxfev == 0):
            maxfev = 200 * (n + 1)
        retval = _minpack._hybrd(func, x0, args, 1, xtol, maxfev, ml, mu,
                                 epsfcn, factor, diag)
    else:
        _check_func('fsolve', 'fprime', Dfun, x0, args, n, (n, n))
        if (maxfev == 0):
            maxfev = 100 * (n + 1)
        retval = _minpack._hybrj(func, Dfun, x0, args, 1, col_deriv, xtol,
                                 maxfev, factor, diag)

    x, status = retval[0], retval[-1]

    errors = {
        0: ["Improper input parameters were entered.", TypeError],
        1: ["The solution converged.", None],
        2: [
            "The number of calls to function has "
            "reached maxfev = %d." % maxfev, ValueError
        ],
        3: [
            "xtol=%f is too small, no further improvement "
            "in the approximate\n  solution "
            "is possible." % xtol, ValueError
        ],
        4: [
            "The iteration is not making good progress, as measured "
            "by the \n  improvement from the last five "
            "Jacobian evaluations.", ValueError
        ],
        5: [
            "The iteration is not making good progress, "
            "as measured by the \n  improvement from the last "
            "ten iterations.", ValueError
        ],
        'unknown': ["An error occurred.", TypeError]
    }

    if status != 1 and not full_output:
        if status in [2, 3, 4, 5]:
            msg = errors[status][0]
            warnings.warn(msg, RuntimeWarning)
        else:
            try:
                raise errors[status][1](errors[status][0])
            except KeyError:
                raise errors['unknown'][1](errors['unknown'][0])

    info = retval[1]
    info['fun'] = info.pop('fvec')
    sol = Result(x=x, success=(status == 1), status=status)
    sol.update(info)
    try:
        sol['message'] = errors[status][0]
    except KeyError:
        info['message'] = errors['unknown'][0]

    return sol
Beispiel #7
0
def root(fun, x0, args=(), method="hybr", jac=None, options=None, callback=None):
    """
    Find a root of a vector function.

    .. versionadded:: 0.11.0

    Parameters
    ----------
    fun : callable
        A vector function to find a root of.
    x0 : ndarray
        Initial guess.
    args : tuple, optional
        Extra arguments passed to the objective function and its Jacobian.
    method : str, optional
        Type of solver.  Should be one of

            - 'hybr'
            - 'lm'
            - 'broyden1'
            - 'broyden2'
            - 'anderson'
            - 'linearmixing'
            - 'diagbroyden'
            - 'excitingmixing'
            - 'krylov'

    jac : bool or callable, optional
        If `jac` is a Boolean and is True, `fun` is assumed to return the
        value of Jacobian along with the objective function. If False, the
        Jacobian will be estimated numerically.
        `jac` can also be a callable returning the Jacobian of `fun`. In
        this case, it must accept the same arguments as `fun`.
    options : dict, optional
        A dictionary of solver options. E.g. `xtol` or `maxiter`, see
        ``show_options('root', method)`` for details.
    callback : function, optional
        Optional callback function. It is called on every iteration as
        ``callback(x, f)`` where `x` is the current solution and `f`
        the corresponding residual. For all methods but 'hybr' and 'lm'.

    Returns
    -------
    sol : Result
        The solution represented as a ``Result`` object.
        Important attributes are: ``x`` the solution array, ``success`` a
        Boolean flag indicating if the algorithm exited successfully and
        ``message`` which describes the cause of the termination. See
        `Result` for a description of other attributes.

    Notes
    -----
    This section describes the available solvers that can be selected by the
    'method' parameter. The default method is *hybr*.

    Method *hybr* uses a modification of the Powell hybrid method as
    implemented in MINPACK [1]_.

    Method *lm* solves the system of nonlinear equations in a least squares
    sense using a modification of the Levenberg-Marquardt algorithm as
    implemented in MINPACK [1]_.

    Methods *broyden1*, *broyden2*, *anderson*, *linearmixing*,
    *diagbroyden*, *excitingmixing*, *krylov* are inexact Newton methods,
    with backtracking or full line searches [2]_. Each method corresponds
    to a particular Jacobian approximations. See `nonlin` for details.

    - Method *broyden1* uses Broyden's first Jacobian approximation, it is
      known as Broyden's good method.
    - Method *broyden2* uses Broyden's second Jacobian approximation, it
      is known as Broyden's bad method.
    - Method *anderson* uses (extended) Anderson mixing.
    - Method *Krylov* uses Krylov approximation for inverse Jacobian. It
      is suitable for large-scale problem.
    - Method *diagbroyden* uses diagonal Broyden Jacobian approximation.
    - Method *linearmixing* uses a scalar Jacobian approximation.
    - Method *excitingmixing* uses a tuned diagonal Jacobian
      approximation.

    .. warning::

        The algorithms implemented for methods *diagbroyden*,
        *linearmixing* and *excitingmixing* may be useful for specific
        problems, but whether they will work may depend strongly on the
        problem.

    References
    ----------
    .. [1] More, Jorge J., Burton S. Garbow, and Kenneth E. Hillstrom.
       1980. User Guide for MINPACK-1.
    .. [2] C. T. Kelley. 1995. Iterative Methods for Linear and Nonlinear
        Equations. Society for Industrial and Applied Mathematics.
        <http://www.siam.org/books/kelley/>

    Examples
    --------
    The following functions define a system of nonlinear equations and its
    jacobian.

    >>> def fun(x):
    ...     return [x[0]  + 0.5 * (x[0] - x[1])**3 - 1.0,
    ...             0.5 * (x[1] - x[0])**3 + x[1]]

    >>> def jac(x):
    ...     return np.array([[1 + 1.5 * (x[0] - x[1])**2,
    ...                       -1.5 * (x[0] - x[1])**2],
    ...                      [-1.5 * (x[1] - x[0])**2,
    ...                       1 + 1.5 * (x[1] - x[0])**2]])

    A solution can be obtained as follows.

    >>> from scipy import optimize
    >>> sol = optimize.root(fun, [0, 0], jac=jac, method='hybr')
    >>> sol.x
    array([ 0.8411639,  0.1588361])
    """
    meth = method.lower()
    if options is None:
        options = {}

    if callback is not None and meth in ("hybr", "lm"):
        warn("Method %s does not accept callback." % method, RuntimeWarning)

    # fun also returns the jacobian
    if not callable(jac) and meth in ("hybr", "lm"):
        if bool(jac):
            fun = MemoizeJac(fun)
            jac = fun.derivative
        else:
            jac = None

    if meth == "hybr":
        sol = _root_hybr(fun, x0, args=args, jac=jac, options=options)
    elif meth == "lm":
        col_deriv = options.get("col_deriv", 0)
        xtol = options.get("xtol", 1.49012e-08)
        ftol = options.get("ftol", 1.49012e-08)
        gtol = options.get("gtol", 0.0)
        maxfev = options.get("maxfev", 0)
        epsfcn = options.get("epsfcn", 0.0)
        factor = options.get("factor", 100)
        diag = options.get("diag", None)
        x, cov_x, info, msg, ier = leastsq(
            fun,
            x0,
            args=args,
            Dfun=jac,
            full_output=True,
            col_deriv=col_deriv,
            xtol=xtol,
            ftol=ftol,
            gtol=gtol,
            maxfev=maxfev,
            epsfcn=epsfcn,
            factor=factor,
            diag=diag,
        )
        sol = Result(x=x, message=msg, status=ier, success=ier in (1, 2, 3, 4), cov_x=cov_x, fun=info.pop("fvec"))
        sol.update(info)
    elif meth in ("broyden1", "broyden2", "anderson", "linearmixing", "diagbroyden", "excitingmixing", "krylov"):
        if jac is not None:
            warn("Method %s does not use the jacobian (jac)." % method, RuntimeWarning)

        jacobian = {
            "broyden1": nonlin.BroydenFirst,
            "broyden2": nonlin.BroydenSecond,
            "anderson": nonlin.Anderson,
            "linearmixing": nonlin.LinearMixing,
            "diagbroyden": nonlin.DiagBroyden,
            "excitingmixing": nonlin.ExcitingMixing,
            "krylov": nonlin.KrylovJacobian,
        }[meth]

        nit = options.get("nit")
        verbose = options.get("disp", False)
        maxiter = options.get("maxiter")
        f_tol = options.get("ftol")
        f_rtol = options.get("frtol")
        x_tol = options.get("xtol")
        x_rtol = options.get("xrtol")
        tol_norm = options.get("tol_norm")
        line_search = options.get("line_search", "armijo")

        jac_opts = options.get("jac_options", dict())

        if args:

            def f(x):
                if jac == True:
                    r = fun(x, *args)[0]
                else:
                    r = fun(x, *args)
                return r

        else:
            f = fun

        x, info = nonlin.nonlin_solve(
            f,
            x0,
            jacobian=jacobian(**jac_opts),
            iter=nit,
            verbose=verbose,
            maxiter=maxiter,
            f_tol=f_tol,
            f_rtol=f_rtol,
            x_tol=x_tol,
            x_rtol=x_rtol,
            tol_norm=tol_norm,
            line_search=line_search,
            callback=callback,
            full_output=True,
            raise_exception=False,
        )
        sol = Result(x=x)
        sol.update(info)
    else:
        raise ValueError("Unknown solver %s" % method)

    return sol
Beispiel #8
0
def root(fun,
         x0,
         args=(),
         method='hybr',
         jac=None,
         options=None,
         callback=None):
    """
    Find a root of a vector function.

    .. versionadded:: 0.11.0

    Parameters
    ----------
    fun : callable
        A vector function to find a root of.
    x0 : ndarray
        Initial guess.
    args : tuple, optional
        Extra arguments passed to the objective function and its Jacobian.
    method : str, optional
        Type of solver.  Should be one of

            - 'hybr'
            - 'lm'
            - 'broyden1'
            - 'broyden2'
            - 'anderson'
            - 'linearmixing'
            - 'diagbroyden'
            - 'excitingmixing'
            - 'krylov'

    jac : bool or callable, optional
        If `jac` is a Boolean and is True, `fun` is assumed to return the
        value of Jacobian along with the objective function. If False, the
        Jacobian will be estimated numerically.
        `jac` can also be a callable returning the Jacobian of `fun`. In
        this case, it must accept the same arguments as `fun`.
    options : dict, optional
        A dictionary of solver options. E.g. `xtol` or `maxiter`, see
        ``show_options('root', method)`` for details.
    callback : function, optional
        Optional callback function. It is called on every iteration as
        ``callback(x, f)`` where `x` is the current solution and `f`
        the corresponding residual. For all methods but 'hybr' and 'lm'.

    Returns
    -------
    sol : Result
        The solution represented as a ``Result`` object.
        Important attributes are: ``x`` the solution array, ``success`` a
        Boolean flag indicating if the algorithm exited successfully and
        ``message`` which describes the cause of the termination. See
        `Result` for a description of other attributes.

    Notes
    -----
    This section describes the available solvers that can be selected by the
    'method' parameter. The default method is *hybr*.

    Method *hybr* uses a modification of the Powell hybrid method as
    implemented in MINPACK [1]_.

    Method *lm* solves the system of nonlinear equations in a least squares
    sense using a modification of the Levenberg-Marquardt algorithm as
    implemented in MINPACK [1]_.

    Methods *broyden1*, *broyden2*, *anderson*, *linearmixing*,
    *diagbroyden*, *excitingmixing*, *krylov* are inexact Newton methods,
    with backtracking or full line searches [2]_. Each method corresponds
    to a particular Jacobian approximations. See `nonlin` for details.

    - Method *broyden1* uses Broyden's first Jacobian approximation, it is
      known as Broyden's good method.
    - Method *broyden2* uses Broyden's second Jacobian approximation, it
      is known as Broyden's bad method.
    - Method *anderson* uses (extended) Anderson mixing.
    - Method *Krylov* uses Krylov approximation for inverse Jacobian. It
      is suitable for large-scale problem.
    - Method *diagbroyden* uses diagonal Broyden Jacobian approximation.
    - Method *linearmixing* uses a scalar Jacobian approximation.
    - Method *excitingmixing* uses a tuned diagonal Jacobian
      approximation.

    .. warning::

        The algorithms implemented for methods *diagbroyden*,
        *linearmixing* and *excitingmixing* may be useful for specific
        problems, but whether they will work may depend strongly on the
        problem.

    References
    ----------
    .. [1] More, Jorge J., Burton S. Garbow, and Kenneth E. Hillstrom.
       1980. User Guide for MINPACK-1.
    .. [2] C. T. Kelley. 1995. Iterative Methods for Linear and Nonlinear
        Equations. Society for Industrial and Applied Mathematics.
        <http://www.siam.org/books/kelley/>

    Examples
    --------
    The following functions define a system of nonlinear equations and its
    jacobian.

    >>> def fun(x):
    ...     return [x[0]  + 0.5 * (x[0] - x[1])**3 - 1.0,
    ...             0.5 * (x[1] - x[0])**3 + x[1]]

    >>> def jac(x):
    ...     return np.array([[1 + 1.5 * (x[0] - x[1])**2,
    ...                       -1.5 * (x[0] - x[1])**2],
    ...                      [-1.5 * (x[1] - x[0])**2,
    ...                       1 + 1.5 * (x[1] - x[0])**2]])

    A solution can be obtained as follows.

    >>> from scipy import optimize
    >>> sol = optimize.root(fun, [0, 0], jac=jac, method='hybr')
    >>> sol.x
    array([ 0.8411639,  0.1588361])
    """
    meth = method.lower()
    if options is None:
        options = {}

    if callback is not None and meth in ('hybr', 'lm'):
        warn('Method %s does not accept callback.' % method, RuntimeWarning)

    # fun also returns the jacobian
    if not callable(jac) and meth in ('hybr', 'lm'):
        if bool(jac):
            fun = MemoizeJac(fun)
            jac = fun.derivative
        else:
            jac = None

    if meth == 'hybr':
        sol = _root_hybr(fun, x0, args=args, jac=jac, options=options)
    elif meth == 'lm':
        col_deriv = options.get('col_deriv', 0)
        xtol = options.get('xtol', 1.49012e-08)
        ftol = options.get('ftol', 1.49012e-08)
        gtol = options.get('gtol', 0.0)
        maxfev = options.get('maxfev', 0)
        epsfcn = options.get('epsfcn', 0.0)
        factor = options.get('factor', 100)
        diag = options.get('diag', None)
        x, cov_x, info, msg, ier = leastsq(fun,
                                           x0,
                                           args=args,
                                           Dfun=jac,
                                           full_output=True,
                                           col_deriv=col_deriv,
                                           xtol=xtol,
                                           ftol=ftol,
                                           gtol=gtol,
                                           maxfev=maxfev,
                                           epsfcn=epsfcn,
                                           factor=factor,
                                           diag=diag)
        sol = Result(x=x,
                     message=msg,
                     status=ier,
                     success=ier in (1, 2, 3, 4),
                     cov_x=cov_x,
                     fun=info.pop('fvec'))
        sol.update(info)
    elif meth in ('broyden1', 'broyden2', 'anderson', 'linearmixing',
                  'diagbroyden', 'excitingmixing', 'krylov'):
        if jac is not None:
            warn('Method %s does not use the jacobian (jac).' % method,
                 RuntimeWarning)

        jacobian = {
            'broyden1': nonlin.BroydenFirst,
            'broyden2': nonlin.BroydenSecond,
            'anderson': nonlin.Anderson,
            'linearmixing': nonlin.LinearMixing,
            'diagbroyden': nonlin.DiagBroyden,
            'excitingmixing': nonlin.ExcitingMixing,
            'krylov': nonlin.KrylovJacobian
        }[meth]

        nit = options.get('nit')
        verbose = options.get('disp', False)
        maxiter = options.get('maxiter')
        f_tol = options.get('ftol')
        f_rtol = options.get('frtol')
        x_tol = options.get('xtol')
        x_rtol = options.get('xrtol')
        tol_norm = options.get('tol_norm')
        line_search = options.get('line_search', 'armijo')

        jac_opts = options.get('jac_options', dict())

        if args:

            def f(x):
                if jac == True:
                    r = fun(x, *args)[0]
                else:
                    r = fun(x, *args)
                return r
        else:
            f = fun

        x, info = nonlin.nonlin_solve(f,
                                      x0,
                                      jacobian=jacobian(**jac_opts),
                                      iter=nit,
                                      verbose=verbose,
                                      maxiter=maxiter,
                                      f_tol=f_tol,
                                      f_rtol=f_rtol,
                                      x_tol=x_tol,
                                      x_rtol=x_rtol,
                                      tol_norm=tol_norm,
                                      line_search=line_search,
                                      callback=callback,
                                      full_output=True,
                                      raise_exception=False)
        sol = Result(x=x)
        sol.update(info)
    else:
        raise ValueError('Unknown solver %s' % method)

    return sol