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 _minimize_anneal(func,
                     x0,
                     args=(),
                     schedule='fast',
                     T0=None,
                     Tf=1e-12,
                     maxfev=None,
                     maxaccept=None,
                     maxiter=400,
                     boltzmann=1.0,
                     learn_rate=0.5,
                     ftol=1e-6,
                     quench=1.0,
                     m=1.0,
                     n=1.0,
                     lower=-100,
                     upper=100,
                     dwell=50,
                     disp=False,
                     **unknown_options):
    """
    Minimization of scalar function of one or more variables using the
    simulated annealing algorithm.

    Options for the simulated annealing algorithm are:
        disp : bool
            Set to True to print convergence messages.
        schedule : str
            Annealing schedule to use. One of: 'fast', 'cauchy' or
            'boltzmann'.
        T0 : float
            Initial Temperature (estimated as 1.2 times the largest
            cost-function deviation over random points in the range).
        Tf : float
            Final goal temperature.
        maxfev : int
            Maximum number of function evaluations to make.
        maxaccept : int
            Maximum changes to accept.
        maxiter : int
            Maximum number of iterations to perform.
        boltzmann : float
            Boltzmann constant in acceptance test (increase for less
            stringent test at each temperature).
        learn_rate : float
            Scale constant for adjusting guesses.
        ftol : float
            Relative error in ``fun(x)`` acceptable for convergence.
        quench, m, n : float
            Parameters to alter fast_sa schedule.
        lower, upper : float or ndarray
            Lower and upper bounds on `x`.
        dwell : int
            The number of times to search the space at each temperature.

    This function is called by the `minimize` function with
    `method=anneal`. It is not supposed to be called directly.
    """
    _check_unknown_options(unknown_options)
    maxeval = maxfev
    feps = ftol

    x0 = asarray(x0)
    lower = asarray(lower)
    upper = asarray(upper)

    schedule = eval(schedule + '_sa()')
    #   initialize the schedule
    schedule.init(dims=shape(x0),
                  func=func,
                  args=args,
                  boltzmann=boltzmann,
                  T0=T0,
                  learn_rate=learn_rate,
                  lower=lower,
                  upper=upper,
                  m=m,
                  n=n,
                  quench=quench,
                  dwell=dwell)

    current_state, last_state, best_state = _state(), _state(), _state()
    if T0 is None:
        x0 = schedule.getstart_temp(best_state)
    else:
        best_state.x = None
        best_state.cost = numpy.Inf

    last_state.x = asarray(x0).copy()
    fval = func(x0, *args)
    schedule.feval += 1
    last_state.cost = fval
    if last_state.cost < best_state.cost:
        best_state.cost = fval
        best_state.x = asarray(x0).copy()
    schedule.T = schedule.T0
    fqueue = [100, 300, 500, 700]
    iters = 0
    while 1:
        for n in xrange(dwell):
            current_state.x = schedule.update_guess(last_state.x)
            current_state.cost = func(current_state.x, *args)
            schedule.feval += 1

            dE = current_state.cost - last_state.cost
            if schedule.accept_test(dE):
                last_state.x = current_state.x.copy()
                last_state.cost = current_state.cost
                if last_state.cost < best_state.cost:
                    best_state.x = last_state.x.copy()
                    best_state.cost = last_state.cost
        schedule.update_temp()
        iters += 1
        # Stopping conditions
        # 0) last saved values of f from each cooling step
        #     are all very similar (effectively cooled)
        # 1) Tf is set and we are below it
        # 2) maxeval is set and we are past it
        # 3) maxiter is set and we are past it
        # 4) maxaccept is set and we are past it

        fqueue.append(squeeze(last_state.cost))
        fqueue.pop(0)
        af = asarray(fqueue) * 1.0
        if all(abs((af - af[0]) / af[0]) < feps):
            retval = 0
            if abs(af[-1] - best_state.cost) > feps * 10:
                retval = 5
                if disp:
                    print "Warning: Cooled to %f at %s but this is not" \
                          % (squeeze(last_state.cost),
                             str(squeeze(last_state.x))) \
                          + " the smallest point found."
            break
        if (Tf is not None) and (schedule.T < Tf):
            retval = 1
            break
        if (maxeval is not None) and (schedule.feval > maxeval):
            retval = 2
            break
        if (iters > maxiter):
            if disp:
                print "Warning: Maximum number of iterations exceeded."
            retval = 3
            break
        if (maxaccept is not None) and (schedule.accepted > maxaccept):
            retval = 4
            break

    result = Result(x=best_state.x,
                    fun=best_state.cost,
                    T=schedule.T,
                    nfev=schedule.feval,
                    nit=iters,
                    accept=schedule.accepted,
                    status=retval,
                    success=(retval <= 1),
                    message={
                        0:
                        'Points no longer changing',
                        1:
                        'Cooled to final temperature',
                        2:
                        'Maximum function evaluations',
                        3:
                        'Maximum cooling iterations reached',
                        4:
                        'Maximum accepted query locations reached',
                        5:
                        'Final point not the minimum amongst '
                        'encountered points'
                    }[retval])
    return result
Beispiel #5
0
def _minimize_tnc(fun, x0, args=(), jac=None, bounds=None, options=None):
    """
    Minimize a scalar function of one or more variables using a truncated
    Newton (TNC) algorithm.

    Options for the TNC algorithm are:
        eps: float
            Step size used for numerical approximation of the jacobian.
        scale : list of floats
            Scaling factors to apply to each variable.  If None, the
            factors are up-low for interval bounded variables and
            1+|x] fo the others.  Defaults to None
        offset : float
            Value to substract from each variable.  If None, the
            offsets are (up+low)/2 for interval bounded variables
            and x for the others.
        disp : bool
           Set to True to print convergence messages.
        maxCGit : int
            Maximum number of hessian*vector evaluations per main
            iteration.  If maxCGit == 0, the direction chosen is
            -gradient if maxCGit < 0, maxCGit is set to
            max(1,min(50,n/2)).  Defaults to -1.
        maxfev : int
            Maximum number of function evaluation.  if None, `maxfev` is
            set to max(100, 10*len(x0)).  Defaults to None.
        eta : float
            Severity of the line search. if < 0 or > 1, set to 0.25.
            Defaults to -1.
        stepmx : float
            Maximum step for the line search.  May be increased during
            call.  If too small, it will be set to 10.0.  Defaults to 0.
        accuracy : float
            Relative precision for finite difference calculations.  If
            <= machine_precision, set to sqrt(machine_precision).
            Defaults to 0.
        minfev : float
            Minimum function value estimate.  Defaults to 0.
        ftol : float
            Precision goal for the value of f in the stoping criterion.
            If ftol < 0.0, ftol is set to 0.0 defaults to -1.
        xtol : float
            Precision goal for the value of x in the stopping
            criterion (after applying x scaling factors).  If xtol <
            0.0, xtol is set to sqrt(machine_precision).  Defaults to
            -1.
        pgtol : float
            Precision goal for the value of the projected gradient in
            the stopping criterion (after applying x scaling factors).
            If pgtol < 0.0, pgtol is set to 1e-2 * sqrt(accuracy).
            Setting it to 0.0 is not recommended.  Defaults to -1.
        rescale : float
            Scaling factor (in log10) used to trigger f value
            rescaling.  If 0, rescale at each iteration.  If a large
            value, never rescale.  If < 0, rescale is set to 1.3.

    This function is called by the `minimize` function with `method=TNC`.
    It is not supposed to be called directly.
    """
    if options is None:
        options = {}
    # retrieve useful options
    epsilon  = options.get('eps', 1e-8)
    scale    = options.get('scale')
    offset   = options.get('offset')
    mesg_num = options.get('mesg_num')
    maxCGit  = options.get('maxCGit', -1)
    maxfun   = options.get('maxfev')
    eta      = options.get('eta', -1)
    stepmx   = options.get('stepmx', 0)
    accuracy = options.get('accuracy', 0)
    fmin     = options.get('minfev', 0)
    ftol     = options.get('ftol', -1)
    xtol     = options.get('xtol', -1)
    pgtol    = options.get('pgtol', -1)
    rescale  = options.get('rescale', -1)
    disp     = options.get('disp', False)

    x0 = asarray(x0, dtype=float).tolist()
    n = len(x0)

    if bounds is None:
        bounds = [(None,None)] * n
    if len(bounds) != n:
        raise ValueError('length of x0 != length of bounds')

    if mesg_num is not None:
        messages = {0:MSG_NONE, 1:MSG_ITER, 2:MSG_INFO, 3:MSG_VERS,
                    4:MSG_EXIT, 5:MSG_ALL}.get(mesg_num, MSG_ALL)
    elif disp:
        messages = MSG_ALL
    else:
        messages = MSG_NONE

    if jac is None:
        def func_and_grad(x):
            x = asarray(x)
            f = fun(x, *args)
            g = approx_fprime(x, fun, epsilon, *args)
            return f, list(g)
    else:
        def func_and_grad(x):
            x = asarray(x)
            f = fun(x, *args)
            g = jac(x, *args)
            return f, list(g)

    """
    low, up   : the bounds (lists of floats)
                if low is None, the lower bounds are removed.
                if up is None, the upper bounds are removed.
                low and up defaults to None
    """
    low = [0]*n
    up = [0]*n
    for i in range(n):
        if bounds[i] is None: l, u = -inf, inf
        else:
            l,u = bounds[i]
            if l is None:
                low[i] = -inf
            else:
                low[i] = l
            if u is None:
                up[i] = inf
            else:
                up[i] = u

    if scale is None:
        scale = []

    if offset is None:
        offset = []

    if maxfun is None:
        maxfun = max(100, 10*len(x0))

    rc, nf, x = moduleTNC.minimize(func_and_grad, x0, low, up, scale, offset,
            messages, maxCGit, maxfun, eta, stepmx, accuracy,
            fmin, ftol, xtol, pgtol, rescale)

    xopt = array(x)
    funv, jacv = func_and_grad(xopt)

    return Result(x=xopt, fun=funv, jac=jacv, nfev=nf, status=rc,
                  message=RCSTRINGS[rc], success=(-1 < rc < 3))
Beispiel #6
0
def _minimize_cobyla(fun, x0, args=(), constraints=(), options=None):
    """
    Minimize a scalar function of one or more variables using the
    Constrained Optimization BY Linear Approximation (COBYLA) algorithm.

    Options for the COBYLA algorithm are:
        rhobeg : float
            Reasonable initial changes to the variables.
        rhoend : float
            Final accuracy in the optimization (not precisely guaranteed).
            This is a lower bound on the size of the trust region.
        disp : bool
            Set to True to print convergence messages. If False,
            `verbosity` is ignored as set to 0.
        maxfev : int
            Maximum number of function evaluations.

    This function is called by the `minimize` function with
    `method=COBYLA`. It is not supposed to be called directly.
    """
    if options is None:
        options = {}
    # retrieve useful options
    rhobeg = options.get('rhobeg', 1.0)
    rhoend = options.get('rhoend', 1e-4)
    iprint = options.get('iprint', 1)
    maxfun = options.get('maxfev', 1000)
    disp = options.get('disp', False)

    if not disp:
        iprint = 0

    # check constraints
    if isinstance(constraints, dict):
        constraints = (constraints, )

    for ic, con in enumerate(constraints):
        # check type
        try:
            ctype = con['type'].lower()
        except KeyError:
            raise KeyError('Constraint %d has no type defined.' % ic)
        except TypeError:
            raise TypeError('Constraints must be defined using a '
                            'dictionary.')
        except AttributeError:
            raise TypeError("Constraint's type must be a string.")
        else:
            if ctype != 'ineq':
                raise ValueError("Constraints of type '%s' not handled by "
                                 "COBYLA." % con['type'])

        # check function
        if 'fun' not in con:
            raise KeyError('Constraint %d has no function defined.' % ic)

        # check extra arguments
        if 'args' not in con:
            con['args'] = ()

    m = len(constraints)

    def calcfc(x, con):
        f = fun(x, *args)
        for k, c in enumerate(constraints):
            con[k] = c['fun'](x, *c['args'])
        return f

    xopt = _cobyla.minimize(calcfc,
                            m=m,
                            x=copy(x0),
                            rhobeg=rhobeg,
                            rhoend=rhoend,
                            iprint=iprint,
                            maxfun=maxfun)

    return Result(x=xopt)
Beispiel #7
0
def _minimize_slsqp(func, x0, args=(), jac=None, bounds=None,
                    constraints=(),
                    maxiter=100, ftol=1.0E-6, iprint=1, disp=False,
                    eps=_epsilon,
                    **unknown_options):
    """
    Minimize a scalar function of one or more variables using Sequential
    Least SQuares Programming (SLSQP).

    Options for the SLSQP algorithm are:
        ftol : float
            Precision goal for the value of f in the stopping criterion.
        eps : float
            Step size used for numerical approximation of the jacobian.
        disp : bool
            Set to True to print convergence messages. If False,
            `verbosity` is ignored and set to 0.
        maxiter : int
            Maximum number of iterations.

    This function is called by the `minimize` function with
    `method=SLSQP`. It is not supposed to be called directly.
    """
    _check_unknown_options(unknown_options)
    fprime = jac
    iter = maxiter
    acc = ftol
    epsilon = eps

    if not disp:
        iprint = 0

    # Constraints are triaged per type into a dictionnary of tuples
    if isinstance(constraints, dict):
        constraints = (constraints, )

    cons = {'eq': (), 'ineq': ()}
    for ic, con in enumerate(constraints):
        # check type
        try:
            ctype = con['type'].lower()
        except KeyError:
            raise KeyError('Constraint %d has no type defined.' % ic)
        except TypeError:
            raise TypeError('Constraints must be defined using a '
                            'dictionary.')
        except AttributeError:
            raise TypeError("Constraint's type must be a string.")
        else:
            if ctype not in ['eq', 'ineq']:
                raise ValueError("Unknown constraint type '%s'." % con['type'])

        # check function
        if 'fun' not in con:
            raise ValueError('Constraint %d has no function defined.' % ic)

        # check jacobian
        cjac = con.get('jac')
        if cjac is None:
            # approximate jacobian function
            def cjac(x, *args):
                return approx_jacobian(x, con['fun'], epsilon, *args)

        # update constraints' dictionary
        cons[ctype] += ({'fun' : con['fun'],
                         'jac' : cjac,
                         'args': con.get('args', ())}, )


    exit_modes = { -1 : "Gradient evaluation required (g & a)",
                    0 : "Optimization terminated successfully.",
                    1 : "Function evaluation required (f & c)",
                    2 : "More equality constraints than independent variables",
                    3 : "More than 3*n iterations in LSQ subproblem",
                    4 : "Inequality constraints incompatible",
                    5 : "Singular matrix E in LSQ subproblem",
                    6 : "Singular matrix C in LSQ subproblem",
                    7 : "Rank-deficient equality constraint subproblem HFTI",
                    8 : "Positive directional derivative for linesearch",
                    9 : "Iteration limit exceeded" }


    # Wrap func
    feval, func = wrap_function(func, args)

    # Wrap fprime, if provided, or approx_jacobian if not
    if fprime:
        geval, fprime = wrap_function(fprime, args)
    else:
        geval, fprime = wrap_function(approx_jacobian, (func, epsilon))

    # Transform x0 into an array.
    x = asfarray(x0).flatten()


    # Set the parameters that SLSQP will need
    # meq, mieq: number of equality and inequality constraints
    meq = sum(map(len, [atleast_1d(c['fun'](x, *c['args'])) for c in cons['eq']]))
    mieq = sum(map(len, [atleast_1d(c['fun'](x, *c['args'])) for c in cons['ineq']]))
    # m = The total number of constraints
    m = meq + mieq
    # la = The number of constraints, or 1 if there are no constraints
    la = array([1,m]).max()
    # n = The number of independent variables
    n = len(x)

    # Define the workspaces for SLSQP
    n1 = n+1
    mineq = m - meq + n1 + n1
    len_w = (3*n1+m)*(n1+1)+(n1-meq+1)*(mineq+2) + 2*mineq+(n1+mineq)*(n1-meq) \
            + 2*meq + n1 +(n+1)*n/2 + 2*m + 3*n + 3*n1 + 1
    len_jw = mineq
    w = zeros(len_w)
    jw = zeros(len_jw)

    # Decompose bounds into xl and xu
    if bounds is None or len(bounds) == 0:
        xl, xu = array([-1.0E12]*n), array([1.0E12]*n)
    else:
        bnds = array(bounds, float)
        if bnds.shape[0] != n:
            raise IndexError('SLSQP Error: the length of bounds is not '
                             'compatible with that of x0.')

        bnderr = where(bnds[:, 0] > bnds[:, 1])[0]
        if bnderr.any():
            raise ValueError('SLSQP Error: lb > ub in bounds %s.' %
                             ', '.join(str(b) for b in bnderr))
        xl, xu = bnds[:, 0], bnds[:, 1]

        # filter -inf and inf values
        infbnd = isinf(bnds)
        xl[infbnd[:, 0]] = -1.0E12
        xu[infbnd[:, 1]] = 1.0E12

    # Initialize the iteration counter and the mode value
    mode = array(0,int)
    acc = array(acc,float)
    majiter = array(iter,int)
    majiter_prev = 0

    # Print the header if iprint >= 2
    if iprint >= 2:
        print "%5s %5s %16s %16s" % ("NIT","FC","OBJFUN","GNORM")

    while 1:

        if mode == 0 or mode == 1: # objective and constraint evaluation requird

            # Compute objective function
            fx = func(x)
            # Compute the constraints
            if cons['eq']:
                c_eq  = concatenate([atleast_1d(con['fun'](x, *con['args']))
                                     for con in cons['eq']])
            else:
                c_eq = zeros(0)
            if cons['ineq']:
                c_ieq = concatenate([atleast_1d(con['fun'](x, *con['args']))
                                     for con in cons['ineq']])
            else:
                c_ieq = zeros(0)

            # Now combine c_eq and c_ieq into a single matrix
            c = concatenate((c_eq, c_ieq))

        if mode == 0 or mode == -1: # gradient evaluation required

            # Compute the derivatives of the objective function
            # For some reason SLSQP wants g dimensioned to n+1
            g = append(fprime(x),0.0)

            # Compute the normals of the constraints
            if cons['eq']:
                a_eq = vstack([con['jac'](x, *con['args'])
                               for con in cons['eq']])
            else: # no equality constraint
                a_eq = zeros((meq, n))

            if cons['ineq']:
                a_ieq = vstack([con['jac'](x, *con['args'])
                                for con in cons['ineq']])
            else: # no inequality constraint
                a_ieq = zeros((mieq, n))

            # Now combine a_eq and a_ieq into a single a matrix
            if m == 0: # no constraints
                a = zeros((la, n))
            else:
                a = vstack((a_eq, a_ieq))
            a = concatenate((a,zeros([la,1])),1)

        # Call SLSQP
        slsqp(m, meq, x, xl, xu, fx, c, g, a, acc, majiter, mode, w, jw)

        # Print the status of the current iterate if iprint > 2 and the
        # major iteration has incremented
        if iprint >= 2 and majiter > majiter_prev:
            print "%5i %5i % 16.6E % 16.6E" % (majiter,feval[0],
                                               fx,linalg.norm(g))

        # If exit mode is not -1 or 1, slsqp has completed
        if abs(mode) != 1:
            break

        majiter_prev = int(majiter)

    # Optimization loop complete.  Print status if requested
    if iprint >= 1:
        print exit_modes[int(mode)] + "    (Exit mode " + str(mode) + ')'
        print "            Current function value:", fx
        print "            Iterations:", majiter
        print "            Function evaluations:", feval[0]
        print "            Gradient evaluations:", geval[0]

    return Result(x=x, fun=fx, jac=g, nit=int(majiter), nfev=feval[0],
                  njev=geval[0], status=int(mode),
                  message=exit_modes[int(mode)], success=(mode == 0))
Beispiel #8
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 #9
0
def _minimize_cobyla(fun,
                     x0,
                     args=(),
                     constraints=(),
                     rhobeg=1.0,
                     tol=1e-4,
                     iprint=1,
                     maxiter=1000,
                     disp=False,
                     **unknown_options):
    """
    Minimize a scalar function of one or more variables using the
    Constrained Optimization BY Linear Approximation (COBYLA) algorithm.

    Options for the COBYLA algorithm are:
        rhobeg : float
            Reasonable initial changes to the variables.
        tol : float
            Final accuracy in the optimization (not precisely guaranteed).
            This is a lower bound on the size of the trust region.
        disp : bool
            Set to True to print convergence messages. If False,
            `verbosity` is ignored as set to 0.
        maxiter : int
            Maximum number of function evaluations.

    This function is called by the `minimize` function with
    `method=COBYLA`. It is not supposed to be called directly.
    """
    _check_unknown_options(unknown_options)
    maxfun = maxiter
    rhoend = tol
    if not disp:
        iprint = 0

    # check constraints
    if isinstance(constraints, dict):
        constraints = (constraints, )

    for ic, con in enumerate(constraints):
        # check type
        try:
            ctype = con['type'].lower()
        except KeyError:
            raise KeyError('Constraint %d has no type defined.' % ic)
        except TypeError:
            raise TypeError('Constraints must be defined using a '
                            'dictionary.')
        except AttributeError:
            raise TypeError("Constraint's type must be a string.")
        else:
            if ctype != 'ineq':
                raise ValueError("Constraints of type '%s' not handled by "
                                 "COBYLA." % con['type'])

        # check function
        if 'fun' not in con:
            raise KeyError('Constraint %d has no function defined.' % ic)

        # check extra arguments
        if 'args' not in con:
            con['args'] = ()

    m = len(constraints)

    def calcfc(x, con):
        f = fun(x, *args)
        for k, c in enumerate(constraints):
            con[k] = c['fun'](x, *c['args'])
        return f

    info = np.zeros(4, np.float64)
    xopt, info = _cobyla.minimize(calcfc,
                                  m=m,
                                  x=np.copy(x0),
                                  rhobeg=rhobeg,
                                  rhoend=rhoend,
                                  iprint=iprint,
                                  maxfun=maxfun,
                                  dinfo=info)

    return Result(x=xopt,
                  status=int(info[0]),
                  success=info[0] == 1,
                  message={
                      1:
                      'Optimization terminated successfully.',
                      2:
                      'Maximum number of function evaluations has '
                      'been exceeded.',
                      3:
                      'Rounding errors are becoming damaging in '
                      'COBYLA subroutine.'
                  }.get(info[0], 'Unknown exit status.'),
                  nfev=int(info[1]),
                  fun=info[2],
                  maxcv=info[3])
Beispiel #10
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 #11
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 #12
0
def _minimize_lbfgsb(fun,
                     x0,
                     args=(),
                     jac=None,
                     bounds=None,
                     disp=None,
                     maxcor=10,
                     ftol=2.2204460492503131e-09,
                     gtol=1e-5,
                     eps=1e-8,
                     maxfun=15000,
                     maxiter=15000,
                     iprint=-1,
                     callback=None,
                     **unknown_options):
    """
    Minimize a scalar function of one or more variables using the L-BFGS-B
    algorithm.

    Options for the L-BFGS-B algorithm are:
        disp : bool
           Set to True to print convergence messages.
        maxcor : int
            The maximum number of variable metric corrections used to
            define the limited memory matrix. (The limited memory BFGS
            method does not store the full hessian but uses this many terms
            in an approximation to it.)
        factr : float
            The iteration stops when ``(f^k -
            f^{k+1})/max{|f^k|,|f^{k+1}|,1} <= factr * eps``, where ``eps``
            is the machine precision, which is automatically generated by
            the code. Typical values for `factr` are: 1e12 for low
            accuracy; 1e7 for moderate accuracy; 10.0 for extremely high
            accuracy.
        gtol : float
            The iteration will stop when ``max{|proj g_i | i = 1, ..., n}
            <= gtol`` where ``pg_i`` is the i-th component of the
            projected gradient.
        eps : float
            Step size used for numerical approximation of the jacobian.
        disp : int
            Set to True to print convergence messages.
        maxfun : int
            Maximum number of function evaluations.
        maxiter : int
            Maximum number of iterations.

    This function is called by the `minimize` function with
    `method=L-BFGS-B`. It is not supposed to be called directly.
    """
    _check_unknown_options(unknown_options)
    m = maxcor
    epsilon = eps
    pgtol = gtol
    factr = ftol / np.finfo(float).eps

    x0 = asarray(x0).ravel()
    n, = x0.shape

    if bounds is None:
        bounds = [(None, None)] * n
    if len(bounds) != n:
        raise ValueError('length of x0 != length of bounds')

    if disp is not None:
        if disp == 0:
            iprint = -1
        else:
            iprint = disp

    if jac is None:

        def func_and_grad(x):
            f = fun(x, *args)
            g = approx_fprime(x, fun, epsilon, *args)
            return f, g
    else:

        def func_and_grad(x):
            f = fun(x, *args)
            g = jac(x, *args)
            return f, g

    nbd = zeros(n, int32)
    low_bnd = zeros(n, float64)
    upper_bnd = zeros(n, float64)
    bounds_map = {(None, None): 0, (1, None): 1, (1, 1): 2, (None, 1): 3}
    for i in range(0, n):
        l, u = bounds[i]
        if l is not None:
            low_bnd[i] = l
            l = 1
        if u is not None:
            upper_bnd[i] = u
            u = 1
        nbd[i] = bounds_map[l, u]

    x = array(x0, float64)
    f = array(0.0, float64)
    g = zeros((n, ), float64)
    wa = zeros(2 * m * n + 5 * n + 11 * m * m + 8 * m, float64)
    iwa = zeros(3 * n, int32)
    task = zeros(1, 'S60')
    csave = zeros(1, 'S60')
    lsave = zeros(4, int32)
    isave = zeros(44, int32)
    dsave = zeros(29, float64)

    task[:] = 'START'

    n_function_evals = 0
    n_iterations = 0

    while 1:
        #        x, f, g, wa, iwa, task, csave, lsave, isave, dsave = \
        _lbfgsb.setulb(m, x, low_bnd, upper_bnd, nbd, f, g, factr, pgtol, wa,
                       iwa, task, iprint, csave, lsave, isave, dsave)
        task_str = task.tostring()
        if task_str.startswith(asbytes('FG')):
            if n_function_evals > maxfun:
                task[:] = 'STOP: TOTAL NO. of f AND g EVALUATIONS EXCEEDS LIMIT'
            else:
                # minimization routine wants f and g at the current x
                n_function_evals += 1
                # Overwrite f and g:
                f, g = func_and_grad(x)
        elif task_str.startswith(asbytes('NEW_X')):
            # new iteration
            if n_iterations > maxiter:
                task[:] = 'STOP: TOTAL NO. of ITERATIONS EXCEEDS LIMIT'
            else:
                n_iterations += 1
                if callback is not None:
                    callback(x)
        else:
            break

    task_str = task.tostring().strip(asbytes('\x00')).strip()
    if task_str.startswith(asbytes('CONV')):
        warnflag = 0
    elif n_function_evals > maxfun:
        warnflag = 1
    elif n_iterations > maxiter:
        warnflag = 1
    else:
        warnflag = 2

    return Result(fun=f,
                  jac=g,
                  nfev=n_function_evals,
                  nit=n_iterations,
                  status=warnflag,
                  message=task_str,
                  x=x,
                  success=(warnflag == 0))
Beispiel #13
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 #14
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