Terms specify how a node variable is build from its parents.


Here is how a term can be setup

from bn_testing.terms import Term
import numpy as np

some_term = Term(
    parents=['a', 'b'],
    term_fn=lambda v: np.sqrt(v['a'])*v['b'],

Afterwards, the term can be applied on pymc variables and distributions:

import pymc as pm

dist = some_term(
   a=pm.Normal.dist(mu=1, sigma=0.4),
   b=pm.Beta.dist(alpha=0.4, beta=0.2),

Existing terms

Here is a list of terms that ease instantiation for some classes of terms frequently used. Assume that the parents are \(x_1,\ldots,x_n\):

  • Linear: A linear term of the form \(\sum_{i=1}^nw_ix_i\)

  • Polynomial: A multivariate polynomial, i.e., a sum of the form \(\sum_{j=1}^mc_j\prod_{i=1}^nx_i^{e_{ji}}\)

Arithmetic with terms

Given two terms term_a and term_b, another term can be constructed by applying a basic arithemtic computation. For instance:

term_a + term_b
term_a * term_b
(2 * term_a + 3 * term_b)**10


Composing terms like term_a(term_b) is currently not supported.

Implementing own terms

Typically, new terms can be formed by combining the basic terms.

Here is a small example how a term can be computed:

from bn_testing.terms import Term
import numpy as np

class RootMeanSquared(Term):

   def __init__(self, parents):
       super(OwnTerm, self).__init__(parents=parents)

   def apply(self, parents_mapping):
       parents = self.get_vars_from_dict(parents_mapping)
       return np.sqrt(np.mean(parents**2))


Generally, Terms are generated by Conditionals and the parents are selected at runtime randomly. Terms, however, should be deterministic and any random selections should be done in the calling Conditionals.