Cookbook: Simulation Tuning¶
Tune expensive, smooth simulation objectives with Nelder-Mead.
Scenario¶
You have a CFD or physics simulation that:
- Takes minutes to hours per evaluation.
- Has a smooth landscape (small parameter changes = small output changes).
- You have a tight evaluation budget (e.g., 50-100 runs).
ArqonHPO will automatically detect this and use Nelder-Mead, which minimizes evaluations.
The PCR Algorithm¶
For simulation tuning, ArqonHPO uses the Probe-Classify-Refine (PCR) algorithm:
- Probe: It samples the parameter space using a multi-scale prime-index grid.
- Classify: It analyzes the residuals of the probe phase. Smooth simulations show fast residual decay ($\alpha > 0.5$).
- Refine: If structured, it launches Nelder-Mead initialized from the best probe points.
This "Hybrid Seeding" allows Nelder-Mead to start exploitation immediately from a high-quality region. This means for CFD simulations with smooth, bowl-shaped objectives, ArqonHPO will:
- Detect geometric decay in residuals (fast convergence signature)
- Automatically select Nelder-Mead without manual configuration
- Use probe results to intelligently initialize the simplex
Example: CFD Parameter Sweep¶
import json
import time
from arqonhpo import ArqonSolver
# Simulate expensive CFD call
def cfd_simulation(params):
inlet_velocity = params["inlet_velocity"]
turbulence_k = params["turbulence_k"]
time.sleep(0.5) # Simulate 30-minute CFD; use 0.5s for demo
# Fake "drag coefficient" as objective
drag = (inlet_velocity - 5.0)**2 + (turbulence_k - 0.1)**2
return drag
# Config
config = {
"seed": 123,
"budget": 30, # Very tight budget
"probe_ratio": 0.2,
"bounds": {
"inlet_velocity": {"min": 1.0, "max": 10.0},
"turbulence_k": {"min": 0.01, "max": 0.5}
}
}
solver = ArqonSolver(json.dumps(config))
best = {"value": float('inf')}
while True:
batch = solver.ask()
if batch is None:
break
results = []
for i, params in enumerate(batch):
drag = cfd_simulation(params)
if drag < best["value"]:
best = {"params": params, "value": drag}
results.append({
"eval_id": i,
"params": params,
"value": drag,
"cost": 30.0 # 30 mins
})
solver.tell(json.dumps(results))
print(f"Optimal: {best}")
# Optimal: {'params': {'inlet_velocity': 5.02, 'turbulence_k': 0.098}, 'value': 0.0004}
Why Nelder-Mead?¶
For smooth landscapes, Nelder-Mead's simplex operations converge faster than random search or TPE because it exploits local gradient information without needing derivatives.
Nelder-Mead Operations¶
ArqonHPO implements all 5 standard NM operations:
| Operation | When Used | Formula |
|---|---|---|
| Reflection | Always tried first | x_r = c + α(c - worst) |
| Expansion | Reflection is best so far | x_e = c + γ(r - c) |
| Outside Contraction | Reflection between 2nd-worst and worst | x_c = c + ρ(r - c) |
| Inside Contraction | Reflection worse than worst | x_c = c + ρ(worst - c) |
| Shrink | Contraction fails | x_i = best + σ(x_i - best) |
Standard coefficients: α=1.0, γ=2.0, ρ=0.5, σ=0.5