def setup_constraints(intersections): # return a list of dictionary of constraints to be used by SLSQP # intersections is a list of tuples of node index. constraints = [] pairs = [] for i in range(NUM_POINTS - 1): pairs.append((i, i + 1)) constr = optimize.NonlinearConstraint(functools.partial(constr_func, pairs=pairs), L0, L0, jac=functools.partial(constr_jac, pairs=pairs)) constraints.append(constr) pairs = [] for i, j in intersections: pairs.append((i, j)) constr = optimize.NonlinearConstraint(functools.partial(constr_func, pairs=pairs), 0.0, 0.0, jac=functools.partial(constr_jac, pairs=pairs)) constraints.append(constr) return constraints
def SSE_outer(param_outer, h, w, ReturnSolution, sigh, sigw, Verbose): [init_params_inner, nparams_inner] = ChooseInitParamsInner(h, w) [lb, ub] = SetInnerParamBounds(nparams_inner) param_bounds_inner = optimize.Bounds(lb, ub) def SSE_inner(inner_params, xbreak, h, w, sigh, sigw): i0 = h < xbreak[0] J0 = (sigw**2 + inner_params[0]**2 * sigh**2)**-1 * sum( (h[i0] * inner_params[0] + inner_params[1] - w[i0])**2) i1 = (h >= xbreak[0]) & (h < xbreak[1]) J1 = (sigw**2 + inner_params[2]**2 * sigh**2)**-1 * sum( (h[i1] * inner_params[2] + inner_params[3] - w[i1])**2) i2 = h >= xbreak[1] J2 = (sigw**2 + inner_params[4]**2 * sigh**2)**-1 * sum( (h[i2] * inner_params[4] + inner_params[5] - w[i2])**2) J = J0 + J1 + J2 return J def cons0_f(x): return x[0] * param_outer[0] + x[1] - x[2] * param_outer[0] - x[ 3] #this constraint requies this function to be equal to zero def cons1_f(x): return x[2] * param_outer[1] + x[3] - x[4] * param_outer[1] - x[ 5] #this constraint requies this function to be equal to zero constraint0 = optimize.NonlinearConstraint(cons0_f, 0, 0) constraint1 = optimize.NonlinearConstraint(cons1_f, 0, 0) constraints = [constraint0, constraint1] ShowDetailedOutput = Verbose if not ReturnSolution: ShowDetailedOutput = False res = optimize.minimize(fun=SSE_inner, x0=init_params_inner, args=(param_outer, h, w, sigh, sigw), bounds=param_bounds_inner, method='trust-constr', constraints=constraints, options={ 'disp': ShowDetailedOutput, 'maxiter': 1e3, 'verbose': 0 }) if ReturnSolution: return res.fun, res.x else: return res.fun
def get_res(nofun, morefun, nexp, xhat, ft, constraintT, sign=1., rank=0): w = np.ones(ft.shape) w[0] *= 10. print('rank {}'.format(rank), end='') res = so.minimize(lambda z: nl.norm(np.multiply(w, nofun(z) - ft))**2, xhat, bounds=[(None, None), (2**-11, None)] * nexp, jac='2-point', hess=so.BFGS(), method='trust-constr', options={ 'verbose': 1, 'maxiter': 2048, 'xtol': 1e-8 }) print('rank {}'.format(rank), end='') res = so.minimize(lambda z: nl.norm(np.multiply(w, nofun(z) - ft))**2, xhat, constraints=so.NonlinearConstraint( lambda z: sign * (nofun(z, constraintT) - morefun(constraintT)), 0, np.inf), bounds=[(None, None), (2**-11, None)] * nexp, jac='2-point', hess=so.BFGS(), method='trust-constr', options={ 'verbose': 1, 'maxiter': 2048, 'xtol': 1e-8 }) i = 1 while res.status == 3 or res.fun > 5e-1: print('rank {}'.format(rank), end='') alpha = 1. / np.sqrt(++i) res = so.minimize(lambda z: nl.norm(np.multiply(w, nofun(z) - ft))**2, res.x * (1. - alpha) + alpha * nr.uniform(-1e-1, 1e-1, xhat.shape[0]), constraints=so.NonlinearConstraint( lambda z: sign * (nofun(z, constraintT) - morefun(constraintT)), 0, np.inf), bounds=[(None, None), (2**-11, None)] * nexp, jac='2-point', hess=so.BFGS(), method='trust-constr', options={ 'verbose': 1, 'maxiter': 2048, 'xtol': 1e-8 }) return res
def add_nonlinear_eq_con(self, poly=None, custom=None): """ Adds nonlinear inequality constraints :math:`g(x) = value` (for poly option) or :math:`g(x) = 0` (for function option) to the optimisation routine. Only ``trust-constr`` and ``SLSQP`` methods can handle equality constraints. If poly object is providedin the poly dictionary, gradients and Hessians will be computed automatically. :param dict poly: Arguments for poly dictionary. :param Poly poly: An instance of the Poly class. :param float value: Value of the nonlinear constraint. :param dict custom: Additional custom callable arguments. :callable function: The constraint function to be called. :callable jac_function: The gradient (or derivative) of the constraint. :callable hess_function: The Hessian of the constraint function. """ assert self.method == 'trust-constr' or 'SLSQP' assert poly is not None or custom is not None if poly is not None: assert 'value' in poly value = poly['value'] g = poly.get_polyfit_function() jac = poly.get_polyfit_grad_function() hess = poly.get_polyfit_hess_function() constraint = lambda x: np.asscalar(g(x)) constraint_deriv = lambda x: jac(x)[:, 0] constraint_hess = lambda x, v: hess(x)[:, :, 0] if self.method == 'trust-constr': self.constraints.append(optimize.NonlinearConstraint(constraint, value, value, jac=constraint_deriv, \ hess=constraint_hess)) else: self.constraints.append({'type':'eq', 'fun': lambda x: constraint(x) - value, \ 'jac': constraint_deriv}) elif custom is not None: assert 'function' in custom constraint = custom['function'] if 'jac_function' in custom: constraint_deriv = custom['jac_function'] else: constraint_deriv = '2-point' if 'hess_function' in custom: constraint_hess = lambda x, v: custom['hess_function'](x) else: constraint_hess = optimize.BFGS() if self.method == 'trust-constr': self.constraints.append(optimize.NonlinearConstraint(constraint, 0.0, 0.0, jac=constraint_deriv, \ hess=constraint_hess)) else: if 'jac_function' in custom: self.constraints.append({ 'type': 'eq', 'fun': constraint, 'jac': constraint_deriv }) else: self.constraints.append({'type': 'eq', 'fun': constraint})
def fit(self, params=None, method='SLSQP', max_iter=10000): ''' :param params: (beta, b), (p+1)*1 :return: beta, b ''' # define constraints, some margin for inequality constraints is required if method == 'SLSQP': # X * beta + b1 >= 0 nonneg_constraint = {'type': 'ineq', 'fun': lambda params: np.dot(self.X, params[:-1]) + params[-1] * np.ones((self.n,), dtype=float) - rtol} # sum(X * beta + b1) = 1 # sum_constraint = {'type': 'eq', 'fun': lambda params: # np.sum(np.dot(self.X, params[:-1]) + params[-1] * np.ones((self.n,), dtype=float)) - 1.0} elif method == 'trust-constr': # X * beta + b1 >= 0 nonneg_constraint = optimize.NonlinearConstraint(self.fun_nonneg_constraint, rtol*np.ones((self.n,), dtype=float), np.ones((self.n,), dtype=float)) else: # unconstrained nonneg_constraint = {} if params is None: # Initialization, start from a feasible point for all parameters # Initialization, start from a feasible point for all parameters (beta, b, _), _, _, _, _ = init_params(self.X, self.exog) params[:-1] = beta params[-1] = b start = time() res = optimize.minimize(self.loglike, params, method=method, jac=self.score, hess='2-point', constraints=[nonneg_constraint], options={'maxiter': max_iter}) end = time() return res.x[:-1], res.x[-1], (end - start)
def minimise_G_tot(x, T, x_m_guess, x_scaling_1, x_scaling_2, T_scaling_1, T_scaling_2, weights): x = np.array([x], dtype="float32") T_fixed = tf.constant([[T]]) x_m_guess = np.append(x_m_guess, (x - x_m_guess[0]) / (x_m_guess[1] - x_m_guess[0])).astype("float32") # Order of variables in x_m is x_1,x_2,f # Constraint on microstructure, and explicit functions for Jacobian and Hessians of constraint. constr = lambda x_m: np.array([(1. - x_m[2]) * x_m[0] + x_m[2] * x_m[1]]) constr_jac = lambda x_m: np.array([[1. - x_m[2], x_m[2], -x_m[0] + x_m[1]]] ) constr_hess = lambda x_m, v: np.array([[0., 0., -v[0]], [0., 0., v[0]], [-v[0], v[0], 0.]]) results = minimize(G_tot_2min, x_m_guess, args=(T_fixed, x_scaling_1, x_scaling_2, T_scaling_1, T_scaling_2, weights), method="trust-constr", jac=True, constraints=opt.NonlinearConstraint(constr, x, x, jac=constr_jac, hess=constr_hess), bounds=[(0.0, 1.0), (0.0, 1.0), (0.0, 1.0)]) return results
def get_constraints(self, constraints, method): if constraints is not None and not isinstance(constraints, sopt.LinearConstraint): assert isinstance(constraints, dict) assert 'fun' in constraints.keys() self.ctr_func = constraints['fun'] use_autograd = constraints.get('use_autograd', True) if method in ['trust-constr']: constraints = sopt.NonlinearConstraint( self._eval_ctr_func, lb=constraints.get('lb', -np.inf), ub=constraints.get('ub', np.inf), jac='2-point', keep_feasible=constraints.get('keep_feasible', False), ) elif method in ['COBYLA', 'SLSQP']: constraints = { 'type': constraints.get('type', 'eq'), 'fun': self._eval_ctr_func, } if use_autograd: constraints['jac'] = self.get_ctr_jac else: raise NotImplementedError elif constraints is None: constraints = () return constraints
def NonlinearConstraint(f, fargs): """ Represents the constraint : np.bincount(indices,weights) >= 0, where (indices, weights) = f(x,*fargs) (Indices may be repeated, and the associated values must be summed.) """ def fun(x): ind, wei = f(x, *fargs) return np.bincount(ind, wei) def grad(x): ind, wei = f(ad.Sparse.identity(constant=x), *fargs) triplets = (wei.coef.reshape(-1), (ind.repeat(wei.size_ad), wei.index.reshape(-1))) return scipy.sparse.coo_matrix(triplets).tocsr() def hess(x, v): # v is a set of weights, provided by the optimizer ind, wei = f(ad.Sparse2.identity(constant=x), *fargs) return np.sum(v[ind] * wei).hessian_operator() return sciopt.NonlinearConstraint(fun, 0., np.inf, jac=grad, hess=hess, keep_feasible=True)
def scipy(fcm_weights, agg_weights, const, func): flat_weights = np.concatenate( (fcm_weights.flatten(), agg_weights.flatten()), axis=None) bounds = optimize.Bounds(-np.ones(flat_weights.shape), np.ones(flat_weights.shape)) nonlinc = optimize.NonlinearConstraint(func, 0, 0) res = optimize.minimize( func, flat_weights, method='trust-constr', bounds=bounds, # constraints=nonlinc, options={ 'disp': True, 'maxiter': 300, 'xtol': 1e-10 }) # res = optimize.minimize(func, flat_weights, method='trust-constr', constraints=nonlinc, options={'disp': True}, bounds=bnds) n, m = const err = func(flat_weights) fcm_weights = np.reshape(res.x[:n * n], (n, n)) agg_weights = np.reshape(res.x[n * n:], (m, n)) return fcm_weights, agg_weights, err
def makeConstraint(i): constr = optimize.NonlinearConstraint( lambda x: optimization_problem.evaluate_nonlinear_constraints(x)[i], lb=-np.inf, ub=0, finite_diff_rel_step=self.finite_diff_rel_step, keep_feasible=True ) return constr
def _solve_constr(x, weight, z0=None, method='trust-constr', rss_lim=0.1, tol=None, **options): method = method.lower() assert method in ['trust-constr', 'slsqp', 'cobyla'] assert x.ndim == 1 assert weight.ndim == 2 if z0 is None: z0 = np.linalg.lstsq(weight, x[:, None], rcond=None)[0][:, 0] assert z0.ndim == 1 # objective f = lambda z: np.sum(np.abs(z)) if method in ['trust-constr', 'slsqp']: jac = lambda z: np.sign(z) else: jac = None if method == 'trust-constr': hess_ = np.zeros((z0.size, z0.size)) hess = lambda z: hess_ else: hess = None # constraints if method == 'trust-constr': constr_hess_ = weight.T @ weight constr = optimize.NonlinearConstraint( fun=lambda z: 0.5 * np.sum((weight.dot(z) - x)**2), lb=-np.inf, ub=rss_lim, jac=lambda z: weight.T @ (weight.dot(z) - x), hess=lambda x, v: v[0] * constr_hess_) else: constr = { 'type': 'ineq', 'fun': lambda z: rss_lim - 0.5 * np.sum((weight.dot(z) - x)**2) } if method == 'slsqp': constr['jac'] = lambda z: -weight.T @ (weight.dot(z) - x) z0 = z0.flatten() res = optimize.minimize(f, z0, method=method, tol=tol, jac=jac, hess=hess, constraints=constr, options=options) zf = res.x return zf
def optimize_trust_constr(x0, f, lb, ub, const_func, maxiter=200): bounds = optimize.Bounds(lb, ub) nonlin_const = optimize.NonlinearConstraint(const_func, 0.0, 0.0, jac=const_func.J, hess=const_func.H) res = optimize.minimize(f, x0, method='trust-constr', constraints=[nonlin_const], bounds=bounds) converged = res.status is 1 or res.status is 2 return res.x, res.fun, {'converged': converged, 'const_val': res.constr[0]}
def solve(self, policy_initial_guess=None, optimization_algorithm='trust-constr'): if (policy_initial_guess is None): policy_initial_guess = np.zeros(self.policy_shape, dtype=float) results = optimize.minimize(self.compute_objective_function_flat_input, policy_initial_guess.flatten(), method=optimization_algorithm, constraints=optimize.NonlinearConstraint( self.compute_constraints_flat_input, 0., np.inf), options={'verbose': 1}) solution = results.x.reshape(self.policy_shape) return solution, results
def optimize_trust_constr(x0, f, lb, ub, const_func=None, maxiter=200): dim = lb.size bounds = [(lb[i], ub[i]) for i in range(dim)] # constraint: const_func(x) == 0 const = optimize.NonlinearConstraint(const_func, 0.0, 0.0) res = optimize.minimize(f, x0=x0, method='trust-constr', jac='3-point', hess='3-point', bounds=bounds, constraints=const) result_x = np.atleast_1d(res.x) result_fx = np.atleast_1d(res.fun) return result_x, result_fx
def nonlinearConstraintBuilder(model, min_scaling_aspect_val, max_scaling_aspect_val, forecasted_metric_val, compose_model_input, jacobian='2-point', hessian=opt.BFGS()): cons_f = nonlinearConstraintFunctionBuilder(model, forecasted_metric_val, compose_model_input) return opt.NonlinearConstraint(cons_f, min_scaling_aspect_val, max_scaling_aspect_val, jac=jacobian, hess=hessian)
def capsule_approximation(vertices): a0, b0, r0 = pca_approximation(vertices) constraint_inflation = CONSTRAINT_INFLATION_RATIO * r0 x0 = np.array(list(a0) + list(b0) + [r0]) constraint_cap = lambda x: distance_points_segment(vertices, x[:3], x[3:6] ) - x[6] capsule_vol = lambda x: capsule_volume(x[:3], x[3:6], x[6]) constraint = optimize.NonlinearConstraint(constraint_cap, lb=-np.inf, ub=-constraint_inflation) res = optimize.minimize(capsule_vol, x0, constraints=constraint) res_constraint = constraint_cap(res.x) assert ( res_constraint <= 1e-4 ), "The computed solution is invalid, a vertex is at a distance {:.5f} of the capsule.".format( res_constraint) a, b, r = res.x[:3], res.x[3:6], res.x[6] return a, b, r
def spatialProjopt_find_feasiblept(Lagnum, include, Olist, UPlistlist): incLagnum = np.sum(include) initincLags = np.random.rand(incLagnum) mineigincfunc = lambda incL: get_modes_ZTT_mineig(incL, include, Olist, UPlistlist) Jacmineigincfunc = lambda incL: get_modes_ZTT_gradmineig( incL, include, Olist, UPlistlist) tolcstrt = 1e-4 cstrt = sopt.NonlinearConstraint(mineigincfunc, tolcstrt, np.inf, jac=Jacmineigincfunc, keep_feasible=False) lb = -np.inf * np.ones(incLagnum) ub = np.inf * np.ones(incLagnum) bnds = sopt.Bounds(lb, ub) try: res = sopt.minimize(Lags_normsqr, initincLags, method='trust-constr', jac=True, hess=Lags_normsqr_Hess_np, bounds=bnds, constraints=cstrt, options={ 'verbose': 2, 'maxiter': 300 }) except ValueError: global feasiblept Lags = np.zeros(Lagnum) Lags[include] = feasiblept return Lags Lags = np.zeros(Lagnum) Lags[include] = res.x Lags[1] = np.abs(Lags[1]) + 0.01 return Lags
def __init__( self, x, fx, lbx, lbfx, initGamma, initC, tau, bias ): self.x = np.vstack((x.reshape((-1,1)), np.array([x.max() + (x[1] - x[0]),x.max() + 2*(x[1] - x[0])]).reshape((-1,1)))) self.fx = fx.reshape((-1,1)) self.lbx = lbx self.lbfx = lbfx self.gamma = initGamma self.tau = tau self.c = initC self.lbx = lbx self.bias = bias.reshape((-1,1)) self.A = (self.x[:x.shape[0]] - self.x.T)**2 self.constraints = [] if not isinstance(lbfx,type(None)): assert not isinstance(lbx,type(None)) self.constraints.append(so.NonlinearConstraint(lambda z: self.evaluate(lbx,gamma=self.gamma,w=z) - lbfx,0,np.inf)) self.z0 = np.empty(self.x.shape[0]) self.z0[:] = np.array(nl.pinv(np.matrix(self.bias*np.exp(-self.gamma*self.A)),self.c)*(self.bias*self.fx)).reshape((-1,)) self.w = self.z0 self.optimize()
def optimise( res: int = 10, area: int = 10, radius: int = 1, volume: int = 2, ) -> optimize.OptimizeResult: assert volume > (area - np.pi * radius**2)**(3 / 2) / (6 * np.sqrt(np.pi)) func_ub = np.array([area, volume]) func_lb = np.array([area, volume]) nonlinear_constraint = optimize.NonlinearConstraint( constraint_func, func_lb, func_ub) bounds = optimize.Bounds( [radius, *np.zeros(res + 1)], [radius, *[np.inf for _ in range(res - 1)], 0, np.inf]) y = np.linspace(radius, 0, res + 1) y0 = [*y, 0.05] x_points = np.arange(0.5, res, 1) result = optimize.minimize(calc_pe, y0, args=(x_points), method='trust-constr', bounds=bounds, constraints=[nonlinear_constraint], options={ 'verbose': 1, 'maxiter': 3000 }) #'xtol': 1e-13, 'gtol': 1e-13}) r = result.x[:-1] z = [i * result.x[-1] for i in range(len(result.x) - 1)] #theta = np.r_[0:2*np.pi:30j] #x = r*np.sin(theta) plt.plot(z, r) return result
def _build_constraints(self, constraints): assert isinstance(constraints, dict) assert 'fun' in constraints assert 'lb' in constraints or 'ub' in constraints to_tensor = lambda x: self._params[0].new_tensor(x) to_array = lambda x: x.cpu().numpy() fun_ = constraints['fun'] lb = constraints.get('lb', -np.inf) ub = constraints.get('ub', np.inf) strict = constraints.get('keep_feasible', False) lb = to_array(lb) if torch.is_tensor(lb) else lb ub = to_array(ub) if torch.is_tensor(ub) else ub strict = to_array(strict) if torch.is_tensor(strict) else strict def fun(x): self._set_flat_param(to_tensor(x)) return to_array(fun_()) def jac(x): self._set_flat_param(to_tensor(x)) with torch.enable_grad(): output = fun_() # this is now a tuple of tensors, one per parameter, each with # shape (num_outputs, *param_shape). J_seq = _jacobian(inputs=tuple(self._params), outputs=output) # flatten and stack the tensors along dim 1 to get our full matrix J = torch.cat([elt.view(output.numel(), -1) for elt in J_seq], 1) return to_array(J) return optimize.NonlinearConstraint(fun, lb, ub, jac=jac, keep_feasible=strict)
#method='dogbox', x_scale='jac', loss='linear', tr_solver='exact', \ #method='dogbox', x_scale='jac', loss='soft_l1', f_scale=1e4, tr_solver='exact', \ #method='dogbox', x_scale='jac', loss=lambda x: rho_alt(x, 1e0), f_scale=1e4, tr_solver='exact', \ method='lm', x_scale='jac', \ max_nfev=200, xtol=1e-8, gtol=1e-8, ftol=None, \ verbose=2) xn = sol.x #print(sol.success) #print(sol.message) sol2 = sciop.minimize(lambda x: la.norm(lib.ml.fun(N, mp, x)[[0,1,2]] - b[[0,1,2]]*C0)**2, \ x0,\ method='SLSQP',\ jac=lambda x: lib.ml.fun(N, mp, x)[0:-1] / la.norm(lib.ml.fun(N, mp, x)[0:-1]),\ hess=lambda x: Jac(N, mp, x)[0:-1],\ constraints = sciop.NonlinearConstraint(\ lambda x: (lib.ml.fun(N, mp, x)[-1] - b[-1]*C0), 0, 0))#, jac=lambda x: lib.ml.Jac(N, mp, x)[-1]) ) xn = sol2.x #sol3 = sciop.root(\ # lambda x: np.array(lib.ml.fun(N, mp, x).T)[0][llsq_active] - b.T[0][llsq_active] * C0, \ # x0, \ # method='lm', \ # jac=lambda x: np.array(lib.ml.Jac(N, mp, x)[llsq_active]), \ # options = {'ftol':1e-4, 'xtol':1e-10} ) #xn = sol3.x mlab.close(all=True) mlab.figure() mlab.points3d(x0[0], x0[1],
return -2 * tmp2 #return -2 * tmp2 + gamma * soft_l1_hessep(v, p, alpha) #def cost(v, A, gamma): # return -v @ A @ v + gamma * np.linalg.norm(v, 1) @numba.njit def cons_f(x): return np.array([np.linalg.norm(x)**2 - 1]) @numba.njit def cons_fjac(x): return 2*x nonlinear_constraint = optimize.NonlinearConstraint(cons_f, 0, 0, jac=cons_fjac) def find_eigvec(samples, gamma, orthogonal_to=None, alpha=1e6): constraints = [nonlinear_constraint] if orthogonal_to is not None and len(orthogonal_to) > 0: ortho = optimize.LinearConstraint(orthogonal_to, 0, 0) constraints.append(ortho) U, _, _ = linalg.svd(samples.T, full_matrices=False) x = U[:, 0] #x_neg = np.maximum(0, -x) #x_pos = np.maximum(0, x) #x = np.stack([x_neg, x_pos]) #x = np.random.randn(samples.shape[1]) opt = optimize.minimize( cost,
def add_nonlinear_ineq_con(self, poly=None, custom=None): """ Adds nonlinear inequality constraints :math:`lb <= g(x) <= ub` (for poly option) with :math:`lb`, :math:`ub = bounds` or :math:`g(x) >= 0` (for function option) to the optimisation problem. Only ``trust-constr``, ``COBYLA``, and ``SLSQP`` methods can handle general constraints. If Poly object is provided in the poly dictionary, gradients and Hessians will be computed automatically. If a lambda function is provided in the ``function`` dictionary, the user may also provide ``jac_function`` for gradients and ``hess_function`` for Hessians; otherwise, a 2-point differentiation rule will be used to approximate the derivative and a BFGS update will be used to approximate the Hessian. :param dict poly: Arguments for poly dictionary. :param Poly poly: An instance of the Poly class. :param numpy.ndarray bounds: An array with two entries specifying the lower and upper bounds of the inequality. If there is no lower bound, set bounds[0] = -np.inf.If there is no upper bound, set bounds[1] = np.inf. :param dict custom: Additional custom callable arguments. :callable function: The constraint function to be called. :callable jac_function: The gradient (or derivative) of the constraint. :callable hess_function: The Hessian of the constraint function. """ assert self.method in ['SLSQP', 'trust-constr', 'COBYLA'] assert poly is not None or custom is not None if poly is not None: assert 'bounds' in poly bounds = poly['bounds'] assert 'poly' in poly gpoly = poly['poly'] # Get lambda functions for function, gradient, and Hessians from poly object g = gpoly.get_polyfit_function() jac = gpoly.get_polyfit_grad_function() hess = gpoly.get_polyfit_hess_function() constraint = lambda x: g(x)[0] constraint_deriv = lambda x: jac(x)[:, 0] constraint_hess = lambda x, v: hess(x)[:, :, 0] if self.method == 'trust-constr': self.constraints.append( optimize.NonlinearConstraint(constraint, bounds[0], bounds[1], jac=constraint_deriv, hess=constraint_hess)) # other methods add inequality constraints using dictionary files elif self.method == 'SLSQP': if not np.isinf(bounds[0]): self.constraints.append({ 'type': 'ineq', 'fun': lambda x: constraint(x) - bounds[0], 'jac': constraint_deriv }) if not np.isinf(bounds[1]): self.constraints.append({ 'type': 'ineq', 'fun': lambda x: -constraint(x) + bounds[1], 'jac': lambda x: -constraint_deriv(x) }) else: if not np.isinf(bounds[0]): self.constraints.append({ 'type': 'ineq', 'fun': lambda x: constraint(x) - bounds[0] }) if not np.isinf(bounds[1]): self.constraints.append({ 'type': 'ineq', 'fun': lambda x: -constraint(x) + bounds[1] }) elif custom is not None: assert 'function' in custom constraint = custom['function'] if 'jac_function' in custom: constraint_deriv = custom['jac_function'] else: constraint_deriv = '2-point' if 'hess_function' in custom: constraint_hess = lambda x, v: custom['hess_function'](x) else: constraint_hess = optimize.BFGS() if self.method == 'trust-constr': self.constraints.append( optimize.NonlinearConstraint(constraint, 0.0, np.inf, jac=constraint_deriv, hess=constraint_hess)) elif self.method == 'SLSQP': if 'jac_function' in custom: self.constraints.append({ 'type': 'ineq', 'fun': constraint, 'jac': constraint_deriv }) else: self.constraints.append({ 'type': 'ineq', 'fun': constraint }) else: self.constraints.append({'type': 'ineq', 'fun': constraint})
def solve(N, n, Rs, h_baro=np.nan, x0=None): # ### check quality of measurements and discard accordingly # scale measurement to distance between stations mp, RD, R, Rn, RD_sc = GenMeasurements(N, n, Rs) # determine problem size dim = len(mp) # ### calculate quadratic form A, V, D, b, singularity = getHyperbolic(N, mp, dim, RD, R, Rn) if h_baro is not np.nan: # use aultitude info --> define equality constraint cons = sciop.NonlinearConstraint( lambda x: WGS84(x, h_baro, mode=0), 0, 0, jac=lambda x: WGS84(x, h_baro, mode=1), hess=lambda x, __: WGS84(x, h_baro, mode=2), ) else: cons = () # ### generate x0 if x0 is None: x0 = genx0(N, mp, RD_sc, h_baro) # ### solve and record xlist = [] sol = sciop.minimize( lambda x: FJsq(x, A, b, dim, V, RD, Rn, mode=0), x0, jac=lambda x: FJsq(x, A, b, dim, V, RD, Rn, mode=1), hess=lambda x: 0.25 * FJsq(x, A, b, dim, V, RD, Rn, mode=2), method='SLSQP', tol=1e-3, constraints=cons, options={ 'maxiter': 100, # 'xtol': 0.1, }, callback=lambda xk: xlist.append(xk), ) xn = sol.x opti = 0 cost = sol.fun nfev = sol.nfev niter = sol.nit ecode = 0 # build diagnostic struct inDict = { 'A': A, 'b': b, 'V': V, 'D': D, 'dim': dim, 'RD': RD, 'xn': xn, 'fun': lambda x, m: FJsq(x, A, b, dim, V, RD, Rn, mode=m), 'xlist': xlist, 'ecode': ecode, 'mp': mp, 'Rn': Rn, 'sol': sol } return xn, opti, cost, nfev, niter, RD, inDict
def runExp(key): key = str(key) print('Running trial', key) pool = pools[key] expDict = {'Initial': {}, 'Annealing': {}, 'Genetic': {}, 'Random': {}} expDict['Initial']['Deck'] = [] for card in pool: expDict['Initial']['Deck'].append(card) expDict['Initial']['Score'] = 0 # Remove basic lands tbr = [] for card in pool: if 'Basic Land' in db[card]['type']: tbr.append(card) for card in tbr: pool.remove(card) # Remove underrepresented colors colorMembers = [] for card in pool: for cardColor in db[card]['colorIdentity']: colorMembers.append(cardColor) colorRef = ['R', 'W', 'G', 'B', 'U'] colorCounts = [colorMembers.count(c) for c in colorRef] removeColors = [] for i in range(3): minColorInd = np.argmin(colorCounts) removeColors.append(colorRef[minColorInd]) del colorRef[minColorInd] del colorCounts[minColorInd] tbr = [] for card in pool: if len(list(set(removeColors).intersection( db[card]['colorIdentity']))) > 0: tbr.append(card) for card in tbr: pool.remove(card) varbound = np.array([[0, len(pool) - 1]] * 23) nlc = optimize.NonlinearConstraint(uniqueConstraint, .5, 1.5) annealRes = optimize.dual_annealing(score, args=(db, pool), bounds=varbound, maxiter=10000) if annealRes.fun == 0: print("Annealing Score:", annealRes.fun) return None genRes = optimize.differential_evolution(score, varbound, args=(db, pool), constraints=(nlc)) randResSel = random.sample(range(len(pool)), 23) print("Annealing Score:", annealRes.fun) print("Genetic Score:", genRes.fun) if annealRes.fun < 0 and genRes.fun < 0: expDict['Annealing']['Deck'] = [] for x in annealRes.x: expDict['Annealing']['Deck'].append(db[pool[int(x)]]['name']) expDict['Annealing']['Score'] = annealRes.fun expDict['Annealing']['Card Score'], expDict['Annealing'][ 'Curve Score'] = getDeckStats(expDict['Annealing']['Deck'], db, pool) expDict['Genetic']['Deck'] = [] for x in genRes.x: expDict['Genetic']['Deck'].append(db[pool[int(x)]]['name']) expDict['Genetic']['Score'] = genRes.fun expDict['Genetic']['Card Score'], expDict['Genetic'][ 'Curve Score'] = getDeckStats(expDict['Genetic']['Deck'], db, pool) expDict['Random']['Deck'] = [] for x in randResSel: expDict['Random']['Deck'].append(db[pool[int(x)]]['name']) expDict['Random']['Card Score'], expDict['Random'][ 'Curve Score'] = getDeckStats(expDict['Random']['Deck'], db, pool) expDict['Random']['Score'] = -expDict['Random'][ 'Card Score'] * expDict['Random']['Curve Score'] return expDict
## some FA to ratio conversion, computed elsewhere # # FA ~ 0.2425 # ratio_min = 1.5 # FA ~ 0.0 ratio_min = 1. # FA ~ 0.8111 ratio_max = 6.0 ################################################# ## nonlinear ratio constraint object fa_cons = opt.NonlinearConstraint(ratio, np.array([ratio_min]), np.array([ratio_max]), jac=ratio_jac, hess=opt.BFGS()) ## uFA for this type of models def microFA(d1, d2, d3, fin, fex, fcsf): # if (fin < 0) or (fex < 0) or (fin + fex > 1): # return np.nan microAx = fin * d1 + fex * d2 + fcsf * 3 microRad = fex * d3 + fcsf * 3 microMean = (microAx + 2 * microRad) / 3. microFA = np.sqrt( (3 / 2.) * ((microAx - microMean)**2 + 2 * (microRad - microMean)**2) / (microAx**2 + 2 * microRad**2))
def update_graph(xaxis_pareto_id, yaxis_pareto_id, cannon_diameter, cannon_power, barrel_length, max_dist, prob_misfire, MC_size): global xopt_diam, xopt_pow, xopt_len # global xobj,yobj # xobj = objslist.index(xaxis_pareto_id) # yobj = objslist.index(yaxis_pareto_id) def obj_range(cannon_diameter, cannon_power): # Ranges 0-2041 maxspeed = math.sqrt( 2 * cannon_power / (cannon_diameter / 50)) # ft/s; assumes 1s of acceleration, 0.2 lb/cm of diameter return (maxspeed**2) * math.sin(math.pi / 2) / 9.8 def obj_cost(cannon_diameter, cannon_power, barrel_length): #Ranges 0 - 78.4 return cannon_diameter * (barrel_length**2) * cannon_power / 1000000 def obj_successrate(cannon_diameter, cannon_power, max_dist, prob_misfire, MC_size): mission = mission_success(cannon_diameter, cannon_power, max_dist, prob_misfire, MC_size) return mission[0] numparetos = 7 paretox = [] # Range paretoy = [] # Cost xopt_diam = [] xopt_pow = [] xopt_len = [] # Vars = {cannon_diameter,cannon_power,barrel_length} x0 = [150, 250, 7] ulb = ((50, 400), (25, 1000), (3, 14)) for i in range(numparetos): # funlist = ['obj_range(x[0],x[1])','obj_cost(x[0],x[1],x[2])','obj_successrate(x[0],x[1],20,5,500)'] def optcon(x): cannon_diameter = x[0] cannon_power = x[1] barrel_length = x[2] # return eval(funlist[xobj]) if xaxis_pareto_id == 'Range (mi)': return obj_range(cannon_diameter, cannon_power) elif xaxis_pareto_id == 'Cost (M$)': return obj_cost(cannon_diameter, cannon_power, barrel_length) elif xaxis_pareto_id == 'Mission Success (%)': return obj_successrate(cannon_diameter, cannon_power, 20, 5, 500) def optobj(x): cannon_diameter = x[0] cannon_power = x[1] barrel_length = x[2] return obj_cost(cannon_diameter, cannon_power, barrel_length) # return -obj_successrate(cannon_diameter,cannon_power,max_dist,prob_misfire) # coneps = (i/(numparetos-1))*2041 # constr = optimize.NonlinearConstraint(optcon,coneps,10000) if xaxis_pareto_id == 'Range (mi)': coneps = 1 + (i / (numparetos - 1)) * 406 constr = optimize.NonlinearConstraint(optcon, coneps, 500) elif xaxis_pareto_id == 'Cost (M$)': coneps = (i / (numparetos - 1)) * 0.5 constr = optimize.NonlinearConstraint(optcon, 0, coneps) elif xaxis_pareto_id == 'Mission Success (%)': coneps = (i / (numparetos - 1)) * 100 constr = optimize.NonlinearConstraint(optcon, coneps, 101) optresult = optimize.minimize( optobj, x0, method='SLSQP', bounds=ulb, constraints=constr) #, options={'eps':0.05}) xmin = optresult.x xopt_diam.append(xmin[0]) xopt_pow.append(xmin[1]) xopt_len.append(xmin[2]) if xaxis_pareto_id == 'Range (mi)': paretox.append(obj_range(xmin[0], xmin[1])) elif xaxis_pareto_id == 'Cost (M$)': paretox.append(obj_cost(xmin[0], xmin[1], xmin[2])) elif xaxis_pareto_id == 'Mission Success (%)': paretox.append(obj_successrate(xmin[0], xmin[1], 20, 5, 500)) # paretox.append(obj_range(xmin[0],xmin[1])) paretoy.append(obj_cost(xmin[0], xmin[1], xmin[2])) return { 'data': [{ 'x': paretox, 'y': paretoy, 'text': ['Pareto point'], 'name': 'Pareto point', 'customdata': [_ for _ in range(numparetos)], 'mode': 'markers', 'marker': { 'size': 15, 'color': 'red', 'opacity': 0.5 } }], 'layout': go.Layout(xaxis={ 'title': xaxis_pareto_id, 'type': 'linear' }, yaxis={ 'title': yaxis_pareto_id, 'type': 'linear' }, hovermode='closest') }
def _solve_constr_bound(x, weight, z0=None, method='trust-constr', rss_lim=0.1, tol=None, **options): method = method.lower() assert method in ['trust-constr', 'slsqp'] assert x.ndim == 1 assert weight.ndim == 2 assert weight.shape[0] == x.shape[0] if z0 is None: z0 = np.linalg.lstsq(weight, x[:, None], rcond=None)[0][:, 0] assert z0.ndim == 1 # store batch_size and code_size n_components = z0.shape[0] # expand pos/neg z0 = np.concatenate([np.maximum(z0, 0), np.maximum(-z0, 0)]) def weight_dot(v): return weight.dot(v[:n_components]) - weight.dot(v[n_components:]) def weightT_dot(v): Wtv = np.zeros(2 * n_components) Wtv[:n_components] = weight.T.dot(v) Wtv[n_components:] = -Wtv[:n_components] return Wtv # objective f = lambda z: np.sum(z) jac = lambda z: np.ones_like(z) if method == 'trust-constr': hess_ = np.zeros((z0.size, z0.size)) hess = lambda z: hess_ else: hess = None # constraints if method == 'trust-constr': H = weight.T @ weight def constr_hess(x, v): def matvec(p): Hp = np.zeros_like(p) Hp[:n_components] = H.dot(p[:n_components]) - H.dot( p[n_components:]) Hp[n_components:] = -Hp[:n_components] return v[0] * Hp return LinearOperator((2 * n_components, 2 * n_components), matvec=matvec) constr = optimize.NonlinearConstraint( fun=lambda z: 0.5 * np.sum((weight_dot(z) - x)**2), lb=-np.inf, ub=rss_lim, jac=lambda z: weightT_dot(weight_dot(z) - x), hess=constr_hess) else: constr = { 'type': 'ineq', 'fun': lambda z: rss_lim - 0.5 * np.sum((weight_dot(z) - x)**2), 'jac': lambda z: -weightT_dot(weight_dot(z) - x) } # bounds bounds = optimize.Bounds(np.zeros(z0.size), np.full(z0.size, np.inf)) z0 = z0.flatten() res = optimize.minimize(f, z0, method=method, tol=tol, jac=jac, hess=hess, constraints=constr, bounds=bounds, options=options) # reverse pos/neg expansion zf = res.x[:n_components] - res.x[n_components:] return zf
N = 50 delta = np.linspace(0.001, 0.75, N) #Create empty array for solutions q_optimal = np.array([]) cmu_optimal = np.array([]) #Find solutions for every delta for i in range(N): R = delta[i] * 2 while np.abs(R - delta[i]) > 1E-4: print(R, delta[i]) x0 = initialize_x(1, init_type='normal') #Must be length of one nonlinear_constraint = optimize.NonlinearConstraint( cons_c, lb=0.0, ub=delta[i], jac='3-point', hess=optimize.BFGS()) res = optimize.minimize(cmu_Q, x0, method='trust-constr', constraints=[nonlinear_constraint], tol=1E-12, options={ 'verbose': 1, 'xtol': 1E-12, 'gtol': 1E-12, 'maxiter': 2500 }, bounds=bounds) q = np.asarray(np.real(res.x)) R = cons_c(q)
def discreteness_constraint(x): return (x - 0.5)*(x - 0.5) - 0.25 def constr_jac(x): return 2 * np.identity(n) * x - 1. def constr_hess(x, v): return 2 * np.identity(n) * v # linear constraint matrix C = np.ones((1, n), dtype=np.float32) # C[1:] = np.identity(n, dtype=np.float32) # lb = np.zeros(n+1, dtype=np.float32) # lb[0] = m # ub = np.ones(n+1, dtype=np.float32) # ub[0] = m with Timer('minimizer'): res = so.minimize(energy, x0=np.ones_like(s), jac=jac, hess=hess, method='trust-constr', constraints=[so.LinearConstraint(C, m, m), so.NonlinearConstraint(discreteness_constraint, 0, 1e-8)]) x = res.x # x = np.round(res.x) print(f"Final energy: {energy(x)}") print(x) print(np.sum(x)) # plot the sites, colored with their value of x plt.figure(figsize=(8, 8)) sc = plt.scatter(positions[:, 0], positions[:, 1], c=x, cmap='viridis') plt.gca().set_aspect('equal') plt.colorbar(sc, fraction=0.046, pad=0.035) plt.show()