Skip to content

Commit

Permalink
fix seeding
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul-Saves committed Feb 2, 2024
1 parent 3e9bf16 commit 9e89632
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 42 deletions.
15 changes: 11 additions & 4 deletions smt/applications/ego.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@

from smt.surrogate_models import KPLS, KRG, KPLSK, MGP, GEKPLS
from smt.applications.application import SurrogateBasedApplication
from smt.applications.mixed_integer import MixedIntegerContext
from smt.applications.mixed_integer import (
MixedIntegerContext,
MixedIntegerSamplingMethod,
)
from smt.utils.design_space import (
BaseDesignSpace,
DesignSpace,
Expand Down Expand Up @@ -271,10 +274,14 @@ def _setup_optimizer(self, fun):

else:
self.mixint = None
self._sampling = lambda n: self.design_space.sample_valid_x(
n,
sampling = MixedIntegerSamplingMethod(
LHS,
self.design_space,
criterion="ese",
random_state=self.options["random_state"],
)[0]
)
self._sampling = lambda n: sampling(n)

self.categorical_kernel = None

# Build DOE
Expand Down
8 changes: 4 additions & 4 deletions smt/applications/mixed_integer.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ def __init__(self, sampling_method_class, design_space, **kwargs):
)
self._design_space = design_space
if "random_state" in kwargs:
self._design_space.seed = kwargs["random_state"]
elif self._design_space.seed is None:
self._design_space.seed = 42
self._design_space.random_state = kwargs["random_state"]
elif self._design_space.random_state is None:
self._design_space.random_state = 42
self._unfolded_xlimits = design_space.get_unfolded_num_bounds()
self._output_in_folded_space = kwargs.get("output_in_folded_space", True)
kwargs.pop("output_in_folded_space", None)
Expand All @@ -60,7 +60,7 @@ def _compute(self, nt, return_is_acting=False):
x_doe, is_acting = self._design_space.sample_valid_x(
nt,
unfolded=not self._output_in_folded_space,
random_state=self._design_space.seed,
random_state=self._design_space.random_state,
)
if return_is_acting:
return x_doe, is_acting
Expand Down
50 changes: 25 additions & 25 deletions smt/applications/tests/test_ego.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def test_rosenbrock_2D(self):
xlimits = fun.xlimits
criterion = "LCB" #'EI' or 'SBO' or 'LCB'
random_state = 42
design_space = DesignSpace(xlimits, seed=random_state)
design_space = DesignSpace(xlimits, random_state=random_state)
xdoe = FullFactorial(xlimits=xlimits)(10)
ego = EGO(
n_start=30,
Expand Down Expand Up @@ -164,7 +164,7 @@ def test_rosenbrock_2D_parallel(self):
xlimits = fun.xlimits
criterion = "LCB" #'EI' or 'SBO' or 'LCB'
random_state = 42
design_space = DesignSpace(xlimits, seed=random_state)
design_space = DesignSpace(xlimits, random_state=random_state)

xdoe = FullFactorial(xlimits=xlimits)(10)
qEI = "KB"
Expand Down Expand Up @@ -250,7 +250,7 @@ def test_branin_2D_mixed_parallel(self):
IntegerVariable(*xlimits[0]),
FloatVariable(*xlimits[1]),
],
seed=random_state,
random_state=random_state,
)
sm = KRG(design_space=design_space, print_global=False, n_start=25)
mixint = MixedIntegerContext(design_space)
Expand Down Expand Up @@ -289,7 +289,7 @@ def test_branin_2D_mixed(self):
IntegerVariable(*xlimits[0]),
FloatVariable(*xlimits[1]),
],
seed=random_state,
random_state=random_state,
)
criterion = "EI" #'EI' or 'SBO' or 'LCB'

Expand Down Expand Up @@ -326,7 +326,7 @@ def test_branin_2D_mixed_tunnel(self):
IntegerVariable(*xlimits[0]),
FloatVariable(*xlimits[1]),
],
seed=random_state,
random_state=random_state,
)
criterion = "EI" #'EI' or 'SBO' or 'LCB'

Expand Down Expand Up @@ -388,10 +388,10 @@ def test_ego_mixed_integer(self):
CategoricalVariable(["large", "small"]),
OrdinalVariable([0, 2, 3]),
],
seed=42,
random_state=42,
)
samp = MixedIntegerSamplingMethod(
LHS, design_space, criterion="ese", random_state=design_space.seed
LHS, design_space, criterion="ese", random_state=design_space.random_state
)
xdoe = samp(n_doe)

Expand All @@ -402,7 +402,7 @@ def test_ego_mixed_integer(self):
xdoe=xdoe,
surrogate=KRG(design_space=design_space, print_global=False),
enable_tunneling=False,
random_state=design_space.seed,
random_state=design_space.random_state,
)
_, y_opt, _, _, _ = ego.optimize(fun=TestEGO.function_test_mixed_integer)

Expand All @@ -420,10 +420,10 @@ def test_ego_mixed_integer_gower_distance(self):
CategoricalVariable(["large", "small"]),
IntegerVariable(0, 2),
],
seed=random_state,
random_state=random_state,
)
samp = MixedIntegerSamplingMethod(
LHS, design_space, criterion="ese", random_state=design_space.seed
LHS, design_space, criterion="ese", random_state=design_space.random_state
)
xdoe = samp(n_doe)

Expand All @@ -440,7 +440,7 @@ def test_ego_mixed_integer_gower_distance(self):
print_global=False,
),
enable_tunneling=False,
random_state=design_space.seed,
random_state=design_space.random_state,
)
_, y_opt, _, _, _ = ego.optimize(fun=TestEGO.function_test_mixed_integer)

Expand Down Expand Up @@ -495,7 +495,7 @@ def f_hv(X):
IntegerVariable(0, 5), # x6
IntegerVariable(0, 5), # x7
],
seed=random_state,
random_state=random_state,
)

# x6 is active when x0 >= 2
Expand Down Expand Up @@ -686,7 +686,7 @@ def f_hv(X):
IntegerVariable(0, 2),
IntegerVariable(0, 2),
],
seed=random_state,
random_state=random_state,
)

# x4 is acting if meta == 1, 3
Expand All @@ -700,7 +700,7 @@ def f_hv(X):

n_doe = 25
samp = MixedIntegerSamplingMethod(
LHS, ds, criterion="ese", random_state=ds.seed
LHS, ds, criterion="ese", random_state=ds.random_state
)
Xt, x_is_active = samp(n_doe, return_is_acting=True)

Expand Down Expand Up @@ -742,7 +742,7 @@ def test_ego_mixed_integer_homo_gaussian(self):
CategoricalVariable(["large", "small"]),
IntegerVariable(0, 2),
],
seed=random_state,
random_state=random_state,
)
n_doe = 5
sampling = MixedIntegerSamplingMethod(
Expand Down Expand Up @@ -782,7 +782,7 @@ def test_ego_mixed_integer_homo_gaussian_pls(self):
CategoricalVariable(["large", "small"]),
IntegerVariable(0, 2),
],
seed=random_state,
random_state=random_state,
)
sampling = MixedIntegerSamplingMethod(
LHS,
Expand Down Expand Up @@ -819,7 +819,7 @@ def test_ydoe_option(self):
xlimits = fun.xlimits
criterion = "LCB" #'EI' or 'SBO' or 'LCB'
random_state = 42
design_space = DesignSpace(xlimits, seed=random_state)
design_space = DesignSpace(xlimits, random_state=random_state)
xdoe = FullFactorial(xlimits=xlimits)(10)
ydoe = fun(xdoe)
ego = EGO(
Expand All @@ -838,7 +838,7 @@ def test_find_best_point(self):
fun = TestEGO.function_test_1d
xlimits = np.array([[0.0, 25.0]])
random_state = 42
design_space = DesignSpace(xlimits, seed=random_state)
design_space = DesignSpace(xlimits, random_state=random_state)
xdoe = FullFactorial(xlimits=xlimits)(3)
ydoe = fun(xdoe)
ego = EGO(
Expand Down Expand Up @@ -874,7 +874,7 @@ def _evaluate(self, x, kx):

fun = TensorProductIndirect(ndim=2, func=func)
random_state = 42
design_space = DesignSpace(fun.xlimits, seed=42)
design_space = DesignSpace(fun.xlimits, random_state=42)

# Construction of the DOE
sampling = LHS(xlimits=fun.xlimits, criterion="m", random_state=random_state)
Expand Down Expand Up @@ -906,7 +906,7 @@ def _evaluate(self, x, kx):

return ego, fun

def test_ego_seeding(self):
def test_ego_random_stateing(self):
def f_obj(X):
"""
s01 objective
Expand Down Expand Up @@ -983,7 +983,7 @@ def f_obj(X):
)

# To define the initial DOE
random_state = 42 # seed value for the sampling
random_state = 42 # random_state value for the sampling
n_doe = 5 # initial doe size
sampling = MixedIntegerSamplingMethod(
LHS, design_space, criterion="ese", random_state=random_state
Expand Down Expand Up @@ -1039,7 +1039,7 @@ def test_qei_criterion_default(self):
fun = TestEGO.function_test_1d
xlimits = np.array([[0.0, 25.0]])
random_state = 42
design_space = DesignSpace(xlimits, seed=random_state)
design_space = DesignSpace(xlimits, random_state=random_state)
xdoe = FullFactorial(xlimits=xlimits)(3)
ydoe = fun(xdoe)
ego = EGO(
Expand Down Expand Up @@ -1094,7 +1094,7 @@ def function_test_1d(x):
xlimits = np.array([[0.0, 25.0]])

random_state = 42 # for reproducibility
design_space = DesignSpace(xlimits, seed=random_state)
design_space = DesignSpace(xlimits, random_state=random_state)
xdoe = np.atleast_2d([0, 7, 25]).T
n_doe = xdoe.size

Expand Down Expand Up @@ -1213,7 +1213,7 @@ def function_test_mixed_integer(X):
CategoricalVariable(["square", "circle"]),
IntegerVariable(0, 2),
],
seed=random_state,
random_state=random_state,
)

criterion = "EI" #'EI' or 'SBO' or 'LCB'
Expand Down Expand Up @@ -1284,7 +1284,7 @@ def function_test_1d(x):
xlimits = np.array([[0.0, 25.0]])

random_state = 42
design_space = DesignSpace(xlimits, seed=random_state)
design_space = DesignSpace(xlimits, random_state=random_state)
xdoe = np.atleast_2d([0, 7, 25]).T
n_doe = xdoe.size

Expand Down
30 changes: 26 additions & 4 deletions smt/utils/design_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,9 @@ class DesignSpace(BaseDesignSpace):
"""

def __init__(
self, design_variables: Union[List[DesignVariable], list, np.ndarray], seed=None
self,
design_variables: Union[List[DesignVariable], list, np.ndarray],
random_state=None,
):
self.sampler = None

Expand All @@ -721,7 +723,7 @@ def _is_num(val):
converted_dvs.append(FloatVariable(bounds[0], bounds[1]))
design_variables = converted_dvs

self.seed = seed # For testing
self.random_state = random_state # For testing

self._cs = None
if HAS_CONFIG_SPACE:
Expand All @@ -742,6 +744,11 @@ def _is_num(val):
cs_vars[name] = CategoricalHyperparameter(name, choices=dv.values)
else:
raise ValueError(f"Unknown variable type: {dv!r}")
seed = None
if isinstance(random_state, int):
seed = random_state
elif isinstance(random_state, np.random.RandomState):
seed = random_state.get_state()[1][0]

self._cs = NoDefaultConfigurationSpace(space=cs_vars, seed=seed)

Expand Down Expand Up @@ -927,11 +934,18 @@ def _sample_valid_x(
"""Sample design vectors"""
# Simplified implementation: sample design vectors in unfolded space
x_limits_unfolded = self.get_unfolded_num_bounds()
if self.seed is None:
self.seed = random_state
if self.random_state is None:
self.random_state = random_state

if self._cs is not None:
# Sample Configuration objects
if not (hasattr(self, "seed")):
seed = None
if isinstance(random_state, int):
seed = random_state
elif isinstance(random_state, np.random.RandomState):
seed = random_state.get_state()[1][0]
self.seed = seed
self._cs.seed(self.seed)
if self.seed is not None:
self.seed += 1
Expand Down Expand Up @@ -984,6 +998,14 @@ def _get_correct_config(self, vector: np.ndarray) -> Configuration:
# At this point, the parameter active statuses are set correctly, so we only need to correct the
# configuration to one that does not violate the forbidden clauses
elif isinstance(e, ForbiddenValueError):
if not (hasattr(self, "seed")):
seed = None
if isinstance(self.random_state, int):
seed = self.random_state
elif isinstance(random_state, np.random.RandomState):
seed = self.random_state.get_state()[1][0]
self.seed = seed

return get_random_neighbor(config, seed=self.seed)

else:
Expand Down
10 changes: 5 additions & 5 deletions smt/utils/test/test_design_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ def test_design_space(self):
IntegerVariable(-1, 2),
FloatVariable(0.5, 1.5),
],
seed=42,
random_state=42,
)
self.assertEqual(len(ds.design_variables), 4)
if HAS_CONFIG_SPACE:
Expand Down Expand Up @@ -340,7 +340,7 @@ def test_design_space_hierarchical(self):
IntegerVariable(0, 1), # x2
FloatVariable(0, 1), # x3
],
seed=42,
random_state=42,
)
ds.declare_decreed_var(
decreed_var=3, meta_var=0, meta_value="A"
Expand Down Expand Up @@ -434,7 +434,7 @@ def test_design_space_hierarchical_config_space(self):
IntegerVariable(0, 1), # x2
FloatVariable(0, 1), # x3
],
seed=42,
random_state=42,
)
ds.declare_decreed_var(
decreed_var=3, meta_var=0, meta_value="A"
Expand Down Expand Up @@ -530,7 +530,7 @@ def _is_conditionally_acting(self) -> np.ndarray:
IntegerVariable(0, 1), # x2
FloatVariable(0, 1), # x3
],
seed=42,
random_state=42,
)
ds.declare_decreed_var(
decreed_var=3, meta_var=0, meta_value="A"
Expand All @@ -550,7 +550,7 @@ def test_check_conditionally_acting_2(self):
IntegerVariable(0, 1), # x2
FloatVariable(0, 1), # x3
],
seed=42,
random_state=42,
)
ds.declare_decreed_var(
decreed_var=0, meta_var=1, meta_value="E"
Expand Down

0 comments on commit 9e89632

Please sign in to comment.