def check_deg_block(s, k, i): fc = s.drillstring.pdm.failure fc.rogp.set_tanh(False) # Initialize parameters alpha = 1 - (1 - s.alpha) / (len(s.Xm) + 1) F = sp.stats.norm.ppf(alpha) X = s.X[k:i] Xvar = s.Xvar delta = {s.X[j]: Xvar[j + 1] - Xvar[j] for j in range(k, i)} dp = [[s.m.rop[x].deltap()] for x in X] dp = _to_np_obj_array(dp) # TODO: make eps = 0.001 a parameter dt = [[delta[x] / (s.m.rop[x].V + 0.001)] for x in X] dt = [[x[0]()] for x in dt] dt = _to_np_obj_array(dt) sep = Sep(X) r = _pyomo_to_np(sep.m.r, ind=X) # Calculate matrices Sig = fc.rogp.predict_cov_latent(dp).astype('float') inv = np.linalg.inv(Sig) hz = fc.rogp.warp(r) mu = fc.rogp.predict_mu_latent(dp) diff = hz - mu obj = np.matmul(dt.T, r)[0, 0] sep.m.Obj = p.Objective(expr=obj, sense=p.maximize) c = np.matmul(np.matmul(diff.T, inv), diff)[0, 0] sep.m.cons.add(c <= F) utils.solve(sep, solver='Baron') if obj() - 1.0 > 10e-5: return False return True
def get_deg_block(s, k, i): fc = s.drillstring.pdm.failure fc.rogp.set_tanh(False) # Initialize parameters alpha = 1 - (1 - s.alpha) / (len(s.Xm) + 1) F = sp.stats.norm.ppf(alpha) X = s.X[k:i] Xvar = s.Xvar delta = {s.X[j]: Xvar[j + 1] - Xvar[j] for j in range(k, i)} dp = [[s.m.rop[x].deltap()] for x in X] dp = _to_np_obj_array(dp) # TODO: make eps = 0.001 a parameter dt = [[delta[x] / (s.m.rop[x].V + 0.001)] for x in X] dt = [[x[0]()] for x in dt] dt = _to_np_obj_array(dt) # Calculate matrices cov = fc.rogp.predict_cov_latent(dp).astype('float') * F mu = fc.rogp.predict_mu_latent(dp).astype('float') c = dt.astype('float') return mu, cov, c.flatten()
def _add_deg_block(self, k, i): # Shorthands fc = self.drillstring.pdm.failure m = self.m # Initialize parameters alpha = 1 - (1 - self.alpha) / (len(self.Xm) + 1) F = sp.stats.norm.ppf(alpha) self.F = F X = self.X[k:i] Xvar = self.Xvar delta = {self.X[j]: Xvar[j + 1] - Xvar[j] for j in range(k, i)} dp = [[m.rop[x].deltap] for x in X] dp = _to_np_obj_array(dp) dt = [[delta[x] / (m.rop[x].V + eps)] for x in X] dt = _to_np_obj_array(dt) r = _pyomo_to_np(m.r, ind=X) # Calculate matrices Sig = fc.rogp.predict_cov_latent(dp) dHinv = 1 / fc.rogp.warp_deriv(r) dHinv = np.diag(dHinv[:, 0]) hz = fc.rogp.warp(r) mu = fc.rogp.predict_mu_latent(dp) u = _pyomo_to_np(m.u, ind=X[-1:]) LHS = np.matmul(Sig, dHinv) LHS = np.matmul(LHS, dt) RHS = LHS LHS = LHS + 2 * u * (hz - mu) # Add stationarity condition for lhs in np.nditer(LHS, ['refs_ok']): m.cons.add(lhs.item() == 0) RHS = np.matmul(dHinv, RHS) rhs = np.matmul(dt.T, RHS)[0, 0] lhs = 4 * u[0, 0]**2 * F # Dual variable constraint m.cons.add(lhs == rhs) # Primal constraint m.cons.add(np.matmul(dt.T, r).item() == m.R[X[-1]])
def _reformulate(self, c, param, uncset, counterpart, initialize_wolfe=False): """ Reformulate an uncertain constraint or objective c: Constraint or Objective param: UncParam uncset: UncSet counterpart: Block """ # Only proceed if uncertainty set is WarpedGPSet from rogp.util.numpy import _pyomo_to_np, _to_np_obj_array repn = self.generate_repn_param(c) assert repn.is_linear(), ("Only constraints which are linear in " "the uncertain parameters are valid for " "uncertainty set WarpedGPSet.") # Constraint may contain subset of elements of UncParam index_set = [p.index() for p in repn.linear_vars] x = [[xi] for xi in repn.linear_coefs] x = _to_np_obj_array(x) # Set up Block for Wolfe duality constraints b = counterpart # Set up extra variables b.y = Var(param.index_set()) # Set bounds for extra variables based on UncParam bounds for i in param: lb, ub = param[i].lb, param[i].ub b.y[i].setlb(lb) b.y[i].setub(ub) if ((lb is not None and lb is not float('-inf')) and (ub is not None and ub is not float('inf'))): b.y[i].value = (ub + lb) / 2 y = _pyomo_to_np(b.y, ind=index_set) # Setup dual vars based on sense if c.ctype is Constraint: if c.has_ub() and not c.has_lb(): b.u = Var(within=NonPositiveReals) elif not c.has_ub() and c.has_lb(): b.u = Var(within=NonNegativeReals) else: raise RuntimeError( "Uncertain constraints with 'WarpedGPSet' " "currently only support either an upper or a " "lower bound, not both.") elif c.ctype is Objective: if c.sense is maximize: b.u = Var(within=NonPositiveReals) else: b.u = Var(within=NonNegativeReals) u = _pyomo_to_np(b.u) # Primal constraint sub_map = {id(param[i]): b.y[i] for i in param} if c.ctype is Constraint: e_new = replace_expressions(c.body, substitution_map=sub_map) b.primal = Constraint(rule=lambda x: (c.lower, e_new, c.upper)) else: e_new = replace_expressions(c.expr, substitution_map=sub_map) b.primal = Objective(expr=e_new, sense=c.sense) # Calculate matrices gp = uncset.gp var = uncset.var if type(var) is dict: z = [var[i] for i in index_set] z = _to_np_obj_array(z) else: var = var[0] assert var.index_set() == param.index_set(), ( "Index set of `UncParam` and `var` in `WarpedGPSet` " "should be the same. Alternatively use " "var = {index: [list of vars]}") z = _pyomo_to_np(var, ind=index_set) Sig = gp.predict_cov_latent(z) mu = gp.predict_mu_latent(z) dHinv = 1 / gp.warp_deriv(y) dHinv = np.diag(dHinv[:, 0]) hz = gp.warp(y) LHS = np.matmul(Sig, dHinv) LHS = np.matmul(LHS, x) RHS = LHS LHS = LHS + 2 * u * (hz - mu) # Add stationarity condition b.stationarity = ConstraintList() for lhs in np.nditer(LHS, ['refs_ok']): b.stationarity.add(lhs.item() == 0) RHS = np.matmul(dHinv, RHS) rhs = np.matmul(x.T, RHS)[0, 0] lhs = 4 * u[0, 0]**2 * uncset.F # Set consistent initial value for u (helps convergence) if initialize_wolfe: u0 = np.sqrt(rhs() / 4 / uncset.F) if u[0, 0].ub == 0: u[0, 0].value = -u0 elif u[0, 0].lb == 0: u[0, 0].value = u0 # Dual variable constraint b.dual = Constraint(expr=lhs == rhs)
def _reformulate(self, c, param, uncset, counterpart): """ Reformulate an uncertain constraint or objective c: Constraint or Objective param: UncParam uncset: UncSet counterpart: Block """ from rogp.util.numpy import _pyomo_to_np, _to_np_obj_array repn = self.generate_repn_param(c) assert repn.is_linear(), ("Only constraints which are linear in " "the uncertain parameters are valid for " "uncertainty set 'GPSet'.") # Constraint may contain subset of elements of UncParam index_set = [p.index() for p in repn.linear_vars] x = [[xi] for xi in repn.linear_coefs] x = _to_np_obj_array(x) # Calculate matrices gp = uncset.gp var = uncset.var if type(var) is dict: pass z = [var[i] for i in index_set] z = _to_np_obj_array(z) else: var = var[0] assert var.index_set() == param.index_set(), ( "Index set of `UncParam` and `var` in `GPSet` " "should be the same. Alternatively use " "var = {index: [list of vars]}") z = _pyomo_to_np(var, ind=index_set) Sig = gp.predict_cov(z) mu = gp.predict_mu(z) nominal = np.matmul(mu.T, x)[0, 0] + repn.constant padding = np.matmul(x.T, Sig) padding = np.matmul(padding, x) padding = uncset.F * pyomo_sqrt(padding[0, 0]) # Counterpart if c.ctype is Constraint: if c.has_ub(): e_new = nominal + padding <= c.upper c_new = Constraint(expr=e_new) counterpart.upper = c_new if c.has_lb(): e_new = nominal - padding >= c.lower c_new = Constraint(expr=e_new) counterpart.lower = c_new else: e_new = nominal + padding * c.sense c_new = Objective(expr=e_new, sense=c.sense) counterpart.obj = c_new