def _process_matrix_weight(self, var_dim, value, length, length_name, is_terminal=False): value = atleast_2d_col(value) value_shape = value.shape if value_shape[0] != value_shape[1]: raise ValueError( f"{self._weight_type} weight for opt_var: '{self._var_name}', must be square. Currently has shape: " f"{value_shape}") elif is_terminal: if value_shape[0] == var_dim: return value else: raise ValueError( f"Row dim of {self._weight_type} terminal weight for opt_var: '{self._var_name}' must " f"be in {{{var_dim}}}") elif value_shape[0] == (var_dim * length): return value elif value_shape[0] == var_dim: return block_diag_dense([value] * length) else: raise ValueError( f"Row dim of {self._weight_type} weight for opt_var: '{self._var_name}', must be in " f"{{{var_dim}, {var_dim}*{length_name}}}")
def update_sim_k(self, k, sim_k=None, **kwargs): sim_k = sim_k if sim_k is not None else {} try: sim_k.update(kwargs) except AttributeError: raise TypeError( f'sim_k must be subtype of dict or None, not: {type(sim_k).__name__!r}' ) insert = self.LogEntry_k(self._nan_insert) if self.get(k): insert.update(self[k]) for var_name, var_k in sim_k.items(): if var_k is not None: var_k = atleast_2d_col(var_k) insert_var = insert.get(var_name) if insert_var is not None and insert_var.shape != var_k.shape: raise ValueError( "shape of var_k must match previous inserts") else: insert[var_name] = var_k self._base_dict_setitem(k, insert) if set(insert).difference(self._nan_insert): self._nan_insert = { var_name: self._nan_if_num(var) for var_name, var in insert.items() }
def _process_vector_weight(self, var_dim, value, length, length_name, is_terminal=False): value = atleast_2d_col(value) value_shape = value.shape if value_shape[1] != 1: raise ValueError( f"Column dim of {self._weight_type} weight for opt_var: '{self._var_name}', must be 1." ) elif is_terminal: if value_shape[0] == var_dim: return value else: raise ValueError( f"Row dim of {self._weight_type} terminal weight for opt_var: '{self._var_name}' must " f"be in {{{var_dim}}}") elif value_shape[0] == (var_dim * length): return value elif value_shape[0] == var_dim: return np.tile(value, (length, 1)) else: raise ValueError( f"Row dim of {self._weight_type} weight for opt_var: '{self._var_name}', must be in " f"{{{var_dim}, {var_dim}*{length_name}}}")
def get_omega_tilde_scenario(self, k, N_tilde, num_scenarios=1): omega_tilde_scenario = None if self.omega_scenarios is not None: scenarios = self._omega_scenario_values nomega = self.mld_info.nomega row = (k % self.intervals_per_day) * nomega assert (scenarios.flags.f_contiguous) limit = scenarios.size - row - (N_tilde * nomega) - 1 if limit <= 0 or limit < (N_tilde * nomega * num_scenarios): raise ValueError( "Insufficient number of scenarios to draw from.") valid_columns = int( np.unravel_index( indices=limit, dims=scenarios.shape, order='F')[1]) - 1 omega_tilde_scenarios = [] for column_sel in np.random.randint(low=0, high=valid_columns, size=num_scenarios): # flat_index = np.ravel_multi_index(multi_index=[row, column_sel], dims=scenarios.shape, order='F') flat_index = scenarios.shape[0] * column_sel + row omega_tilde_scenarios.append( atleast_2d_col( scenarios.ravel(order='F')[flat_index:flat_index + (N_tilde * nomega)])) if omega_tilde_scenarios: omega_tilde_scenario = np.hstack(omega_tilde_scenarios) return omega_tilde_scenario
def get_price_vector(self, date_time_0, N_tilde, control_ts): if isinstance(control_ts, TimeDelta): delta_time = control_ts else: delta_time = TimeDelta(seconds=control_ts) if not isinstance(date_time_0, DateTime): raise TypeError(f"date_time_0 must be of type {DateTime.__name__!r}") time_vector = [date_time_0 + i * delta_time for i in range(N_tilde)] price_vector = atleast_2d_col([self.get_import_price(time_vector[i]) for i in range(N_tilde)]) return price_vector
def _set_atom_from_string(self, update_atoms, string_in, value, N_p, N_tilde, mld_info_k): atom_info = string_in.split('_') weight_type_name = 'vector' if "".join( atom_info[0:1]).islower() else 'matrix' atom_type_name = "".join(atom_info[1:2]).capitalize() if not self._regex_atom_type_pat.search(atom_type_name): atom_type_name = "Linear" if weight_type_name == 'vector' else "Quadratic" var_name = "".join(atom_info[1:2]).lower() post_fix = "_".join(atom_info[2:]) else: var_name = "".join(atom_info[2:3]).lower() post_fix = "_".join(atom_info[3:]) is_rate_atom = False if self._regex_atom_is_rate_pat.search( var_name): # ^e to enable capture of delta variable var_name = var_name[1:] is_rate_atom = True atom_name = "_".join([atom_type_name, weight_type_name ]) + ("_d" if is_rate_atom else "") if var_name in self._var_names and post_fix in self._allowed_post_fix: if value is None: return value = atleast_2d_col(value) var_dim = mld_info_k.get_var_dim(var_name) if post_fix: weight_length_name = "_".join(['weight', post_fix]) elif value.shape[0] == var_dim or value.shape[ 0] == var_dim * N_tilde: weight_length_name = "weight_N_tilde" else: weight_length_name = "weight_N_p" atom_type: ObjectiveAtomBase = _ATOM_TYPES_MAP[atom_type_name] weight_type: ObjectiveWeightBase = _WEIGHT_TYPES_MAP[ weight_type_name] self._set_atom(update_atoms, var_name, atom_name, atom_type, is_rate_atom, weight_type, weight_length_name, value) else: raise ValueError( f"weight_name: '{string_in}' is not valid. Must be of the form:\n" f" \"lower/upper[_Linear|_Quadratic|_L1|_L22|_Linf]_[d]var_name[_N_tilde|_N_p|_f]\"" )
def get_min_max_dhw_scenario(k, N_tilde, min_dhw_day, max_dhw_day): min_dhw_day = min_dhw_day.flatten() max_dhw_day = max_dhw_day.flatten() if len(min_dhw_day) != steps_per_day: raise ValueError("Invalid shape for min_dhw_day") if len(max_dhw_day) != steps_per_day: raise ValueError("Invalid shape for max_dhw_day") pos = k % steps_per_day mult = N_tilde // steps_per_day + 1 return [ atleast_2d_col(np.roll(np.tile(dwh_day, mult), -pos)[:N_tilde]) for dwh_day in [min_dhw_day, max_dhw_day] ]
def _process_parameter_update(name, parameter, required_shape, new_value=None): if 0 not in required_shape: if new_value is not None: if isinstance(new_value, cvx_e.Expression): set_value = new_value if set_value.shape == required_shape: return set_value else: set_value = atleast_2d_col(new_value) if set_value.dtype == np.object_: raise TypeError( f"'new_value' must be a subclass of a cvxpy {cvx_e.Expression.__name__}, an numeric array " f"like object or None.") if set_value.shape != required_shape: raise ValueError( f"Incorrect shape:{set_value.shape} for {name}, a shape of {required_shape} is required.") else: set_value = None if parameter is None or parameter.shape != required_shape: if set_value is None: if parameter is not None and not isinstance(parameter, cvx.Parameter): raise ValueError( f"'{name}' is currently a '{parameter.__class__.__name__}' object and can therefore not be " f"automatically set to a zero 'cvx.Parameter' object. It needs to be set explicitly.") set_value = np.zeros((required_shape)) return cvx.Parameter(shape=required_shape, name=name, value=set_value) elif set_value is not None: if isinstance(parameter, cvx.Parameter): parameter.value = set_value else: return cvx.Parameter(shape=required_shape, name=name, value=set_value) else: return None elif parameter is None or parameter.shape != required_shape: return np.empty(required_shape) else: return None
def _nan_if_num(var): if np.issubsctype(var, np.number) or np.issubsctype(var, np.bool_): return var * np.NaN else: return atleast_2d_col([None] * var.size)
def omega_tilde_k(self, value): self._omega_tilde_k = atleast_2d_col(value)
def x_k(self, value): self._x_k = atleast_2d_col(value)
def extact_price_tilde_act(price_profile, k, N_tilde): start = int( pd.Timedelta(self.forecast_lag) / price_profile.index.freq) + k end = start + N_tilde return atleast_2d_col( price_profile.values[start:end].flatten(order='C'))
def extact_omega_tilde_hat(omega_profile, k, N_tilde): start = k end = start + N_tilde return atleast_2d_col( omega_profile.values[start:end].flatten(order='C'))