Skip to content

Commit

Permalink
Update to ropt 0.14
Browse files Browse the repository at this point in the history
  • Loading branch information
verveerpj committed Feb 12, 2025
1 parent 947ed41 commit a67fc77
Show file tree
Hide file tree
Showing 11 changed files with 116 additions and 190 deletions.
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ everest = [
"decorator",
"resdata",
"colorama",
"ropt[pandas]>=0.13,<0.14",
"ropt-dakota>=0.11,<0.12",
"ropt[pandas]>=0.14,<0.15",
"ropt-dakota>=0.14,<0.15",
]

[tool.setuptools]
Expand Down
31 changes: 4 additions & 27 deletions src/everest/config/everest_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -657,23 +657,9 @@ def objective_names(self) -> list[str]:

@property
def constraint_names(self) -> list[str]:
names: list[str] = []

def _add_output_constraint(rhs_value: float | None, suffix=None):
if rhs_value is not None:
name = constr.name
names.append(name if suffix is None else f"{name}:{suffix}")

for constr in self.output_constraints or []:
_add_output_constraint(constr.target)
_add_output_constraint(
constr.upper_bound, None if constr.lower_bound is None else "upper"
)
_add_output_constraint(
constr.lower_bound, None if constr.upper_bound is None else "lower"
)

return names
if self.output_constraints:
return [constraint.name for constraint in self.output_constraints]
return []

@property
def result_names(self):
Expand All @@ -689,20 +675,11 @@ def result_names(self):

@property
def function_aliases(self) -> dict[str, str]:
aliases = {
return {
objective.name: objective.alias
for objective in self.objective_functions
if objective.alias is not None
}
constraints = self.output_constraints or []
for constraint in constraints:
if (
constraint.upper_bound is not None
and constraint.lower_bound is not None
):
aliases[f"{constraint.name}:lower"] = constraint.name
aliases[f"{constraint.name}:upper"] = constraint.name
return aliases

def to_dict(self) -> dict:
the_dict = self.model_dump(exclude_none=True)
Expand Down
86 changes: 39 additions & 47 deletions src/everest/optimizer/everest2ropt.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
import os
from typing import Any

import numpy as np
from ropt.config.enopt import EnOptConfig, EnOptContext
from ropt.enums import ConstraintType, PerturbationType, VariableType
from ropt.enums import PerturbationType, VariableType
from ropt.transforms import OptModelTransforms

from everest.config import (
Expand All @@ -23,13 +24,12 @@ def _parse_controls(controls: FlattenedControls, ropt_config):
None if type_ is None else VariableType[type_.upper()]
for type_ in controls.types
]
indices = [idx for idx, is_enabled in enumerate(controls.enabled) if is_enabled]
ropt_config["variables"] = {
"types": None if all(item is None for item in control_types) else control_types,
"initial_values": controls.initial_guesses,
"lower_bounds": controls.lower_bounds,
"upper_bounds": controls.upper_bounds,
"indices": indices if indices else None,
"mask": controls.enabled,
}

if "gradients" not in ropt_config:
Expand Down Expand Up @@ -119,36 +119,35 @@ def _get_control_index(name: str):
return formatted_control_names_dotdash.index(name)

coefficients_matrix = []
rhs_values = []
types = []

def _add_input_constraint(rhs_value, coefficients, constraint_type):
if rhs_value is not None:
coefficients_matrix.append(coefficients)
rhs_values.append(rhs_value)
types.append(constraint_type)
lower_bounds = []
upper_bounds = []

for constr in input_constraints:
coefficients = [0.0] * len(formatted_control_names)
for name, value in constr.weights.items():
index = _get_control_index(name)
coefficients[index] = value
coefficients_matrix.append(coefficients)

target = constr.target
upper_bound = constr.upper_bound
lower_bound = constr.lower_bound
if target is not None and (upper_bound is not None or lower_bound is not None):
raise RuntimeError(
"input constraint error: target cannot be combined with bounds"
if constr.target is None:
lower_bounds.append(
-np.inf if constr.lower_bound is None else constr.lower_bound
)
upper_bounds.append(
np.inf if constr.upper_bound is None else constr.upper_bound
)
_add_input_constraint(target, coefficients, ConstraintType.EQ)
_add_input_constraint(upper_bound, coefficients, ConstraintType.LE)
_add_input_constraint(lower_bound, coefficients, ConstraintType.GE)
else:
if constr.lower_bound is not None or constr.upper_bound is not None:
raise RuntimeError(
"input constraint error: target cannot be combined with bounds"
)
lower_bounds.append(constr.target)
upper_bounds.append(constr.target)

ropt_config["linear_constraints"] = {
"coefficients": coefficients_matrix,
"rhs_values": rhs_values,
"types": types,
"lower_bounds": lower_bounds,
"upper_bounds": upper_bounds,
}


Expand All @@ -158,35 +157,28 @@ def _parse_output_constraints(
if not output_constraints:
return

rhs_values: list[float] = []
types: list[ConstraintType] = []

def _add_output_constraint(
rhs_value: float | None, constraint_type: ConstraintType, suffix=None
):
if rhs_value is not None:
rhs_values.append(rhs_value)
types.append(constraint_type)
lower_bounds = []
upper_bounds = []

for constr in output_constraints:
target = constr.target
upper_bound = constr.upper_bound
lower_bound = constr.lower_bound
if target is not None and (upper_bound is not None or lower_bound is not None):
raise RuntimeError(
"output constraint error: target cannot be combined with bounds"
if constr.target is None:
lower_bounds.append(
-np.inf if constr.lower_bound is None else constr.lower_bound
)
_add_output_constraint(target, ConstraintType.EQ)
_add_output_constraint(
upper_bound, ConstraintType.LE, None if lower_bound is None else "upper"
)
_add_output_constraint(
lower_bound, ConstraintType.GE, None if upper_bound is None else "lower"
)
upper_bounds.append(
np.inf if constr.upper_bound is None else constr.upper_bound
)
else:
if constr.lower_bound is not None or constr.upper_bound is not None:
raise RuntimeError(
"input constraint error: target cannot be combined with bounds"
)
lower_bounds.append(constr.target)
upper_bounds.append(constr.target)

ropt_config["nonlinear_constraints"] = {
"rhs_values": rhs_values,
"types": types,
"lower_bounds": lower_bounds,
"upper_bounds": upper_bounds,
}


Expand Down Expand Up @@ -282,7 +274,7 @@ def _parse_optimization(
# filter implementing cvar:
objective_count = len(ropt_config["objectives"]["weights"])
constraint_count = len(
ropt_config.get("nonlinear_constraints", {}).get("rhs_values", [])
ropt_config.get("nonlinear_constraints", {}).get("lower_bounds", [])
)
ropt_config["objectives"]["realization_filters"] = objective_count * [0]
if constraint_count > 0:
Expand Down
45 changes: 16 additions & 29 deletions src/everest/optimizer/opt_model_transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import numpy as np
from numpy.typing import NDArray
from ropt.enums import ConstraintType
from ropt.transforms import OptModelTransforms
from ropt.transforms.base import (
NonLinearConstraintTransform,
Expand Down Expand Up @@ -49,12 +48,18 @@ def transform_magnitudes(self, values: NDArray[np.float64]) -> NDArray[np.float6
return values / self._scales

def transform_linear_constraints(
self, coefficients: NDArray[np.float64], rhs_values: NDArray[np.float64]
) -> tuple[NDArray[np.float64], NDArray[np.float64]]:
return (
coefficients * self._scales,
rhs_values - np.matmul(coefficients, self._offsets),
)
self,
coefficients: NDArray[np.float64],
lower_bounds: NDArray[np.float64],
upper_bounds: NDArray[np.float64],
) -> tuple[NDArray[np.float64], NDArray[np.float64], NDArray[np.float64]]:
if self._offsets is not None:
offsets = np.matmul(coefficients, self._offsets)
lower_bounds = lower_bounds - offsets # noqa: PLR6104
upper_bounds = upper_bounds - offsets # noqa: PLR6104
if self._scales is not None:
coefficients = coefficients * self._scales # noqa: PLR6104
return coefficients, lower_bounds, upper_bounds


class ObjectiveScaler(ObjectiveTransform):
Expand Down Expand Up @@ -96,28 +101,10 @@ def __init__(
self._auto_scales = np.asarray(auto_scales, dtype=np.bool_)
self._weights = np.asarray(weights, dtype=np.float64)

def transform_rhs_values(
self, rhs_values: NDArray[np.float64], types: NDArray[np.ubyte]
) -> tuple[NDArray[np.float64], NDArray[np.ubyte]]:
def flip_type(constraint_type: ConstraintType) -> ConstraintType:
match constraint_type:
case ConstraintType.GE:
return ConstraintType.LE
case ConstraintType.LE:
return ConstraintType.GE
case _:
return constraint_type

rhs_values = rhs_values / self._scales # noqa: PLR6104
# Flip inequality types if self._scales < 0 in the division above:
types = np.fromiter(
(
flip_type(type_) if scale < 0 else type_
for type_, scale in zip(types, self._scales, strict=False)
),
np.ubyte,
)
return rhs_values, types
def transform_bounds(
self, lower_bounds: NDArray[np.float64], upper_bounds: NDArray[np.float64]
) -> tuple[NDArray[np.float64], NDArray[np.float64]]:
return lower_bounds / self._scales, upper_bounds / self._scales

def forward(self, constraints: NDArray[np.float64]) -> NDArray[np.float64]:
return constraints / self._scales
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,40 +37,28 @@
1.0
]
],
"rhs_values": [
0.4
"lower_bounds": [
null
],
"types": [
1
"upper_bounds": [
0.4
]
},
"nonlinear_constraints": {
"auto_scale": [
false
],
"function_estimators": null,
"realization_filters": null,
"rhs_values": [
1.0
],
"scales": [
"lower_bounds": [
1.0
],
"types": [
2
"realization_filters": null,
"upper_bounds": [
null
]
},
"objectives": {
"auto_scale": [
false
],
"function_estimators": [
0
],
"realization_filters": null,
"scales": [
1.0
],
"weights": [
1.0
]
Expand Down Expand Up @@ -102,11 +90,6 @@
}
],
"variables": {
"indices": [
0,
1,
2
],
"initial_values": [
0.25,
0.25,
Expand All @@ -117,8 +100,11 @@
-1.0,
-1.0
],
"offsets": null,
"scales": null,
"mask": [
true,
true,
true
],
"types": [
1,
1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,10 @@
"linear_constraints": null,
"nonlinear_constraints": null,
"objectives": {
"auto_scale": [
false
],
"function_estimators": [
0
],
"realization_filters": null,
"scales": [
1.0
],
"weights": [
1.0
]
Expand Down Expand Up @@ -72,11 +66,6 @@
}
],
"variables": {
"indices": [
0,
1,
2
],
"initial_values": [
0.1,
0.1,
Expand All @@ -87,8 +76,11 @@
-1.0,
-1.0
],
"offsets": null,
"scales": null,
"mask": [
true,
true,
true
],
"types": [
1,
1,
Expand Down
Loading

0 comments on commit a67fc77

Please sign in to comment.