diff --git a/index.html b/index.html index 3ac25969..6a5afc30 100644 --- a/index.html +++ b/index.html @@ -1,3 +1,2 @@ - diff --git a/previews/PR240/BUGS_notes/index.html b/previews/PR240/BUGS_notes/index.html index 51564b02..af18072c 100644 --- a/previews/PR240/BUGS_notes/index.html +++ b/previews/PR240/BUGS_notes/index.html @@ -1,461 +1,2 @@ -Notes on BUGS Implementations · JuliaBUGS.jl - - - - - -

Miscellaneous Notes on BUGS

Here are some exert from BUGS Developer Manual and notes on the original BUGS implementations.

Lexing

  • The BUGS language has the convention that if a name is followed immediately by a round bracket, that is by a "(", then the names is a reserved name in the BUGS language and does not represent a variable in the model.
  • By scanning the stream of tokens that constitute a BUGS language model the names of all the variables in the model can be found.

Table of Names

  • The BUGS language compiler expands all the for loops in the model and records the value of the indices of each use of a tensor on the left hand side of each relation.
  • The range of each index, for a tensor, is set at the maximum value observed value of the index and added to the name table. There is one exception to this procedure for finding index bounds: names that are data, that is in the data source, have the ranges of their indices fixed in the data source.
  • Each scalar and each component of a tensor used on the right hand side of a relation must occur either on the left hand side of a relation and or in a data source.

Data Transformations

If the compiler can prove that a logical assignment can be evaluated to a constant then the assignment is called a data transformation. This occurs if an assignment's right hand side does not depend on any variable quantities. The BUGS language has a general rule that there must only be one assignment statement for each scalar or component of a tensor. This rule is slightly relaxed for data transformations. The language allows a logical assignment and a stochastic assignment to the same scalar or tensor component if and only if the logical assignment is a data transformation.

Generated Quantities

Only need to be evaluated after the inference algorithm has finished its task.

  • Generally, these are leaf nodes that logical variables
  • In the case of stochastic variables that are leaf nodes, do “forward sampling”, also part of the generated Quantities

Computation

  • All the nodes in the graphical model representing logical relations are placed into an

array and sorted by their nesting level with the first array entries only depending on quantities defined by stochastic relations. Traversing this array and evaluating nodes gives up to date values to all logical relations.

Types

The BUGS compiler uses the properties of the distribution on the right-hand side of a stochastic assignment statement to make deductions about the variable on the left-hand side. For example, r ~ dbin(p, n) implies that r is integer-valued, while x ~ dnorm(mu, tau) implies that x is real-valued.

Some distributions are real-valued but have support on a restricted range of the reals. For example, p ~ dbeta(a, b) implies that p is real-valued with support on the unit interval, while x ~ dgamma(r, lambda) implies that x is real-valued but with support on the positive real line.

There are two multivariate distributions in the BUGS language, the Dirichlet and the Wishart, that have support on a complex subspace of the reals. The Dirichlet has support on the unit simplex, while the Wishart has support on symmetric positive definite matrices.

The BUGS compiler tries to infer if logical relations return an integer value by looking at whether their parents are integer-valued and the operators that combine the values of their parents into the return value. For example, in the cure model example above, the logical relation state1[i] <- state[i] + 1 is integer-valued because state[i] is a Bernoulli variable and therefore integer, the literal 1 is integer, and the sum of two integers is an integer.

When the BUGS system reads in data from a data source, it can tag whether the number read is an integer or a real and propagate this information to logical relations. Again, using the cure model as an example, the statement t[i] <- x[i] + y[i] is integer-valued because both x and y are data and are given as integers in the data source.

One special type of data is constants: that is just numbers with no associated distribution. Constants have many uses in BUGS language models, but one of the most important is as covariates. A model can contain a large number of constants that are used as covariates. Because of the possible large numbers of these covariate-type constants, they are given special treatment by the BUGS compiler. If a name read in from a data source is only used on the right-hand side of logical relations, no nodes in the graphical model are created to hold its values; they are directly incorporated in the objects that represent the right-hand sides of the logical relations.

For example, the large Methadone model contains the regression:

mu.indexed[i] <- beta[1] * x1[i] + beta[2] * x2[i] + beta[3] * x3[i] + beta[4] * x4[i] + region.effect[region.indexed[i]] + source.effect[region.indexed[i]] * source.indexed[i] + person.effect[person.indexed[i]]

where i ranges from 1 to 240776. Not having to create a node in the graphical model to represent x1, x2, x3, x4, region.indexed, source.index, and person.indexed saves a large amount of space.

In the BUGS language, the type information is fine-grained: each component of a tensor can have different type information. This is quite distinct from the situation in STAN and can make it much easier to specify a statistical model. One common case is where some components of a tensor have been observed while other components need to be estimated. The STAN documentation suggests workarounds for these situations, but these are somewhat complex.

  • The type propagation is interesting and maybe useful. But we don’t necessarily need to implement a type system. A dirty way to get type information is simply do a dry run with some tricks.

Work flow

The statistical model and data are presented to the BUGS system in a series of stages. In the first stage the model text is parsed into a tree and the name table constructed. The data is then loaded and checked against the model. The data can be split over a number of source. Once all the data has been loaded the model is compiled. Compiling builds the graphical model and does a large number of checks on the consistency of the model. Finally initial values can be given or generated for the model.

The compiler creates a node in the graphical model for each scalar name and each component of a tensor name in the BUGS language model. The compiler checks that only one node is created for each scalar name or component of a tensor name.

Reading in a data source causes the compiler to create special nodes called constant nodes to hold the values of the data.

The compiler processes logical relations before stochastic relations. Any logical relations that only have constant nodes on their right hand side become new constant nodes with the appropriate fixed value. Even if a logical relation can not be reduced to a constant some parts of the relation might be reduced to constants.

Any constant nodes that have an associated stochastic relation become data nodes in the graphical model.

Logical relations in the BUGS Language

The OpenBUGS software compiles a description of a statistical model in the BUGS language into a graph of objects. Each relation in the statistical model gives rise to a node in the graph of objects. Each distinct type of relation in the statistical model is represented by a node of a distinct class. For stochastic relations there is a fixed set of distributions that can be used in the modelling. For logical relations the situation is more complex. The software can use arbitrary logical expressions build out of a fixed set of basic operators and functions. For each distinct logical expression a new software source code module is written to implement a class to represent that logical expression in the graph of objects. The software module is then compiled using the Components Pascal compiler and the executable code merged into the running OpenBUGS software using the run time loading linker.

The BUGS language description of a statistical model is parsed into a list of trees. The sub-trees that represent logical relations in the statistical model are first converted into a stack based representation and then into Component Pascal source code. The source code is generated in module BugsCPWrite and the source code is then compiled in module BugsCPCompiler. Usually the generated source code is not displayed. Checking the Verbose option in the Info menu will cause each each source code module generated by the OpenBUGS software to be displayed in a separate window.

One advantage of a stack based representation of an expression is that it is straight forward to use it to derive source code that calculates the derivative of the expression with respect to its arguments. This part of the source code generation is carried out in module BugsCPWrite in procedure WriteEvaluateDiffMethod. Each operator in the stack representation of the logical expression causes a snippet of Component Pascal code to be written. These code snippets are generally very simple with those of binary operators slightly more complex than those of unitary operators. Each binary operators can emit three different code snippets: the general case and two special snippets depending on whether the left or right operands are numerical constants. The only complex code snippet is when an operand that is a logical relation in the statistical model is pushed onto the stack – the > case of nested logical relations. In this case the nested logical relation will have its own code to calculate derivatives and these values can be passed up the nesting level.

The OpenBUGS software now uses a backward mode scheme to calculate the value of logical nodes in the statistical model. All the logical nodes in the statistical model are held in a global array and sorted according to their nesting level with unnested nodes at the start of the array. To evaluate all the logical nodes in the statistical model this array is then traversed and each logical node evaluated and the value stored in the node. The same scheme is used to calculate derivatives.

The graphs derived from the BUGS language representation of statistical models are generally sparse. The OpenBUGS software uses conditional independence arguments to exploit sparsity in the stochastic parts of the model. There is also a sparsity structure in logical relations.Each logical relation will often depend on just a few stochastic parents and derivatives with respect to other stochastic nodes in the model will be structurally zero. Each logical node has an associated array of stochastic parents for which the derivatives are non zero. Moving up the level of nesting the number of parents can grow. Dealing with this issue leads to the complexity in the code snippet for the operator that pushes a logical node onto the stack. These issues can be seen in the non-linear random effects model called Orange trees in volume II of the OpenBUGS examples. In this model eta[i,] is a function of phi[i,1], phi[i,2] and phi[i,3] where the phi are also logical functions of the stochastic theta[i,].

One refinement of the backward mode scheme used to calculate the value of logical nodes is to consider separately any logical nodes in the statistical model which are only used for prediction and do not affect the calculation of the joint probability distribution. These nodes need only be evaluated once per iteration of the inference algorithm. Examples of such nodes are sigma[k] and sigma.C in the Orange trees example. There is no need to evaluate the derivatives of these prediction nodes.

The workings of the backward mode scheme are easy to visualize when the inference algorithm updates all the stochastic nodes in the statistical model in one block. Local versions of the backward mode scheme can be used when the inference algorithm works on single nodes or when a small blocks of nodes are updated. Each stochastic node is given its own vector of logical nodes that depend on it either directly or via other logical nodes and this vector is sorted by nesting level. Each updater that works on small blocks of nodes contains a vector of logical nodes which is the union of the vectors of dependent logical nodes for each of its components.

The idea of the backward mode scheme for evaluating logical nodes can be used with caching in Metropolis Hastings sampling. First the vector of logical nodes depending on the relevant stochastic node(s) is evaluated and their values cached. The log of the conditional distribution is then calculated. Next a new value of the stochastic node is proposed. The vector of logical nodes is re-evaluated and the log of the > conditional distribution calculated. If the proposed value is rejected then the cache is used to set the vector of logical nodes back to its old values.

The OpenBUGS software also calculates what class of function each logical node is in terms of its stochastic parents. If the software can prove for example that a logical node is a linear function of its parents more efficient sampling algorithms can be used. If a linear relation can be proved then the calculation of derivatives can also be optimized in some cases because they will be constant and so only need to be calculated once. Generalized linear models are implemented in a way that allows fast calculation of derivatives. The structure of the algorithm to classify the functional form of logical nodes is very similar to that for derivatives and uses a backward mode scheme

BUGS separates management of logical and stochastic variables, essentially two graphs. Logical variables are stored in an array and values are updated with values in earlier positions of the array.

- +Notes on BUGS Implementations · JuliaBUGS.jl

Miscellaneous Notes on BUGS

Here are some exert from BUGS Developer Manual and notes on the original BUGS implementations.

Lexing

  • The BUGS language has the convention that if a name is followed immediately by a round bracket, that is by a "(", then the names is a reserved name in the BUGS language and does not represent a variable in the model.
  • By scanning the stream of tokens that constitute a BUGS language model the names of all the variables in the model can be found.

Table of Names

  • The BUGS language compiler expands all the for loops in the model and records the value of the indices of each use of a tensor on the left hand side of each relation.
  • The range of each index, for a tensor, is set at the maximum value observed value of the index and added to the name table. There is one exception to this procedure for finding index bounds: names that are data, that is in the data source, have the ranges of their indices fixed in the data source.
  • Each scalar and each component of a tensor used on the right hand side of a relation must occur either on the left hand side of a relation and or in a data source.

Data Transformations

If the compiler can prove that a logical assignment can be evaluated to a constant then the assignment is called a data transformation. This occurs if an assignment's right hand side does not depend on any variable quantities. The BUGS language has a general rule that there must only be one assignment statement for each scalar or component of a tensor. This rule is slightly relaxed for data transformations. The language allows a logical assignment and a stochastic assignment to the same scalar or tensor component if and only if the logical assignment is a data transformation.

Generated Quantities

Only need to be evaluated after the inference algorithm has finished its task.

  • Generally, these are leaf nodes that logical variables
  • In the case of stochastic variables that are leaf nodes, do “forward sampling”, also part of the generated Quantities

Computation

  • All the nodes in the graphical model representing logical relations are placed into an

array and sorted by their nesting level with the first array entries only depending on quantities defined by stochastic relations. Traversing this array and evaluating nodes gives up to date values to all logical relations.

Types

The BUGS compiler uses the properties of the distribution on the right-hand side of a stochastic assignment statement to make deductions about the variable on the left-hand side. For example, r ~ dbin(p, n) implies that r is integer-valued, while x ~ dnorm(mu, tau) implies that x is real-valued.

Some distributions are real-valued but have support on a restricted range of the reals. For example, p ~ dbeta(a, b) implies that p is real-valued with support on the unit interval, while x ~ dgamma(r, lambda) implies that x is real-valued but with support on the positive real line.

There are two multivariate distributions in the BUGS language, the Dirichlet and the Wishart, that have support on a complex subspace of the reals. The Dirichlet has support on the unit simplex, while the Wishart has support on symmetric positive definite matrices.

The BUGS compiler tries to infer if logical relations return an integer value by looking at whether their parents are integer-valued and the operators that combine the values of their parents into the return value. For example, in the cure model example above, the logical relation state1[i] <- state[i] + 1 is integer-valued because state[i] is a Bernoulli variable and therefore integer, the literal 1 is integer, and the sum of two integers is an integer.

When the BUGS system reads in data from a data source, it can tag whether the number read is an integer or a real and propagate this information to logical relations. Again, using the cure model as an example, the statement t[i] <- x[i] + y[i] is integer-valued because both x and y are data and are given as integers in the data source.

One special type of data is constants: that is just numbers with no associated distribution. Constants have many uses in BUGS language models, but one of the most important is as covariates. A model can contain a large number of constants that are used as covariates. Because of the possible large numbers of these covariate-type constants, they are given special treatment by the BUGS compiler. If a name read in from a data source is only used on the right-hand side of logical relations, no nodes in the graphical model are created to hold its values; they are directly incorporated in the objects that represent the right-hand sides of the logical relations.

For example, the large Methadone model contains the regression:

mu.indexed[i] <- beta[1] * x1[i] + beta[2] * x2[i] + beta[3] * x3[i] + beta[4] * x4[i] + region.effect[region.indexed[i]] + source.effect[region.indexed[i]] * source.indexed[i] + person.effect[person.indexed[i]]

where i ranges from 1 to 240776. Not having to create a node in the graphical model to represent x1, x2, x3, x4, region.indexed, source.index, and person.indexed saves a large amount of space.

In the BUGS language, the type information is fine-grained: each component of a tensor can have different type information. This is quite distinct from the situation in STAN and can make it much easier to specify a statistical model. One common case is where some components of a tensor have been observed while other components need to be estimated. The STAN documentation suggests workarounds for these situations, but these are somewhat complex.

  • The type propagation is interesting and maybe useful. But we don’t necessarily need to implement a type system. A dirty way to get type information is simply do a dry run with some tricks.

Work flow

The statistical model and data are presented to the BUGS system in a series of stages. In the first stage the model text is parsed into a tree and the name table constructed. The data is then loaded and checked against the model. The data can be split over a number of source. Once all the data has been loaded the model is compiled. Compiling builds the graphical model and does a large number of checks on the consistency of the model. Finally initial values can be given or generated for the model.

The compiler creates a node in the graphical model for each scalar name and each component of a tensor name in the BUGS language model. The compiler checks that only one node is created for each scalar name or component of a tensor name.

Reading in a data source causes the compiler to create special nodes called constant nodes to hold the values of the data.

The compiler processes logical relations before stochastic relations. Any logical relations that only have constant nodes on their right hand side become new constant nodes with the appropriate fixed value. Even if a logical relation can not be reduced to a constant some parts of the relation might be reduced to constants.

Any constant nodes that have an associated stochastic relation become data nodes in the graphical model.

Logical relations in the BUGS Language

The OpenBUGS software compiles a description of a statistical model in the BUGS language into a graph of objects. Each relation in the statistical model gives rise to a node in the graph of objects. Each distinct type of relation in the statistical model is represented by a node of a distinct class. For stochastic relations there is a fixed set of distributions that can be used in the modelling. For logical relations the situation is more complex. The software can use arbitrary logical expressions build out of a fixed set of basic operators and functions. For each distinct logical expression a new software source code module is written to implement a class to represent that logical expression in the graph of objects. The software module is then compiled using the Components Pascal compiler and the executable code merged into the running OpenBUGS software using the run time loading linker.

The BUGS language description of a statistical model is parsed into a list of trees. The sub-trees that represent logical relations in the statistical model are first converted into a stack based representation and then into Component Pascal source code. The source code is generated in module BugsCPWrite and the source code is then compiled in module BugsCPCompiler. Usually the generated source code is not displayed. Checking the Verbose option in the Info menu will cause each each source code module generated by the OpenBUGS software to be displayed in a separate window.

One advantage of a stack based representation of an expression is that it is straight forward to use it to derive source code that calculates the derivative of the expression with respect to its arguments. This part of the source code generation is carried out in module BugsCPWrite in procedure WriteEvaluateDiffMethod. Each operator in the stack representation of the logical expression causes a snippet of Component Pascal code to be written. These code snippets are generally very simple with those of binary operators slightly more complex than those of unitary operators. Each binary operators can emit three different code snippets: the general case and two special snippets depending on whether the left or right operands are numerical constants. The only complex code snippet is when an operand that is a logical relation in the statistical model is pushed onto the stack – the > case of nested logical relations. In this case the nested logical relation will have its own code to calculate derivatives and these values can be passed up the nesting level.

The OpenBUGS software now uses a backward mode scheme to calculate the value of logical nodes in the statistical model. All the logical nodes in the statistical model are held in a global array and sorted according to their nesting level with unnested nodes at the start of the array. To evaluate all the logical nodes in the statistical model this array is then traversed and each logical node evaluated and the value stored in the node. The same scheme is used to calculate derivatives.

The graphs derived from the BUGS language representation of statistical models are generally sparse. The OpenBUGS software uses conditional independence arguments to exploit sparsity in the stochastic parts of the model. There is also a sparsity structure in logical relations.Each logical relation will often depend on just a few stochastic parents and derivatives with respect to other stochastic nodes in the model will be structurally zero. Each logical node has an associated array of stochastic parents for which the derivatives are non zero. Moving up the level of nesting the number of parents can grow. Dealing with this issue leads to the complexity in the code snippet for the operator that pushes a logical node onto the stack. These issues can be seen in the non-linear random effects model called Orange trees in volume II of the OpenBUGS examples. In this model eta[i,] is a function of phi[i,1], phi[i,2] and phi[i,3] where the phi are also logical functions of the stochastic theta[i,].

One refinement of the backward mode scheme used to calculate the value of logical nodes is to consider separately any logical nodes in the statistical model which are only used for prediction and do not affect the calculation of the joint probability distribution. These nodes need only be evaluated once per iteration of the inference algorithm. Examples of such nodes are sigma[k] and sigma.C in the Orange trees example. There is no need to evaluate the derivatives of these prediction nodes.

The workings of the backward mode scheme are easy to visualize when the inference algorithm updates all the stochastic nodes in the statistical model in one block. Local versions of the backward mode scheme can be used when the inference algorithm works on single nodes or when a small blocks of nodes are updated. Each stochastic node is given its own vector of logical nodes that depend on it either directly or via other logical nodes and this vector is sorted by nesting level. Each updater that works on small blocks of nodes contains a vector of logical nodes which is the union of the vectors of dependent logical nodes for each of its components.

The idea of the backward mode scheme for evaluating logical nodes can be used with caching in Metropolis Hastings sampling. First the vector of logical nodes depending on the relevant stochastic node(s) is evaluated and their values cached. The log of the conditional distribution is then calculated. Next a new value of the stochastic node is proposed. The vector of logical nodes is re-evaluated and the log of the > conditional distribution calculated. If the proposed value is rejected then the cache is used to set the vector of logical nodes back to its old values.

The OpenBUGS software also calculates what class of function each logical node is in terms of its stochastic parents. If the software can prove for example that a logical node is a linear function of its parents more efficient sampling algorithms can be used. If a linear relation can be proved then the calculation of derivatives can also be optimized in some cases because they will be constant and so only need to be calculated once. Generalized linear models are implemented in a way that allows fast calculation of derivatives. The structure of the algorithm to classify the functional form of logical nodes is very similar to that for derivatives and uses a backward mode scheme

BUGS separates management of logical and stochastic variables, essentially two graphs. Logical variables are stored in an array and values are updated with values in earlier positions of the array.

diff --git a/previews/PR240/R_interface/index.html b/previews/PR240/R_interface/index.html index e886fad1..03f407db 100644 --- a/previews/PR240/R_interface/index.html +++ b/previews/PR240/R_interface/index.html @@ -1,461 +1,2 @@ -R Interface · JuliaBUGS.jl - - - - - -
- +R Interface · JuliaBUGS.jl
diff --git a/previews/PR240/api/api/index.html b/previews/PR240/api/api/index.html index 59c7b419..8e8583d6 100644 --- a/previews/PR240/api/api/index.html +++ b/previews/PR240/api/api/index.html @@ -1,462 +1,3 @@ -General · JuliaBUGS.jl - - - - - -

API

JuliaBUGS.Parser.@bugsMacro
@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 to true, all periods (.) in the BUGS code are replaced. This is enabled by default.
  • no_enclosure::Bool: When true, the parser does not require the BUGS program to be enclosed within model{ ... } brackets. By default, this is set to false.
source
JuliaBUGS.compileFunction
compile(model_def, data[, initial_params])

Compile the model with model definition and data. Optionally, initializations can be provided. If initializations are not provided, values will be sampled from the prior distributions.

source
JuliaBUGS.initialize!Function
initialize!(model::BUGSModel, initial_params::NamedTuple)

Initialize the model with a NamedTuple of initial values, the values are expected to be in the original space.

source
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.

source
- +General · JuliaBUGS.jl

API

JuliaBUGS.Parser.@bugsMacro
@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 to true, all periods (.) in the BUGS code are replaced. This is enabled by default.
  • no_enclosure::Bool: When true, the parser does not require the BUGS program to be enclosed within model{ ... } brackets. By default, this is set to false.
source
JuliaBUGS.compileFunction
compile(model_def, data[, initial_params])

Compile the model with model definition and data. Optionally, initializations can be provided. If initializations are not provided, values will be sampled from the prior distributions.

source
JuliaBUGS.initialize!Function
initialize!(model::BUGSModel, initial_params::NamedTuple)

Initialize the model with a NamedTuple of initial values, the values are expected to be in the original space.

source
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.

source
diff --git a/previews/PR240/api/distributions/index.html b/previews/PR240/api/distributions/index.html index 3b50981b..a433d0c7 100644 --- a/previews/PR240/api/distributions/index.html +++ b/previews/PR240/api/distributions/index.html @@ -1,462 +1,3 @@ -Distributions · JuliaBUGS.jl - - - - - -
JuliaBUGS.BUGSPrimitives.dnormFunction
dnorm(μ, τ)

Returns an instance of Normal with mean $μ$ and standard deviation $\frac{1}{√τ}$.

\[p(x|μ,τ) = \sqrt{\frac{τ}{2π}} e^{-τ \frac{(x-μ)^2}{2}}\]

source
JuliaBUGS.BUGSPrimitives.dlogisFunction
dlogis(μ, τ)

Return an instance of Logistic with location parameter $μ$ and scale parameter $\frac{1}{√τ}$.

\[p(x|μ,τ) = \frac{\sqrt{τ} e^{-\sqrt{τ}(x-μ)}}{(1+e^{-\sqrt{τ}(x-μ)})^2}\]

source
JuliaBUGS.BUGSPrimitives.dtFunction
dt(μ, τ, ν)

If $μ = 0$ and $σ = 1$, the function returns an instance of TDist with $ν$ degrees of freedom, location $μ$, and scale $σ = \frac{1}{\sqrt{τ}}$. Otherwise, it returns an instance of TDistShiftedScaled.

\[p(x|ν,μ,σ) = \frac{Γ((ν+1)/2)}{Γ(ν/2) \sqrt{νπσ}} -\left(1+\frac{1}{ν}\left(\frac{x-μ}{σ}\right)^2\right)^{-\frac{ν+1}{2}}\]

source
JuliaBUGS.BUGSPrimitives.TDistShiftedScaledType
TDistShiftedScaled(ν, μ, σ)

Student's t-distribution with $ν$ degrees of freedom, location $μ$, and scale $σ$.

This struct allows for a shift (determined by $μ$) and a scale (determined by $σ$) of the standard Student's t-distribution provided by the Distributions.jl package.

Only pdf and logpdf are implemented for this distribution.

See Also

TDist

source
JuliaBUGS.BUGSPrimitives.dflatFunction
dflat()

Returns an instance of Flat or TruncatedFlat if truncated.

Flat represents a flat (uniform) prior over the real line, which is an improper distribution. And TruncatedFlat represents a truncated version of the Flat distribution.

Only pdf, logpdf, minimum, and maximum are implemented for these Distributions.

When use in a model, the parameters always need to be initialized.

source
JuliaBUGS.BUGSPrimitives.dweibFunction
dweib(a, b)

Returns an instance of Weibull distribution object with shape parameter $a$ and scale parameter $\frac{1}{b}$.

The Weibull distribution is a common model for event times. The hazard or instantaneous risk of the event is $abx^{a-1}$. For $a < 1$ the hazard decreases with $x$; for $a > 1$ it increases. $a = 1$ results in the exponential distribution with constant hazard.

\[p(x|a,b) = abx^{a-1}e^{-b x^a}\]

source
JuliaBUGS.BUGSPrimitives.dgevFunction
dgev(μ, σ, η)

Returns an instance of GeneralizedExtremeValue with location $μ$, scale $σ$, and shape $η$.

\[p(x|μ,σ,η) = \frac{1}{σ} \left(1 + η \frac{x - μ}{σ}\right)^{-\frac{1}{η} - 1} e^{-\left(1 + η \frac{x - μ}{σ}\right)^{-\frac{1}{η}}}\]

where $\frac{η(x - μ)}{σ} > -1$.

source
JuliaBUGS.BUGSPrimitives.dfFunction
df(n, m, μ=0, τ=1)

Returns an instance of F-distribution object with $n$ and $m$ degrees of freedom, location $μ$, and scale $τ$. This function is only valid when $μ = 0$ and $τ = 1$,

\[p(x|n, m, μ, τ) = \frac{\Gamma\left(\frac{n+m}{2}\right)}{\Gamma\left(\frac{n}{2}\right) \Gamma\left(\frac{m}{2}\right)} \left(\frac{n}{m}\right)^{\frac{n}{2}} \sqrt{τ} \left(\sqrt{τ}(x - μ)\right)^{\frac{n}{2}-1} \left(1 + \frac{n \sqrt{τ}(x-μ)}{m}\right)^{-\frac{n+m}{2}}\]

where $\frac{n \sqrt{τ} (x - μ)}{m} > -1$.

source
JuliaBUGS.BUGSPrimitives.dmnormFunction
dmnorm(μ::AbstractVector, T::AbstractMatrix)

Returns an instance of Multivariate Normal with mean vector μ and covariance matrix $T^{-1}$.

\[p(x|μ,T) = (2π)^{-k/2} |T|^{1/2} e^{-1/2 (x-μ)' T (x-μ)}\]

where $k$ is the dimension of x.

source
JuliaBUGS.BUGSPrimitives.dmtFunction
dmt(μ::AbstractVector, T::AbstractMatrix, k)

Returns an instance of Multivariate T with mean vector $μ$, scale matrix $T^{-1}$, and $k$ degrees of freedom.

\[p(x|k,μ,Σ) = \frac{\Gamma((k+d)/2)}{\Gamma(k/2) (k\pi)^{p/2} |Σ|^{1/2}} \left(1 + \frac{1}{k} (x-μ)^T Σ^{-1} (x-μ)\right)^{-\frac{k+p}{2}}\]

where $p$ is the dimension of $x$.

source
JuliaBUGS.BUGSPrimitives.dwishFunction
dwish(R::AbstractMatrix, k)

Returns an instance of Wishart with $k$ degrees of freedom and the scale matrix $T^{-1}$.

\[p(X|R,k) = |R|^{k/2} |X|^{(k-p-1)/2} e^{-(1/2) tr(RX)} / (2^{kp/2} Γ_p(k/2))\]

where $p$ is the dimension of $X$, and it should be less than or equal to $k$.

source
JuliaBUGS.BUGSPrimitives.ddirichFunction
ddirich(θ::AbstractVector)

Return an instance of Dirichlet with parameters $θ_i$.

\[p(x|θ) = \frac{Γ(\sum θ)}{∏ Γ(θ)} ∏ x_i^{θ_i - 1}\]

where $\theta_i > 0, x_i \in [0, 1], \sum_i x_i = 1$

source
JuliaBUGS.BUGSPrimitives.dbinFunction
dbin(p, n)

Returns an instance of Binomial with number of trials n and success probability p.

\[p(x|n,p) = \binom{n}{x} p^x (1 - p)^{n-x}\]

end

where $\theta \in [0, 1], n \in \mathbb{Z}^+,$ and $x = 0, \ldots, n$.

source
JuliaBUGS.BUGSPrimitives.dhyperFunction
dhyper(n₁, n₂, m₁, ψ=1)

Returns an instance of Hypergeometric. This distribution is used when sampling without replacement from a population consisting of $n₁$ successes and $n₂$ failures, with $m₁$ being the number of trials or the sample size. The function currently only allows for $ψ = 1$.

\[p(x | n₁, n₂, m₁, \psi) = \frac{\binom{n₁}{x} \binom{n₂}{m₁ - x} \psi^x}{\sum_{i=u_0}^{u_1} \binom{n1}{i} \binom{n2}{m₁ - i} \psi^i}\]

where $u_0 = \max(0, m₁-n₂), u_1 = \min(n₁,m₁),$ and $u_0 \leq x \leq u_1$

source
- +Distributions · JuliaBUGS.jl
JuliaBUGS.BUGSPrimitives.dnormFunction
dnorm(μ, τ)

Returns an instance of Normal with mean $μ$ and standard deviation $\frac{1}{√τ}$.

\[p(x|μ,τ) = \sqrt{\frac{τ}{2π}} e^{-τ \frac{(x-μ)^2}{2}}\]

source
JuliaBUGS.BUGSPrimitives.dlogisFunction
dlogis(μ, τ)

Return an instance of Logistic with location parameter $μ$ and scale parameter $\frac{1}{√τ}$.

\[p(x|μ,τ) = \frac{\sqrt{τ} e^{-\sqrt{τ}(x-μ)}}{(1+e^{-\sqrt{τ}(x-μ)})^2}\]

source
JuliaBUGS.BUGSPrimitives.dtFunction
dt(μ, τ, ν)

If $μ = 0$ and $σ = 1$, the function returns an instance of TDist with $ν$ degrees of freedom, location $μ$, and scale $σ = \frac{1}{\sqrt{τ}}$. Otherwise, it returns an instance of TDistShiftedScaled.

\[p(x|ν,μ,σ) = \frac{Γ((ν+1)/2)}{Γ(ν/2) \sqrt{νπσ}} +\left(1+\frac{1}{ν}\left(\frac{x-μ}{σ}\right)^2\right)^{-\frac{ν+1}{2}}\]

source
JuliaBUGS.BUGSPrimitives.TDistShiftedScaledType
TDistShiftedScaled(ν, μ, σ)

Student's t-distribution with $ν$ degrees of freedom, location $μ$, and scale $σ$.

This struct allows for a shift (determined by $μ$) and a scale (determined by $σ$) of the standard Student's t-distribution provided by the Distributions.jl package.

Only pdf and logpdf are implemented for this distribution.

See Also

TDist

source
JuliaBUGS.BUGSPrimitives.dflatFunction
dflat()

Returns an instance of Flat or TruncatedFlat if truncated.

Flat represents a flat (uniform) prior over the real line, which is an improper distribution. And TruncatedFlat represents a truncated version of the Flat distribution.

Only pdf, logpdf, minimum, and maximum are implemented for these Distributions.

When use in a model, the parameters always need to be initialized.

source
JuliaBUGS.BUGSPrimitives.dweibFunction
dweib(a, b)

Returns an instance of Weibull distribution object with shape parameter $a$ and scale parameter $\frac{1}{b}$.

The Weibull distribution is a common model for event times. The hazard or instantaneous risk of the event is $abx^{a-1}$. For $a < 1$ the hazard decreases with $x$; for $a > 1$ it increases. $a = 1$ results in the exponential distribution with constant hazard.

\[p(x|a,b) = abx^{a-1}e^{-b x^a}\]

source
JuliaBUGS.BUGSPrimitives.dgevFunction
dgev(μ, σ, η)

Returns an instance of GeneralizedExtremeValue with location $μ$, scale $σ$, and shape $η$.

\[p(x|μ,σ,η) = \frac{1}{σ} \left(1 + η \frac{x - μ}{σ}\right)^{-\frac{1}{η} - 1} e^{-\left(1 + η \frac{x - μ}{σ}\right)^{-\frac{1}{η}}}\]

where $\frac{η(x - μ)}{σ} > -1$.

source
JuliaBUGS.BUGSPrimitives.dfFunction
df(n, m, μ=0, τ=1)

Returns an instance of F-distribution object with $n$ and $m$ degrees of freedom, location $μ$, and scale $τ$. This function is only valid when $μ = 0$ and $τ = 1$,

\[p(x|n, m, μ, τ) = \frac{\Gamma\left(\frac{n+m}{2}\right)}{\Gamma\left(\frac{n}{2}\right) \Gamma\left(\frac{m}{2}\right)} \left(\frac{n}{m}\right)^{\frac{n}{2}} \sqrt{τ} \left(\sqrt{τ}(x - μ)\right)^{\frac{n}{2}-1} \left(1 + \frac{n \sqrt{τ}(x-μ)}{m}\right)^{-\frac{n+m}{2}}\]

where $\frac{n \sqrt{τ} (x - μ)}{m} > -1$.

source
JuliaBUGS.BUGSPrimitives.dmnormFunction
dmnorm(μ::AbstractVector, T::AbstractMatrix)

Returns an instance of Multivariate Normal with mean vector μ and covariance matrix $T^{-1}$.

\[p(x|μ,T) = (2π)^{-k/2} |T|^{1/2} e^{-1/2 (x-μ)' T (x-μ)}\]

where $k$ is the dimension of x.

source
JuliaBUGS.BUGSPrimitives.dmtFunction
dmt(μ::AbstractVector, T::AbstractMatrix, k)

Returns an instance of Multivariate T with mean vector $μ$, scale matrix $T^{-1}$, and $k$ degrees of freedom.

\[p(x|k,μ,Σ) = \frac{\Gamma((k+d)/2)}{\Gamma(k/2) (k\pi)^{p/2} |Σ|^{1/2}} \left(1 + \frac{1}{k} (x-μ)^T Σ^{-1} (x-μ)\right)^{-\frac{k+p}{2}}\]

where $p$ is the dimension of $x$.

source
JuliaBUGS.BUGSPrimitives.dwishFunction
dwish(R::AbstractMatrix, k)

Returns an instance of Wishart with $k$ degrees of freedom and the scale matrix $T^{-1}$.

\[p(X|R,k) = |R|^{k/2} |X|^{(k-p-1)/2} e^{-(1/2) tr(RX)} / (2^{kp/2} Γ_p(k/2))\]

where $p$ is the dimension of $X$, and it should be less than or equal to $k$.

source
JuliaBUGS.BUGSPrimitives.ddirichFunction
ddirich(θ::AbstractVector)

Return an instance of Dirichlet with parameters $θ_i$.

\[p(x|θ) = \frac{Γ(\sum θ)}{∏ Γ(θ)} ∏ x_i^{θ_i - 1}\]

where $\theta_i > 0, x_i \in [0, 1], \sum_i x_i = 1$

source
JuliaBUGS.BUGSPrimitives.dbinFunction
dbin(p, n)

Returns an instance of Binomial with number of trials n and success probability p.

\[p(x|n,p) = \binom{n}{x} p^x (1 - p)^{n-x}\]

end

where $\theta \in [0, 1], n \in \mathbb{Z}^+,$ and $x = 0, \ldots, n$.

source
JuliaBUGS.BUGSPrimitives.dhyperFunction
dhyper(n₁, n₂, m₁, ψ=1)

Returns an instance of Hypergeometric. This distribution is used when sampling without replacement from a population consisting of $n₁$ successes and $n₂$ failures, with $m₁$ being the number of trials or the sample size. The function currently only allows for $ψ = 1$.

\[p(x | n₁, n₂, m₁, \psi) = \frac{\binom{n₁}{x} \binom{n₂}{m₁ - x} \psi^x}{\sum_{i=u_0}^{u_1} \binom{n1}{i} \binom{n2}{m₁ - i} \psi^i}\]

where $u_0 = \max(0, m₁-n₂), u_1 = \min(n₁,m₁),$ and $u_0 \leq x \leq u_1$

source
diff --git a/previews/PR240/api/functions/index.html b/previews/PR240/api/functions/index.html index d0845e96..e23e7e49 100644 --- a/previews/PR240/api/functions/index.html +++ b/previews/PR240/api/functions/index.html @@ -1,463 +1,5 @@ -Functions · JuliaBUGS.jl - - - - - -

Most of the functions from BUGS have been implemented.

JuliaBUGS directly utilizes functions from the Julia Standard Library when they share the same names and functionalities. For functions not available in the Julia Standard Library and other popular libraries, we have developed equivalents within JuliaBUGS.BUGSPrimitives.

Function defined in Julia Standard Library

No keyword arguments syntax in BUGS

Please note that some functions listed may accept additional arguments (e.g. trunc) and/or keyword arguments (e.g. sum, sort, mean). However, at the moment JuliaBUGS only supports function arguments of type Real or AbstractArray{Real}. Furthermore, JuliaBUGS does not accommodate the use of keyword argument syntax. Thus, the default values for any optional or keyword arguments will be automatically applied.

Base.absFunction
abs(x)

The absolute value of x.

When abs is applied to signed integers, overflow may occur, resulting in the return of a negative value. This overflow occurs only when abs is applied to the minimum representable value of a signed integer. That is, when x == typemin(typeof(x)), abs(x) == x < 0, not -x as might be expected.

See also: abs2, unsigned, sign.

Examples

julia> abs(-3)
+Functions · JuliaBUGS.jl

Most of the functions from BUGS have been implemented.

JuliaBUGS directly utilizes functions from the Julia Standard Library when they share the same names and functionalities. For functions not available in the Julia Standard Library and other popular libraries, we have developed equivalents within JuliaBUGS.BUGSPrimitives.

Function defined in Julia Standard Library

No keyword arguments syntax in BUGS

Please note that some functions listed may accept additional arguments (e.g. trunc) and/or keyword arguments (e.g. sum, sort, mean). However, at the moment JuliaBUGS only supports function arguments of type Real or AbstractArray{Real}. Furthermore, JuliaBUGS does not accommodate the use of keyword argument syntax. Thus, the default values for any optional or keyword arguments will be automatically applied.

Base.absFunction
abs(x)

The absolute value of x.

When abs is applied to signed integers, overflow may occur, resulting in the return of a negative value. This overflow occurs only when abs is applied to the minimum representable value of a signed integer. That is, when x == typemin(typeof(x)), abs(x) == x < 0, not -x as might be expected.

See also: abs2, unsigned, sign.

Examples

julia> abs(-3)
 3
 
 julia> abs(1 + im)
@@ -602,5 +144,4 @@
 

Compute the complementary log-log, log(-log(1 - x)).

LogExpFunctions.logitFunction
logit(x)
 

The logit or log-odds transformation, defined as

\[\operatorname{logit}(x) = \log\left(\frac{x}{1-x}\right)\]

for $0 < x < 1$.

Its inverse is the logistic function.

LogExpFunctions.logisticFunction
logistic(x)
-

The logistic sigmoid function mapping a real number to a value in the interval $[0,1]$,

\[\sigma(x) = \frac{1}{e^{-x} + 1} = \frac{e^x}{1+e^x}.\]

Its inverse is the logit function.

Function defined in JuliaBUGS.BUGSPrimitives

- +

The logistic sigmoid function mapping a real number to a value in the interval $[0,1]$,

\[\sigma(x) = \frac{1}{e^{-x} + 1} = \frac{e^x}{1+e^x}.\]

Its inverse is the logit function.

Function defined in JuliaBUGS.BUGSPrimitives

diff --git a/previews/PR240/api/user_defined_functions/index.html b/previews/PR240/api/user_defined_functions/index.html index b824e1b7..7a956101 100644 --- a/previews/PR240/api/user_defined_functions/index.html +++ b/previews/PR240/api/user_defined_functions/index.html @@ -1,463 +1,5 @@ -User-Defined Functions and Distributions · JuliaBUGS.jl - - - - - -

Define and Use Your Own Functions and Distributions

Out of the box, JuliaBUGS only allows functions and distributions defined in BUGSPrimitives, Base, and Distributions.jl to be used in the model. With the @register_primitive macro, users can register their own functions and distributions with JuliaBUGS. It is important to ensure that any functions used are pure mathematical functions. This implies that such functions should not alter any external state including but not limited to modifying global variables, writing data to files. (Printing might be okay, but do at discretion.)

julia> JuliaBUGS.@register_primitive function f(x)
+User-Defined Functions and Distributions · JuliaBUGS.jl

Define and Use Your Own Functions and Distributions

Out of the box, JuliaBUGS only allows functions and distributions defined in BUGSPrimitives, Base, and Distributions.jl to be used in the model. With the @register_primitive macro, users can register their own functions and distributions with JuliaBUGS. It is important to ensure that any functions used are pure mathematical functions. This implies that such functions should not alter any external state including but not limited to modifying global variables, writing data to files. (Printing might be okay, but do at discretion.)

julia> JuliaBUGS.@register_primitive function f(x)
     return x + 1
 end
 f (generic function with 1 method)
@@ -469,5 +11,4 @@
 julia> JuliaBUGS.@register_primitive(f);
 
 julia> JuliaBUGS.f(1)
-2

After registering the function or distributions, they can be used just like any other functions or distributions provided by BUGS.

- +2

After registering the function or distributions, they can be used just like any other functions or distributions provided by BUGS.

diff --git a/previews/PR240/differences/index.html b/previews/PR240/differences/index.html index 5d04f1ad..be93d092 100644 --- a/previews/PR240/differences/index.html +++ b/previews/PR240/differences/index.html @@ -1,463 +1,5 @@ -Differences from Other BUGS Implementations · JuliaBUGS.jl - - - - - -

Differences From Other BUGS Implementations

There exist many implementations of BUGS, notably WinBUGS, OpenBUGS, MultiBUGS, JAGS, and nimble.

This section aims to outline some differences between JuliaBUGS and other BUGS implementations. This comparison is not exhaustive, and we welcome any further discussion and reports on the matter.

Use of generaic function in distribution functions

In WinBUGS, OpenBUGS, and MultiBUGS, the arguments to distribution functions are typically restricted to variables or constants, not general expressions. JuliaBUGS, however, allows for more flexibility in these arguments.

For example, the following expressions are allowed in all BUGS implementations, including JuliaBUGS (assuming y = [1, 2, 3]):

model {
+Differences from Other BUGS Implementations · JuliaBUGS.jl

Differences From Other BUGS Implementations

There exist many implementations of BUGS, notably WinBUGS, OpenBUGS, MultiBUGS, JAGS, and nimble.

This section aims to outline some differences between JuliaBUGS and other BUGS implementations. This comparison is not exhaustive, and we welcome any further discussion and reports on the matter.

Use of generaic function in distribution functions

In WinBUGS, OpenBUGS, and MultiBUGS, the arguments to distribution functions are typically restricted to variables or constants, not general expressions. JuliaBUGS, however, allows for more flexibility in these arguments.

For example, the following expressions are allowed in all BUGS implementations, including JuliaBUGS (assuming y = [1, 2, 3]):

model {
  x ~ dnorm(y[y[2]], 1)
 }
 
@@ -504,5 +46,4 @@
     alpha12 ~ dnorm(0.0, 1.0e-6)
     tau ~ dgamma(0.001, 0.001)
     sigma = 1 / sqrt(tau)
-end

(When the program is in the original BUGS syntax, the link function syntax is supported.)

It's also worth noting that JuliaBUGS uses Bijectors.jl to handle constrained parameters.

Compare with nimble

In the BUGS language, link functions are only supported in logical assignments. However, nimble extends this functionality by allowing link functions to be used in stochastic assignments as well. nimble will creates new node as intermediate variables. JuliaBUGS doesn't currently support this syntax.

- +end

(When the program is in the original BUGS syntax, the link function syntax is supported.)

It's also worth noting that JuliaBUGS uses Bijectors.jl to handle constrained parameters.

Compare with nimble

In the BUGS language, link functions are only supported in logical assignments. However, nimble extends this functionality by allowing link functions to be used in stochastic assignments as well. nimble will creates new node as intermediate variables. JuliaBUGS doesn't currently support this syntax.

diff --git a/previews/PR240/example/index.html b/previews/PR240/example/index.html index c3de137a..4dbd003c 100644 --- a/previews/PR240/example/index.html +++ b/previews/PR240/example/index.html @@ -1,463 +1,5 @@ -Example · JuliaBUGS.jl - - - - - -

Example: Logistic Regression with Random Effects

We will use the Seeds for demonstration. This example concerns the proportion of seeds that germinated on each of 21 plates. Here, we transform the data into a NamedTuple:

data = (
+Example · JuliaBUGS.jl

Example: Logistic Regression with Random Effects

We will use the Seeds for demonstration. This example concerns the proportion of seeds that germinated on each of 21 plates. Here, we transform the data into a NamedTuple:

data = (
     r = [10, 23, 23, 26, 17, 5, 53, 55, 32, 46, 10, 8, 10, 8, 23, 0, 3, 22, 15, 32, 3],
     n = [39, 62, 81, 51, 39, 6, 74, 72, 51, 79, 13, 16, 30, 28, 45, 4, 12, 41, 30, 51, 7],
     x1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
@@ -689,5 +231,4 @@
     init_params = [initial_θ for _ = 1:n_chains], # each chain has its own initial parameters
     discard_initial = n_adapts,
     progress = false, # Base.TTY creating problems in distributed setting
-)

In this case, we pass two additional arguments to AbstractMCMC.sample:

  • AbstractMCMC.MCMCDistributed(): the sampler type, and
  • n_chains: the number of chains to sample.

Note that the init_params argument is now a vector of initial parameters for each chain. Sometimes the progress logger can cause problems in distributed setting, so we can disable it by setting progress = false.

More Examples

We have transcribed all the examples from the first volume of the BUGS Examples (original and transcribed). All programs and data are included, and can be compiled using the steps described in the tutorial above.

- +)

In this case, we pass two additional arguments to AbstractMCMC.sample:

  • AbstractMCMC.MCMCDistributed(): the sampler type, and
  • n_chains: the number of chains to sample.

Note that the init_params argument is now a vector of initial parameters for each chain. Sometimes the progress logger can cause problems in distributed setting, so we can disable it by setting progress = false.

More Examples

We have transcribed all the examples from the first volume of the BUGS Examples (original and transcribed). All programs and data are included, and can be compiled using the steps described in the tutorial above.

diff --git a/previews/PR240/graph_plotting/index.html b/previews/PR240/graph_plotting/index.html index 2683875d..114c287b 100644 --- a/previews/PR240/graph_plotting/index.html +++ b/previews/PR240/graph_plotting/index.html @@ -1,463 +1,5 @@ -Plotting · JuliaBUGS.jl - - - - - -

Plotting graphs

Plotting the graphical model can be very beneficial for debugging the model.

Plate notation is not yet supported

Users are advised to begin with a model that contains fewer nodes, so that the graph is easier to visualize.

We have set up standard plotting routines with GraphMakie.jl and GraphPlot.jl, via package extensions.

Observed nodes are colored in gray, unobserved nodes are colored in white, and deterministic nodes are colored in light blue.

model_def = @bugs begin
+Plotting · JuliaBUGS.jl

Plotting graphs

Plotting the graphical model can be very beneficial for debugging the model.

Plate notation is not yet supported

Users are advised to begin with a model that contains fewer nodes, so that the graph is easier to visualize.

We have set up standard plotting routines with GraphMakie.jl and GraphPlot.jl, via package extensions.

Observed nodes are colored in gray, unobserved nodes are colored in white, and deterministic nodes are colored in light blue.

model_def = @bugs begin
     a ~ dnorm(f, c)
     f = b - 1
     b ~ dnorm(0, 1)
@@ -485,5 +27,4 @@
 
 model = compile(model_def, data, inits)

GraphPlot.jl

using GraphPlot
 gplot(model)

GraphPlot

GraphMakie.jl

using GLMakie, GraphMakie
-graphplot(model)

GraphMakie

- +graphplot(model)

GraphMakie

diff --git a/previews/PR240/index.html b/previews/PR240/index.html index 6b166ade..301cf305 100644 --- a/previews/PR240/index.html +++ b/previews/PR240/index.html @@ -1,461 +1,2 @@ -Home · JuliaBUGS.jl - - - - - -

JuliaBUGS.jl

JuliaBUGS is a graph-based probabilistic programming framework inspired by the BUGS language.

Key features of JuliaBUGS include:

  • Compatibility with existing BUGS programs
  • Extensibility through user-defined functions and distributions; programmable inference
  • Seamless integration with Julia's high-performance numerical and scientific computing libraries
  • Automatic differentiation and sampling using Hamiltonian Monte Carlo

It's important to note that while BUGS traditionally refers to either the software system, the language, or the inference algorithm, JuliaBUGS is a pure Julia implementation of the BUGS language, not a wrapper for the BUGS system.

Understanding the BUGS Language

The BUGS (Bayesian inference Using Gibbs Sampling) language is designed for specifying directed graphical models in probabilistic programming. Unlike imperative probabilistic programming languages such as Turing.jl or Pyro, BUGS focuses on declarative relationships between nodes in a graph.

This graph-based approach offers several advantages:

  1. Clarity: It provides a clear understanding of dependencies and relationships within complex systems.
  2. Transparency: Users can explicitly state conditional dependencies between variables, making model structure and assumptions more transparent.
  3. Ease of development and interpretation: The graphical representation aids in both model development and result interpretation.
  4. Efficient inference: The graph structure facilitates the application of advanced inference algorithms, enabling more efficient computation by leveraging the model's structure.

By adopting this approach, JuliaBUGS aims to combine the clarity and power of graphical models with the performance and flexibility of the Julia programming language.

- +Home · JuliaBUGS.jl

JuliaBUGS.jl

JuliaBUGS is a graph-based probabilistic programming framework inspired by the BUGS language.

Key features of JuliaBUGS include:

  • Compatibility with existing BUGS programs
  • Extensibility through user-defined functions and distributions; programmable inference
  • Seamless integration with Julia's high-performance numerical and scientific computing libraries
  • Automatic differentiation and sampling using Hamiltonian Monte Carlo

It's important to note that while BUGS traditionally refers to either the software system, the language, or the inference algorithm, JuliaBUGS is a pure Julia implementation of the BUGS language, not a wrapper for the BUGS system.

Understanding the BUGS Language

The BUGS (Bayesian inference Using Gibbs Sampling) language is designed for specifying directed graphical models in probabilistic programming. Unlike imperative probabilistic programming languages such as Turing.jl or Pyro, BUGS focuses on declarative relationships between nodes in a graph.

This graph-based approach offers several advantages:

  1. Clarity: It provides a clear understanding of dependencies and relationships within complex systems.
  2. Transparency: Users can explicitly state conditional dependencies between variables, making model structure and assumptions more transparent.
  3. Ease of development and interpretation: The graphical representation aids in both model development and result interpretation.
  4. Efficient inference: The graph structure facilitates the application of advanced inference algorithms, enabling more efficient computation by leveraging the model's structure.

By adopting this approach, JuliaBUGS aims to combine the clarity and power of graphical models with the performance and flexibility of the Julia programming language.

diff --git a/previews/PR240/parser/index.html b/previews/PR240/parser/index.html index ac6a56dc..4a5b1963 100644 --- a/previews/PR240/parser/index.html +++ b/previews/PR240/parser/index.html @@ -1,461 +1,2 @@ -Parser · JuliaBUGS.jl - - - - - -

BUGS Parser

The macro @bugs produces a Julia Expr object that represents the BUGS model definition.

If the input is a String, it's assumed to be a program in the original BUGS language. In this case, the macro will first convert the program to an equivalent Julia program, then use the Julia parser to parse the program into an Expr object.

Both model definitions written in Julia and those written in the original BUGS and subsequently parsed are now represented as a Julia Expr object. These objects go through syntax checking and post-processing to create the input for the compile function.

Below, we describe how the original BUGS program is translated to an equivalent Julia program and detail the post-processing done to the Expr object.

BUGS to Julia Translation

In this section, we refer to the translation program as the "parser" and the translating process as "parsing". Although the parser doesn't produce a syntax tree, it does follow the form of a recursive descent parser, building a Julia program in the form of a vector of tokens rather than a syntax tree.

This general implementation is heavily inspired by JuliaSyntax.jl, the official parser for Julia since version 1.10.

The BUGS parser implemented here takes a token stream with a recursive descent structure and checks the program's correctness. Here's how it works:

  1. Use tokenize to obtain the token vector.
  2. Inspect the tokens and build the Julia version of the program as a vector of tokens.
  3. Push the token to the Julia version of the program vector when appropriate.
  4. Detect errors and make necessary alterations to tokens, such as deletion, combination, or replacement.

During the recursive descent, BUGS syntax tokens will be translated into Julia syntax tokens. Some tokens will remain as they are, while others will be transformed, removed, or new tokens may be added.

The parser will throw an error if it encounters a program that does not adhere to strict BUGS syntax.

Some Notes on Error Recovery

The current error recovery is ad hoc and primarily rudimentary. If the program is correct, it will produce the correct result. If the program is syntactically or semantically incorrect, the token stream will not be pushed forward, resulting in failure.

The failure detection mechanism checks if two errors occur with the same "current token". If they do, the parser stops and reports the error. This ensures that the parser won't incorrectly parse a flawed program.

- +Parser · JuliaBUGS.jl

BUGS Parser

The macro @bugs produces a Julia Expr object that represents the BUGS model definition.

If the input is a String, it's assumed to be a program in the original BUGS language. In this case, the macro will first convert the program to an equivalent Julia program, then use the Julia parser to parse the program into an Expr object.

Both model definitions written in Julia and those written in the original BUGS and subsequently parsed are now represented as a Julia Expr object. These objects go through syntax checking and post-processing to create the input for the compile function.

Below, we describe how the original BUGS program is translated to an equivalent Julia program and detail the post-processing done to the Expr object.

BUGS to Julia Translation

In this section, we refer to the translation program as the "parser" and the translating process as "parsing". Although the parser doesn't produce a syntax tree, it does follow the form of a recursive descent parser, building a Julia program in the form of a vector of tokens rather than a syntax tree.

This general implementation is heavily inspired by JuliaSyntax.jl, the official parser for Julia since version 1.10.

The BUGS parser implemented here takes a token stream with a recursive descent structure and checks the program's correctness. Here's how it works:

  1. Use tokenize to obtain the token vector.
  2. Inspect the tokens and build the Julia version of the program as a vector of tokens.
  3. Push the token to the Julia version of the program vector when appropriate.
  4. Detect errors and make necessary alterations to tokens, such as deletion, combination, or replacement.

During the recursive descent, BUGS syntax tokens will be translated into Julia syntax tokens. Some tokens will remain as they are, while others will be transformed, removed, or new tokens may be added.

The parser will throw an error if it encounters a program that does not adhere to strict BUGS syntax.

Some Notes on Error Recovery

The current error recovery is ad hoc and primarily rudimentary. If the program is correct, it will produce the correct result. If the program is syntactically or semantically incorrect, the token stream will not be pushed forward, resulting in failure.

The failure detection mechanism checks if two errors occur with the same "current token". If they do, the parser stops and reports the error. This ensures that the parser won't incorrectly parse a flawed program.

diff --git a/previews/PR240/pitfalls/index.html b/previews/PR240/pitfalls/index.html index 773e00cc..2b7f3b0d 100644 --- a/previews/PR240/pitfalls/index.html +++ b/previews/PR240/pitfalls/index.html @@ -1,463 +1,5 @@ -Pitfalls · JuliaBUGS.jl - - - - - -

Understanding Pitfalls in Model Definitions

Consequence of Observations on Model Parameters

When providing observations for the parameters of a model, the dependencies may become disrupted. Consider the following example written in Julia:

model_def = @bugs begin
+Pitfalls · JuliaBUGS.jl
- +}
diff --git a/previews/PR240/search/index.html b/previews/PR240/search/index.html index 59748eba..aefa05fd 100644 --- a/previews/PR240/search/index.html +++ b/previews/PR240/search/index.html @@ -1,461 +1,2 @@ -Search · JuliaBUGS.jl - - - - - -

Loading search...

    - +Search · JuliaBUGS.jl

    Loading search...