Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor graph creation and node function handling (#163)
This PR introduces several enhancements and refactors the graph creation process and node function handling in JuliaBUGS. The main changes include: * Sharing node function expressions across nodes: Previously, each node in the graph had its own unique node function expression. This PR modifies the behavior so that nodes originating from the same statement in the model definition share the same node function expression. Example: ```julia @bugs begin for i in 1:2 x[i] ~ dnorm(0, 1) y[i] ~ dnorm(x[i], i) end end ```` In the previous version, the nodes for x[1], x[2], y[1], and y[2] would have separate node function expressions. Now, they will share the expressions dnorm(0, 1) and dnorm(x[i], i) based on the corresponding statements. The function `replace_constants_in_expr` used to plugin all the scalar values into the node function expr, now the function is removed. The new node function is a function takes all the variable on the RHS as arguments (including loop variables). E.g., ```julia function (;x::AbstractArray{Float64}, i::Int) return dnorm(x[1], i) end ``` The binding of loop variables to values are stored at nodes, and used when evaluating node function. This change reduces memory usage and paves the way for potentially evaluating node functions once and using compiled functions during model evaluation. * Simplifying the graph creation process: The graph building algorithm has been overhauled for clarity. Example: ```julia @bugs begin x[1:2] ~ dmnorm(...) x[3] ~ dnorm(0, 1) y ~ dnorm(sum(x[2:3]), 1) end ``` In the previous version, temporary nodes were created for variables used on the RHS that were not explicitly defined in the model, such as `x[1], x[2], x[2:3]`. These temporary nodes needed to be removed later, adding complexity to the graph construction process. The new approach follows a two-stage process: - In the first stage, nodes are created for all variables explicitly defined in the model, also a matrix containing node id is created for each variable. In this example, `x[1:2]` has id `1`, `x[3]` has id `2`, `y` has id `3`. And id tracker looks like `x_ids = [1, 1, 2]` - In the second stage, edges are inserted between the nodes based on the dependencies specified in the model statements. The node id is looked up and edges are created accordingly. This eliminates the need for creating and removing temporary nodes, resulting in a cleaner and more efficient graph construction process. * Renaming `_eval` to `bugs_eval` * The Var struct and associated functions have been removed. Variables are now represented using Tuple{Symbol, Vararg{Union{Int,UnitRange{Int}}}}. ```julia # Previous representation using Var x = Var(:x) y = Var(:y, (1, 2)) # New representation using tuples x = (:x,) y = (:y, 1, 2) ``` --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
- Loading branch information
dddc106
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JuliaRegistrator register
dddc106
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Registration pull request created: JuliaRegistries/General/103005
Tip: Release Notes
Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.
To add them here just re-invoke and the PR will be updated.
Tagging
After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.
This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via: