Skip to content

API Reference

Matryoshka.AbstractComponent Type
julia
AbstractComponent

Abstract supertype for predictor-term components (InterceptComponent, FixedEffectsComponent, RandomInterceptComponent). A component holds the data-contact artifacts for one formula term (design matrix, group indices, factor levels) and implements four functions: compprefix, submodel, priorslots, rebuild. New term types (e.g. Gaussian-process or smooth terms) are added by subtyping AbstractComponent, implementing these four, and adding a lower dispatch (see src/lowering.jl) that turns a matching formula term into the component. Vector-valued parameters sample as plain (unlabeled) arrays; new term types that introduce one should keep its label vector in the struct (see FixedEffectsComponent.names/RandomInterceptComponent.levels) so positional entries can be mapped onto labels by rekey at chain-build time.

Example

julia
using Matryoshka
using Matryoshka: InterceptComponent

InterceptComponent(4) isa AbstractComponent
source
Matryoshka.BernoulliFamily Type
julia
BernoulliFamily <: Family

Bernoulli response family for binary outcomes: mu (success probability) is supplied by the predictor formula on the logit scale. obsmodel applies BernoulliLogit directly to the link-scale linear predictor rather than inverse-linking to a probability first, so extreme eta never saturates p == 1.0 under autodiff.

Example

julia
using Matryoshka

lik = @likelihood Bernoulli y ~ x
lik.family isa BernoulliFamily
source
Matryoshka.Family Type
julia
Family

Abstract supertype for response families (NormalFamily, BernoulliFamily, PoissonFamily). A family declares its distribution parameters, per-parameter links, default priors, and observation submodel via parameters, links, default_priors, and obsmodel. New families are added by subtyping Family and implementing these four functions, plus a to_family dispatch (from the Distributions.jl type name used as the first argument to @likelihood).

Example

julia
using Matryoshka

NormalFamily() isa Family
source
Matryoshka.FixedEffect Type
julia
FixedEffect([coef::Symbol])

Selector for a fixed-effect coefficient. FixedEffect(:x) names the :x coefficient exactly; FixedEffect() (no argument) is the class selector matching every fixed-effect coefficient.

Example

julia
using Matryoshka
using Matryoshka: isexact, matches

isexact(FixedEffect(:x))               # true
matches(FixedEffect(:x), FixedEffect())  # true — :x is in the class
source
Matryoshka.FixedEffectsComponent Type
julia
FixedEffectsComponent(X::Matrix{Float64}, names::Vector{Symbol}, term) <: AbstractComponent

Population-level slope component for one or more predictor columns. Samples a single vector-valued coefficient (b ~ arraydist(priors) — DynamicPPL does not support per-name VarNames inside a Dict, so X's columns map onto b positionally, in names order; see test/spike_notes.md Q3) and returns X * b. term is the concrete StatsModels term used to recompute X from new data in rebuild; it may be nothing when FixedEffectsComponent is constructed directly (e.g. in unit tests) rather than via lower.

Example

julia
using Matryoshka, Distributions
using Matryoshka: FixedEffectsComponent, submodel

X = [1.0 2.0; 3.0 4.0]
c = FixedEffectsComponent(X, [:x1, :x2], nothing)
m = submodel(c, [Normal(0, 1), Normal(0, 5)])
source
Matryoshka.Intercept Type
julia
Intercept()

Selector for the model's intercept parameter. Always exact — there is no class form.

Example

julia
using Matryoshka

Intercept()
source
Matryoshka.InterceptComponent Type
julia
InterceptComponent(n::Int) <: AbstractComponent

Population-level intercept component. Contributes a single sampled intercept parameter, broadcast across all n observations.

Example

julia
using Matryoshka
using Matryoshka: InterceptComponent

c = InterceptComponent(4)
c.n == 4
source
Matryoshka.Likelihood Type
julia
Likelihood{F,T}

Parsed output of @likelihood: family::F (a Family instance) paired with formulas::T, a tuple of StatsModels.FormulaTerms — the response formula first, any distributional-regression formulas after. Construct via the @likelihood macro, not directly.

Example

julia
using Matryoshka

lik = @likelihood Normal y ~ x
lik.family isa NormalFamily
source
Matryoshka.MatryoshkaModel Type
julia
MatryoshkaModel

Wrapper around the DynamicPPL.Model built by model. Owning this type lets Matryoshka provide sample, predict, and returned methods that speak the selector vocabulary without pirating DynamicPPL methods. The raw model is the documented escape hatch m.inner — use it with any DynamicPPL/Turing tooling Matryoshka does not forward.

source
Matryoshka.MatryoshkaParam Type
julia
MatryoshkaParam

Abstract supertype for the parameter selector vocabulary (Intercept, Residuals, FixedEffect, SD, RandomEffect). A selector either names one parameter exactly (an exact selector, isexact(s) == true) or leaves one or more fields unset to target a family of parameters (a class selector). Exact selectors are valid chain keys; class selectors are valid prior targets and sub-chain indices. ==/hash are defined explicitly on each concrete type since selectors are used as dict keys in FlexiChain storage.

Example

julia
using Matryoshka
using Matryoshka: isexact

isexact(FixedEffect(:x))   # true — exact selector
isexact(FixedEffect())     # false — class selector
source
Matryoshka.NormalFamily Type
julia
NormalFamily <: Family

Normal (Gaussian) response family: mu is supplied by the predictor formula on the identity scale; sigma is sampled with its own prior (default Exponential(1)) unless targeted by a formula (distributional regression; not yet supported in v0).

Example

julia
using Matryoshka

lik = @likelihood Normal y ~ x
lik.family isa NormalFamily
source
Matryoshka.PoissonFamily Type
julia
PoissonFamily <: Family

Poisson response family for count outcomes: mu (rate) is supplied by the predictor formula on the log scale.

Example

julia
using Matryoshka

lik = @likelihood Poisson y ~ x
lik.family isa PoissonFamily
source
Matryoshka.Priors Type
julia
Priors

Parsed output of @priors: an ordered list of PriorSpec(target, dist) targets. Construct via the @priors macro, not directly. Passed to model (or default_priors(lik, tbl)) for resolution against a fitted formula's actual parameters — exact targets beat class targets, and unmatched targets error with the list of valid ones.

Example

julia
using Matryoshka, Distributions

pri = @priors begin
    Intercept() ~ TDist(3)
    FixedEffect() ~ Normal(0, 1)
end
pri isa Priors
source
Matryoshka.RandomEffect Type
julia
RandomEffect([group::Symbol[, level::Symbol]])

Selector for a group-level (random) effect. RandomEffect(:g, :a) names the :a level of group :g exactly; RandomEffect(:g) is the class selector for all levels of group :g; RandomEffect() is the class selector for every group-level effect. A level cannot be given without a group.

Example

julia
using Matryoshka
using Matryoshka: isexact, matches

isexact(RandomEffect(:g, :a))                    # true
matches(RandomEffect(:g, :a), RandomEffect(:g))  # true — :a is a level of :g
source
Matryoshka.RandomInterceptComponent Type
julia
RandomInterceptComponent(group::Symbol, idx::Vector{Int}, levels::Vector) <: AbstractComponent

Group-level (random) intercept component for one grouping variable — (1 | group) in formula syntax. Uses a non-centered parameterisation: samples sd (from its prior, default Exponential(1)) and z ~ filldist(Normal(), nlevels), returning (sd .* z)[idx]. idx maps each observation to its group's position in levels; levels are the training-time factor levels, enforced (not extended) on rebuild — a new level in newdata raises an ArgumentError.

Example

julia
using Matryoshka
using Matryoshka: RandomInterceptComponent, compprefix

c = RandomInterceptComponent(:g, [1, 1, 2], ["a", "b"])
compprefix(c) === :g
source
Matryoshka.Residuals Type
julia
Residuals()

Selector for the model's residual (observation-level) parameter. Always exact — there is no class form.

Example

julia
using Matryoshka

Residuals()
source
Matryoshka.SD Type
julia
SD([group::Symbol])

Selector for a group-level standard deviation parameter. SD(:g) names the :g group's SD exactly; SD() (no argument) is the class selector matching every group's SD.

Example

julia
using Matryoshka
using Matryoshka: isexact

isexact(SD(:g))  # true
isexact(SD())    # false — class selector
source
FlexiChains.parameters Function
julia
parameters(f::Family) -> Tuple{Vararg{Symbol}}

Names of f's distribution parameters, response (predictor-supplied) parameter first.

Example

julia
using Matryoshka

parameters(NormalFamily()) == (:mu, :sigma)
source
Matryoshka.compprefix Function
julia
compprefix(c::AbstractComponent) -> Union{Symbol,Nothing}

Namespace prefix for c's submodel, or nothing for an unprefixed submodel. RandomInterceptComponent returns its grouping variable (e.g. :g, so its parameters appear as g.sd, g.z); InterceptComponent and FixedEffectsComponent return nothing.

Example

julia
using Matryoshka
using Matryoshka: RandomInterceptComponent

compprefix(RandomInterceptComponent(:g, [1, 2, 1], ["a", "b"])) === :g
source
Matryoshka.default_priors Function
julia
default_priors(f::Family) -> NamedTuple

Default prior distribution for each of f's parameters that is not supplied by a formula — e.g. sigma for NormalFamily, sampled with its own prior unless a formula such as sigma ~ z targets it (distributional regression; not yet supported in v0).

See also the default_priors(lik::Likelihood, tbl) method, which returns the full resolved-prior table for a model and dataset rather than one family's defaults alone.

Example

julia
using Matryoshka

default_priors(NormalFamily()) == (sigma = Exponential(1),)
source
Matryoshka.default_priors Method
julia
default_priors(lik::Likelihood, tbl) -> Vector{<:NamedTuple}

Resolve the full prior table for lik against data tbl, without fitting. Returns a vector of (target, class, prior) rows — one per parameter the model introduces (each component's slots, then the family's own parameters) — with target and class as MatryoshkaParam selectors and prior the resolved Distributions.jl default. Mirrors brms' default_prior(): inspect before writing a @priors block, or to confirm what a partial @priors block leaves untouched.

See also the default_priors(f::Family) method, which returns only a family's own parameter defaults (as a NamedTuple, not a table).

Example

julia
using Matryoshka, Distributions

df = (y = [1.0, 2.0, 3.0], x = [0.1, 0.2, 0.3], g = ["a", "b", "a"])
lik = @likelihood Normal y ~ x + (1 | g)
tab = default_priors(lik, df)
[r.target for r in tab]   # [Intercept(), SD(:g), FixedEffect(:x), Residuals()]
source
Matryoshka.links Function
julia
links(f::Family) -> NamedTuple

Default link function for each of f's parameters, keyed by parameter name and given as a Symbol (:identity, :log, or :logit).

Example

julia
using Matryoshka

links(PoissonFamily()) == (mu = :log,)
source
Matryoshka.model Method
julia
model(lik::Likelihood, pri::Priors, tbl) -> MatryoshkaModel

Build a MatryoshkaModel wrapping a DynamicPPL.Model from a @likelihood spec, a @priors spec, and a Tables.jl-compatible data source tbl. Applies the StatsModels schema, lowers each formula term into a component, resolves priors (exact target > class target > component default > family default), and wires everything into one model via to_submodel. The recipe (components, schema, family, resolved priors) travels inside m.inner.args.recipe (see Matryoshka.recipe), so model(m, newdata) can rebuild it later.

Errors at model() time — never at sampling time — on: unknown prior targets, formula variables missing from tbl, formulas on a parameter the family lacks, or a predictor-less formula.

Example

julia
using Matryoshka, Distributions, Turing

df = (y = [1.1, 2.3, 0.9, 1.8], x = [0.5, 1.0, 0.2, 0.9])
lik = @likelihood Normal y ~ x
pri = @priors begin
    Intercept() ~ Normal(0, 10)
    FixedEffect() ~ Normal(0, 1)
    Residuals() ~ Exponential(1)
end
m = model(lik, pri, df)
chain = sample(m, NUTS(), 100; progress = false)
chain[FixedEffect(:x)]                 # one coefficient's draws
chain[FixedEffect(), stack = true]     # (iter, chain, coef) labeled DimArray
source
Matryoshka.model Method
julia
model(m::MatryoshkaModel, newdata) -> MatryoshkaModel

Rebuild m — a model previously returned by model(lik, pri, tbl) — against newdata, reusing the recipe stored in m.inner.args.recipe (same components, schema, and resolved priors; grouping variables enforce training-time factor levels and reject unseen ones). If newdata has no response column, the rebuilt model's y is missing, ready for Turing.predict. If it does have the response column, the rebuilt model is fit-ready (a refit-on-new-data workflow).

Example

julia
using Matryoshka, Distributions, Turing

df = (y = [1.1, 2.3, 0.9, 1.8], x = [0.5, 1.0, 0.2, 0.9])
lik = @likelihood Normal y ~ x
pri = @priors begin
    Intercept() ~ Normal(0, 10)
    FixedEffect() ~ Normal(0, 1)
    Residuals() ~ Exponential(1)
end
m = model(lik, pri, df)
chain = sample(m, NUTS(), 100; progress = false)

m_new = model(m, (x = [0.4, 1.2],))   # no y column → predict-mode
preds = predict(m_new, chain)
source
Matryoshka.obsmodel Function
julia
obsmodel(f::Family) -> (eta, priors, y) -> DynamicPPL.Model

Observation-submodel constructor for f. Returns a callable built by model()/model(m, newdata) as obsmodel(f)(eta, fam_priors, y):

  • eta: the link-scale linear predictor for f's response parameter — the sum of all component contributions, before any inverse link is applied. Not the mean.

  • fam_priors: a NamedTuple of resolved priors for f's other parameters (e.g. (sigma = Exponential(1),) for NormalFamily).

  • y: the observed response, or missing when predicting.

Each family applies its own inverse link to eta inside the returned model (not by first computing a mean-scale parameter), which is numerically safer under autodiff:

Familyuses eta as
NormalFamilymu directly (identity link)
BernoulliFamilyBernoulliLogit.(eta) (logit link)
PoissonFamilyPoisson.(exp.(eta)) (log link)

Example

julia
using Matryoshka, Distributions, DynamicPPL

eta = [0.1, -0.2, 0.3]
y = [0, 1, 0]
m = obsmodel(BernoulliFamily())(eta, NamedTuple(), y)
m isa DynamicPPL.Model
source
Matryoshka.priorslots Function
julia
priorslots(c::AbstractComponent) -> Vector{Tuple{MatryoshkaParam, MatryoshkaParam, Distribution}}

Prior-targeting slots for c, one per parameter c introduces. Each slot is an (exact, class, default) triple: exact and class are MatryoshkaParam selectors (an exact selector and its class selector, e.g. SD(:g) and SD()), and default is the Distributions.jl prior used when no @priors line matches either. Consumed by resolve_priors at model() time, and by default_priors(lik, tbl) for introspection.

Example

julia
using Matryoshka, Distributions
using Matryoshka: RandomInterceptComponent

priorslots(RandomInterceptComponent(:g, [1, 2, 1], ["a", "b"])) == [(SD(:g), SD(), Exponential(1))]
source
Matryoshka.rebuild Function
julia
rebuild(c::AbstractComponent, tbl) -> AbstractComponent

Recompute c against new data tbl, keeping training-time artifacts (factor levels, contrasts) fixed. Used by model(m, newdata) to rebuild each component for prediction or refitting. Grouping variables reject unseen factor levels with an ArgumentError (allow_new_levels is not yet supported).

Example

julia
using Matryoshka
using Matryoshka: InterceptComponent

rebuild(InterceptComponent(4), (y = [1.0, 2.0],)).n == 2
source
Matryoshka.recipe Method
julia
recipe(m::MatryoshkaModel)

Return the Recipe stored in m.inner.args.recipe (components, schema, family, resolved priors).

source
Matryoshka.rekey Method
julia
rekey(m::MatryoshkaModel, chn::FlexiChain{<:VarName}) -> FlexiChain{MatryoshkaParam}

Convert a VarName-keyed chain sampled from m.inner into the selector-keyed chain that sample(m, ...) returns: vector-valued parameters are flattened into one scalar key per coefficient/level (FixedEffect(:x), RandomEffect(:g, :a), ...), with labels and order taken from m's recipe. Sampler extras and chain metadata are preserved. Errors if the chain contains a parameter the recipe cannot map — the escape hatch for chains sampled via m.inner directly.

source
Matryoshka.selectors Function
julia
selectors(f::Family) -> NamedTuple

Exact selector for each of f's non-response parameters, keyed by parameter name — e.g. (sigma = Residuals(),) for NormalFamily. Used to resolve @priors targets and to key family parameters in sampled chains.

source
Matryoshka.submodel Function
julia
submodel(c::AbstractComponent, prior) -> DynamicPPL.Model

Build c's own @model, parameterised by prior (the resolved prior, or vector of priors, for c's slot(s) — as targeted by priorslots). The submodel samples its own parameter(s) and returns its n-vector contribution to the linear predictor. Both the sampled draws and the n-vector contribution returned to core_model are plain, unlabeled arrays; positional entries are mapped onto labels (FixedEffectsComponent.names, RandomInterceptComponent.levels) by rekey at chain-build time.

Example

julia
using Matryoshka, Distributions, DynamicPPL
using Matryoshka: InterceptComponent

c = InterceptComponent(4)
m = submodel(c, Normal(0, 10))
m isa DynamicPPL.Model
source
Matryoshka.to_vnchain Method
julia
to_vnchain(m::MatryoshkaModel, chn::FlexiChain{<:MatryoshkaParam}) -> FlexiChain{VarName}

Inverse of rekey: reassemble the VarName-keyed chain the inner DynamicPPL model understands, using m's recipe for coefficient/level order. Needs the full sampled chain — errors if a selector key is missing (e.g. on a class-indexed sub-chain).

source
Matryoshka.@likelihood Macro
julia
@likelihood(family, ex)

Build a Likelihood spec from a family and one or more tilde-formula lines.

family names the response family as a Distributions.jl distribution type (Normal, Bernoulli, Poisson). ex is either a single lhs ~ rhs expression or a begin...end block of them: the first line is the response formula (e.g. y ~ x + (1 | g)); further lines target other family parameters (e.g. sigma ~ z) — supported by the design but not yet implemented in v0 (model() raises an ArgumentError if any are present). Term parsing delegates to StatsModels.@formula, so formula syntax (+, (1 | g), 0, ...) matches StatsModels exactly.

Example

julia
using Matryoshka

lik = @likelihood Normal begin
    y ~ x + (1 | g)
end
source
Matryoshka.@priors Macro
julia
@priors(ex)

Build a Priors spec from one or more Selector(...) ~ Distribution lines.

Selector(...) is one of the MatryoshkaParam selector types (Intercept(), Residuals(), FixedEffect()/FixedEffect(:x), SD()/SD(:g), RandomEffect()/RandomEffect(:g)/RandomEffect(:g, :a)). A class selector (no argument, or missing fields) targets a family of parameters; an exact selector (all fields given) targets one parameter exactly. ex is a single expression or a begin...end block. Distributions are Distributions.jl objects — there is no string DSL. Targets are not checked against a model here; that happens later, in model() or default_priors(lik, tbl), where exact targets override class targets and unknown targets raise an ArgumentError listing the valid ones.

Example

julia
using Matryoshka, Distributions

pri = @priors begin
    Intercept() ~ TDist(3)
    FixedEffect() ~ Normal(0, 1)
    FixedEffect(:x) ~ Normal(0, 5)   # overrides the FixedEffect() class for coefficient :x
    SD(:g) ~ Exponential(0.5)
end
source