Model Composition — DAG IR¶
Models are defined as a directed acyclic graph (DAG) — spectrafit-core's model intermediate representation (IR) — at the Python level, serialised to JSON, and evaluated entirely in Rust.
Nodes¶
Each node is a ModelNodeSpec: a typed model
instance with a unique id, one ModelType
kernel (Gaussian, Lorentzian, Voigt, …), and its parameters keyed by name.
An optional dataset_index scopes the node to one dataset in a multi-dataset
("global analysis") fit — None (the default) makes it a global node
contributing to every dataset's points; i restricts it to dataset i's
residuals and Jacobian columns.
Edges¶
Edges encode parameter constraints (ties) across nodes, and are evaluated in
Rust — expr_edges are parsed into an Expr/TiedPlan abstract syntax
tree (AST) in spectrafit-graph::expr at compile time, then re-applied every
solver iteration by LmProblem::set_free_and_tied
(crates/spectrafit-solver/src/lm_problem.rs, shared by both the
nalgebra-LM and faer trust-region front-ends) so each tied target is
recomputed from its expression before the model is evaluated:
Each edge is an ExprEdge: a target_node /
target_param pair naming the parameter to constrain, plus an expression
string that references other nodes' parameters in node_id.param form
(e.g. "0.5 * peak1.amplitude").
Aggregation¶
Node outputs are summed at each x point. This is fixed behaviour, not a
selectable default: crates/spectrafit-graph/src/executor.rs accumulates
sum += node.model.eval(...) on every evaluation path, and neither
FitGraphSpec nor the compiled FitGraph carries an aggregation
discriminator. There is no product/max/custom mode to choose.
Why not operator overloading (lmfit-style)?¶
lmfit's model1 + model2 creates a binary tree evaluated recursively at
Python speed, allocating N temporary NumPy arrays per iteration. Our DAG is
compiled once to a Rust struct; evaluation is a single O(N_nodes * N_x) loop
with no Python round-trips.
See also¶
- Related examples:
shared_params.md(an expression edge tying one node's parameter to another's),multi_dataset.md(several datasets composed into one graph),3d_fitting.md(composition at scale). - Related explanation: Parameter Model (what the parameters the nodes declare can be bound to).
- Glossary: Glossary — definitions for this page's
project-specific terms (
DAG IR,ExprEdge,ModelNodeSpec,trust-region,LM).