API
Model Definition and Compilation
JuliaBUGS.Parser.@bugs — Macro
@bugs(program::Expr)
@bugs(program::String; replace_period::Bool=true, no_enclosure::Bool=false)Constructs a Julia Abstract Syntax Tree (AST) representation of a BUGS program. This macro supports two forms of input: a Julia expression or a string containing the BUGS program code.
- When provided with a string, the macro parses it as a BUGS program, with optional arguments to control parsing behavior.
- When given an expression, it performs syntactic checks to ensure compatibility with BUGS syntax.
Arguments for String Input
For the string input variant, the following optional arguments are available:
replace_period::Bool: When set totrue, all periods (.) in the BUGS code are replaced. This is enabled by default.no_enclosure::Bool: Whentrue, the parser does not require the BUGS program to be enclosed withinmodel{ ... }brackets. By default, this is set tofalse.
JuliaBUGS.@model — Macro
@model function_definitionDefine a probabilistic model using JuliaBUGS syntax.
The @model macro transforms a function definition into a model-generating function. When called, this function returns a compiled BUGSModel object that can be used for inference.
Function Signature
The macro creates a function with this pattern:
@model function model_name(
(; param1, param2, ...)::OptionalOfType, # Stochastic parameters (first argument)
constant1, constant2, ... # Constants and covariates
)
# Model body with probabilistic statements using ~
endThis generates a function model_name that, when called with appropriate arguments, returns a BUGSModel instance.
Arguments
- First argument: A named tuple destructuring pattern for stochastic parameters
- Must use the syntax
(; name1, name2, ...) - Can optionally include an
oftype annotation like(; x, y)::MyOfType - Contains all variables that have probability distributions in the model
- Must use the syntax
- Remaining arguments: Constants, covariates, and structural parameters
- These are deterministic values that don't have distributions
- Examples: covariate matrices, sample sizes, fixed hyperparameters
Model Body
Inside the model body, use the ~ operator to specify probability distributions:
y ~ dnorm(mu, tau) # y follows a normal distribution
theta ~ dgamma(a, b) # theta follows a gamma distributionReturns
The generated function returns a BUGSModel object when called with appropriate arguments.
Examples
Simple Linear Regression
# Define the model-generating function
@model function regression(
(; y, beta, sigma), # y is observed data, beta and sigma are parameters
X, N # X is covariate matrix, N is number of observations
)
for i in 1:N
mu[i] = X[i, :] ⋅ beta
y[i] ~ dnorm(mu[i], sigma)
end
beta ~ dnorm(0, 0.001)
sigma ~ dgamma(0.001, 0.001)
end
# Call the function to create a model instance
model = regression((; y = observed_data), X_matrix, length(observed_data))
# `model` is now a BUGSModel objectWith Type Specification
# Define parameter structure
RegressionParams = @of(
y = of(Array, Float64, 100),
beta = of(Array, Float64, 3),
sigma = of(Real, 0, nothing)
)
# Define the model-generating function with type annotation
@model function typed_regression(
(; y, beta, sigma)::RegressionParams,
X, N
)
# Model body...
end
# Create a model instance
model = typed_regression((; y = data), X, N)Notes
- The macro performs compile-time validation of the model structure
- Type annotations are validated after model compilation
- Only
oftypes created with@ofare supported for type annotations - The first argument must always be a destructuring pattern, not a regular variable
- Each call to the generated function creates a new
BUGSModelinstance
JuliaBUGS.compile — Function
compile(model_def, data[, initial_params]; adtype=nothing)Compile a BUGS model. Returns BUGSModel, or BUGSModelWithGradient if adtype is provided.
Arguments
model_def::Expr: Model definition from@bugsmacrodata::NamedTuple: Observed datainitial_params::NamedTuple: Initial parameter values (optional, defaults to prior samples)adtype: AD backend from ADTypes.jl (e.g.,AutoReverseDiff(),AutoForwardDiff(),AutoMooncake())
Examples
model = compile(model_def, data)
model = compile(model_def, data; adtype=AutoReverseDiff())JuliaBUGS.Model.initialize! — Function
initialize!(model::BUGSModel, initial_params::NamedTuple{<:Any, <:Tuple{Vararg{AllowedValue}}})Initialize the model with a NamedTuple of initial values, the values are expected to be in the original space.
initialize!(model::BUGSModel, initial_params::AbstractVector)Initialize the model with a vector of initial values, the values can be in transformed space if model.transformed is set to true.
Type Specifications
JuliaBUGS.of — Function
of(T, args...; constant::Bool=false)Create an OfType specification from various inputs.
Main Methods
Arrays
of(Array, dims...) # Float64 array with given dimensions
of(Array, T, dims...) # Array with element type T and given dimensionsReal Numbers
of(Float64) # Unbounded Float64
of(Float64, lower, upper) # Bounded Float64
of(Float32) # Unbounded Float32
of(Float32, lower, upper) # Bounded Float32
of(Real) # Unbounded Real (defaults to Float64)
of(Real, lower, upper) # Bounded Real (defaults to Float64)Integers
of(Int) # Unbounded integer
of(Int, lower, upper) # Bounded integerNamed Tuples
of((;field1=spec1, field2=spec2, ...)) # NamedTuple with typed fieldsFrom Values (Type Inference)
of(1.0) # Infers of(Float64)
of([1, 2, 3]) # Infers of(Array, Int, 3)
of((a=1, b=2.0)) # Infers OfNamedTupleArguments
T: Type to create specification forargs...: Type-specific arguments (bounds, dimensions, etc.)constant: Mark type as constant/hyperparameter (default: false)
Returns
An OfType subtype encoding the specification in its type parameters.
Examples
# Basic types
T1 = of(Float64, 0, 1) # OfReal{Float64, 0, 1}
T2 = of(Array, 3, 4) # OfArray{Float64, 2, (3, 4)}
T3 = of(Int; constant=true) # OfConstantWrapper{OfInt{Nothing, Nothing}}
# With @of macro for cleaner syntax
T4 = @of(
n = of(Int; constant=true),
data = of(Array, n, 2) # Symbolic dimension
)
# Type concretization
T5 = of(T4; n=10) # Concrete type with n=10See also
of(model::BUGSModel)Extract the of type specification from a compiled BUGSModel.
This function introspects the model's evaluation environment to reconstruct the corresponding of type specification. This is useful for:
- Model introspection and debugging
- Type validation after compilation
- Generic code that needs to work with models without knowing their structure
- Model serialization and deserialization
Arguments
model::BUGSModel: A compiled BUGS model
Returns
- An
OfNamedTupletype representing the structure of all variables in the model
Example
# Define and compile a model
@model function regression((; y, beta, sigma), X, N)
# ... model definition ...
end
model = regression((; y = data), X, N)
# Extract the of type from the compiled model
ModelType = of(model)
# ModelType might be: @of(y = of(Array, Float64, 100), beta = of(Array, Float64, 3), sigma = of(Real, 0, nothing))
# Use the extracted type
rand(ModelType) # Generate random values matching the model structureof(::Type{T}, replacements::NamedTuple) where T<:OfType
of(::Type{T}; kwargs...) where T<:OfType
of(::Type{T}, pairs::Pair{Symbol}...) where T<:OfTypeCreate a concrete type by resolving symbolic dimensions and removing constants.
This function takes an OfType with symbolic dimensions or constants and creates a new type with some or all symbols resolved to concrete values. Constants that are provided are removed from the resulting type.
Arguments
T<:OfType: The type to concretizereplacements: Named tuple or keyword arguments mapping symbols to values
Returns
A new OfType with symbols replaced and constants removed.
Examples
# Define type with symbolic dimensions
T = @of(
n = of(Int; constant=true),
data = of(Array, n, 2)
)
# Create concrete type
ConcreteT = of(T; n=10) # @of(data=of(Array, 10, 2))
# Partial concretization
T2 = @of(
rows = of(Int; constant=true),
cols = of(Int; constant=true),
matrix = of(Array, rows, cols)
)
Partial = of(T2; rows=5) # @of(cols=of(Int; constant=true), matrix=of(Array, 5, :cols))See also
JuliaBUGS.@of — Macro
@of(field1=spec1, field2=spec2, ...)Create an OfNamedTuple type with cleaner syntax for field references.
The @of macro provides a more intuitive syntax for creating named tuple types where fields can reference each other. Field names used in dimensions or bounds are automatically converted to symbolic references.
Syntax
@of(
field_name = of_specification,
...
)Features
- Direct field references without quoting (e.g.,
ninstead of:n) - Support for arithmetic expressions in dimensions (e.g.,
n+1,2*n) - Automatic conversion to appropriate
OfNamedTupletype - Fields are processed in order, allowing later fields to reference earlier ones
Examples
# Basic usage with constants and arrays
T = @of(
n = of(Int; constant=true),
mu = of(Real),
data = of(Array, n, 2) # 'n' automatically converted to symbolic reference
)
# With arithmetic expressions
T = @of(
n = of(Int; constant=true),
original = of(Array, n, n),
padded = of(Array, n+1, n+1),
doubled = of(Array, 2*n, n)
)
# Nested structures
T = @of(
dims = @of(
rows = of(Int; constant=true),
cols = of(Int; constant=true)
),
matrix = of(Array, dims.rows, dims.cols)
)See also
JuliaBUGS.of — Method
of(model::BUGSModel)Extract the of type specification from a compiled BUGSModel.
This function introspects the model's evaluation environment to reconstruct the corresponding of type specification. This is useful for:
- Model introspection and debugging
- Type validation after compilation
- Generic code that needs to work with models without knowing their structure
- Model serialization and deserialization
Arguments
model::BUGSModel: A compiled BUGS model
Returns
- An
OfNamedTupletype representing the structure of all variables in the model
Example
# Define and compile a model
@model function regression((; y, beta, sigma), X, N)
# ... model definition ...
end
model = regression((; y = data), X, N)
# Extract the of type from the compiled model
ModelType = of(model)
# ModelType might be: @of(y = of(Array, Float64, 100), beta = of(Array, Float64, 3), sigma = of(Real, 0, nothing))
# Use the extracted type
rand(ModelType) # Generate random values matching the model structure