def _fg(x): return func(x) if grad is None else func(x), grad(x)
for strongwolfe in wolfe_kinds: # run BFGS results = hanso(func, x0=x0, grad=grad, sampgrad=True, strongwolfe=strongwolfe, maxit=1000, gradnormtol=2 * 1e-3, fvalquit=1e-4, verbose=2) xmin, fmin = results[:2] pobj = results[-1] assert fmin == func(xmin) print "xopt:", xmin print "fmin:", fmin times, pobj = map(np.array, zip(*pobj)) plt.plot(times, pobj, label="%swolfe" % (['weak', 'strong'][strongwolfe])) plt.xlabel('Time') plt.ylabel('Primal') plt.gca().set_xscale('log') plt.gca().set_yscale('log') plt.legend()
def _fg(x): return func(x) if grad is None else func(x), grad(x)
def getbundle(func, x0, grad=None, g0=None, samprad=1e-4, n=None): """ Get bundle of n-1 gradients at points near x, in addition to g, which is gradient at x and goes in first column intended to be called by gradsampfixed Parameters ---------- func: callable function on 1D arrays of length nvar function being optimized grad: callable function gradient of func x0: 1D array of len nvar, optional (default None) intial points, one per column g0: 1D array of len nvar, optional (default None) gradient at point x0 samprad: float, optional (default 1e-4) sampling radius; this should be a small positive float n: int, optional (default min(100, 2 * nvar, nvar + 10)) number of points and gradients to sample Returns ------- xbundle: 2D array of shape (nvar, n) bundle of n points sampled in the samprand-ball around x0 xbundle: 2D array of shape (nvar, n) bundle of n gradients sampled in the samprand-ball around x0 Raises ------ RuntimeError """ def _fg(x): return func(x) if grad is None else (func(x), grad(x)) x0 = np.ravel(x0) nvar = len(x0) n = min(100, min(2 * nvar, nvar + 10)) if n is None else n xbundle = np.ndarray((nvar, n)) gbundle = np.ndarray((nvar, n)) xbundle[..., 0] = x0 gbundle[..., 0] = g0 if not g0 is None else _fg(x0)[1] for k in xrange(1, n): # note the 1 xpert = x0 + samprad * (np.random.rand(nvar) - 0.5 ) # uniform distribution f, g = _fg(xpert) count = 0 # in particular, disallow infinite function values while np.isnan(f) or np.isinf(f) or np.any(np.isnan(g)) or np.any( np.isinf(g)): xpert = (x0 + xpert) / 2. # contract back until feasible f, g = func(xpert), grad(xpert) count = count + 1 if count > 100: # should never happen, but just in case raise RuntimeError( 'getbundle: too many contractions needed to find finite' ' func and grad values') xbundle[..., k] = xpert gbundle[..., k] = g return xbundle, gbundle
def getbundle(func, x0, grad=None, g0=None, samprad=1e-4, n=None): """ Get bundle of n-1 gradients at points near x, in addition to g, which is gradient at x and goes in first column intended to be called by gradsampfixed Parameters ---------- func: callable function on 1D arrays of length nvar function being optimized grad: callable function gradient of func x0: 1D array of len nvar, optional (default None) intial points, one per column g0: 1D array of len nvar, optional (default None) gradient at point x0 samprad: float, optional (default 1e-4) sampling radius; this should be a small positive float n: int, optional (default min(100, 2 * nvar, nvar + 10)) number of points and gradients to sample Returns ------- xbundle: 2D array of shape (nvar, n) bundle of n points sampled in the samprand-ball around x0 xbundle: 2D array of shape (nvar, n) bundle of n gradients sampled in the samprand-ball around x0 Raises ------ RuntimeError """ def _fg(x): return func(x) if grad is None else (func(x), grad(x)) x0 = np.ravel(x0) nvar = len(x0) n = min(100, min(2 * nvar, nvar + 10)) if n is None else n xbundle = np.ndarray((nvar, n)) gbundle = np.ndarray((nvar, n)) xbundle[..., 0] = x0 gbundle[..., 0] = g0 if not g0 is None else _fg(x0)[1] for k in xrange(1, n): # note the 1 xpert = x0 + samprad * (np.random.rand(nvar) - 0.5 ) # uniform distribution f, g = _fg(xpert) count = 0 # in particular, disallow infinite function values while np.isnan(f) or np.isinf(f) or np.any( np.isnan(g)) or np.any(np.isinf(g)): xpert = (x0 + xpert) / 2. # contract back until feasible f, g = func(xpert), grad(xpert) count = count + 1 if count > 100: # should never happen, but just in case raise RuntimeError( 'getbundle: too many contractions needed to find finite' ' func and grad values') xbundle[..., k] = xpert gbundle[..., k] = g return xbundle, gbundle
results = hanso(func, x0=x0, grad=grad, sampgrad=True, strongwolfe=strongwolfe, maxit=1000, gradnormtol=2 * 1e-3, fvalquit=1e-4, nvec=10, ngrad=10, verbose=2 ) xmin, fmin = results[:2] pobj = results[-1] assert fmin == func(xmin) print "xopt:", xmin print "fmin:", fmin times, pobj = map(np.array, zip(*pobj)) plt.plot(times, pobj, label="%swolfe" % ( ['weak', 'strong'][strongwolfe])) plt.xlabel('Time') plt.ylabel('Primal') plt.gca().set_xscale('log') plt.gca().set_yscale('log') plt.legend() plt.title(func_name)