Skip to content

Commit 71e4f10

Browse files
committed
Add seed_strategy option for Monte Carlo sampling
Sampling all parameters in one LHS call means adding, removing or reordering a single parameter reshuffles every other parameter, which makes design matrices hard to extend without invalidating existing runs. The new 'seed_strategy' key in general_input selects between: - 'joint' (default): existing behaviour, unchanged. - 'independent': each uncorrelated parameter and each correlation group is keyed off distribution_seed, so editing one parameter leaves the others bit-identical. Correlation groups stay single sampling units, so requested correlations are induced as before.
1 parent 5cae5f0 commit 71e4f10

7 files changed

Lines changed: 9836 additions & 94 deletions

File tree

src/semeio/fmudesign/_excel_to_dict.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ def parse_value(value: object) -> object:
234234
"repeats",
235235
"correlation_iterations",
236236
"distribution_seed",
237+
"seed_strategy",
237238
"rms_seeds",
238239
"background",
239240
}
@@ -247,7 +248,13 @@ def parse_value(value: object) -> object:
247248
raise LookupError(msg)
248249

249250
# Copy keys over if they exist
250-
keys = ["designtype", "repeats", "correlation_iterations", "distribution_seed"]
251+
keys = [
252+
"designtype",
253+
"repeats",
254+
"correlation_iterations",
255+
"distribution_seed",
256+
"seed_strategy",
257+
]
251258
for key in keys:
252259
if key not in generalinput:
253260
continue

src/semeio/fmudesign/config_validation.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,26 @@
44

55
import copy
66
import numbers
7+
from enum import StrEnum
78
from typing import Any
89

910

11+
class SeedStrategy(StrEnum):
12+
"""How Monte Carlo samples are seeded.
13+
14+
JOINT:
15+
All parameters are drawn in one Latin Hypercube Sampling call (the
16+
default). Adding, removing or reordering a parameter reshuffles every
17+
other parameter.
18+
INDEPENDENT:
19+
Each parameter, and each correlation group, is seeded separately from
20+
the base seed, so changing one leaves the others bit-identical.
21+
"""
22+
23+
JOINT = "joint"
24+
INDEPENDENT = "independent"
25+
26+
1027
def validate_configuration(
1128
config: dict[str, Any], verbosity: int = 0
1229
) -> dict[str, Any]:
@@ -67,6 +84,22 @@ def validate_configuration(
6784
f"{key!r} must be a non-negative integer or None, got: {config[key]}"
6885
)
6986

87+
# 'seed_strategy' controls how Monte Carlo samples are seeded.
88+
# See the SeedStrategy docstring for what each strategy means.
89+
key = "seed_strategy"
90+
value = config.get(key)
91+
if isinstance(value, str):
92+
value = value.strip().lower()
93+
if value is None or value == "none":
94+
value = SeedStrategy.JOINT
95+
try:
96+
config[key] = SeedStrategy(value)
97+
except (ValueError, TypeError) as err:
98+
raise ValueError(
99+
f"{key!r} must be one of {[s.value for s in SeedStrategy]}, "
100+
f"got: {config[key]}"
101+
) from err
102+
70103
# 'seeds' here is 'rms_seeds' in the input. It can be either:
71104
# - 'default' => gives seed numbers 1000, 1001, 1002, ...
72105
# - 'None' => seed number not added

0 commit comments

Comments
 (0)