A staged, sequential campaign#

Extend, reorder and subsample a base design as an experimental campaign grows in stages.

An experimental campaign that unfolds in stages: an initial design is run, results come back, and the design is then grown and reorganised for the next batch. This example walks through Mergen’s sequential toolkit end to end, printing the row count at each step so the staging is easy to follow.

Parameters#

  • x1, x2 (discrete grids): two inputs on explicit grids so every design point is an exact grid node throughout the staged workflow.

What to look at#

  • The printed row count after each step: the base design, the extended design, the reordered design, and the small subsampled pilot. These counts are how the staging is made legible.

  • The two saved pairplots (base and extended): the extended design keeps the original points and fills the remaining gaps, rather than starting over.

  • ordered_design.csv: the final design with an added run_order column, ready as an execution list for the next batch.

Mergen features used#

  • mergen.sequential.extend: augment an existing design with new, space-filling points without discarding the originals.

  • mergen.sequential.run_order: assign an execution order that is robust to drift, so early runs already cover the space.

  • mergen.sequential.subsample: pick a small representative subset (a pilot) from a larger design.

  • mergen.sequential.k_fold_split: partition the design into folds for cross-validation.

Estimated runtime: a minute or two.

from mergen import ParameterSpace, Sampler
from mergen import sequential

# 1. Build a base design for the first batch.
space = ParameterSpace({
    'x1': range(0, 101, 5),
    'x2': range(0, 101, 5),
})
sampler = Sampler(space)
sampler.set_design(n_samples=15)
base = sampler.run()
print(f"base design           : {len(base.best_design)} points")

# 2. Results came back; grow the design with 10 more points. extend()
#    keeps the original points and adds space-filling ones around them.
extended = sequential.extend(sampler, base.best_design, n_new=10)
print(f"after extend          : {len(extended.best_design)} points")

# 3. Assign a drift-robust execution order to the combined design.
ordered = sequential.run_order(sampler, extended.best_design)
print(f"ordered design        : {len(ordered)} rows (run_order column added)")

# 4. Pick a small representative pilot from the full design.
pilot = sequential.subsample(sampler, extended.best_design, n_select=6)
print(f"subsampled pilot      : {len(pilot)} points")

# 5. Partition the design into folds for cross-validation.
folds = sequential.k_fold_split(sampler, extended.best_design, k=3)
print(f"k-fold split          : {len(folds)} folds")

# 6. Save the two coverage views and the final ordered run list.
base.plot('pairplot', save=True)
extended.plot('pairplot', save=True)
ordered.to_csv('outputs/ordered_design.csv', index=False)
  [WARNING]  n_samples (15) < recommended 10*n_parameters (20, Loeppky et al. 2009). Design quality may be reduced.

════════════════════════════════════════════════════════════
  MERGEN — Space-filling Design
════════════════════════════════════════════════════════════
  Parameters      : 2
  Candidates      : 441
  n_samples       : 15  (prescribed_in=0, focus_in=0, optimised_slots=15)
  Total design    : 15
  Validation      : 3
  Criterion       : umaxpro
  Algorithm(s)    : sa
────────────────────────────────────────────────────────────
  [MERGEN]   Optimising (criterion=umaxpro, algorithm=sa)...
  [SA]       Restart 1/5
  [SA]       Tuning temperature...
  [SA]       Start  log(score)=12.508  T=1.4286e+17  iters=2000  swappable=15  hybrid=0.50
    iter  500/2000  T=1.429e+16  best log(score)=12.508
    iter 1000/2000  T=1.429e+15  best log(score)=12.508
    iter 1500/2000  T=1.429e+14  best log(score)=12.508
    iter 2000/2000  T=1.429e+13  best log(score)=12.508
  [SA]       Done   log(score)=12.508  (accepted=1831/2000, rate=91.5%)
  [SA]       Restart 1: new best  log(score)=12.508
  [SA]       Restart 2/5
  [SA]       Tuning temperature...
  [SA]       Start  log(score)=29.220  T=2.8571e+17  iters=2000  swappable=15  hybrid=0.50
    iter  500/2000  T=2.857e+16  best log(score)=26.720
    iter 1000/2000  T=2.857e+15  best log(score)=26.563
    iter 1500/2000  T=2.857e+14  best log(score)=26.364
    iter 2000/2000  T=2.857e+13  best log(score)=26.364
  [SA]       Done   log(score)=26.364  (accepted=1854/2000, rate=92.7%)
  [SA]       Restart 3/5
  [SA]       Tuning temperature...
  [SA]       Start  log(score)=28.027  T=3.8666e+12  iters=2000  swappable=15  hybrid=0.50
    iter  500/2000  T=3.867e+11  best log(score)=26.225
    iter 1000/2000  T=3.867e+10  best log(score)=26.225
    iter 1500/2000  T=3.867e+09  best log(score)=26.225
    iter 2000/2000  T=3.867e+08  best log(score)=26.225
  [SA]       Done   log(score)=26.225  (accepted=1860/2000, rate=93.0%)
  [SA]       Restart 4/5
  [SA]       Tuning temperature...
  [SA]       Start  log(score)=26.425  T=4.1373e+12  iters=2000  swappable=15  hybrid=0.50
    iter  500/2000  T=4.137e+11  best log(score)=26.038
    iter 1000/2000  T=4.137e+10  best log(score)=26.038
    iter 1500/2000  T=4.137e+09  best log(score)=26.038
    iter 2000/2000  T=4.137e+08  best log(score)=26.038
  [SA]       Done   log(score)=26.038  (accepted=1858/2000, rate=92.9%)
  [SA]       Restart 5/5
  [SA]       Tuning temperature...
  [SA]       Start  log(score)=29.183  T=1.4286e+17  iters=2000  swappable=15  hybrid=0.50
    iter  500/2000  T=1.429e+16  best log(score)=26.799
    iter 1000/2000  T=1.429e+15  best log(score)=26.799
    iter 1500/2000  T=1.429e+14  best log(score)=26.799
    iter 2000/2000  T=1.429e+13  best log(score)=26.463
  [SA]       Done   log(score)=26.463  (accepted=1859/2000, rate=93.0%)
  [MERGEN]   sa     done -- score=2.705e+05  (elapsed 3.4s)

────────────────────────────────────────────────────────────
  MERGEN — Final Design
────────────────────────────────────────────────────────────
  Prescribed (in)  : 0
  Prescribed (out) : 0
  Focus (in)       : 0
  Focus (out)      : 0
  Optimised        : 15
  Total design     : 15
  Validation       : 3
════════════════════════════════════════════════════════════
base design           : 15 points

════════════════════════════════════════════════════════════
  MERGEN — Space-filling Design
════════════════════════════════════════════════════════════
  Parameters      : 2
  Candidates      : 441
  n_samples       : 25  (prescribed_in=15, focus_in=0, optimised_slots=10)
  Total design    : 25
  Validation      : 0
  Criterion       : cd2
  Algorithm(s)    : sa
────────────────────────────────────────────────────────────
  [MERGEN]   Preparing anchor points...
  [MERGEN]   Optimising (criterion=cd2, algorithm=sa)...
  [SA]       Restart 1/5
  [SA]       Tuning temperature...
  [SA]       Start  log(score)=-2.762  T=3.0583e-02  iters=2500  swappable=10  hybrid=0.50
    iter  500/2500  T=4.847e-03  best log(score)=-3.189
    iter 1000/2500  T=7.682e-04  best log(score)=-3.297
    iter 1500/2500  T=1.218e-04  best log(score)=-3.309
    iter 2000/2500  T=1.930e-05  best log(score)=-3.325
    iter 2500/2500  T=3.058e-06  best log(score)=-3.325
  [SA]       Done   log(score)=-3.325  (accepted=157/2500, rate=6.3%)
  [SA]       Restart 1: new best  log(score)=-3.325
  [SA]       Restart 2/5
  [SA]       Tuning temperature...
  [SA]       Start  log(score)=-2.902  T=3.9357e-02  iters=2500  swappable=10  hybrid=0.50
    iter  500/2500  T=6.238e-03  best log(score)=-3.191
    iter 1000/2500  T=9.886e-04  best log(score)=-3.279
    iter 1500/2500  T=1.567e-04  best log(score)=-3.281
    iter 2000/2500  T=2.483e-05  best log(score)=-3.281
    iter 2500/2500  T=3.936e-06  best log(score)=-3.281
  [SA]       Done   log(score)=-3.281  (accepted=160/2500, rate=6.4%)
  [SA]       Restart 3/5
  [SA]       Tuning temperature...
  [SA]       Start  log(score)=-2.748  T=4.4755e-02  iters=2500  swappable=10  hybrid=0.50
    iter  500/2500  T=7.093e-03  best log(score)=-3.190
    iter 1000/2500  T=1.124e-03  best log(score)=-3.267
    iter 1500/2500  T=1.782e-04  best log(score)=-3.281
    iter 2000/2500  T=2.824e-05  best log(score)=-3.316
    iter 2500/2500  T=4.475e-06  best log(score)=-3.323
  [SA]       Done   log(score)=-3.323  (accepted=188/2500, rate=7.5%)
  [SA]       Restart 4/5
  [SA]       Tuning temperature...
  [SA]       Start  log(score)=-2.754  T=4.5236e-02  iters=2500  swappable=10  hybrid=0.50
    iter  500/2500  T=7.169e-03  best log(score)=-3.138
    iter 1000/2500  T=1.136e-03  best log(score)=-3.172
    iter 1500/2500  T=1.801e-04  best log(score)=-3.246
    iter 2000/2500  T=2.854e-05  best log(score)=-3.262
    iter 2500/2500  T=4.524e-06  best log(score)=-3.262
  [SA]       Done   log(score)=-3.262  (accepted=226/2500, rate=9.0%)
  [SA]       Restart 5/5
  [SA]       Tuning temperature...
  [SA]       Start  log(score)=-2.683  T=4.6123e-02  iters=2500  swappable=10  hybrid=0.50
    iter  500/2500  T=7.310e-03  best log(score)=-3.216
    iter 1000/2500  T=1.159e-03  best log(score)=-3.228
    iter 1500/2500  T=1.836e-04  best log(score)=-3.237
    iter 2000/2500  T=2.910e-05  best log(score)=-3.237
    iter 2500/2500  T=4.612e-06  best log(score)=-3.237
  [SA]       Done   log(score)=-3.237  (accepted=167/2500, rate=6.7%)
  [MERGEN]   sa     done -- score=0.03597  (elapsed 6.4s)

────────────────────────────────────────────────────────────
  MERGEN — Final Design
────────────────────────────────────────────────────────────
  Prescribed (in)  : 15
  Prescribed (out) : 0
  Focus (in)       : 0
  Focus (out)      : 0
  Optimised        : 10
  Total design     : 25
  Validation       : 0
════════════════════════════════════════════════════════════
after extend          : 25 points
ordered design        : 25 rows (run_order column added)
subsampled pilot      : 6 points
k-fold split          : 3 folds
  Saved: outputs/pairplot_10.png
  Saved: outputs/pairplot_11.png
  • 09 sequential workflow
  • 09 sequential workflow

Total running time of the script: (0 minutes 10.300 seconds)

Gallery generated by Sphinx-Gallery