synthesizer.emission_models.expansion

A submodule containing the expansion of parameter variations into models.

An EmissionModel can declare that one of its parameters should be varied over a set of values, by passing a ParameterList or ParameterDistribution instead of a single value. Nothing happens until EmissionModel.expand_models is called, at which point the declarations in the tree are turned into concrete models by the machinery in this module.

The expansion works by repeatedly duplicating the “cone” of a varied model, i.e. the model itself plus every model which depends on it:

  1. Every ParameterDistribution is realised into a ParameterList. This happens once, up front, so that models downstream of a varied model share one set of samples rather than resampling in each branch.

  2. The deepest model still carrying a variation is found, and its cone is duplicated once per value, with each copy labelled using the variation’s label_modifier. Models the cone depends on are not duplicated, they are shared by every copy.

  3. Step 2 repeats until no variations remain. Duplicating a cone leaves several copies of any downstream variation, each of which is then expanded in turn, so independent variations multiply out.

Working cone by cone means a model which is depended on by two different models is only duplicated once, since the cone contains both routes. It also means the labels accumulate their suffixes in dependency order without any explicit sorting.

The result is a single root model with the other root variants attached as related models. ModelQueue treats related models as extra roots and prunes to whatever feeds a saved output, so one get_spectra call generates every variant while computing the shared, unvaried models exactly once.

Each pass around the loop re-derives the label keyed view of every model (see _gather), so the work is proportional to the number of variations times the number of models: ~8 ms for 100 variants in 522 models, ~53 s for 20,000 variants in 50,501. It is paid once whatever follows, so it is cheap next to generating those variants for every emitter in a sample. What scales with the model count and does not go away is memory: every model holds an emission while the tree is being generated.

Functions

synthesizer.emission_models.expansion.expand_models(root)[source]

Expand every parameter variation in a model tree into new models.

Parameters:

root (EmissionModel) – The root of the model tree to expand. This model is not modified, the expansion is performed on a copy.

Returns:

The root of the expanded tree. If the root itself was varied (or depends on something which was) this is the first of the root’s variants, with the rest attached as related models.

Return type:

EmissionModel