general
import "github.com/umbralcalc/stochadex/pkg/general"Package general provides general-purpose iteration functions and utilities for stochadex simulations. It includes data transformation functions, aggregation utilities, and flexible iteration patterns that can be composed to create complex simulation behaviors.
Key Features:
- Data transformation and reduction functions
- Flexible function-based iterations
- Parameter value management and copying
- Constant value generation and propagation
- Cumulative computation utilities
- Embedded simulation run support
Usage Patterns:
- Create reusable iteration functions for common simulation patterns
- Transform and aggregate simulation data
- Manage parameter values across simulation runs
- Implement custom computation logic with flexible interfaces
Index
- func AppendFloatToKey(key string, value float64, precision int) string
- func CountAggregation(defaultValues []float64, outputIndexByGroup map[string]int, groupings map[string][]float64, weightings map[string][]float64) []float64
- func DataValuesFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, stateHistoryDepthIndex int) []float64
- func DataValuesVarianceFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, stateHistoryDepthIndex int) []float64
- func FloatTupleToKey(tuple []float64, precision int) string
- func MaxAggregation(defaultValues []float64, outputIndexByGroup map[string]int, groupings map[string][]float64, weightings map[string][]float64) []float64
- func MeanAggregation(defaultValues []float64, outputIndexByGroup map[string]int, groupings map[string][]float64, weightings map[string][]float64) []float64
- func MinAggregation(defaultValues []float64, outputIndexByGroup map[string]int, groupings map[string][]float64, weightings map[string][]float64) []float64
- func NewTransformReduceFunction(transform func(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) map[string][]float64, reduce func(values map[string][]float64) []float64) func(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64
- func NextNonEmptyPopIndexFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) (int, bool)
- func OtherPartitionPushFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) ([]float64, bool)
- func OtherValuesFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, stateHistoryDepthIndex int) []float64
- func ParamValuesPushFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) ([]float64, bool)
- func ParamsEventFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64
- func ParamsTransform(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) map[string][]float64
- func PartitionEventFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64
- func PastDiscountedDataValuesFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, stateHistoryDepthIndex int) []float64
- func PastDiscountedOtherValuesFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, stateHistoryDepthIndex int) []float64
- func PopFromOtherCollectionPushFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) ([]float64, bool)
- func SumAggregation(defaultValues []float64, outputIndexByGroup map[string]int, groupings map[string][]float64, weightings map[string][]float64) []float64
- func SumReduce(values map[string][]float64) []float64
- func UnitValueFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, stateHistoryDepthIndex int) []float64
- type ConstantValuesIteration
- type CopyValuesIteration
- type CumulativeIteration
- type
DiscountedCumulativeIteration
- func (d *DiscountedCumulativeIteration) Configure(partitionIndex int, settings *simulator.Settings)
- func (d *DiscountedCumulativeIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64
- type
EmbeddedSimulationRunIteration
- func NewEmbeddedSimulationRunIteration(settings *simulator.Settings, implementations *simulator.Implementations) *EmbeddedSimulationRunIteration
- func (e *EmbeddedSimulationRunIteration) Configure(partitionIndex int, settings *simulator.Settings)
- func (e *EmbeddedSimulationRunIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64
- func (e *EmbeddedSimulationRunIteration) SetReseedBase(base uint64)
- type ExpressionBinding
- type ExpressionField
- type ExpressionIteration
- type FromHistoryIteration
- func (f *FromHistoryIteration) Configure(partitionIndex int, settings *simulator.Settings)
- func (f *FromHistoryIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64
- func (f *FromHistoryIteration) UpdateMemory(params *simulator.Params, update StateMemoryUpdate)
- type FromHistoryTimestepFunction
- type FromStorageIteration
- type FromStorageTimestepFunction
- type NamedIndexedState
- type ParamValuesIteration
- type SortingValues
- func OtherPartitionsPushAndSortFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) (SortingValues, bool)
- func ParamValuesPushAndSortFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) (SortingValues, bool)
- type StateMemoryIteration
- type StateMemoryUpdate
- type
ValuesChangingEventsIteration
- func (v *ValuesChangingEventsIteration) Configure(partitionIndex int, settings *simulator.Settings)
- func (v *ValuesChangingEventsIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64
- type ValuesCollectionIteration
- type ValuesFunctionIteration
- type
ValuesFunctionVectorCovarianceIteration
- func (v *ValuesFunctionVectorCovarianceIteration) Configure(partitionIndex int, settings *simulator.Settings)
- func (v *ValuesFunctionVectorCovarianceIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64
- type
ValuesFunctionVectorMeanIteration
- func (v *ValuesFunctionVectorMeanIteration) Configure(partitionIndex int, settings *simulator.Settings)
- func (v *ValuesFunctionVectorMeanIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64
- type
ValuesGroupedAggregationIteration
- func (v *ValuesGroupedAggregationIteration) Configure(partitionIndex int, settings *simulator.Settings)
- func (v *ValuesGroupedAggregationIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64
- type
ValuesSortedCollectionCovarianceIteration
- func (v *ValuesSortedCollectionCovarianceIteration) Configure(partitionIndex int, settings *simulator.Settings)
- func (v *ValuesSortedCollectionCovarianceIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64
- type
ValuesSortedCollectionMeanIteration
- func (v *ValuesSortedCollectionMeanIteration) Configure(partitionIndex int, settings *simulator.Settings)
- func (v *ValuesSortedCollectionMeanIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64
- type
ValuesSortingCollectionIteration
- func (v *ValuesSortingCollectionIteration) Configure(partitionIndex int, settings *simulator.Settings)
- func (v *ValuesSortingCollectionIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64
- type
ValuesWeightedResamplingIteration
- func (v *ValuesWeightedResamplingIteration) Configure(partitionIndex int, settings *simulator.Settings)
- func (v *ValuesWeightedResamplingIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64
func AppendFloatToKey
func AppendFloatToKey(key string, value float64, precision int) stringAppendFloatToKey appends a formatted float to a composite grouping key at a fixed precision.
func CountAggregation
func CountAggregation(defaultValues []float64, outputIndexByGroup map[string]int, groupings map[string][]float64, weightings map[string][]float64) []float64CountAggregation outputs, per group, the sum of weights (i.e., a count when weights are all 1).
func DataValuesFunction
func DataValuesFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, stateHistoryDepthIndex int) []float64DataValuesFunction returns values from “data_values_partition”, optionally subselecting indices.
func DataValuesVarianceFunction
func DataValuesVarianceFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, stateHistoryDepthIndex int) []float64DataValuesVarianceFunction returns per-index squared deviations from the provided “mean” for “data_values_partition”.
func FloatTupleToKey
func FloatTupleToKey(tuple []float64, precision int) stringFloatTupleToKey converts a vector to a composite key string at fixed precision, suitable for use as a map key.
func MaxAggregation
func MaxAggregation(defaultValues []float64, outputIndexByGroup map[string]int, groupings map[string][]float64, weightings map[string][]float64) []float64MaxAggregation computes the maximum of weighted values per group.
func MeanAggregation
func MeanAggregation(defaultValues []float64, outputIndexByGroup map[string]int, groupings map[string][]float64, weightings map[string][]float64) []float64MeanAggregation computes the weighted mean of values per group.
func MinAggregation
func MinAggregation(defaultValues []float64, outputIndexByGroup map[string]int, groupings map[string][]float64, weightings map[string][]float64) []float64MinAggregation computes the minimum of weighted values per group.
func NewTransformReduceFunction
func NewTransformReduceFunction(transform func(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) map[string][]float64, reduce func(values map[string][]float64) []float64) func(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64NewTransformReduceFunction returns a function that first transforms the provided simulation context into a map of vectors, then reduces those vectors into a single vector.
Usage hints:
- Compose transform/reduce pipelines to feed ValuesFunctionIteration.
func NextNonEmptyPopIndexFunction
func NextNonEmptyPopIndexFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) (int, bool)NextNonEmptyPopIndexFunction scans the rolling collection for the next occupied slot (index > 0) and returns its index for popping.
Usage hints:
- Index 0 is reserved for the most recently popped values.
- Configure “values_state_width” and “empty_value” to mark empty slots.
func OtherPartitionPushFunction
func OtherPartitionPushFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) ([]float64, bool)OtherPartitionPushFunction collects the latest values from another partition to push into the collection, subject to empty_value.
Usage hints:
- Provide: “other_partition” and “value_indices”.
- If the first element equals “empty_value”, the push is skipped.
func OtherValuesFunction
func OtherValuesFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, stateHistoryDepthIndex int) []float64OtherValuesFunction returns values from “other_values_partition”, optionally subselecting indices.
func ParamValuesPushFunction
func ParamValuesPushFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) ([]float64, bool)ParamValuesPushFunction reads the next values directly from params under “next_values_push”, subject to empty_value.
Usage hints:
- Provide: “next_values_push” and “empty_value”.
func ParamsEventFunction
func ParamsEventFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64ParamsEventFunction emits an event value from the “event” params.
func ParamsTransform
func ParamsTransform(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) map[string][]float64ParamsTransform is a convenience transform that returns the current params map. Useful as a building block for transform/reduce pipelines.
func PartitionEventFunction
func PartitionEventFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64PartitionEventFunction emits an event value from the latest state of another partition.
Usage hints:
- Provide: “event_partition_index” and “event_state_value_index”.
func PastDiscountedDataValuesFunction
func PastDiscountedDataValuesFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, stateHistoryDepthIndex int) []float64PastDiscountedDataValuesFunction reads from “data_values_partition” and applies an exponential discount factor raised to the history depth index. Useful with a kernel for a past-discounted rolling mean.
func PastDiscountedOtherValuesFunction
func PastDiscountedOtherValuesFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, stateHistoryDepthIndex int) []float64PastDiscountedOtherValuesFunction mirrors PastDiscountedDataValuesFunction for “other_values_partition”, optionally subselecting indices.
func PopFromOtherCollectionPushFunction
func PopFromOtherCollectionPushFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) ([]float64, bool)PopFromOtherCollectionPushFunction pulls the current popped values from another collection-like partition and uses them as the next values to push.
Usage hints:
- Provide: “other_partition” and “values_state_width”.
- If the first element equals “empty_value”, the push is skipped.
func SumAggregation
func SumAggregation(defaultValues []float64, outputIndexByGroup map[string]int, groupings map[string][]float64, weightings map[string][]float64) []float64SumAggregation computes the weighted sum of values per group.
func SumReduce
func SumReduce(values map[string][]float64) []float64SumReduce reduces a map of equally sized vectors by summing them element-wise into a single output vector.
Usage hints:
- Combine with NewTransformReduceFunction to compose dataflow operations.
func UnitValueFunction
func UnitValueFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, stateHistoryDepthIndex int) []float64UnitValueFunction returns [1]. Combine with “without_normalisation” to compute a kernel density (sum of weights) directly.
type ConstantValuesIteration
ConstantValuesIteration leaves initial state values unchanged over time.
Usage hints:
- Useful for fixed baselines or as a placeholder partition.
type ConstantValuesIteration struct {
}func (*ConstantValuesIteration) Configure
func (c *ConstantValuesIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*ConstantValuesIteration) Iterate
func (c *ConstantValuesIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type CopyValuesIteration
CopyValuesIteration copies selected values from other partitions’ latest states into its own state.
Usage hints:
- Provide params: “partitions” (indices) and “partition_state_values”.
type CopyValuesIteration struct {
}func (*CopyValuesIteration) Configure
func (c *CopyValuesIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*CopyValuesIteration) Iterate
func (c *CopyValuesIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type CumulativeIteration
CumulativeIteration accumulates a provided iteration’s outputs over time.
Usage hints:
- Wrap another iteration to compute cumulative sums step-by-step.
type CumulativeIteration struct {
Iteration simulator.Iteration
}func (*CumulativeIteration) Configure
func (c *CumulativeIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*CumulativeIteration) Iterate
func (c *CumulativeIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type DiscountedCumulativeIteration
DiscountedCumulativeIteration accumulates a provided iteration’s outputs over time with a discount factor applied to the previous accumulated state. This implements the recurrence: R_k = r_k + γ * R_{k-1}, which is the standard discounted return when wrapping a reward-producing iteration.
Usage hints:
- Wrap another iteration to compute discounted cumulative sums step-by-step.
- Provide: “discount_factor” (single float γ in [0, 1]).
type DiscountedCumulativeIteration struct {
Iteration simulator.Iteration
}func (*DiscountedCumulativeIteration) Configure
func (d *DiscountedCumulativeIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*DiscountedCumulativeIteration) Iterate
func (d *DiscountedCumulativeIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type EmbeddedSimulationRunIteration
EmbeddedSimulationRunIteration runs a nested simulation to termination at each outer step.
Usage hints:
- Configure params on the outer iteration with keys of the form “<innerPartitionName>/<param_name>” to forward into the inner simulation.
- Use “<innerPartitionName>/initial_state_from_partition_history” to seed inner initial states from an outer partition’s history.
- Use “<innerPartitionName>/update_from_partition_history” to stream outer histories into inner iterations that implement StateMemoryIteration.
- Use “<innerPartitionName>/init_state_values_from_outer” with value [offset, width] to seed the named inner partition’s InitStateValues from a slice of the outer partition’s previous state at each step. Enables warm-starting inner optimisers across outer steps.
- Optional “burn_in_steps” skips initial outer steps before running inner sim.
This is a stream by default: Configure seeds the inner iterations once and each outer step advances them from wherever the last run left their RNGs, so two runs with identical inputs give different answers. That is what advancing a nested simulation alongside an outer one wants.
SetReseedBase makes a run a pure function of its inputs instead, for when the nested simulation is being evaluated rather than advanced — a model re-run over a window, a proposal scored more than once. simulator.ReentrantSimulation is the same capability as a standalone value.
type EmbeddedSimulationRunIteration struct {
// contains filtered or unexported fields
}func NewEmbeddedSimulationRunIteration
func NewEmbeddedSimulationRunIteration(settings *simulator.Settings, implementations *simulator.Implementations) *EmbeddedSimulationRunIterationNewEmbeddedSimulationRunIteration constructs an embedded run iteration from prepared settings and implementations.
func (*EmbeddedSimulationRunIteration) Configure
func (e *EmbeddedSimulationRunIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*EmbeddedSimulationRunIteration) Iterate
func (e *EmbeddedSimulationRunIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64func (*EmbeddedSimulationRunIteration) SetReseedBase
func (e *EmbeddedSimulationRunIteration) SetReseedBase(base uint64)SetReseedBase makes every run reseed its inner iterations from base mixed with the outer step number, so a run becomes a pure function of its inputs.
Off by default: enabling it changes the numbers a configuration produces, because the inner noise stream is restarted rather than continued.
type ExpressionBinding
ExpressionBinding is one named intermediate value in the evaluation DAG. Bindings are evaluated in order, and each may refer to any binding declared before it.
type ExpressionBinding struct {
// Name is how later expressions refer to this value.
Name string `yaml:"name"`
// Expr is the expression computing it.
Expr string `yaml:"expr"`
}type ExpressionField
ExpressionField names a contiguous block of a partition’s state so that expressions can refer to it by name instead of by index. Fields are laid out in the order given, so a partition with fields soc and charge has state [soc, charge], and one with a 40-wide infectious and a 40-wide cumulative has an 80-wide state of two 40-wide blocks.
type ExpressionField struct {
// Name is how expressions refer to this block.
Name string `yaml:"name"`
// Width is the number of state elements in the block, defaulting to 1.
Width int `yaml:"width,omitempty"`
}type ExpressionIteration
ExpressionIteration is a declarative Iteration: the per-step update is given as string expressions rather than as Go, so a whole partition can be specified as data (and hence from YAML, or by an agent) with no compilation step.
The update is a small DAG. Bindings are named intermediates evaluated in order, then one Outputs expression per field produces that field’s next value. Everything is evaluated elementwise over vectors, with length-1 values broadcasting, so the same expression works for a scalar partition and a 10,000-element one.
Names available to expressions:
- each of this partition’s own fields, holding its current value;
- each entry of the partition’s params, by key;
- each alias in Upstreams, holding that partition’s current state (index it as alias[i]);
- dt, the timestep increment; t, the current cumulative time; step, the step number;
- pi;
- any binding declared earlier.
Functions: where, clamp, min, max, abs, floor, exp, log, sqrt, pow, sin, cos, erf, erfc, fill, width, slice, concat, sum, dot, lag, each, scan, iid and shared, plus the draws normal, uniform, exponential, poisson, gamma, beta and binomial. Draws take expressions as their parameters, so compound sampling composes naturally: a negative-binomial branching step is just poisson(gamma(shape, rate)).
sin and cos carry seasonality; erfc is the primitive a Gaussian CDF is built from, as 0.5 * erfc(-x / sqrt(2)), which is what a probit link or a threshold-exceedance probability needs.
Reaching past the current element, and past the current row
Everything above is elementwise over the current row, which four things in the model catalogue could not be written with. Each has one construct:
- slice(v, start, width) takes a block out of a vector, and concat(a, b, …) joins values, for state and params that pack several quantities end to end. width(v) is how many elements v has, for a spec that adapts to a param’s length rather than fixing it. A width of zero is allowed and gives an empty value, because that is what the running end of a prefix operation is: each(n, i, sum(slice(q, 0, i))) has to ask for nothing at lane 0, and sum of nothing is 0.
- lag(name, n) reads a partition’s committed state n rows back, where a bare field name or an Upstreams alias only ever gives row 0. The partition must keep that many rows (its state_history_depth), and lag(x, 0) is x.
- each(n, i, expr) builds a width-n value whose element i is expr evaluated with the lane index i bound. See below.
- scan(n, i, acc, init, expr) is each with an accumulator threaded through the lanes, for the things a lane needs to see what earlier lanes did. See below.
each is the first construct that is not elementwise, and it is what makes an index shift, a per-lane guard and a per-lane draw order sayable:
- Element i may read element i-1 of something, so a cohort can age: each(60, age, where(age == 0, births, survivors[age-1] * p)).
- Inside a lane every value is a scalar, so where is lazy there. A lane that is switched off evaluates nothing and draws nothing — unlike a vector-guarded where, which must evaluate both branches and so consumes randomness in every lane.
- Lanes run in order, so a lane’s draws are taken before the next lane starts. An elementwise gamma(shape, rate) followed by poisson takes every gamma before any poisson; each(n, i, poisson(gamma(shape[i], rate[i]))) interleaves them per lane, the way a loop over areas does.
each binds only the index and returns only values, so there is still no assignment and no recursion, and an expression still always terminates. Draws inside it are explicit in the sense below, exactly as they are inside iid.
What each cannot say is anything where a lane must see what earlier lanes did: its lanes are independent, and each must produce a scalar, so nothing is carried between them. That is what scan(n, i, acc, init, expr) adds. It runs n lanes in order with acc bound to the previous lane’s value — init for lane 0 — and the value of the whole call is the last lane’s, so it is a fold rather than a map. Unlike an each lane, a scan lane may be any width, and that width is the point: the blocking case is allocation, where what has to be carried is which slots are now taken rather than a running total. Assigning k arrivals to the first k free slots is
scan(k, a, taken, occupied, each(6, j, where(j == first_free, 1, taken[j])))where first_free stands in for the sub-expression finding it (there are no local names inside a lane, so it is written out where it is used), and each arrival sees the slots the previous ones just took. Running quantities are the same shape, either threaded as a scalar (a running maximum is scan(n, i, m, v[0], max(m, v[i]))) or grown into the value being built, which is prefix sums in O(n) rather than the O(n^2) of an each of sums:
slice(scan(6, i, acc, 0, concat(acc, acc[i] + q[i])), 0, 6)scan stays bounded exactly as each does: the lane count is fixed before the loop, acc is threaded rather than assigned to, and there is no recursion, so an expression still always terminates. A zero lane count is allowed and gives init, which is the right answer for a fold over nothing and lets the count come from data.
Conditionals are expressions, not statements: where(cond, a, b). When cond is a scalar the untaken branch is not evaluated, so a guard such as where(n > 0, binomial(n, p), 0) is safe and draws no randomness on the guarded path. When cond is a vector both branches must be evaluated to select elementwise, as in NumPy, which means a vector-guarded draw consumes randomness in every lane, and each branch must then be either the condition’s width or a scalar. Prefer scalar guards where that matters — and see each below, which makes a per-element guard scalar and so gets laziness back.
How wide a draw is
A draw produces one independent sample per element of its broadcast parameters, so poisson(rates) over a 40-wide rates gives 40 independent draws. When every parameter is a scalar the width is instead ambiguous: one sample reused across a field and forty independent ones are both reasonable readings, and both are things people mean. Rather than pick silently, a scalar-parameter draw is rejected unless the intent is stated:
iid(40, normal(0, 1)) forty independent samples
shared(normal(0, 1)) one sample, free to broadcast across a fieldSo x + normal(0, 1) over a 40-wide x is an error rather than quietly adding the same shock to all forty elements. Draws with a vector parameter need no annotation.
This is deliberately not a general-purpose language: there is no assignment and no recursion, and the only repetition is each’s bounded comprehension, so an expression always terminates.
type ExpressionIteration struct {
// Fields names the blocks of this partition's state, in layout order.
Fields []ExpressionField `yaml:"fields"`
// Upstreams maps an alias used in expressions to another partition's name, making that
// partition's current state readable.
Upstreams map[string]string `yaml:"upstreams,omitempty"`
// Bindings are ordered named intermediates.
Bindings []ExpressionBinding `yaml:"bindings,omitempty"`
// Outputs holds one expression per entry of Fields, in the same order.
Outputs []string `yaml:"outputs"`
// contains filtered or unexported fields
}func (*ExpressionIteration) Configure
func (e *ExpressionIteration) Configure(partitionIndex int, settings *simulator.Settings)Configure resolves the state layout, resolves upstream partition names to indices, parses every expression once, and seeds the draw sampler from the partition’s seed. It panics on a malformed specification: a partition that cannot be built is a configuration error, not something to discover mid-run.
func (*ExpressionIteration) Iterate
func (e *ExpressionIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64Iterate evaluates the bindings in order and then each field’s output expression, concatenating the results into the next state.
type FromHistoryIteration
FromHistoryIteration streams data from an in-memory StateHistory.
Usage hints:
- Use with EmbeddedSimulationRun or analysis windows to replay data.
- Set Data to the source history; supports initial offset via InitStepsTaken.
type FromHistoryIteration struct {
Data *simulator.StateHistory
InitStepsTaken int
}func (*FromHistoryIteration) Configure
func (f *FromHistoryIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*FromHistoryIteration) Iterate
func (f *FromHistoryIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64func (*FromHistoryIteration) UpdateMemory
func (f *FromHistoryIteration) UpdateMemory(params *simulator.Params, update StateMemoryUpdate)type FromHistoryTimestepFunction
FromHistoryTimestepFunction streams timesteps from an in-memory CumulativeTimestepsHistory.
Usage hints:
- Set Data to the source timestep series; supports initial offset via InitStepsTaken.
type FromHistoryTimestepFunction struct {
Data *simulator.CumulativeTimestepsHistory
InitStepsTaken int
}func (*FromHistoryTimestepFunction) NextIncrement
func (f *FromHistoryTimestepFunction) NextIncrement(timestepsHistory *simulator.CumulativeTimestepsHistory) float64type FromStorageIteration
FromStorageIteration streams data from an in-memory [][]float64.
Usage hints:
- Provide Data (rows over time); supports initial offset via InitStepsTaken.
type FromStorageIteration struct {
Data [][]float64
InitStepsTaken int
}func (*FromStorageIteration) Configure
func (f *FromStorageIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*FromStorageIteration) Iterate
func (f *FromStorageIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type FromStorageTimestepFunction
FromStorageTimestepFunction streams timesteps from an in-memory []float64.
Usage hints:
- Provide Data; supports initial offset via InitStepsTaken.
type FromStorageTimestepFunction struct {
Data []float64
InitStepsTaken int
}func (*FromStorageTimestepFunction) NextIncrement
func (f *FromStorageTimestepFunction) NextIncrement(timestepsHistory *simulator.CumulativeTimestepsHistory) float64type NamedIndexedState
NamedIndexedState pairs a partition’s name/index with its state history. Useful for initialising inner histories from a chosen outer partition.
type NamedIndexedState struct {
NamedIndex simulator.NamedPartitionIndex
History *simulator.StateHistory
}type ParamValuesIteration
ParamValuesIteration writes the float param values under “param_values” directly to the state.
Usage hints:
- Useful for injecting immediate parameter-driven values.
type ParamValuesIteration struct {
}func (*ParamValuesIteration) Configure
func (p *ParamValuesIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*ParamValuesIteration) Iterate
func (p *ParamValuesIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type SortingValues
SortingValues encapsulates a new entry to add to the sorting collection.
type SortingValues struct {
SortBy float64
Values []float64
}func OtherPartitionsPushAndSortFunction
func OtherPartitionsPushAndSortFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) (SortingValues, bool)OtherPartitionsPushAndSortFunction retrieves values from one partition and sorts by another partition’s value.
Usage hints:
- Provide: “other_partition”, “value_indices”, “other_partition_sort_by”, and “value_index_sort_by”. Skip push if first value equals “empty_value”.
func ParamValuesPushAndSortFunction
func ParamValuesPushAndSortFunction(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) (SortingValues, bool)ParamValuesPushAndSortFunction uses params for both values and sort key.
Usage hints:
- Provide: “next_values_push”, “empty_value”, and “next_values_sort_by”.
type StateMemoryIteration
StateMemoryIteration marks iterations that can receive state/time from a parent simulation and store it for later use.
type StateMemoryIteration interface {
UpdateMemory(params *simulator.Params, update StateMemoryUpdate)
}type StateMemoryUpdate
StateMemoryUpdate carries a named partition’s state and timestep history from an outer simulation into an inner (embedded) simulation.
Usage hints:
- Used by iterations implementing StateMemoryIteration to receive context.
- Set Name to the outer partition name for disambiguation.
type StateMemoryUpdate struct {
Name string
StateHistory *simulator.StateHistory
TimestepsHistory *simulator.CumulativeTimestepsHistory
}type ValuesChangingEventsIteration
ValuesChangingEventsIteration calls and outputs from an iteration in the map keyed by an event. If no event key matches, it returns previous values or optional “default_values”.
Usage hints:
- Set EventIteration to produce the event key; provide IterationByEvent map.
- Optional: set “default_values” to override fallback behaviour.
type ValuesChangingEventsIteration struct {
EventIteration simulator.Iteration
IterationByEvent map[float64]simulator.Iteration
}func (*ValuesChangingEventsIteration) Configure
func (v *ValuesChangingEventsIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*ValuesChangingEventsIteration) Iterate
func (v *ValuesChangingEventsIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type ValuesCollectionIteration
ValuesCollectionIteration maintains a fixed-width rolling collection of value vectors.
Usage hints:
- Provide: “values_state_width” and “empty_value” for sentinel handling.
- Set Push to define how new values are appended; set PopIndex to surface an existing entry into index 0 and clear that slot.
type ValuesCollectionIteration struct {
PopIndex func(
params *simulator.Params,
partitionIndex int,
stateHistories []*simulator.StateHistory,
timestepsHistory *simulator.CumulativeTimestepsHistory,
) (int, bool)
Push func(
params *simulator.Params,
partitionIndex int,
stateHistories []*simulator.StateHistory,
timestepsHistory *simulator.CumulativeTimestepsHistory,
) ([]float64, bool)
}func (*ValuesCollectionIteration) Configure
func (v *ValuesCollectionIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*ValuesCollectionIteration) Iterate
func (v *ValuesCollectionIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type ValuesFunctionIteration
ValuesFunctionIteration provides a flexible way to compute derived values from simulation state and parameters using user-defined functions.
This iteration type allows for custom computation logic within simulations, enabling feature engineering, data transformation, and complex derived value calculations. It’s particularly useful for creating custom aggregation functions, feature extraction, and data preprocessing.
Design Philosophy: The function-based approach emphasizes composition and reusability. By providing a pure function interface, this iteration enables:
- Stateless computation (no side effects)
- Easy testing and validation
- Composition with other iteration types
- Reusable computation logic across simulations
Function Signature: The Function field must implement a pure mapping from simulation context to output values. It receives:
- params: Current simulation parameters
- partitionIndex: Index of the current partition
- stateHistories: All partition state histories
- timestepsHistory: Time and timestep information
And returns a slice of float64 values representing the computed output.
Applications:
- Feature engineering: Compute derived features from raw simulation data
- Data transformation: Apply mathematical transformations to state values
- Custom aggregations: Implement specialized aggregation logic
- Parameter synthesis: Combine multiple parameters into derived values
- Event detection: Compute indicators for significant events
Example:
iteration := &ValuesFunctionIteration{
Function: func(params *simulator.Params, partitionIndex int,
stateHistories []*simulator.StateHistory,
timestepsHistory *simulator.CumulativeTimestepsHistory) []float64 {
// Extract current state from first partition
currentState := stateHistories[0].Values.RawRowView(0)
// Compute derived feature: moving average
if len(currentState) >= 2 {
return []float64{(currentState[0] + currentState[1]) / 2.0}
}
return []float64{0.0}
},
}Performance Considerations:
- Function is called once per simulation step
- Avoid expensive computations in the function body
- Consider caching for repeated calculations
- Memory allocations should be minimized
API Stability:
- This interface is stable and will not change in future versions
- Function signature is compatible across all stochadex versions
Related Types:
- See NewTransformReduceFunction for composed transform-reduce operations
- See ParamsTransform for parameter extraction utilities
- See SumReduce for simple reduction operations
type ValuesFunctionIteration struct {
Function func(
params *simulator.Params,
partitionIndex int,
stateHistories []*simulator.StateHistory,
timestepsHistory *simulator.CumulativeTimestepsHistory,
) []float64
}func (*ValuesFunctionIteration) Configure
func (v *ValuesFunctionIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*ValuesFunctionIteration) Iterate
func (v *ValuesFunctionIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type ValuesFunctionVectorCovarianceIteration
ValuesFunctionVectorCovarianceIteration computes a kernel-weighted rolling covariance of a function over historical values and times.
Usage hints:
- Provide Function that accepts a history index (-1 for latest) and returns a vector matching the partition state width.
- Set Kernel and related params (e.g., bandwidth, discounting).
- Requires a “mean” param vector for centring.
- The upper-triangular covariance is returned flattened.
type ValuesFunctionVectorCovarianceIteration struct {
Function func(
params *simulator.Params,
partitionIndex int,
stateHistories []*simulator.StateHistory,
stateHistoryDepthIndex int,
) []float64
Kernel kernels.IntegrationKernel
}func (*ValuesFunctionVectorCovarianceIteration) Configure
func (v *ValuesFunctionVectorCovarianceIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*ValuesFunctionVectorCovarianceIteration) Iterate
func (v *ValuesFunctionVectorCovarianceIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type ValuesFunctionVectorMeanIteration
ValuesFunctionVectorMeanIteration computes a kernel-weighted rolling mean of a function over historical values and times.
Usage hints:
- Provide Function that accepts a history index (-1 for latest) and returns a vector matching the partition state width.
- Set Kernel and related params (e.g., discount factors, bandwidth, etc.).
- Use “without_normalisation” to return the weighted sum rather than mean; “subtract_from_normalisation” adjusts the normaliser if needed.
type ValuesFunctionVectorMeanIteration struct {
Function func(
params *simulator.Params,
partitionIndex int,
stateHistories []*simulator.StateHistory,
stateHistoryDepthIndex int,
) []float64
Kernel kernels.IntegrationKernel
}func (*ValuesFunctionVectorMeanIteration) Configure
func (v *ValuesFunctionVectorMeanIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*ValuesFunctionVectorMeanIteration) Iterate
func (v *ValuesFunctionVectorMeanIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type ValuesGroupedAggregationIteration
ValuesGroupedAggregationIteration collects historical values and weights into grouping buckets (defined by tupled grouping series) and applies a caller-provided aggregation per bucket.
Usage hints:
- Configure accepted group tuples via params: “accepted_value_group_tupindex_k”.
- Provide grouping source partitions/indices via “grouping_partition_tupindex_k” and “grouping_value_indices_tupindex_k”.
- Provide the state series via “state_partition” and “state_value_indices”.
- Set Kernel and precision (“float_precision”); optionally set “default_values”.
type ValuesGroupedAggregationIteration struct {
Aggregation func(
defaultValues []float64,
outputIndexByGroup map[string]int,
groupings map[string][]float64,
weightings map[string][]float64,
) []float64
Kernel kernels.IntegrationKernel
// contains filtered or unexported fields
}func (*ValuesGroupedAggregationIteration) Configure
func (v *ValuesGroupedAggregationIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*ValuesGroupedAggregationIteration) Iterate
func (v *ValuesGroupedAggregationIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type ValuesSortedCollectionCovarianceIteration
ValuesSortedCollectionCovarianceIteration computes a weighted covariance matrix of the top entries in a sorted collection around a provided mean, blended with its own previous state via a learning rate. This enables adaptive covariance updates for evolution strategies or similar rank-based optimisation algorithms.
Usage hints:
- Provide: “sorted_collection” (flattened sorted state from upstream), “weights” (rank-based weights for top-μ entries, should sum to 1), “learning_rate” (blend factor α), “values_state_width” (dimension D of each entry, excluding sort key), and “mean” (current mean vector from the mean update partition).
- Output is a D×D flattened symmetric covariance matrix, consistent with mat.SymDense.RawSymmetric().Data format.
type ValuesSortedCollectionCovarianceIteration struct {
}func (*ValuesSortedCollectionCovarianceIteration) Configure
func (v *ValuesSortedCollectionCovarianceIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*ValuesSortedCollectionCovarianceIteration) Iterate
func (v *ValuesSortedCollectionCovarianceIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type ValuesSortedCollectionMeanIteration
ValuesSortedCollectionMeanIteration computes a weighted mean of the top entries in a sorted collection, blended with its own previous state via a learning rate. This enables adaptive mean updates for evolution strategies or similar rank-based optimisation algorithms.
Usage hints:
- Provide: “sorted_collection” (flattened sorted state from upstream), “weights” (rank-based weights for top-μ entries, should sum to 1), “learning_rate” (blend factor α), and “values_state_width” (dimension D of each entry, excluding sort key).
- Sorted collection entries are ordered highest sort key first (index 0).
type ValuesSortedCollectionMeanIteration struct {
}func (*ValuesSortedCollectionMeanIteration) Configure
func (v *ValuesSortedCollectionMeanIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*ValuesSortedCollectionMeanIteration) Iterate
func (v *ValuesSortedCollectionMeanIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type ValuesSortingCollectionIteration
ValuesSortingCollectionIteration maintains a sorted collection of entries.
Usage hints:
- Provide: “values_state_width” (entry width minus 1 for sort key) and “empty_value” sentinel. Set PushAndSort to define insertion behaviour.
type ValuesSortingCollectionIteration struct {
PushAndSort func(
params *simulator.Params,
partitionIndex int,
stateHistories []*simulator.StateHistory,
timestepsHistory *simulator.CumulativeTimestepsHistory,
) (SortingValues, bool)
}func (*ValuesSortingCollectionIteration) Configure
func (v *ValuesSortingCollectionIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*ValuesSortingCollectionIteration) Iterate
func (v *ValuesSortingCollectionIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64type ValuesWeightedResamplingIteration
ValuesWeightedResamplingIteration resamples historical values from other partitions according to provided (optionally discounted) weights.
Usage hints:
- Provide: “log_weight_partitions” (and optional “log_weight_indices”).
- Provide: “data_values_partitions” to choose which values to resample.
- Use “past_discounting_factor” to downweight older history (exponential).
type ValuesWeightedResamplingIteration struct {
// contains filtered or unexported fields
}func (*ValuesWeightedResamplingIteration) Configure
func (v *ValuesWeightedResamplingIteration) Configure(partitionIndex int, settings *simulator.Settings)func (*ValuesWeightedResamplingIteration) Iterate
func (v *ValuesWeightedResamplingIteration) Iterate(params *simulator.Params, partitionIndex int, stateHistories []*simulator.StateHistory, timestepsHistory *simulator.CumulativeTimestepsHistory) []float64Generated by gomarkdoc