示例#1
0
def _line_search_wolfe12(f, fprime, xk, pk, gfk, old_fval, old_old_fval,
                         **kwargs):
    """
    Same as line_search_wolfe1, but fall back to line_search_wolfe2 if
    suitable step length is not found, and raise an exception if a
    suitable step length is not found.

    Raises
    ------
    _LineSearchError
        If no suitable step size is found

    """
    ret = line_search_wolfe1(f, fprime, xk, pk, gfk, old_fval, old_old_fval,
                             **kwargs)

    if ret[0] is None:
        # line search failed: try different one.
        ret = line_search_wolfe2(f, fprime, xk, pk, gfk, old_fval,
                                 old_old_fval, **kwargs)

    if ret[0] is None:
        raise _LineSearchError()

    return ret
    def test_line_search_wolfe1(self):
        c = 0
        smax = 100
        for name, f, fprime, x, p, old_f in self.line_iter():
            f0 = f(x)
            g0 = fprime(x)
            self.fcount = 0
            s, fc, gc, fv, ofv, gv = ls.line_search_wolfe1(f,
                                                           fprime,
                                                           x,
                                                           p,
                                                           g0,
                                                           f0,
                                                           old_f,
                                                           amax=smax)
            assert_equal(self.fcount, fc + gc)
            assert_fp_equal(ofv, f(x))
            if s is None:
                continue
            assert_fp_equal(fv, f(x + s * p))
            assert_array_almost_equal(gv, fprime(x + s * p), decimal=14)
            if s < smax:
                c += 1
                assert_line_wolfe(x, p, s, f, fprime, err_msg=name)

        assert_(c > 3)  # check that the iterator really works...
示例#3
0
def _line_search_wolfe12(f, fprime, xk, pk, gfk, old_fval, old_old_fval,
                         **kwargs):
    """
    Same as line_search_wolfe1, but fall back to line_search_wolfe2 if
    suitable step length is not found, and raise an exception if a
    suitable step length is not found.

    Raises
    ------
    _LineSearchError
        If no suitable step size is found

    """
    ret = line_search_wolfe1(f, fprime, xk, pk, gfk,
                             old_fval, old_old_fval,
                             **kwargs)

    if ret[0] is None:
        # line search failed: try different one.
        ret = line_search_wolfe2(f, fprime, xk, pk, gfk,
                                 old_fval, old_old_fval, **kwargs)

    if ret[0] is None:
        raise _LineSearchError()

    return ret
示例#4
0
def ls_wolfe12(f, fprime, xk, pk, gfk, old_fval, old_old_fval):
    """
    Same as line_search_wolfe1, but fall back to line_search_wolfe2 if
    suitable step length is not found, and raise an exception if a
    suitable step length is not found.
    Raises
    ------
    _LineSearchError
        If no suitable step size is found
    """

    ret = line_search_wolfe1(f, fprime, xk, pk, gfk, old_fval, old_old_fval)
    alpha = ret[0]

    if alpha is None or alpha < 1e-12:
        #print('A')
        # line search failed: try different one.
        ret = line_search_wolfe2(f, fprime, xk, pk, gfk, old_fval,
                                 old_old_fval)
        alpha = ret[0]

    if alpha is None or alpha < 1e-12:
        #print('B')
        ret = line_search_armijo(f, xk, pk, gfk, old_fval)
        alpha = ret[0]

    if alpha is None or alpha < 1e-12:
        #print('C')
        alpha = backtracking_line_search(f, gfk, xk, pk)

    return alpha
示例#5
0
def nonlinearConjugateGradient(func, grad, x0, tol=1e-6, maxIter=10000):
    '''
    func,grad: f(x),gf(x)=func(x),grad(x)
    x0: starting point of x
    tol: stop while the grad is less than tol
    maxIter: maximum iteration number
    
    return value:
    x: the optimized point of x
    
    line_search_wolfe1 is the wrap of minpack from scipy
    '''
    gf0=grad(x0)
    p0=-gf0
    iterNum=1
    while(norm(gf0)>tol):
        alpha=line_search_wolfe1(func, grad, x0, p0, c2=0.5)
        x0=x0+alpha*p0
        if iterNum==maxIter:
            return x0
        gf1=grad(x0)
        beta=(norm(gf1)/norm(gf0))**2
        p0=-gf1+beta*p0
        gf0=gf1
        iterNum=iterNum+1
    return x0
示例#6
0
def nonlinearConjugateGradient(func, grad, x0, tol=1e-6, maxIter=10000):
    '''
    func,grad: f(x),gf(x)=func(x),grad(x)
    x0: starting point of x
    tol: stop while the grad is less than tol
    maxIter: maximum iteration number
    
    return value:
    x: the optimized point of x
    
    line_search_wolfe1 is the wrap of minpack from scipy
    '''
    gf0 = grad(x0)
    p0 = -gf0
    iterNum = 1
    while (norm(gf0) > tol):
        alpha = line_search_wolfe1(func, grad, x0, p0, c2=0.5)
        x0 = x0 + alpha * p0
        if iterNum == maxIter:
            return x0
        gf1 = grad(x0)
        beta = (norm(gf1) / norm(gf0))**2
        p0 = -gf1 + beta * p0
        gf0 = gf1
        iterNum = iterNum + 1
    return x0
示例#7
0
文件: lmmdm.py 项目: mpharrigan/KDML
    def find_X(self, rho, X1):
        """Find X that maximizes the objective function at fixed rho"""

        objective = lambda X: self.minus_square_objective_and_grad(rho, as_matrix(X))[0]
        gradient = lambda X: as_vector(self.minus_square_objective_and_grad(rho, as_matrix(X))[2])
        as_vector = lambda X: np.reshape(np.array(X), self.dim * self.dim)
        as_matrix = lambda V: np.matrix(np.reshape(V, (self.dim, self.dim)))

        #print >> self.printer, 'alg2 starting', objective(X1)
        for i in range(self.num_inner):
            current_grad = as_matrix(gradient(X1))
            try:
                u, v = sparse_eigsh(-current_grad, k=1, which='LA')
            except Exception as e:
                print >> self.printer, 'Warning: Sparse solver failed'
                u, v = np.linalg.eigh(-current_grad)
            u = np.real(u)[0]

            v = np.matrix(np.real(v))
            p = (v * v.T - X1)

            if u < 0:
                #print >> self.printer, 'u < 0', u
                break

            try:
                u2, v2 = sparse_eigsh(X1, k=1, which='LM', sigma=1)
                #u2 = np.linalg.eigvals(X1)
            except NotImplementedError:
                warnings.warn("Warning: Your sparse eigensolver does not support shift-invert mode")
                u2, v2 = sparse_eigsh(X1, k=1, which='LM')
            except Exception as e:
                print >> self.printer, 'Warning: Sparse solver failed'
                u2 = np.linalg.eigvals(X1)


            u2 = np.real(u2)[0]
            if u2 > 1 + self.epsilon:
                print >> self.printer, 'u2 > 1', u2
                break

            stp, f_count, g_count, f_val, old_fval, gval = line_search_wolfe1(f=objective, fprime=gradient, xk=as_vector(X1), pk=as_vector(p))
            #print 'stp', stp
            if stp == None:
                #print >> self.printer, 'breaking for stp=None'
                break

            if np.abs((f_val - old_fval) / old_fval) < self.epsilon:
                #print >> self.printer, 'breaking for insufficient gain'
                break

            X1 = X1 + stp * p

        #print >> self.printer, 'j: {0}'.format(i)
        return X1, i == 0
示例#8
0
def _line_search_wolfe12(f, fprime, xk, pk, gfk, old_fval, old_old_fval,
                         **kwargs):
    """
    Same as line_search_wolfe1, but fall back to line_search_wolfe2 if
    suitable step length is not found, and raise an exception if a
    suitable step length is not found.

    Raises
    ------
    _LineSearchError
        If no suitable step size is found

    """

    extra_condition = kwargs.pop('extra_condition', None)

    ret = line_search_wolfe1(f, fprime, xk, pk, gfk, old_fval, old_old_fval,
                             **kwargs)

    if ret[0] is not None and extra_condition is not None:
        xp1 = xk + ret[0] * pk
        if not extra_condition(ret[0], xp1, ret[3], ret[5]):
            # Reject step if extra_condition fails
            ret = (None, )

    if ret[0] is None:
        # line search failed: try different one.
        with warnings.catch_warnings():
            warnings.simplefilter('ignore', LineSearchWarning)
            kwargs2 = {}
            for key in ('c1', 'c2', 'amax'):
                if key in kwargs:
                    kwargs2[key] = kwargs[key]
            ret = line_search_wolfe2(f,
                                     fprime,
                                     xk,
                                     pk,
                                     gfk,
                                     old_fval,
                                     old_old_fval,
                                     extra_condition=extra_condition,
                                     **kwargs2)

    if ret[0] is None:
        raise _LineSearchError()

    return ret
    def test_line_search_wolfe1(self):
        c = 0
        smax = 100
        for name, f, fprime, x, p, old_f in self.line_iter():
            f0 = f(x)
            g0 = fprime(x)
            self.fcount = 0
            s, fc, gc, fv, ofv, gv = ls.line_search_wolfe1(f, fprime, x, p,
                                                           g0, f0, old_f,
                                                           amax=smax)
            assert_equal(self.fcount, fc+gc)
            assert_equal(ofv, f(x))
            if s is None:
                continue
            assert_equal(fv, f(x + s*p))
            assert_equal(gv, fprime(x + s*p))
            if s < smax:
                c += 1
                assert_line_wolfe(x, p, s, f, fprime, err_msg=name)

        assert_(c > 3) # check that the iterator really works...
示例#10
0
def fmin_barrier_bfgs(
    f,
    x0,
    fprime=None,
    gtol=1e-6,
    norm=Inf,
    epsilon=_epsilon,
    maxiter=None,
    full_output=0,
    disp=1,
    retall=0,
    callback=None,
    barrier=None,
):
    """Minimize a function using the BFGS algorithm without jumping a barrier.

    Parameters
    ----------
    f : callable f(x,*args)
        Objective function to be minimized.
    x0 : ndarray
        Initial guess.
    fprime : callable f'(x,*args)
        Gradient of f.
    args : tuple
        Extra arguments passed to f and fprime.
    gtol : float
        Gradient norm must be less than gtol before succesful termination.
    norm : float
        Order of norm (Inf is max, -Inf is min)
    epsilon : int or ndarray
        If fprime is approximated, use this value for the step size.
    callback : callable
        An optional user-supplied function to call after each
        iteration.  Called as callback(xk), where xk is the
        current parameter vector.
    barrier : callable
        barrier(x) returns true iff a barrier has been jumped.

    Returns
    -------
    xopt : ndarray
        Parameters which minimize f, i.e. f(xopt) == fopt.
    fopt : float
        Minimum value.
    gopt : ndarray
        Value of gradient at minimum, f'(xopt), which should be near 0.
    Bopt : ndarray
        Value of 1/f''(xopt), i.e. the inverse hessian matrix.
    func_calls : int
        Number of function_calls made.
    grad_calls : int
        Number of gradient calls made.
    warnflag : integer
        1 : Maximum number of iterations exceeded.
        2 : Gradient and/or function calls not changing.
    allvecs  :  list
        Results at each iteration.  Only returned if retall is True.

    Other Parameters
    ----------------
    maxiter : int
        Maximum number of iterations to perform.
    full_output : bool
        If True,return fopt, func_calls, grad_calls, and warnflag
        in addition to xopt.
    disp : bool
        Print convergence message if True.
    retall : bool
        Return a list of results at each iteration if True.

    Notes
    -----
    Optimize the function, f, whose gradient is given by fprime
    using the quasi-Newton method of Broyden, Fletcher, Goldfarb,
    and Shanno (BFGS) See Wright, and Nocedal 'Numerical
    Optimization', 1999, pg. 198.

    """
    x0 = asarray(x0).squeeze()
    if x0.ndim == 0:
        x0.shape = (1,)
    if maxiter is None:
        maxiter = len(x0) * 200
    func_calls, f = wrap_function(f)
    if barrier is None:
        barr_calls, barr = wrap_function(lambda _: 0)
    else:
        barr_calls, barr = wrap_function(barrier)
    if fprime is None:
        grad_calls, myfprime = wrap_function(approx_fprime, (f, epsilon))
    else:
        grad_calls, myfprime = wrap_function(fprime)
    #    debug_here()
    if barr(x0):
        print "Optimization started with value violating constraints!"
        sys.stdout.flush()
    gfk = myfprime(x0)
    k = 0
    N = len(x0)

    Hk = numpy.eye(N)
    old_fval = f(x0)
    old_old_fval = old_fval + 5000
    xk = x0
    if retall:
        allvecs = [x0]
    sk = [2 * gtol]
    warnflag = 0
    gnorm = vecnorm(gfk, ord=norm)
    best_x = xk
    best_f = old_fval
    best_k = 0
    best_g = gfk
    while (gnorm > gtol) and (k < maxiter):
        pk = -numpy.dot(Hk, gfk)

        amax, bamax = backtrack(xk, pk, barr)  # scipy.optimize.fmin_bfgs
        # modified here
        # and line_searches below!
        #        amax = 50.
        famax = f(xk + amax * pk)
        if disp:
            print "Iter:%d  f:%14.10g  #b:%d  #f:%d" % (k, old_fval, barr_calls[0], func_calls[0]),
            if barrier is not None:
                print "barrier%d:%3g f(amax):%3g" % (bamax, amax, famax),
        method = ""

        if (bamax == 0) and (famax < old_fval):
            alpha_k = amax
            old_fval2 = famax
        else:
            alpha_k = None
            try:
                alpha_k, fc, gc, old_fval2, old_old_fval2, gfkp1 = line_search_wolfe2(
                    f, myfprime, xk, pk, gfk, old_fval, old_old_fval, amax=amax
                )
            except:
                if disp:
                    print "Warning: error in line_search_wolfe2.."

            if alpha_k is not None:
                method = "wolfe2"
            else:
                # line search failed: try different one.
                alpha_k, fc, gc, old_fval2, old_old_fval2, gfkp1 = line_search_wolfe1(
                    f, myfprime, xk, pk, gfk, old_fval, old_old_fval, amax=amax
                )

            if alpha_k is None:
                alpha_k, old_fval2 = simple_search(f, xk, pk, amax)
                if alpha_k is not None:
                    method = "simple"

            if alpha_k is None:
                pk = -pk
                alpha_k, old_fval2 = simple_search(f, xk, pk, amax)
                if alpha_k is not None:
                    method = "simple2"

            ##        debug_here()
            #        if old_fval>famax and isfinite(famax):
            #            alpha_k = amax
            #            old_fval = famax
            #            gfkp1   = myfprime(xk + amax*pk)
            #        else:
            #            alpha_k = minimum(alpha_k,amax)

            print

            if alpha_k is not None:
                bval = barr(xk + alpha_k * pk)
            else:
                bval = 1
            if bval:
                if bamax:
                    warnflag = 2
                    break
                if famax < old_fval:
                    alpha_k = amax
                else:
                    alpha_k, old_fval = simple_search(f, xk, pk, amax)
                    method = "simple3"

        #        if alpha_k is not None:
        #            old_fval= f(xk + alpha_k*pk)
        #            gfkp1   = myfprime(xk + alpha_k*pk)

        if alpha_k is None:
            old_fval = f(xk)
            warnflag = 2
            break

        old_old_fval = old_fval
        old_fval = old_fval2

        xkp1 = xk + alpha_k * pk
        gfkp1 = myfprime(xk + alpha_k * pk)

        gnorm = vecnorm(gfkp1, ord=norm)
        print "gnorm:%4e %s" % (gnorm, method)

        if callback is not None:
            callback(xk)

        if retall:
            allvecs.append(xkp1)
        sk = xkp1 - xk
        xk = xkp1

        old_fval = f(xk)
        if not isfinite(old_fval):
            pass
        #            debug_here()

        if gfkp1 is None:
            gfkp1 = myfprime(xkp1)

        yk = gfkp1 - gfk
        gfk = gfkp1
        k += 1

        if old_fval < best_f:
            best_x = xk
            best_f = old_fval
            best_k = k
            best_g = gfk

        if (gnorm <= gtol) or (k > best_k + 10):
            break

        try:  # this was handled in numeric, let it remaines for more safety
            rhok = 1.0 / (numpy.dot(yk, sk))
        except ZeroDivisionError:
            rhok = 1000.0
            print "Divide-by-zero encountered: rhok assumed large"
        if isinf(rhok):  # this is patch for numpy
            rhok = 1000.0
            print "Divide-by-zero encountered: rhok assumed large"

        #        I = numpy.eye(N,dtype=int)
        #        A1 = I - sk[:,numpy.newaxis] * yk[numpy.newaxis,:] * rhok
        #        A2 = I - yk[:,numpy.newaxis] * sk[numpy.newaxis,:] * rhok
        #        Hk = numpy.dot(A1,numpy.dot(Hk,A2)) + rhok * sk[:,numpy.newaxis] \
        #                 * sk[numpy.newaxis,:]

        # Same as above with inplace operations
        Hkyk = numpy.dot(Hk, yk) * rhok
        numpy.add(Hk, -Hkyk[:, numpy.newaxis] * sk[numpy.newaxis, :], Hk)
        Hkyk = numpy.dot(Hk.T, yk) * rhok
        numpy.add(Hk, -sk[:, numpy.newaxis] * Hkyk[numpy.newaxis, :], Hk)
        numpy.add(Hk, rhok * sk[:, numpy.newaxis] * sk[numpy.newaxis, :], Hk)

    if disp or full_output:
        fval = best_f
    if warnflag == 2:
        if disp:
            print "Warning: Desired error not necessarily achieved " "due to precision loss"
            print "         Current function value: %f" % fval
            print "         Iterations: %d" % k
            print "         Function evaluations: %d" % func_calls[0]
            print "         Barrier  evaluations: %d" % barr_calls[0]
            print "         Gradient evaluations: %d" % grad_calls[0]

    elif k >= maxiter:
        warnflag = 1
        if disp:
            print "Warning: Maximum number of iterations has been exceeded"
            print "         Current function value: %f" % fval
            print "         Iterations: %d" % k
            print "         Function evaluations: %d" % func_calls[0]
            print "         Barrier  evaluations: %d" % barr_calls[0]
            print "         Gradient evaluations: %d" % grad_calls[0]
    else:
        if disp:
            print "Optimization terminated successfully."
            print "         Current function value: %f" % fval
            print "         Iterations: %d" % k
            print "         Function evaluations: %d" % func_calls[0]
            print "         Barrier  evaluations: %d" % barr_calls[0]
            print "         Gradient evaluations: %d" % grad_calls[0]

    if full_output:
        retlist = best_x, fval, best_g, func_calls[0], grad_calls[0], warnflag
        if retall:
            retlist += (allvecs,)
    else:
        retlist = best_x
        if retall:
            retlist = (best_x, allvecs)

    return retlist
示例#11
0
    def run(self, *a, **kw):
        status = RUNNING

        fi = self.f(self.x0)
        fi_old = fi + 5000

        gi, ur, si = self.reset(self.x0, *a, **kw)
        xi = self.x0
        xi_old = numpy.nan
        it = 0

        while it < self.maxiter:
            if not self.runsignal.is_set():
                break

            if self.f_call.value > self.max_f_eval:
                status = MAX_F_EVAL

            gi = -self.df(xi, *a, **kw)
            if numpy.dot(gi.T, gi) <= self.gtol:
                status = CONVERGED
                break
            if numpy.isnan(numpy.dot(gi.T, gi)):
                if numpy.any(numpy.isnan(xi_old)):
                    status = CONVERGED
                    break
                self.reset(xi_old)

            gammai = ur(gi)
            if gammai < 1e-6 or it % xi.shape[0] == 0:
                gi, ur, si = self.reset(xi, *a, **kw)
            si = gi + gammai * si
            alphai, _, _, fi2, fi_old2, gfi = line_search_wolfe1(
                self.f, self.df, xi, si, gi, fi, fi_old)
            if alphai is None:
                alphai, _, _, fi2, fi_old2, gfi = \
                         line_search_wolfe2(self.f, self.df,
                                            xi, si, gi,
                                            fi, fi_old)
                if alphai is None:
                    # This line search also failed to find a better solution.
                    status = LINE_SEARCH
                    break
            if fi2 < fi:
                fi, fi_old = fi2, fi_old2
            if gfi is not None:
                gi = gfi

            if numpy.isnan(fi) or fi_old < fi:
                gi, ur, si = self.reset(xi, *a, **kw)

            else:
                xi += numpy.dot(alphai, si)
                if self.messages:
                    sys.stdout.write("\r")
                    sys.stdout.flush()
                    sys.stdout.write(
                        "iteration: {0:> 6g}  f:{1:> 12e}  |g|:{2:> 12e}".
                        format(it, fi, numpy.dot(gi.T, gi)))

            if it % self.report_every == 0:
                self.callback(xi, fi, gi, it, self.f_call.value,
                              self.df_call.value, status)
            it += 1
        else:
            status = MAXITER
        self.callback_return(xi, fi, gi, it, self.f_call.value,
                             self.df_call.value, status)
        self.result = [
            xi, fi, gi, it, self.f_call.value, self.df_call.value, status
        ]
示例#12
0
    def run(self, *a, **kw):
        status = RUNNING

        fi = self.f(self.x0)
        fi_old = fi + 5000

        gi, ur, si = self.reset(self.x0, *a, **kw)
        xi = self.x0
        xi_old = numpy.nan
        it = 0

        while it < self.maxiter:
            if not self.runsignal.is_set():
                break

            if self.f_call.value > self.max_f_eval:
                status = MAX_F_EVAL

            gi = -self.df(xi, *a, **kw)
            if numpy.dot(gi.T, gi) <= self.gtol:
                status = CONVERGED
                break
            if numpy.isnan(numpy.dot(gi.T, gi)):
                if numpy.any(numpy.isnan(xi_old)):
                    status = CONVERGED
                    break
                self.reset(xi_old)

            gammai = ur(gi)
            if gammai < 1e-6 or it % xi.shape[0] == 0:
                gi, ur, si = self.reset(xi, *a, **kw)
            si = gi + gammai * si
            alphai, _, _, fi2, fi_old2, gfi = line_search_wolfe1(self.f, self.df, xi, si, gi, fi, fi_old)
            if alphai is None:
                alphai, _, _, fi2, fi_old2, gfi = line_search_wolfe2(self.f, self.df, xi, si, gi, fi, fi_old)
                if alphai is None:
                    # This line search also failed to find a better solution.
                    status = LINE_SEARCH
                    break
            if fi2 < fi:
                fi, fi_old = fi2, fi_old2
            if gfi is not None:
                gi = gfi

            if numpy.isnan(fi) or fi_old < fi:
                gi, ur, si = self.reset(xi, *a, **kw)

            else:
                xi += numpy.dot(alphai, si)
                if self.messages:
                    sys.stdout.write("\r")
                    sys.stdout.flush()
                    sys.stdout.write(
                        "iteration: {0:> 6g}  f:{1:> 12e}  |g|:{2:> 12e}".format(it, fi, numpy.dot(gi.T, gi))
                    )

            if it % self.report_every == 0:
                self.callback(xi, fi, gi, it, self.f_call.value, self.df_call.value, status)
            it += 1
        else:
            status = MAXITER
        self.callback_return(xi, fi, gi, it, self.f_call.value, self.df_call.value, status)
        self.result = [xi, fi, gi, it, self.f_call.value, self.df_call.value, status]
示例#13
0
def fmin_LBFGS(func, x0, funcprime, args=(), maxIter=1000):
    """
	func: callable f(x)
		Objective function to be minimized.
	x0: ndarray
		Initial guess.
	funcprime: callable f'(x)
		Gradient of f.
	maxIter: int, optional
		Maximum number of Iterations to perform

	return:
		x_opt: ndarray
	"""
    x0 = np.asarray(x0, dtype=np.float64).flatten()
    if (x0.ndim == 0):
        x0.shape = (1, )

    len_x = x0.size
    x_k = x0
    old_fval = func(x0, *args)
    old_old_fval = None
    gf_k = funcprime(x0, *args)

    maxHistory = 10

    history_S = []
    history_Y = []
    rho = []
    warnFlag = 0
    step_k = 0

    gtol = 1e-5
    gnorm = np.linalg.norm(gf_k, np.inf)
    lineSearchConverged = True
    while (not lineSearchConverged or gnorm > gtol) and (step_k < maxIter):
        lineSearchConverged = True

        #direction d_k = - B_k * g_k
        d_k = computeDirection(maxHistory, step_k, gf_k, history_S, history_Y,
                               rho)

        #lineSearch
        alpha_k, fc, gc, old_fval, old_old_fval, gf_kp1 = \
         line_search_wolfe1(func, funcprime, x_k, d_k, gf_k, old_fval, old_old_fval, args=args)

        if (alpha_k is None):
            # Line search failed to find a better solution.
            print 'Step:', step_k, "Line search did not converge. Set alpha_k for a small value"
            lineSearchConverged = False
            alpha_k = 0.01

        x_kp1 = x_k + alpha_k * d_k

        if (not lineSearchConverged):
            gf_kp1 = funcprime(x_kp1, *args)

        if (step_k > maxHistory):
            history_S.pop(0)
            history_Y.pop(0)
            rho.pop(0)

        #save new pair
        s_k = x_kp1 - x_k
        history_S.append(s_k)
        y_k = gf_kp1 - gf_k
        history_Y.append(y_k)
        try:
            dem = float(np.dot(s_k, y_k))
            rhok = 1.0 / dem
        except ZeroDivisionError:
            rhok = 1000.0
            print("Divide-by-zero encountered: rhok assumed large")
        if np.isinf(rhok):
            rhok = 1000.0
        rho.append(rhok)

        gnorm = np.linalg.norm(gf_kp1, np.inf)
        x_k = x_kp1
        gf_k = gf_kp1

        if (not np.isfinite(old_fval)):
            #optimal value is +-Inf
            warnFlag = 2
            break

        step_k += 1

    if (warnFlag == 2):
        print "Stopped due to precission loss"
    print "Steps:", step_k
    print "function value", old_fval
    return x_k
示例#14
0
def _minimize_bfgs(fun, x0, args=(), jac=None, callback=None,
                   tol=1e-5, norm=Inf, eps=_epsilon, maxiter=None,
                   disp=False, return_all=False,
                   **unknown_options):
    """
    Minimization of scalar function of one or more variables using the
    BFGS algorithm.

    Options for the BFGS algorithm are:
        disp : bool
            Set to True to print convergence messages.
        maxiter : int
            Maximum number of iterations to perform.
        tol : float
            Cost change must be less than `tol` before succesful termination.
        norm : float
            Order of norm (Inf is max, -Inf is min).
        eps : float or ndarray
            If `jac` is approximated, use this value for the step size.

    This function is called by the `minimize` function with `method=BFGS`.
    It is not supposed to be called directly.
    """
    _check_unknown_options(unknown_options)
    f = fun
    fprime = jac
    epsilon = eps
    retall = return_all

    x0 = asarray(x0).flatten()
    if x0.ndim == 0:
        x0.shape = (1,)
    if maxiter is None:
        maxiter = len(x0)*200
    func_calls, f = wrap_function(f, args)
    if fprime is None:
        grad_calls, myfprime = wrap_function(approx_fprime, (f, epsilon))
    else:
        grad_calls, myfprime = wrap_function(fprime, args)
    gfk = myfprime(x0)
    k = 0
    N = len(x0)
    I = numpy.eye(N, dtype=int)
    Hk = I
    old_fval = f(x0)
    old_old_fval = old_fval + 5000
    xk = x0
    if retall:
        allvecs = [x0]
    sk = [2*0.1]
    warnflag = 0
    gnorm = vecnorm(gfk, ord=norm)
    while (fabs(old_fval - old_old_fval) > tol) and (k < maxiter):
        pk = -numpy.dot(Hk, gfk)
        alpha_k, fc, gc, old_fval2, old_old_fval2, gfkp1 = \
           line_search_wolfe1(f, myfprime, xk, pk, gfk,
                              old_fval, old_old_fval)
        if alpha_k is not None:
            old_fval = old_fval2
            old_old_fval = old_old_fval2
        else:
            # line search failed: try different one.
            alpha_k, fc, gc, old_fval, old_old_fval, gfkp1 = \
                     line_search_wolfe2(f, myfprime, xk, pk, gfk,
                                        old_fval, old_old_fval)
            if alpha_k is None:
                # This line search also failed to find a better solution.
                warnflag = 2
                break
        xkp1 = xk + alpha_k * pk
        if retall:
            allvecs.append(xkp1)
        sk = xkp1 - xk
        xk = xkp1
        if gfkp1 is None:
            gfkp1 = myfprime(xkp1)

        yk = gfkp1 - gfk
        gfk = gfkp1
        if callback is not None:
            callback(xk)
        k += 1
        gnorm = vecnorm(gfk, ord=norm)
        #if (gnorm <= gtol):
        #    break

        if not numpy.isfinite(old_fval):
            # We correctly found +-Inf as optimal value, or something went
            # wrong.
            warnflag = 2
            break

        try:  #this was handled in numeric, let it remaines for more safety
            rhok = 1.0 / (numpy.dot(yk, sk))
        except ZeroDivisionError:
            rhok = 1000.0
            print("Divide-by-zero encountered: rhok assumed large")
        if isinf(rhok):  #this is patch for numpy
            rhok = 1000.0
            print("Divide-by-zero encountered: rhok assumed large")
        A1 = I - sk[:, numpy.newaxis] * yk[numpy.newaxis, :] * rhok
        A2 = I - yk[:, numpy.newaxis] * sk[numpy.newaxis, :] * rhok
        Hk = numpy.dot(A1, numpy.dot(Hk, A2)) + rhok * sk[:, numpy.newaxis] \
                * sk[numpy.newaxis, :]

    fval = old_fval
    if warnflag == 2:
        msg = _status_message['pr_loss']
        if disp:
            print("Warning:", msg)
            print("         Current function value:",fval)
            print("         Iterations:", k)
            print("         Function evaluations:", func_calls[0])
            print("         Gradient evaluations:", grad_calls[0])

    elif k >= maxiter:
        warnflag = 1
        msg = _status_message['maxiter']
        if disp:
            print("Warning:", msg)
            print("         Current function value:", fval)
            print("         Iterations:", k)
            print("         Function evaluations:", func_calls[0])
            print("         Gradient evaluations:", grad_calls[0])
    else:
        msg = _status_message['success']
        if disp:
            print(msg)
            print("         Current function value:", fval)
            print("         Iterations:", k)
            print("         Function evaluations:", func_calls[0])
            print("         Gradient evaluations:", grad_calls[0])

    result = Result(fun=fval, jac=gfk, hess=Hk, nfev=func_calls[0],
                    njev=grad_calls[0], status=warnflag,
                    success=(warnflag == 0), message=msg, x=xk)
    if retall:
        result['allvecs'] = allvecs
    return result