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...
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
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
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
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
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...
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
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 ]
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]
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
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