[DEPRECATED] Renamed to mizchi/differentiable_ecs. Use mizchi/differentiable_ecs instead.
moon add mizchi/differencial_ecsfn simulate(params : Array[Double], seed : Int) -> @dec.Metrics {
let speed = params[0]
let hp = params[1]
// ... run your simulation ...
let m = @dec.Metrics::new()
m.set("survival_time", 120.0)
m.set("kill_rate", 3.5)
m
}
fn main {
let specs : Array[@dec.ParamSpec] = [
{ name: "speed", initial: 2.0, min: 0.5, max: 5.0 },
{ name: "hp", initial: 100.0, min: 10.0, max: 500.0 },
]
let targets : Array[@dec.BalanceTarget] = [
{ metric: "survival_time", target: 180.0, weight: 1.0 },
{ metric: "kill_rate", target: 5.0, weight: 1.5 },
]
let config = { ..@dec.TuneConfig::default(specs, targets), max_generations: 50 }
let result = @dec.tune(config, simulate)
println("Loss: " + result.loss.to_string())
}| Type | Description |
|---|---|
| Metrics | Map[String, Double] wrapper for simulation results |
| ParamSpec | { name, initial, min, max } — parameter definition |
| BalanceTarget | { metric, target, weight } — optimization target |
| TuneConfig | Full configuration (specs, targets, seeds, generations, sigma) |
| TuneResult | { params, loss, generation, metrics } — optimization result |
| Function | Signature | Description |
|---|---|---|
| tune | (TuneConfig, sim_fn) -> TuneResult | Run CMA-ES optimization |
| TuneConfig::default | (specs, targets) -> TuneConfig | Create config with sensible defaults |
| sq_err | (actual, target) -> Double | Squared relative error |
| compute_loss | (Metrics, targets) -> Double | Compute loss from metrics |
| compute_loss_averaged | (sim, params, targets, seeds) -> (Double, Metrics) | Multi-seed averaged loss |
seeds: [42, 137, 256, 512] (4 seeds for robustness)
max_generations: 40
sigma: 0.3 (initial step size)
rng_seed: 42
log_interval: 10 (0 to disable)| Function | n | Result | Loss | Expected |
|---|---|---|---|---|
| Sphere | 10 | PASS | <1e-10 | Trivial for CMA-ES |
| Rosenbrock | 5 | PASS | <1e-10 | CMA-ES learns valley curvature |
| Rosenbrock | 10 | PASS | <1e-10 | Needs ~1000 gens to learn 10D valley |
| Rastrigin | 5 | FAIL | 99.0 | Multimodal — needs restarts |
| Ackley | 10 | PASS | 4.4e-8 | Narrow basin detection (500 gens) |
| Schwefel | 5 | FAIL | 1.2M | Deceptive landscape |
| Griewank | 10 | GOOD | 0.0004 | Non-separable interactions |
| n | JS/V8 (ms/gen) | Native release (ms/gen) |
|---|---|---|
| 5 | 0.12 | 0.03 |
| 10 | 0.19 | 0.15 |
| 20 | 0.60 | 1.35 |
| 50 | 13.90 | 32.85 |
| 100 | 193 | 402 |
pub(all) struct BalanceTarget {
metric : String
target : Double
weight : Double
}pub(all) struct ParamSpec {
name : String
initial : Double
min : Double
max : Double
}pub(all) struct TuneConfig {
param_specs : Array[ParamSpec]
targets : Array[BalanceTarget]
seeds : Array[Int]
max_generations : Int
sigma : Double
rng_seed : Int
log_interval : Int
}fn TuneConfig::default(param_specs : Array[ParamSpec], targets : Array[BalanceTarget]) -> TuneConfig[DEPRECATED] Renamed to mizchi/differentiable_ecs. Use mizchi/differentiable_ecs instead.