def handle_results(self, res): # sympy to pyomo converter self._results[Metrics.RMSE] = self.alamopy_results['rmse'] self._results[Metrics.SSE] = self.alamopy_results['ssr'] self._results[Metrics.Time] = self.alamopy_results['totaltime'] self._results[Metrics.MSE] = float(self.alamopy_results['rmse']) ** 2 self._results[Metrics.Order] = self.alamopy_results['nbas'] self._results[Metrics.R2] = self.alamopy_results['R2'] # Generate pyomo expression m = pyo.ConcreteModel() m.x = pyo.Var(range(len(self._rdata_in))) obj_map = PyomoSympyBimap() obj_map.sympy2pyomo = {} sympy_locals = {} i = 1 for label in res['xlabels']: sympy_locals[label] = sympy.Symbol(label) sympy_obj = sympy.Symbol(label) obj_map.sympy2pyomo[sympy_obj] = m.x[i] i += 1 model_string = "" if type(res['model']) is dict: key = list(res['model'].keys())[0] model_string = res['model'][key].split('=')[1] else: model_string = res['model'].split('=')[1] model_symp = parse_expr(model_string.replace("^", "**"), local_dict=sympy_locals) model_pyomo = sympy2pyomo_expression(model_symp, obj_map) self._model = model_pyomo
def model_is_valid(model): ''' Possibilities: Deterministic model has a single objective Deterministic model has no objective Deterministic model has multiple objectives :param model: the deterministic model :return: True if it satisfies certain properties, else False. ''' objectives = list(model.component_data_objects(Objective)) for o in objectives: o.deactivate() if len(objectives) == 1: ''' Ensure objective is a minimization. If not, change the sense. ''' obj = objectives[0] if obj.sense is not minimize: sympy_obj = sympyify_expression(-obj.expr) # Use sympy to distribute the negation so the method for determining first/second stage costs is valid min_obj = Objective(expr=sympy2pyomo_expression( sympy_obj[1].simplify(), sympy_obj[0])) model.del_component(obj) model.add_component( unique_component_name(model, obj.name + '_min'), min_obj) return True elif len(objectives) > 1: ''' User should deactivate all Objectives in the model except the one represented by the output of first_stage_objective + second_stage_objective ''' return False else: ''' No Objective objects provided as part of the model, please provide an Objective to your model so that PyROS can infer first- and second-stage objective. ''' return False
def differentiate(expr, wrt=None, wrt_list=None): """Return derivative of expression. This function returns an expression or list of expression objects corresponding to the derivative of the passed expression 'expr' with respect to a variable 'wrt' or list of variables 'wrt_list' Args: expr (Expression): Pyomo expression wrt (Var): Pyomo variable wrt_list (list): list of Pyomo variables Returns: Expression or list of Expression objects """ if not sympy_available: raise RuntimeError( "The sympy module is not available.\n\t" "Cannot perform automatic symbolic differentiation.") if not ((wrt is None) ^ (wrt_list is None)): raise ValueError( "differentiate(): Must specify exactly one of wrt and wrt_list") import sympy # # Convert the Pyomo expression to a sympy expression # objectMap, sympy_expr = sympyify_expression(expr) # # The partial_derivs dict holds intermediate sympy expressions that # we can re-use. We will prepopulate it with None for all vars that # appear in the expression (so that we can detect wrt combinations # that are, by definition, 0) # partial_derivs = {x: None for x in objectMap.sympyVars()} # # Setup the WRT list # if wrt is not None: wrt_list = [wrt] else: # Copy the list because we will normalize things in place below wrt_list = list(wrt_list) # # Convert WRT vars into sympy vars # ans = [None] * len(wrt_list) for i, target in enumerate(wrt_list): if target.__class__ is not tuple: target = (target, ) wrt_list[i] = tuple(objectMap.getSympySymbol(x) for x in target) for x in wrt_list[i]: if x not in partial_derivs: ans[i] = 0. break # # We assume that users will not request duplicate derivatives. We # will only cache up to the next-to last partial, and if a user # requests the exact same derivative twice, then we will just # re-calculate it. # last_partial_idx = max(len(x) for x in wrt_list) - 1 # # Calculate all the derivatives # for i, target in enumerate(wrt_list): if ans[i] is not None: continue part = sympy_expr for j, wrt_var in enumerate(target): if j == last_partial_idx: part = sympy.diff(part, wrt_var) else: partial_target = target[:j + 1] if partial_target in partial_derivs: part = partial_derivs[partial_target] else: part = sympy.diff(part, wrt_var) partial_derivs[partial_target] = part ans[i] = sympy2pyomo_expression(part, objectMap) # # Return the answer # return ans if wrt is None else ans[0]