// Run without external services or input files. The default worker policy respects local allocation.
// All 1000 repetitions receive an isolated copy of the same initial scenario parameters.
import aner.parallel

// Synthetic multiplicative stochastic growth model; adapt its assumptions to your research question.
// Parameters: initial level, per-step drift, noise scale, number of steps.
// The abstract level has no domain calibration or empirical predictive claim.
fn simulate_growth_path(parameters: List, iteration: Int64, seed: Int64) -> List {
    let initial_level = cast<Float64>(parameters.get(0))
    let drift = cast<Float64>(parameters.get(1))
    let noise_scale = cast<Float64>(parameters.get(2))
    let steps = cast<Int64>(parameters.get(3))
    var level = initial_level
    var peak = initial_level
    var largest_relative_decline = 0.0
    var step = 0
    while step < steps {
        let shock = parallel.normal(seed: seed, draw: step)
        level = level * (1.0 + drift + noise_scale * shock)
        if level > peak { peak = level }
        let relative_decline = (peak - level) / peak
        if relative_decline > largest_relative_decline { largest_relative_decline = relative_decline }
        step = step + 1
    }
    return List(level / initial_level - 1.0, largest_relative_decline)
}

let initial_parameters = List(100000.0, 0.0002, 0.01, 64)
let results = parallel.repeat(iterations: 1000, task: simulate_growth_path,
    parameters: initial_parameters, execution: parallel.local(), seed: 42)
print(results.rows()) // 1000
print(results.cols()) // 2: relative change and largest relative decline
print(results.mean(column: 0))
print(results.std(column: 0, sample: true))
print(results.mean(column: 1))
print(results.seed(iteration: 0))
print(results.summary())
// Explicit four-worker variant: use parallel.local(workers: 4) only with at least four admitted CPU slots.
// Optional output: uncomment only when growth-results.csv does not already exist.
// results.save_csv("growth-results.csv")
