probabilistic_model.probabilistic_circuit.jax

Contents

probabilistic_model.probabilistic_circuit.jax#

Submodules#

Classes#

SumUnit

Class for inner units

ProductUnit

Decomposable Product Units for Probabilistic Circuits

Unit

Class for all units of a probabilistic circuit.

NXProbabilisticCircuit

Probabilistic Circuits as a directed, rooted, acyclic graph.

Layer

Abstract class for Layers of a layered circuit.

InnerLayer

Abstract Base Class for inner layers

InputLayer

Abstract base class for univariate input units.

SumLayer

Abstract Base Class for inner layers

SparseSumLayer

Abstract Base Class for inner layers

DenseSumLayer

Abstract Base Class for inner layers

ProductLayer

A layer that represents the product of multiple other units.

NXConverterLayer

Class used for conversion from a probabilistic circuit in networkx to a layered circuit in jax.

InputLayer

Abstract base class for univariate input units.

NXConverterLayer

Class used for conversion from a probabilistic circuit in networkx to a layered circuit in jax.

Unit

Class for all units of a probabilistic circuit.

NXProbabilisticCircuit

Probabilistic Circuits as a directed, rooted, acyclic graph.

UnivariateContinuousLeaf

Class for Leaf units.

DiracDeltaDistribution

Class for Dirac delta distributions.

ContinuousLayer

Abstract base class for continuous univariate input units.

ContinuousLayerWithFiniteSupport

Abstract class for continuous univariate input units with finite support.

DiracDeltaLayer

A layer that represents Dirac delta distributions over a single variable.

NXConverterLayer

Class used for conversion from a probabilistic circuit in networkx to a layered circuit in jax.

ContinuousLayerWithFiniteSupport

Abstract class for continuous univariate input units with finite support.

Unit

Class for all units of a probabilistic circuit.

NXProbabilisticCircuit

Probabilistic Circuits as a directed, rooted, acyclic graph.

UnivariateContinuousLeaf

Class for Leaf units.

UniformDistribution

Class for uniform distributions over the half-open interval [lower, upper).

UniformLayer

A layer that represents uniform distributions over a single variable.

Functions#

timeit_print(func)

copy_bcoo(→ jax.experimental.sparse.BCOO)

copy_bcsr(→ jax.experimental.sparse.BCSR)

simple_interval_to_open_array(→ jax.numpy.array)

create_bcoo_indices_from_row_lengths(→ numpy.array)

Create the indices of a BCOO array with the given row lengths.

create_bcoo_indices_from_row_lengths_np(→ numpy.array)

Create the indices of a BCOO array with the given row lengths.

create_bcsr_indices_from_row_lengths(...)

Create the column indices and indent pointer of bcsr array with the given row lengths.

embed_sparse_array_in_nan_array(→ jax.Array)

sample_from_sparse_probabilities_csc(...)

Sample from a sparse array of probabilities.

remove_rows_and_cols_where_all(→ jax.Array)

Remove rows and columns from an array where all elements are equal to a given value.

shrink_index_array(→ jax.Array)

Shrink an index array to only contain successive indices.

sparse_remove_rows_and_cols_where_all(...)

Remove rows and columns from a sparse tensor where all elements are equal to a given value.

copy_bcoo(→ jax.experimental.sparse.BCOO)

inverse_class_of(→ typing_extensions.Type[Layer])

simple_interval_to_open_array(→ jax.numpy.array)

Package Contents#

probabilistic_model.probabilistic_circuit.jax.timeit_print(func)#
probabilistic_model.probabilistic_circuit.jax.copy_bcoo(x: jax.experimental.sparse.BCOO) jax.experimental.sparse.BCOO#
probabilistic_model.probabilistic_circuit.jax.copy_bcsr(x: jax.experimental.sparse.BCSR) jax.experimental.sparse.BCSR#
probabilistic_model.probabilistic_circuit.jax.simple_interval_to_open_array(interval: random_events.interval.SimpleInterval) jax.numpy.array#
probabilistic_model.probabilistic_circuit.jax.create_bcoo_indices_from_row_lengths(row_lengths: numpy.array) numpy.array#

Create the indices of a BCOO array with the given row lengths.

The shape of the indices is (2, sum(row_lengths)). The shape of the sparse tensor that the indices describe should be (len(row_lengths), max(row_lengths)).

Example:

>>> row_lengths = jnp.array([2, 3])
>>> create_bcoo_indices_from_row_lengths(row_lengths)
    [[0 0]
     [0 1]
     [1 0]
     [1 1]
     [1 2]]
Parameters:

row_lengths – The row lengths.

Returns:

The indices of the sparse tensor

probabilistic_model.probabilistic_circuit.jax.create_bcoo_indices_from_row_lengths_np(row_lengths: numpy.array) numpy.array#

Create the indices of a BCOO array with the given row lengths.

The shape of the indices is (2, sum(row_lengths)). The shape of the sparse tensor that the indices describe should be (len(row_lengths), max(row_lengths)).

Example:

>>> row_lengths = jnp.array([2, 3])
>>> create_bcoo_indices_from_row_lengths(row_lengths)
    [[0 0]
     [0 1]
     [1 0]
     [1 1]
     [1 2]]
Parameters:

row_lengths – The row lengths.

Returns:

The indices of the sparse tensor

probabilistic_model.probabilistic_circuit.jax.create_bcsr_indices_from_row_lengths(row_lengths: jax.Array) typing_extensions.Tuple[jax.Array, jax.Array]#

Create the column indices and indent pointer of bcsr array with the given row lengths.

The shape of the sparse tensor that the indices describe should be (len(row_lengths), max(row_lengths)).

Example:

>>> row_lengths = jnp.array([2, 3])
>>> create_bcsr_indices_from_row_lengths(row_lengths)
(Array([0, 1, 0, 1, 2], dtype=int32), Array([0, 2, 5], dtype=int32))
Parameters:

row_lengths – The row lengths.

Returns:

The indices of the sparse tensor

probabilistic_model.probabilistic_circuit.jax.embed_sparse_array_in_nan_array(sparse_array: jax.experimental.sparse.BCOO) jax.Array#
probabilistic_model.probabilistic_circuit.jax.sample_from_sparse_probabilities_csc(probabilities: scipy.sparse.csr_array, amount: numpy.array) scipy.sparse.csc_array#

Sample from a sparse array of probabilities. Each row in the sparse array encodes a categorical probability distribution.

Parameters:
  • probabilities – The sparse array of probabilities.

  • amount – The amount of samples to draw from each row.

Returns:

The samples that are drawn for each state in the probabilities indicies.

probabilistic_model.probabilistic_circuit.jax.remove_rows_and_cols_where_all(array: jax.Array, value: float) jax.Array#

Remove rows and columns from an array where all elements are equal to a given value.

Parameters:
  • array – The tensor to remove rows and columns from.

  • value – The value to remove.

Returns:

The tensor without the rows and columns.

Example:

>>> a = jnp.array([[1, 0, 3], [0, 0, 0], [7, 0, 9]])
>>> remove_rows_and_cols_where_all(a, 0)
array([[1, 3], [7, 9]])
probabilistic_model.probabilistic_circuit.jax.shrink_index_array(index_array: jax.Array) jax.Array#

Shrink an index array to only contain successive indices.

Example:

>>> shrink_index_array(jnp.array([[0, 3], [1, 0], [4, 1]]))
    [[0 2]
     [1 0]
     [2 1]]
Parameters:

index_array – The index tensor to shrink.

Returns:

The shrunken index tensor.

probabilistic_model.probabilistic_circuit.jax.sparse_remove_rows_and_cols_where_all(array: jax.experimental.sparse.BCOO, value: float) jax.experimental.sparse.BCOO#

Remove rows and columns from a sparse tensor where all elements are equal to a given value.

Example::
>>> array = BCOO.fromdense(jnp.array([[1, 0, 3], [0, 0, 0], [7, 0, 9]]))
>>> sparse_remove_rows_and_cols_where_all(array, 0).todense()
    [[1 3]
     [7 9]]
Parameters:
  • array – The sparse tensor to remove rows and columns from.

  • value – The value to remove.

Returns:

The tensor without the unnecessary rows and columns.

probabilistic_model.probabilistic_circuit.jax.copy_bcoo(x: jax.experimental.sparse.BCOO) jax.experimental.sparse.BCOO#
class probabilistic_model.probabilistic_circuit.jax.SumUnit#

Bases: InnerUnit

Class for inner units

_latent_variable: typing_extensions.Optional[random_events.variable.Symbolic] = None#

The latent variable of this unit. This has to be here due to the rvalue/lvalue problem in random events.

TODO remove this when RE is fixed

__repr__()#
__hash__#
property representation: str#
property drawio_label: str#

The label of the object as a drawio compatible string.

property log_weighted_subcircuits: typing_extensions.List[typing_extensions.Tuple[float, Unit]]#
Returns:

The weighted subcircuits of this unit.

property variables: sortedcontainers.SortedSet#
property latent_variable: random_events.variable.Symbolic#
forward(*args, **kwargs)#
log_forward(*args, **kwargs)#
moment#
log_forward_conditioning(*args, **kwargs)#
support()#

Calculate the support of this unit.

property log_weights: numpy.array#
Returns:

The log_weights of the subcircuits.

sample(*args, **kwargs) numpy.array#

Draw samples from the circuit.

For sampling, a node gets requested a number of samples from all his parents. The parents write into the result_of_current_query attribute a tuple describing the beginning index of the sampling and how many samples are requested.

classmethod _from_json(data: typing_extensions.Dict[str, typing_extensions.Any]) typing_extensions.Self#

Create a variable from a json dict. This method is called from the from_json method after the correct subclass is determined and should be overwritten by the respective subclass.

Parameters:

data – The json dict

Returns:

The deserialized object

mount_with_interaction_terms(other: typing_extensions.Self, interaction_model: probabilistic_model.probabilistic_model.ProbabilisticModel)#

Create a distribution that factorizes as follows:

\[p(self.latent\_variable) \cdot p(self.variables | self.latent\_variable) \cdot p(other.latent\_variable | self.latent\_variable) \cdot p(other.variables | other.latent\_variable)\]

where self.latent_variable and other.latent_variable are the results of the latent variable interpretation of mixture models.

Parameters:
  • other – The other distribution to mount at this distribution children level.

  • interaction_model – The interaction probabilities between both latent variables

mount_from_bayesian_network(other: SumUnit)#

Mount a distribution from tge to_probabilistic_circuit method in bayesian networks. The distribution is mounted as follows:

Parameters:

other – The other distribution to mount at this distribution children level.

Returns:

simplify()#

Simplify the circuit by removing nodes and redirected edges that have no impact in-place. Essentially, this method transforms the circuit into an alternating order of sum and product units.

Returns:

The simplified circuit.

normalize()#

Normalize the log_weights of the subcircuits such that they sum up to 1 inplace.

is_deterministic() bool#
Returns:

If this unit is deterministic or not.

log_mode()#
subcircuit_index_of_samples(samples: numpy.array) numpy.array#
Returns:

the index of the subcircuit where p(sample) > 0 and None if p(sample) = 0 for all subcircuits.

class probabilistic_model.probabilistic_circuit.jax.ProductUnit#

Bases: InnerUnit

Decomposable Product Units for Probabilistic Circuits

representation = '×'#
__hash__#
property drawio_label: str#

The label of the object as a drawio compatible string.

__repr__()#
forward(*args, **kwargs)#
log_forward(*args, **kwargs)#
moment#
property variables: sortedcontainers.SortedSet#
support()#

Calculate the support of this unit.

is_decomposable()#
log_mode()#
__copy__()#
simplify()#

Simplify the circuit by removing nodes and redirected edges that have no impact in-place. Essentially, this method transforms the circuit into an alternating order of sum and product units.

Returns:

The simplified circuit.

sample(*args, **kwargs)#

Draw samples from the circuit.

For sampling, a node gets requested a number of samples from all his parents. The parents write into the result_of_current_query attribute a tuple describing the beginning index of the sampling and how many samples are requested.

class probabilistic_model.probabilistic_circuit.jax.Unit#

Bases: random_events.utils.SubclassJSONSerializer, probabilistic_model.interfaces.drawio.drawio.DrawIOInterface, abc.ABC

Class for all units of a probabilistic circuit.

This class should not be used by users directly. Use ProbabilisticCircuit as interface to users.

probabilistic_circuit: typing_extensions.Optional[ProbabilisticCircuit] = None#

The circuit this component is part of.

result_of_current_query: typing_extensions.Any = None#

The result of the current query.

index: typing_extensions.Optional[int] = None#

The index of the node in the graph of its circuit.

__post_init__()#
property subcircuits: typing_extensions.List[Unit]#
Returns:

The subcircuits of this unit.

property parents: typing_extensions.List[InnerUnit]#
Returns:

The parents of this unit.

abstract support()#

Calculate the support of this unit.

abstract property is_leaf#
Returns:

If this unit is a leaf unit.

property variables: sortedcontainers.SortedSet#
Abstractmethod:

property leaves: typing_extensions.List[LeafUnit]#
Returns:

The leaves of the circuit that are descendants of this node.

update_variables(new_variables: random_events.product_algebra.VariableMap)#

Update the variables of this unit and its descendants.

Parameters:

new_variables – A map that maps the variables that should be replaced to their new variable.

connect_incoming_edges_to(other: Unit)#

Connect all incoming edges to this unit to another unit.

Parameters:

other – The other unit to connect the incoming edges to.

filter_variable_map_by_self(variable_map: random_events.product_algebra.VariableMap)#

Filter a variable map by the variables of this unit.

Parameters:

variable_map – The map to filter

Returns:

The map filtered by the variables of this unit.

property impossible_condition_result: typing_extensions.Tuple[typing_extensions.Optional[Unit], float]#
Returns:

The result of an impossible truncated query.

abstract log_mode()#
__hash__()#
copy_without_graph()#
empty_copy() typing_extensions.Self#

Creat a copy of this circuit without any subcircuits. Only the parameters should be copied. This is used whenever a new circuit has to be created during inference.

Returns:

A copy of this circuit without any subcircuits that is not in this units graph.

abstract simplify()#

Simplify the circuit by removing nodes and redirected edges that have no impact in-place. Essentially, this method transforms the circuit into an alternating order of sum and product units.

Returns:

The simplified circuit.

abstract sample(*args, **kwargs)#

Draw samples from the circuit.

For sampling, a node gets requested a number of samples from all his parents. The parents write into the result_of_current_query attribute a tuple describing the beginning index of the sampling and how many samples are requested.

abstract marginal(*args, **kwargs) typing_extensions.Optional[typing_extensions.Self]#

Remove nodes that are not part of the marginal distribution.

abstract moment(*args, **kwargs)#
property drawio_style: typing_extensions.Dict[str, typing_extensions.Any]#

The style of the object.

class probabilistic_model.probabilistic_circuit.jax.NXProbabilisticCircuit#

Bases: probabilistic_model.probabilistic_model.ProbabilisticModel, random_events.utils.SubclassJSONSerializer

Probabilistic Circuits as a directed, rooted, acyclic graph.

The nodes of the graph are the units of the circuit. The edges of the graph indicate how the units are connected. The outgoing edges of a sum unit contain the log-log_weights of the subcircuits.

graph: rustworkx.PyDAG[Unit]#

The graph to check connectivity from.

__len__()#

Return the number of nodes in the graph.

Returns:

The number of nodes in the graph.

__iter__()#

Return an iterator over the nodes in the graph.

Returns:

An iterator over the nodes in the graph.

classmethod from_other(other: typing_extensions.Self) typing_extensions.Self#
property variables: sortedcontainers.SortedSet#
Returns:

The variables of the model.

property variable_to_index_map: typing_extensions.Dict[random_events.variable.Variable, int]#
property layers: typing_extensions.List[typing_extensions.List[Unit]]#
property leaves: typing_extensions.List[LeafUnit]#
is_valid() bool#

Check if this graph is:

  • acyclic

  • connected

Returns:

True if the graph is valid, False otherwise.

add_node(node: Unit)#
add_nodes_from(units: typing_extensions.Iterable[Unit])#
add_edge(parent: Unit, child: Unit, log_weight: typing_extensions.Optional[float] = None)#
add_edges_from(edges: typing_extensions.Iterable[typing_extensions.Union[typing_extensions.Tuple[Unit, Unit], typing_extensions.Tuple[Unit, Unit, float]]])#
successors(unit: Unit) typing_extensions.List[Unit]#
descendants(unit: Unit) random_events.set.Set[Unit]#
predecessors(unit: Unit) typing_extensions.List[InnerUnit]#
remove_node(unit: Unit)#
remove_nodes_from(units: typing_extensions.Iterable[Unit])#
remove_edge(parent: Unit, child: Unit)#
remove_edges_from(edges: typing_extensions.Iterable[typing_extensions.Tuple[Unit, Unit]])#
in_edges(unit: Unit) typing_extensions.List[typing_extensions.Tuple[Unit, Unit, typing_extensions.Optional[float]]]#
add_from_subgraph(subgraph: rustworkx.PyDAG[Unit]) typing_extensions.Dict[int, Unit]#

Add nodes and edges from a subgraph to this circuit.

Parameters:

subgraph – The subgraph to add nodes from.

Returns:

A dictionary mapping the node indices in the subgraph to the new units in this circuit.

nodes() typing_extensions.List[Unit]#

Return an iterator over the nodes.

Returns:

An iterator over the nodes.

edges() typing_extensions.List[typing_extensions.Tuple[Unit, Unit, typing_extensions.Optional[float]]]#
in_degree(unit: Unit)#
has_edge(parent: Unit, child: Unit) bool#
property root: Unit#

The root of the circuit is the node with in-degree 0. This is the output node, that will perform the final computation.

Returns:

The root of the circuit.

log_likelihood(events: numpy.array) numpy.array#

Calculate the log-likelihood of an event.

Check the documentation of likelihood for more information.

Parameters:

events – The full evidence event with shape (#events, #variables)

Returns:

The log-likelihood of the event with shape (#events).

cdf(events: numpy.array) numpy.array#

Calculate the cumulative distribution function of an event-array.

The event belongs to the class of full evidence queries.

..Note:: The cdf only exists if all variables are continuous or integers.

Parameters:

events – The array of full evidence events. The shape of the array has to be (n, len(self.variables)).

Returns:

The cumulative distribution function of the event as an array of shape (n,).

probability_of_simple_event(event: random_events.product_algebra.SimpleEvent) float#

Calculate the probability of a simple event.

The event belongs to the class of marginal queries.

Note

You can read more about queries of this class in Definition 11 in [CVVdB20] or watch the video tutorial. [US20]

Parameters:

event – The event.

Returns:

The probability of the event.

log_mode(check_determinism: bool = True) typing_extensions.Tuple[random_events.product_algebra.Event, float]#

Calculate the mode of the model.

Check the documentation of mode for more information.

Returns:

The mode and its log-likelihood.

remove_unreachable_nodes(root: Unit)#

Remove all nodes that are not reachable from the root.

log_truncated_of_simple_event_in_place(simple_event: random_events.product_algebra.SimpleEvent) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#

Construct the truncated circuit from a simple event.

Parameters:

simple_event – The simple event to condition on.

Returns:

The truncated circuit and the log-probability of the event

log_truncated_in_place(event: random_events.product_algebra.Event) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#

Efficiently compute the truncated for an Event, batching as much as possible.

log_truncated(event: random_events.product_algebra.Event) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#

Calculate the truncated distribution P(*| event) and the probability of the event.

Check the documentation of truncated for more information.

Parameters:

event – The event to condition on.

Returns:

The truncated distribution and the log-probability of the event.

marginal_in_place(variables: typing_extensions.Iterable[random_events.variable.Variable]) typing_extensions.Optional[typing_extensions.Self]#
log_conditional_in_place(point: typing_extensions.Dict[random_events.variable.Variable, typing_extensions.Any]) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#
log_conditional(point: typing_extensions.Dict[random_events.variable.Variable, typing_extensions.Any]) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#

Calculate the truncated distribution P(*| point) and the probability of the event. Check the documentation of conditional for more information.

Parameters:

point – A partial point to calculate the truncated distribution on.

Returns:

The truncated distribution and the log-probability of the point.

marginal(variables: typing_extensions.Iterable[random_events.variable.Variable]) typing_extensions.Optional[typing_extensions.Self]#

Calculate the marginal distribution of a set of variables.

Parameters:

variables – The variables to calculate the marginal distribution on.

Returns:

The marginal distribution over the variables.

sample(amount: int) numpy.array#

Sample from the model.

Parameters:

amount – The number of samples to draw.

Returns:

The samples.

moment(order: probabilistic_model.probabilistic_model.OrderType, center: probabilistic_model.probabilistic_model.CenterType) probabilistic_model.probabilistic_model.MomentType#

Calculate the (centralized) moment of the distribution.

\[\int_{-\infty}^{\infty} (x - center)^{order} pdf(x) dx\]

Note

You can read more about queries of this class in Definition 22 in :cite:p:`choi2020probabilistic`_. [US20]

Parameters:
  • order – The orders of the moment as a variable map for every continuous and integer variable.

  • center – The center of the moment as a variable map for every continuous and integer variable.

Returns:

The moments of the variables in order.

simplify() typing_extensions.Self#

Simplify the circuit inplace.

property support: random_events.product_algebra.Event#
Returns:

The support of the model.

is_decomposable() bool#

Check if the whole circuit is decomposed.

A circuit is decomposed if all its product units are decomposed.

Returns:

if the whole circuit is decomposed

abstract __eq__(other: typing_extensions.Self)#
empty_copy() typing_extensions.Self#

Create a copy of this circuit without any nodes. Only the parameters should be copied. This is used whenever a new circuit has to be created during inference.

Returns:

A copy of this circuit without any subcircuits that is not in this units graph.

__deepcopy__(memo=None) typing_extensions.Self#

Deep copy of the circuit.

Parameters:

memo – A dictionary that is used to keep track of objects that have already been copied.

Returns:

A deep copy of the circuit.

to_json() typing_extensions.Dict[str, typing_extensions.Any]#
classmethod parameters_from_json(data: typing_extensions.Dict[str, typing_extensions.Any]) typing_extensions.Self#
classmethod _from_json(data: typing_extensions.Dict[str, typing_extensions.Any]) typing_extensions.Self#

Create a variable from a json dict. This method is called from the from_json method after the correct subclass is determined and should be overwritten by the respective subclass.

Parameters:

data – The json dict

Returns:

The deserialized object

update_variables(new_variables: random_events.product_algebra.VariableMap)#

Update the variables of this unit and its descendants.

Parameters:

new_variables – The new variables to set.

is_deterministic() bool#
Returns:

Whether, this circuit is deterministic or not.

normalize()#

Normalize every sum node of this circuit in-place.

add_edges_and_nodes_from_circuit(other: typing_extensions.Self)#

Add all edges and nodes from another circuit to this circuit.

Parameters:

other – The other circuit to add.

add_weighted_edges_from(ebunch_to_add, weight='log_weight', **attr)#
subgraph_of(node: Unit) typing_extensions.Self#

Create a subgraph with a node as root.

Parameters:

node – The root of the subgraph.

Returns:

The subgraph.

fill_node_colors(node_colors: typing_extensions.Dict[Unit, str])#

Fill the node colors for the structure plot.

Parameters:

node_colors – The node colors to fill.

bfs_layout(scale: float = 1.0, align: PlotAlignment = PlotAlignment.VERTICAL) typing_extensions.Dict[int, numpy.array]#

Generate a bfs layout for this circuit.

Returns:

A dict mapping the node indices to 2d coordinates.

plot_structure(node_colors: typing_extensions.Optional[typing_extensions.Dict[Unit, str]] = None, variable_name_offset=0.2, plot_inference=False, inference_representation: typing_extensions.Callable = lambda node: ..., inference_result_offset: float = -0.25)#

Plot the structure of the circuit using matplotlib.

Parameters:

node_colors – Optionally specified colors of the node.

If nodes are not specified in the dictionary, they will be black. :param node_size: The size of the nodes :param variable_name_offset: The offset to the right of the variable names. :param plot_inference: If the results of the inference should be plotted. :param inference_representation: The representation of the inference results as a function from node to string. :param inference_result_offset: The vertical offset of the inference results.

nodes_weights() dict#
Returns:

dict with keys as nodes and values as list of all the log_weights for the node.

replace_discrete_distribution_with_deterministic_sum()#

splits the distribution into sum unit with all the discrete possibilities as leaf.

translate(translation: typing_extensions.Dict[random_events.variable.Variable, float])#

Translate the model in-place. Translation is done by adding the translation to the variable location influencing values. The translation can be viewed as what happens when you shift the numeric variables of the model by a constant vector.

Parameters:

translation – The variable value pairs to translate the model by.

scale(scale: typing_extensions.Dict[random_events.variable.Variable, float])#

Scale the model in-place. Scaling is done by multiplying the variable location influencing values. The scaling can be viewed as what happens when you multiply the numeric variables of the model by a constant vector.

Parameters:

scaling – The variable value pairs to scale the model by.

mount(other: Unit) typing_extensions.Dict[int, Unit]#

Mount another unit including its descendants. There will be no edge from self to other. This will also remove the nodes in other and their descendants from their circuit.

Parameters:

other – The other unit to mount.

__repr__()#
probabilistic_model.probabilistic_circuit.jax.inverse_class_of(clazz: typing_extensions.Type[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.Unit]) typing_extensions.Type[Layer]#
class probabilistic_model.probabilistic_circuit.jax.Layer#

Bases: equinox.Module, random_events.utils.SubclassJSONSerializer, abc.ABC

Abstract class for Layers of a layered circuit.

Layers have the same scope (set of variables) for every node in them.

_variables: typing_extensions.Optional[jax.numpy.array]#

The variable indices of the layer.

property variables: jax.Array#
Abstractmethod:

abstract set_variables(value: jax.Array)#
abstract log_likelihood_of_nodes_single(x: jax.numpy.array) jax.numpy.array#

Calculate the log-likelihood of the distribution.

Parameters:

x – The input vector.

Returns:

The log-likelihood of every node in the layer for x.

log_likelihood_of_nodes(x: jax.numpy.array) jax.numpy.array#

Vectorized version of log_likelihood_of_nodes_single()

abstract validate()#

Validate the parameters and their layouts.

property number_of_nodes: int#
Abstractmethod:

Returns:

The number of nodes in the layer.

all_layers() typing_extensions.List[Layer]#
Returns:

A list of all layers in the circuit.

all_layers_with_depth(depth: int = 0) typing_extensions.List[typing_extensions.Tuple[int, Layer]]#
Returns:

A list of tuples of all layers in the circuit with their depth.

abstract __deepcopy__(memo=None) Layer#

Create a deep copy of the layer.

Parameters:

memo – A dictionary that is used to keep track of objects that have already been copied.

classmethod nx_classes() typing_extensions.Tuple[typing_extensions.Type, Ellipsis]#
Returns:

The tuple of matching classes of the layer in the probabilistic_model.probabilistic_circuit.rx package.

abstract to_nx(variables: sortedcontainers.SortedSet[random_events.variable.Variable], result: probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.ProbabilisticCircuit, progress_bar: typing_extensions.Optional[tqdm.tqdm] = None) typing_extensions.List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.Unit]#

Convert the layer to a networkx circuit. For every node in this circuit, a corresponding node in the networkx circuit is created. The nodes all belong to the same circuit.

Parameters:
  • variables – The variables of the circuit.

  • result – The resulting circuit to write into

  • progress_bar – A progress bar to show the progress.

Returns:

The nodes of the networkx circuit.

static create_layers_from_nodes(nodes: typing_extensions.List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.Unit], child_layers: typing_extensions.List[NXConverterLayer], progress_bar: bool = True) typing_extensions.List[NXConverterLayer]#

Create a layer from a list of nodes.

classmethod create_layer_from_nodes_with_same_type_and_scope(nodes: typing_extensions.List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.Unit], child_layers: typing_extensions.List[NXConverterLayer], progress_bar: bool = True) NXConverterLayer#
Abstractmethod:

Create a layer from a list of nodes with the same type and scope.

partition() typing_extensions.Tuple[typing_extensions.Any, typing_extensions.Any]#

Partition the layer into the parameters and the static structure.

Returns:

A tuple containing the parameters and the static structure as pytrees.

property number_of_trainable_parameters#
Returns:

The trainable parameters of the layer and all child layers.

property number_of_components: int#
Returns:

The number of components (leaves + edges) of the entire circuit

class probabilistic_model.probabilistic_circuit.jax.InnerLayer(child_layers: typing_extensions.List[Layer])#

Bases: Layer, abc.ABC

Abstract Base Class for inner layers

child_layers: typing_extensions.List[Layer]#

The child layers of this layer.

set_variables(value: jax.numpy.array)#
reset_variables()#
all_layers() typing_extensions.List[Layer]#
Returns:

A list of all layers in the circuit.

all_layers_with_depth(depth: int = 0) typing_extensions.List[typing_extensions.Tuple[int, Layer]]#
Returns:

A list of tuples of all layers in the circuit with their depth.

to_json() typing_extensions.Dict[str, typing_extensions.Any]#
class probabilistic_model.probabilistic_circuit.jax.InputLayer(variable: int)#

Bases: Layer, abc.ABC

Abstract base class for univariate input units.

Input layers contain only one type of distribution such that the vectorization of the log likelihood calculation works without bottleneck statements like if/else or loops.

_variables#

The variable indices of the layer.

property variables: jax.Array#
set_variables(value: jax.Array)#
to_json() typing_extensions.Dict[str, typing_extensions.Any]#
property variable#
class probabilistic_model.probabilistic_circuit.jax.SumLayer(child_layers: typing_extensions.List[Layer], log_weights: typing_extensions.List[typing_extensions.Union[jax.array, jax.experimental.sparse.BCOO]])#

Bases: InnerLayer, abc.ABC

Abstract Base Class for inner layers

log_weights: typing_extensions.List[typing_extensions.Union[jax.array, jax.experimental.sparse.BCOO]]#
child_layers: typing_extensions.Union[typing_extensions.List[[ProductLayer]], typing_extensions.List[InputLayer]]#

The child layers of this layer.

validate()#

Validate the parameters and their layouts.

property log_weighted_child_layers: typing_extensions.Iterator[typing_extensions.Tuple[jax.experimental.sparse.BCOO, Layer]]#
Returns:

Yields log log_weights and the child layers zipped together.

property variables: jax.Array#
property number_of_nodes: int#
Returns:

The number of nodes in the layer.

class probabilistic_model.probabilistic_circuit.jax.SparseSumLayer(child_layers: typing_extensions.List[Layer], log_weights: typing_extensions.List[typing_extensions.Union[jax.array, jax.experimental.sparse.BCOO]])#

Bases: SumLayer

Abstract Base Class for inner layers

log_weights: typing_extensions.List[jax.experimental.sparse.BCOO]#
classmethod nx_classes() typing_extensions.Tuple[typing_extensions.Type, Ellipsis]#
Returns:

The tuple of matching classes of the layer in the probabilistic_model.probabilistic_circuit.rx package.

property number_of_components: int#
Returns:

The number of components (leaves + edges) of the entire circuit

property concatenated_log_weights: jax.experimental.sparse.BCOO#
Returns:

The concatenated log_weights of the child layers for each node.

property log_normalization_constants: jax.Array#
property normalized_weights#
Returns:

The normalized log_weights of the child layers for each node.

log_likelihood_of_nodes_single(x: jax.Array) jax.Array#

Calculate the log-likelihood of the distribution.

Parameters:

x – The input vector.

Returns:

The log-likelihood of every node in the layer for x.

__deepcopy__(memo=None)#

Create a deep copy of the layer.

Parameters:

memo – A dictionary that is used to keep track of objects that have already been copied.

to_json() typing_extensions.Dict[str, typing_extensions.Any]#
classmethod _from_json(data: typing_extensions.Dict[str, typing_extensions.Any]) typing_extensions.Self#

Create a variable from a json dict. This method is called from the from_json method after the correct subclass is determined and should be overwritten by the respective subclass.

Parameters:

data – The json dict

Returns:

The deserialized object

classmethod create_layer_from_nodes_with_same_type_and_scope(nodes: typing_extensions.List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.SumUnit], child_layers: typing_extensions.List[NXConverterLayer], progress_bar: bool = True) NXConverterLayer#

Create a layer from a list of nodes with the same type and scope.

to_nx(variables: sortedcontainers.SortedSet[random_events.variable.Variable], result: probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.ProbabilisticCircuit, progress_bar: typing_extensions.Optional[tqdm.tqdm] = None) typing_extensions.List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.Unit]#

Convert the layer to a networkx circuit. For every node in this circuit, a corresponding node in the networkx circuit is created. The nodes all belong to the same circuit.

Parameters:
  • variables – The variables of the circuit.

  • result – The resulting circuit to write into

  • progress_bar – A progress bar to show the progress.

Returns:

The nodes of the networkx circuit.

class probabilistic_model.probabilistic_circuit.jax.DenseSumLayer(child_layers: typing_extensions.List[Layer], log_weights: typing_extensions.List[typing_extensions.Union[jax.array, jax.experimental.sparse.BCOO]])#

Bases: SumLayer

Abstract Base Class for inner layers

log_weights: typing_extensions.List[jax.numpy.array]#
child_layers: typing_extensions.Union[typing_extensions.List[[ProductLayer]], typing_extensions.List[InputLayer]]#

The child layers of this layer.

classmethod create_layer_from_nodes_with_same_type_and_scope(nodes: typing_extensions.List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.Unit], child_layers: typing_extensions.List[NXConverterLayer], progress_bar: bool = True) NXConverterLayer#
Abstractmethod:

Create a layer from a list of nodes with the same type and scope.

property number_of_components: int#
Returns:

The number of components (leaves + edges) of the entire circuit

classmethod nx_classes() typing_extensions.Tuple[typing_extensions.Type, Ellipsis]#
Returns:

The tuple of matching classes of the layer in the probabilistic_model.probabilistic_circuit.rx package.

property concatenated_log_weights: jax.numpy.array#
Returns:

The concatenated log_weights of the child layers for each node.

property log_normalization_constants: jax.Array#
property normalized_weights#
Returns:

The normalized log_weights of the child layers for each node.

log_likelihood_of_nodes_single(x: jax.Array) jax.Array#

Calculate the log-likelihood of the distribution.

Parameters:

x – The input vector.

Returns:

The log-likelihood of every node in the layer for x.

__deepcopy__(memo=None)#

Create a deep copy of the layer.

Parameters:

memo – A dictionary that is used to keep track of objects that have already been copied.

to_json() typing_extensions.Dict[str, typing_extensions.Any]#
classmethod _from_json(data: typing_extensions.Dict[str, typing_extensions.Any]) typing_extensions.Self#

Create a variable from a json dict. This method is called from the from_json method after the correct subclass is determined and should be overwritten by the respective subclass.

Parameters:

data – The json dict

Returns:

The deserialized object

to_nx(variables: sortedcontainers.SortedSet[random_events.variable.Variable], result: probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.ProbabilisticCircuit, progress_bar: typing_extensions.Optional[tqdm.tqdm] = None) typing_extensions.List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.Unit]#

Convert the layer to a networkx circuit. For every node in this circuit, a corresponding node in the networkx circuit is created. The nodes all belong to the same circuit.

Parameters:
  • variables – The variables of the circuit.

  • result – The resulting circuit to write into

  • progress_bar – A progress bar to show the progress.

Returns:

The nodes of the networkx circuit.

class probabilistic_model.probabilistic_circuit.jax.ProductLayer(child_layers: typing_extensions.List[Layer], edges: jax.experimental.sparse.BCOO)#

Bases: InnerLayer

A layer that represents the product of multiple other units.

child_layers: typing_extensions.List[typing_extensions.Union[SparseSumLayer, InputLayer]]#

The child of a product layer is a list that contains groups sum units with the same scope or groups of input units with the same scope.

edges: jaxtyping.Int[jax.experimental.sparse.BCOO, len(child_layers), number_of_nodes]#

The edges consist of a sparse matrix containing integers. The first dimension describes the edges for each child layer. The second dimension describes the edges for each node in the child layer. The integers are interpreted in such a way that n-th value represents a edge (n, edges[n]).

Nodes in the child layer can be mapped to by multiple nodes in this layer.

The shape is (#child_layers, #nodes).

validate()#

Validate the parameters and their layouts.

property number_of_nodes: int#
Returns:

The number of nodes in the layer.

classmethod nx_classes() typing_extensions.Tuple[typing_extensions.Type, Ellipsis]#
Returns:

The tuple of matching classes of the layer in the probabilistic_model.probabilistic_circuit.rx package.

property number_of_components: int#
Returns:

The number of components (leaves + edges) of the entire circuit

variables() jax.Array#
log_likelihood_of_nodes_single(x: jax.Array) jax.Array#

Calculate the log-likelihood of the distribution.

Parameters:

x – The input vector.

Returns:

The log-likelihood of every node in the layer for x.

__deepcopy__(memo=None)#

Create a deep copy of the layer.

Parameters:

memo – A dictionary that is used to keep track of objects that have already been copied.

to_json() typing_extensions.Dict[str, typing_extensions.Any]#
classmethod _from_json(data: typing_extensions.Dict[str, typing_extensions.Any]) typing_extensions.Self#

Create a variable from a json dict. This method is called from the from_json method after the correct subclass is determined and should be overwritten by the respective subclass.

Parameters:

data – The json dict

Returns:

The deserialized object

classmethod create_layer_from_nodes_with_same_type_and_scope(nodes: typing_extensions.List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.Unit], child_layers: typing_extensions.List[NXConverterLayer], progress_bar: bool = True) NXConverterLayer#

Create a layer from a list of nodes with the same type and scope.

to_nx(variables: sortedcontainers.SortedSet[random_events.variable.Variable], result: probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.ProbabilisticCircuit, progress_bar: typing_extensions.Optional[tqdm.tqdm] = None) typing_extensions.List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.Unit]#

Convert the layer to a networkx circuit. For every node in this circuit, a corresponding node in the networkx circuit is created. The nodes all belong to the same circuit.

Parameters:
  • variables – The variables of the circuit.

  • result – The resulting circuit to write into

  • progress_bar – A progress bar to show the progress.

Returns:

The nodes of the networkx circuit.

class probabilistic_model.probabilistic_circuit.jax.NXConverterLayer#

Class used for conversion from a probabilistic circuit in networkx to a layered circuit in jax.

layer: Layer#
nodes: typing_extensions.List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.Unit]#
hash_remap: typing_extensions.Dict[int, int]#
class probabilistic_model.probabilistic_circuit.jax.InputLayer(variable: int)#

Bases: Layer, abc.ABC

Abstract base class for univariate input units.

Input layers contain only one type of distribution such that the vectorization of the log likelihood calculation works without bottleneck statements like if/else or loops.

_variables#

The variable indices of the layer.

property variables: jax.Array#
set_variables(value: jax.Array)#
to_json() typing_extensions.Dict[str, typing_extensions.Any]#
property variable#
class probabilistic_model.probabilistic_circuit.jax.NXConverterLayer#

Class used for conversion from a probabilistic circuit in networkx to a layered circuit in jax.

layer: Layer#
nodes: typing_extensions.List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.Unit]#
hash_remap: typing_extensions.Dict[int, int]#
class probabilistic_model.probabilistic_circuit.jax.Unit#

Bases: random_events.utils.SubclassJSONSerializer, probabilistic_model.interfaces.drawio.drawio.DrawIOInterface, abc.ABC

Class for all units of a probabilistic circuit.

This class should not be used by users directly. Use ProbabilisticCircuit as interface to users.

probabilistic_circuit: typing_extensions.Optional[ProbabilisticCircuit] = None#

The circuit this component is part of.

result_of_current_query: typing_extensions.Any = None#

The result of the current query.

index: typing_extensions.Optional[int] = None#

The index of the node in the graph of its circuit.

__post_init__()#
property subcircuits: typing_extensions.List[Unit]#
Returns:

The subcircuits of this unit.

property parents: typing_extensions.List[InnerUnit]#
Returns:

The parents of this unit.

abstract support()#

Calculate the support of this unit.

abstract property is_leaf#
Returns:

If this unit is a leaf unit.

property variables: sortedcontainers.SortedSet#
Abstractmethod:

property leaves: typing_extensions.List[LeafUnit]#
Returns:

The leaves of the circuit that are descendants of this node.

update_variables(new_variables: random_events.product_algebra.VariableMap)#

Update the variables of this unit and its descendants.

Parameters:

new_variables – A map that maps the variables that should be replaced to their new variable.

connect_incoming_edges_to(other: Unit)#

Connect all incoming edges to this unit to another unit.

Parameters:

other – The other unit to connect the incoming edges to.

filter_variable_map_by_self(variable_map: random_events.product_algebra.VariableMap)#

Filter a variable map by the variables of this unit.

Parameters:

variable_map – The map to filter

Returns:

The map filtered by the variables of this unit.

property impossible_condition_result: typing_extensions.Tuple[typing_extensions.Optional[Unit], float]#
Returns:

The result of an impossible truncated query.

abstract log_mode()#
__hash__()#
copy_without_graph()#
empty_copy() typing_extensions.Self#

Creat a copy of this circuit without any subcircuits. Only the parameters should be copied. This is used whenever a new circuit has to be created during inference.

Returns:

A copy of this circuit without any subcircuits that is not in this units graph.

abstract simplify()#

Simplify the circuit by removing nodes and redirected edges that have no impact in-place. Essentially, this method transforms the circuit into an alternating order of sum and product units.

Returns:

The simplified circuit.

abstract sample(*args, **kwargs)#

Draw samples from the circuit.

For sampling, a node gets requested a number of samples from all his parents. The parents write into the result_of_current_query attribute a tuple describing the beginning index of the sampling and how many samples are requested.

abstract marginal(*args, **kwargs) typing_extensions.Optional[typing_extensions.Self]#

Remove nodes that are not part of the marginal distribution.

abstract moment(*args, **kwargs)#
property drawio_style: typing_extensions.Dict[str, typing_extensions.Any]#

The style of the object.

class probabilistic_model.probabilistic_circuit.jax.NXProbabilisticCircuit#

Bases: probabilistic_model.probabilistic_model.ProbabilisticModel, random_events.utils.SubclassJSONSerializer

Probabilistic Circuits as a directed, rooted, acyclic graph.

The nodes of the graph are the units of the circuit. The edges of the graph indicate how the units are connected. The outgoing edges of a sum unit contain the log-log_weights of the subcircuits.

graph: rustworkx.PyDAG[Unit]#

The graph to check connectivity from.

__len__()#

Return the number of nodes in the graph.

Returns:

The number of nodes in the graph.

__iter__()#

Return an iterator over the nodes in the graph.

Returns:

An iterator over the nodes in the graph.

classmethod from_other(other: typing_extensions.Self) typing_extensions.Self#
property variables: sortedcontainers.SortedSet#
Returns:

The variables of the model.

property variable_to_index_map: typing_extensions.Dict[random_events.variable.Variable, int]#
property layers: typing_extensions.List[typing_extensions.List[Unit]]#
property leaves: typing_extensions.List[LeafUnit]#
is_valid() bool#

Check if this graph is:

  • acyclic

  • connected

Returns:

True if the graph is valid, False otherwise.

add_node(node: Unit)#
add_nodes_from(units: typing_extensions.Iterable[Unit])#
add_edge(parent: Unit, child: Unit, log_weight: typing_extensions.Optional[float] = None)#
add_edges_from(edges: typing_extensions.Iterable[typing_extensions.Union[typing_extensions.Tuple[Unit, Unit], typing_extensions.Tuple[Unit, Unit, float]]])#
successors(unit: Unit) typing_extensions.List[Unit]#
descendants(unit: Unit) random_events.set.Set[Unit]#
predecessors(unit: Unit) typing_extensions.List[InnerUnit]#
remove_node(unit: Unit)#
remove_nodes_from(units: typing_extensions.Iterable[Unit])#
remove_edge(parent: Unit, child: Unit)#
remove_edges_from(edges: typing_extensions.Iterable[typing_extensions.Tuple[Unit, Unit]])#
in_edges(unit: Unit) typing_extensions.List[typing_extensions.Tuple[Unit, Unit, typing_extensions.Optional[float]]]#
add_from_subgraph(subgraph: rustworkx.PyDAG[Unit]) typing_extensions.Dict[int, Unit]#

Add nodes and edges from a subgraph to this circuit.

Parameters:

subgraph – The subgraph to add nodes from.

Returns:

A dictionary mapping the node indices in the subgraph to the new units in this circuit.

nodes() typing_extensions.List[Unit]#

Return an iterator over the nodes.

Returns:

An iterator over the nodes.

edges() typing_extensions.List[typing_extensions.Tuple[Unit, Unit, typing_extensions.Optional[float]]]#
in_degree(unit: Unit)#
has_edge(parent: Unit, child: Unit) bool#
property root: Unit#

The root of the circuit is the node with in-degree 0. This is the output node, that will perform the final computation.

Returns:

The root of the circuit.

log_likelihood(events: numpy.array) numpy.array#

Calculate the log-likelihood of an event.

Check the documentation of likelihood for more information.

Parameters:

events – The full evidence event with shape (#events, #variables)

Returns:

The log-likelihood of the event with shape (#events).

cdf(events: numpy.array) numpy.array#

Calculate the cumulative distribution function of an event-array.

The event belongs to the class of full evidence queries.

..Note:: The cdf only exists if all variables are continuous or integers.

Parameters:

events – The array of full evidence events. The shape of the array has to be (n, len(self.variables)).

Returns:

The cumulative distribution function of the event as an array of shape (n,).

probability_of_simple_event(event: random_events.product_algebra.SimpleEvent) float#

Calculate the probability of a simple event.

The event belongs to the class of marginal queries.

Note

You can read more about queries of this class in Definition 11 in [CVVdB20] or watch the video tutorial. [US20]

Parameters:

event – The event.

Returns:

The probability of the event.

log_mode(check_determinism: bool = True) typing_extensions.Tuple[random_events.product_algebra.Event, float]#

Calculate the mode of the model.

Check the documentation of mode for more information.

Returns:

The mode and its log-likelihood.

remove_unreachable_nodes(root: Unit)#

Remove all nodes that are not reachable from the root.

log_truncated_of_simple_event_in_place(simple_event: random_events.product_algebra.SimpleEvent) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#

Construct the truncated circuit from a simple event.

Parameters:

simple_event – The simple event to condition on.

Returns:

The truncated circuit and the log-probability of the event

log_truncated_in_place(event: random_events.product_algebra.Event) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#

Efficiently compute the truncated for an Event, batching as much as possible.

log_truncated(event: random_events.product_algebra.Event) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#

Calculate the truncated distribution P(*| event) and the probability of the event.

Check the documentation of truncated for more information.

Parameters:

event – The event to condition on.

Returns:

The truncated distribution and the log-probability of the event.

marginal_in_place(variables: typing_extensions.Iterable[random_events.variable.Variable]) typing_extensions.Optional[typing_extensions.Self]#
log_conditional_in_place(point: typing_extensions.Dict[random_events.variable.Variable, typing_extensions.Any]) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#
log_conditional(point: typing_extensions.Dict[random_events.variable.Variable, typing_extensions.Any]) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#

Calculate the truncated distribution P(*| point) and the probability of the event. Check the documentation of conditional for more information.

Parameters:

point – A partial point to calculate the truncated distribution on.

Returns:

The truncated distribution and the log-probability of the point.

marginal(variables: typing_extensions.Iterable[random_events.variable.Variable]) typing_extensions.Optional[typing_extensions.Self]#

Calculate the marginal distribution of a set of variables.

Parameters:

variables – The variables to calculate the marginal distribution on.

Returns:

The marginal distribution over the variables.

sample(amount: int) numpy.array#

Sample from the model.

Parameters:

amount – The number of samples to draw.

Returns:

The samples.

moment(order: probabilistic_model.probabilistic_model.OrderType, center: probabilistic_model.probabilistic_model.CenterType) probabilistic_model.probabilistic_model.MomentType#

Calculate the (centralized) moment of the distribution.

\[\int_{-\infty}^{\infty} (x - center)^{order} pdf(x) dx\]

Note

You can read more about queries of this class in Definition 22 in :cite:p:`choi2020probabilistic`_. [US20]

Parameters:
  • order – The orders of the moment as a variable map for every continuous and integer variable.

  • center – The center of the moment as a variable map for every continuous and integer variable.

Returns:

The moments of the variables in order.

simplify() typing_extensions.Self#

Simplify the circuit inplace.

property support: random_events.product_algebra.Event#
Returns:

The support of the model.

is_decomposable() bool#

Check if the whole circuit is decomposed.

A circuit is decomposed if all its product units are decomposed.

Returns:

if the whole circuit is decomposed

abstract __eq__(other: typing_extensions.Self)#
empty_copy() typing_extensions.Self#

Create a copy of this circuit without any nodes. Only the parameters should be copied. This is used whenever a new circuit has to be created during inference.

Returns:

A copy of this circuit without any subcircuits that is not in this units graph.

__deepcopy__(memo=None) typing_extensions.Self#

Deep copy of the circuit.

Parameters:

memo – A dictionary that is used to keep track of objects that have already been copied.

Returns:

A deep copy of the circuit.

to_json() typing_extensions.Dict[str, typing_extensions.Any]#
classmethod parameters_from_json(data: typing_extensions.Dict[str, typing_extensions.Any]) typing_extensions.Self#
classmethod _from_json(data: typing_extensions.Dict[str, typing_extensions.Any]) typing_extensions.Self#

Create a variable from a json dict. This method is called from the from_json method after the correct subclass is determined and should be overwritten by the respective subclass.

Parameters:

data – The json dict

Returns:

The deserialized object

update_variables(new_variables: random_events.product_algebra.VariableMap)#

Update the variables of this unit and its descendants.

Parameters:

new_variables – The new variables to set.

is_deterministic() bool#
Returns:

Whether, this circuit is deterministic or not.

normalize()#

Normalize every sum node of this circuit in-place.

add_edges_and_nodes_from_circuit(other: typing_extensions.Self)#

Add all edges and nodes from another circuit to this circuit.

Parameters:

other – The other circuit to add.

add_weighted_edges_from(ebunch_to_add, weight='log_weight', **attr)#
subgraph_of(node: Unit) typing_extensions.Self#

Create a subgraph with a node as root.

Parameters:

node – The root of the subgraph.

Returns:

The subgraph.

fill_node_colors(node_colors: typing_extensions.Dict[Unit, str])#

Fill the node colors for the structure plot.

Parameters:

node_colors – The node colors to fill.

bfs_layout(scale: float = 1.0, align: PlotAlignment = PlotAlignment.VERTICAL) typing_extensions.Dict[int, numpy.array]#

Generate a bfs layout for this circuit.

Returns:

A dict mapping the node indices to 2d coordinates.

plot_structure(node_colors: typing_extensions.Optional[typing_extensions.Dict[Unit, str]] = None, variable_name_offset=0.2, plot_inference=False, inference_representation: typing_extensions.Callable = lambda node: ..., inference_result_offset: float = -0.25)#

Plot the structure of the circuit using matplotlib.

Parameters:

node_colors – Optionally specified colors of the node.

If nodes are not specified in the dictionary, they will be black. :param node_size: The size of the nodes :param variable_name_offset: The offset to the right of the variable names. :param plot_inference: If the results of the inference should be plotted. :param inference_representation: The representation of the inference results as a function from node to string. :param inference_result_offset: The vertical offset of the inference results.

nodes_weights() dict#
Returns:

dict with keys as nodes and values as list of all the log_weights for the node.

replace_discrete_distribution_with_deterministic_sum()#

splits the distribution into sum unit with all the discrete possibilities as leaf.

translate(translation: typing_extensions.Dict[random_events.variable.Variable, float])#

Translate the model in-place. Translation is done by adding the translation to the variable location influencing values. The translation can be viewed as what happens when you shift the numeric variables of the model by a constant vector.

Parameters:

translation – The variable value pairs to translate the model by.

scale(scale: typing_extensions.Dict[random_events.variable.Variable, float])#

Scale the model in-place. Scaling is done by multiplying the variable location influencing values. The scaling can be viewed as what happens when you multiply the numeric variables of the model by a constant vector.

Parameters:

scaling – The variable value pairs to scale the model by.

mount(other: Unit) typing_extensions.Dict[int, Unit]#

Mount another unit including its descendants. There will be no edge from self to other. This will also remove the nodes in other and their descendants from their circuit.

Parameters:

other – The other unit to mount.

__repr__()#
class probabilistic_model.probabilistic_circuit.jax.UnivariateContinuousLeaf#

Bases: UnivariateLeaf

Class for Leaf units.

distribution: typing_extensions.Optional[probabilistic_model.distributions.ContinuousDistribution]#

The distribution contained in this leaf unit.

__hash__#
log_truncated_of_simple_event_in_place(event: random_events.product_algebra.SimpleEvent)#
univariate_log_truncated_of_simple_event_in_place(event: random_events.interval.Interval)#

Condition this distribution on a simple event in-place but use sum units to create conditions on composite intervals. :param event: The simple event to condition on.

class probabilistic_model.probabilistic_circuit.jax.DiracDeltaDistribution(variable: random_events.variable.Continuous, location: float, density_cap: float = np.inf, tolerance: float = 1e-06)#

Bases: ContinuousDistribution

Class for Dirac delta distributions. The Dirac measure is used whenever evidence is given as a singleton instance.

https://en.wikipedia.org/wiki/Dirac_delta_function

variable: random_events.variable.Continuous#
location: float#

The location of the Dirac delta distribution.

density_cap: float#

The density cap of the Dirac delta distribution. This value will be used to replace infinity in likelihood.

tolerance: float = 1e-06#

The tolerance of deviations of the location of the Dirac delta distribution. This is used during calculations to take precision problems into account.

log_likelihood(events: numpy.array) numpy.array#

Calculate the log-likelihood of an event.

Check the documentation of likelihood for more information.

Parameters:

events – The full evidence event with shape (#events, #variables)

Returns:

The log-likelihood of the event with shape (#events).

cdf(x: numpy.array) numpy.array#

Calculate the cumulative distribution function at x. :param x: The data :return: The cumulative distribution function at x

property abbreviated_symbol: str#
property univariate_support: random_events.variable.Interval#
Returns:

The univariate support of the distribution. This is not an Event.

log_conditional_from_simple_interval(interval: random_events.variable.SimpleInterval) typing_extensions.Tuple[typing_extensions.Self, float]#

Calculate the truncated distribution given a simple interval.

Parameters:

interval – The simple interval

Returns:

The truncated distribution and the log-probability of the interval.

probability_of_simple_event(event: random_events.product_algebra.SimpleEvent) float#

Calculate the probability of a simple event.

The event belongs to the class of marginal queries.

Note

You can read more about queries of this class in Definition 11 in [CVVdB20] or watch the video tutorial. [US20]

Parameters:

event – The event.

Returns:

The probability of the event.

univariate_log_mode() typing_extensions.Tuple[random_events.variable.AbstractCompositeSet, float]#
Returns:

The univariate mode of the distribution and its log-likelihood. The mode is not an Event.

sample(amount: int) numpy.array#

Sample from the model.

Parameters:

amount – The number of samples to draw.

Returns:

The samples.

moment(order: probabilistic_model.probabilistic_model.OrderType, center: probabilistic_model.probabilistic_model.CenterType) probabilistic_model.probabilistic_model.MomentType#

Calculate the (centralized) moment of the distribution.

\[\int_{-\infty}^{\infty} (x - center)^{order} pdf(x) dx\]

Note

You can read more about queries of this class in Definition 22 in :cite:p:`choi2020probabilistic`_. [US20]

Parameters:
  • order – The orders of the moment as a variable map for every continuous and integer variable.

  • center – The center of the moment as a variable map for every continuous and integer variable.

Returns:

The moments of the variables in order.

__eq__(other)#
__hash__()#
property representation#

The symbol used to represent this distribution.

__repr__()#
__copy__()#
__deepcopy__(memo=None)#
to_json() typing_extensions.Dict[str, typing_extensions.Any]#
classmethod _from_json(data: typing_extensions.Dict[str, typing_extensions.Any]) typing_extensions.Self#

Create a variable from a json dict. This method is called from the from_json method after the correct subclass is determined and should be overwritten by the respective subclass.

Parameters:

data – The json dict

Returns:

The deserialized object

plot(**kwargs) typing_extensions.List#

Generate traces that can be plotted with plotly.

Parameters:
  • number_of_samples – The number of samples to draw.

  • surface – If True, plot the model as a surface plot.

  • mode – If True, plot the mode of the model.

Returns:

The traces.

translate(translation: random_events.product_algebra.VariableMap[random_events.variable.Variable, float])#

Translate the model in-place. Translation is done by adding the translation to the variable location influencing values. The translation can be viewed as what happens when you shift the numeric variables of the model by a constant vector.

Parameters:

translation – The variable value pairs to translate the model by.

scale(scaling: random_events.product_algebra.VariableMap[random_events.variable.Variable, float])#

Scale the model in-place. Scaling is done by multiplying the variable location influencing values. The scaling can be viewed as what happens when you multiply the numeric variables of the model by a constant vector.

Parameters:

scaling – The variable value pairs to scale the model by.

class probabilistic_model.probabilistic_circuit.jax.ContinuousLayer(variable: int)#

Bases: probabilistic_model.probabilistic_circuit.jax.inner_layer.InputLayer, abc.ABC

Abstract base class for continuous univariate input units.

class probabilistic_model.probabilistic_circuit.jax.ContinuousLayerWithFiniteSupport(variable: int, interval: jax.Array)#

Bases: ContinuousLayer, abc.ABC

Abstract class for continuous univariate input units with finite support.

interval: jax.Array#

The interval of the distribution as a array of shape (num_nodes, 2). The first column contains the lower bounds and the second column the upper bounds. The intervals are treated as open intervals (>/< comparator).

property lower: jax.Array#
property upper: jax.Array#
left_included_condition(x: jax.Array) jax.Array#

Check if x is included in the left bound of the intervals. :param x: The data :return: A boolean array of shape (#x, #nodes)

right_included_condition(x: jax.Array) jax.Array#

Check if x is included in the right bound of the intervals. :param x: The data :return: A boolean array of shape (#x, #nodes)

included_condition(x: jax.Array) jax.Array#

Check if x is included in the interval. :param x: The data :return: A boolean array of shape (#x, #nodes)

to_json() Dict[str, Any]#
__deepcopy__(memo=None)#

Create a deep copy of the layer.

Parameters:

memo – A dictionary that is used to keep track of objects that have already been copied.

class probabilistic_model.probabilistic_circuit.jax.DiracDeltaLayer(variable_index, location, density_cap)#

Bases: ContinuousLayer

A layer that represents Dirac delta distributions over a single variable.

location: jax.Array#

The locations of the Dirac delta distributions.

density_cap: jax.Array#

The density caps of the Dirac delta distributions. This value will be used to replace infinity in likelihoods.

validate()#

Validate the parameters and their layouts.

property number_of_nodes#
Returns:

The number of nodes in the layer.

log_likelihood_of_nodes(x: jax.Array) jax.Array#

Vectorized version of log_likelihood_of_nodes_single()

log_likelihood_of_nodes_single(x: jax.Array) jax.Array#

Calculate the log-likelihood of the distribution.

Parameters:

x – The input vector.

Returns:

The log-likelihood of every node in the layer for x.

classmethod nx_classes() typing_extensions.Tuple[typing_extensions.Type, Ellipsis]#
Returns:

The tuple of matching classes of the layer in the probabilistic_model.probabilistic_circuit.rx package.

classmethod create_layer_from_nodes_with_same_type_and_scope(nodes: List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.UnivariateContinuousLeaf], child_layers: List[probabilistic_model.probabilistic_circuit.jax.inner_layer.NXConverterLayer], progress_bar: bool = True) probabilistic_model.probabilistic_circuit.jax.inner_layer.NXConverterLayer#

Create a layer from a list of nodes with the same type and scope.

to_json() Dict[str, Any]#
classmethod _from_json(data: Dict[str, Any]) typing_extensions.Self#

Create a variable from a json dict. This method is called from the from_json method after the correct subclass is determined and should be overwritten by the respective subclass.

Parameters:

data – The json dict

Returns:

The deserialized object

to_nx(variables: sortedcontainers.SortedSet[random_events.variable.Variable], result: probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.ProbabilisticCircuit, progress_bar: typing_extensions.Optional[tqdm.tqdm] = None) List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.Unit]#

Convert the layer to a networkx circuit. For every node in this circuit, a corresponding node in the networkx circuit is created. The nodes all belong to the same circuit.

Parameters:
  • variables – The variables of the circuit.

  • result – The resulting circuit to write into

  • progress_bar – A progress bar to show the progress.

Returns:

The nodes of the networkx circuit.

class probabilistic_model.probabilistic_circuit.jax.NXConverterLayer#

Class used for conversion from a probabilistic circuit in networkx to a layered circuit in jax.

layer: Layer#
nodes: typing_extensions.List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.Unit]#
hash_remap: typing_extensions.Dict[int, int]#
class probabilistic_model.probabilistic_circuit.jax.ContinuousLayerWithFiniteSupport(variable: int, interval: jax.Array)#

Bases: ContinuousLayer, abc.ABC

Abstract class for continuous univariate input units with finite support.

interval: jax.Array#

The interval of the distribution as a array of shape (num_nodes, 2). The first column contains the lower bounds and the second column the upper bounds. The intervals are treated as open intervals (>/< comparator).

property lower: jax.Array#
property upper: jax.Array#
left_included_condition(x: jax.Array) jax.Array#

Check if x is included in the left bound of the intervals. :param x: The data :return: A boolean array of shape (#x, #nodes)

right_included_condition(x: jax.Array) jax.Array#

Check if x is included in the right bound of the intervals. :param x: The data :return: A boolean array of shape (#x, #nodes)

included_condition(x: jax.Array) jax.Array#

Check if x is included in the interval. :param x: The data :return: A boolean array of shape (#x, #nodes)

to_json() Dict[str, Any]#
__deepcopy__(memo=None)#

Create a deep copy of the layer.

Parameters:

memo – A dictionary that is used to keep track of objects that have already been copied.

probabilistic_model.probabilistic_circuit.jax.simple_interval_to_open_array(interval: random_events.interval.SimpleInterval) jax.numpy.array#
class probabilistic_model.probabilistic_circuit.jax.Unit#

Bases: random_events.utils.SubclassJSONSerializer, probabilistic_model.interfaces.drawio.drawio.DrawIOInterface, abc.ABC

Class for all units of a probabilistic circuit.

This class should not be used by users directly. Use ProbabilisticCircuit as interface to users.

probabilistic_circuit: typing_extensions.Optional[ProbabilisticCircuit] = None#

The circuit this component is part of.

result_of_current_query: typing_extensions.Any = None#

The result of the current query.

index: typing_extensions.Optional[int] = None#

The index of the node in the graph of its circuit.

__post_init__()#
property subcircuits: typing_extensions.List[Unit]#
Returns:

The subcircuits of this unit.

property parents: typing_extensions.List[InnerUnit]#
Returns:

The parents of this unit.

abstract support()#

Calculate the support of this unit.

abstract property is_leaf#
Returns:

If this unit is a leaf unit.

property variables: sortedcontainers.SortedSet#
Abstractmethod:

property leaves: typing_extensions.List[LeafUnit]#
Returns:

The leaves of the circuit that are descendants of this node.

update_variables(new_variables: random_events.product_algebra.VariableMap)#

Update the variables of this unit and its descendants.

Parameters:

new_variables – A map that maps the variables that should be replaced to their new variable.

connect_incoming_edges_to(other: Unit)#

Connect all incoming edges to this unit to another unit.

Parameters:

other – The other unit to connect the incoming edges to.

filter_variable_map_by_self(variable_map: random_events.product_algebra.VariableMap)#

Filter a variable map by the variables of this unit.

Parameters:

variable_map – The map to filter

Returns:

The map filtered by the variables of this unit.

property impossible_condition_result: typing_extensions.Tuple[typing_extensions.Optional[Unit], float]#
Returns:

The result of an impossible truncated query.

abstract log_mode()#
__hash__()#
copy_without_graph()#
empty_copy() typing_extensions.Self#

Creat a copy of this circuit without any subcircuits. Only the parameters should be copied. This is used whenever a new circuit has to be created during inference.

Returns:

A copy of this circuit without any subcircuits that is not in this units graph.

abstract simplify()#

Simplify the circuit by removing nodes and redirected edges that have no impact in-place. Essentially, this method transforms the circuit into an alternating order of sum and product units.

Returns:

The simplified circuit.

abstract sample(*args, **kwargs)#

Draw samples from the circuit.

For sampling, a node gets requested a number of samples from all his parents. The parents write into the result_of_current_query attribute a tuple describing the beginning index of the sampling and how many samples are requested.

abstract marginal(*args, **kwargs) typing_extensions.Optional[typing_extensions.Self]#

Remove nodes that are not part of the marginal distribution.

abstract moment(*args, **kwargs)#
property drawio_style: typing_extensions.Dict[str, typing_extensions.Any]#

The style of the object.

class probabilistic_model.probabilistic_circuit.jax.NXProbabilisticCircuit#

Bases: probabilistic_model.probabilistic_model.ProbabilisticModel, random_events.utils.SubclassJSONSerializer

Probabilistic Circuits as a directed, rooted, acyclic graph.

The nodes of the graph are the units of the circuit. The edges of the graph indicate how the units are connected. The outgoing edges of a sum unit contain the log-log_weights of the subcircuits.

graph: rustworkx.PyDAG[Unit]#

The graph to check connectivity from.

__len__()#

Return the number of nodes in the graph.

Returns:

The number of nodes in the graph.

__iter__()#

Return an iterator over the nodes in the graph.

Returns:

An iterator over the nodes in the graph.

classmethod from_other(other: typing_extensions.Self) typing_extensions.Self#
property variables: sortedcontainers.SortedSet#
Returns:

The variables of the model.

property variable_to_index_map: typing_extensions.Dict[random_events.variable.Variable, int]#
property layers: typing_extensions.List[typing_extensions.List[Unit]]#
property leaves: typing_extensions.List[LeafUnit]#
is_valid() bool#

Check if this graph is:

  • acyclic

  • connected

Returns:

True if the graph is valid, False otherwise.

add_node(node: Unit)#
add_nodes_from(units: typing_extensions.Iterable[Unit])#
add_edge(parent: Unit, child: Unit, log_weight: typing_extensions.Optional[float] = None)#
add_edges_from(edges: typing_extensions.Iterable[typing_extensions.Union[typing_extensions.Tuple[Unit, Unit], typing_extensions.Tuple[Unit, Unit, float]]])#
successors(unit: Unit) typing_extensions.List[Unit]#
descendants(unit: Unit) random_events.set.Set[Unit]#
predecessors(unit: Unit) typing_extensions.List[InnerUnit]#
remove_node(unit: Unit)#
remove_nodes_from(units: typing_extensions.Iterable[Unit])#
remove_edge(parent: Unit, child: Unit)#
remove_edges_from(edges: typing_extensions.Iterable[typing_extensions.Tuple[Unit, Unit]])#
in_edges(unit: Unit) typing_extensions.List[typing_extensions.Tuple[Unit, Unit, typing_extensions.Optional[float]]]#
add_from_subgraph(subgraph: rustworkx.PyDAG[Unit]) typing_extensions.Dict[int, Unit]#

Add nodes and edges from a subgraph to this circuit.

Parameters:

subgraph – The subgraph to add nodes from.

Returns:

A dictionary mapping the node indices in the subgraph to the new units in this circuit.

nodes() typing_extensions.List[Unit]#

Return an iterator over the nodes.

Returns:

An iterator over the nodes.

edges() typing_extensions.List[typing_extensions.Tuple[Unit, Unit, typing_extensions.Optional[float]]]#
in_degree(unit: Unit)#
has_edge(parent: Unit, child: Unit) bool#
property root: Unit#

The root of the circuit is the node with in-degree 0. This is the output node, that will perform the final computation.

Returns:

The root of the circuit.

log_likelihood(events: numpy.array) numpy.array#

Calculate the log-likelihood of an event.

Check the documentation of likelihood for more information.

Parameters:

events – The full evidence event with shape (#events, #variables)

Returns:

The log-likelihood of the event with shape (#events).

cdf(events: numpy.array) numpy.array#

Calculate the cumulative distribution function of an event-array.

The event belongs to the class of full evidence queries.

..Note:: The cdf only exists if all variables are continuous or integers.

Parameters:

events – The array of full evidence events. The shape of the array has to be (n, len(self.variables)).

Returns:

The cumulative distribution function of the event as an array of shape (n,).

probability_of_simple_event(event: random_events.product_algebra.SimpleEvent) float#

Calculate the probability of a simple event.

The event belongs to the class of marginal queries.

Note

You can read more about queries of this class in Definition 11 in [CVVdB20] or watch the video tutorial. [US20]

Parameters:

event – The event.

Returns:

The probability of the event.

log_mode(check_determinism: bool = True) typing_extensions.Tuple[random_events.product_algebra.Event, float]#

Calculate the mode of the model.

Check the documentation of mode for more information.

Returns:

The mode and its log-likelihood.

remove_unreachable_nodes(root: Unit)#

Remove all nodes that are not reachable from the root.

log_truncated_of_simple_event_in_place(simple_event: random_events.product_algebra.SimpleEvent) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#

Construct the truncated circuit from a simple event.

Parameters:

simple_event – The simple event to condition on.

Returns:

The truncated circuit and the log-probability of the event

log_truncated_in_place(event: random_events.product_algebra.Event) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#

Efficiently compute the truncated for an Event, batching as much as possible.

log_truncated(event: random_events.product_algebra.Event) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#

Calculate the truncated distribution P(*| event) and the probability of the event.

Check the documentation of truncated for more information.

Parameters:

event – The event to condition on.

Returns:

The truncated distribution and the log-probability of the event.

marginal_in_place(variables: typing_extensions.Iterable[random_events.variable.Variable]) typing_extensions.Optional[typing_extensions.Self]#
log_conditional_in_place(point: typing_extensions.Dict[random_events.variable.Variable, typing_extensions.Any]) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#
log_conditional(point: typing_extensions.Dict[random_events.variable.Variable, typing_extensions.Any]) typing_extensions.Tuple[typing_extensions.Optional[typing_extensions.Self], float]#

Calculate the truncated distribution P(*| point) and the probability of the event. Check the documentation of conditional for more information.

Parameters:

point – A partial point to calculate the truncated distribution on.

Returns:

The truncated distribution and the log-probability of the point.

marginal(variables: typing_extensions.Iterable[random_events.variable.Variable]) typing_extensions.Optional[typing_extensions.Self]#

Calculate the marginal distribution of a set of variables.

Parameters:

variables – The variables to calculate the marginal distribution on.

Returns:

The marginal distribution over the variables.

sample(amount: int) numpy.array#

Sample from the model.

Parameters:

amount – The number of samples to draw.

Returns:

The samples.

moment(order: probabilistic_model.probabilistic_model.OrderType, center: probabilistic_model.probabilistic_model.CenterType) probabilistic_model.probabilistic_model.MomentType#

Calculate the (centralized) moment of the distribution.

\[\int_{-\infty}^{\infty} (x - center)^{order} pdf(x) dx\]

Note

You can read more about queries of this class in Definition 22 in :cite:p:`choi2020probabilistic`_. [US20]

Parameters:
  • order – The orders of the moment as a variable map for every continuous and integer variable.

  • center – The center of the moment as a variable map for every continuous and integer variable.

Returns:

The moments of the variables in order.

simplify() typing_extensions.Self#

Simplify the circuit inplace.

property support: random_events.product_algebra.Event#
Returns:

The support of the model.

is_decomposable() bool#

Check if the whole circuit is decomposed.

A circuit is decomposed if all its product units are decomposed.

Returns:

if the whole circuit is decomposed

abstract __eq__(other: typing_extensions.Self)#
empty_copy() typing_extensions.Self#

Create a copy of this circuit without any nodes. Only the parameters should be copied. This is used whenever a new circuit has to be created during inference.

Returns:

A copy of this circuit without any subcircuits that is not in this units graph.

__deepcopy__(memo=None) typing_extensions.Self#

Deep copy of the circuit.

Parameters:

memo – A dictionary that is used to keep track of objects that have already been copied.

Returns:

A deep copy of the circuit.

to_json() typing_extensions.Dict[str, typing_extensions.Any]#
classmethod parameters_from_json(data: typing_extensions.Dict[str, typing_extensions.Any]) typing_extensions.Self#
classmethod _from_json(data: typing_extensions.Dict[str, typing_extensions.Any]) typing_extensions.Self#

Create a variable from a json dict. This method is called from the from_json method after the correct subclass is determined and should be overwritten by the respective subclass.

Parameters:

data – The json dict

Returns:

The deserialized object

update_variables(new_variables: random_events.product_algebra.VariableMap)#

Update the variables of this unit and its descendants.

Parameters:

new_variables – The new variables to set.

is_deterministic() bool#
Returns:

Whether, this circuit is deterministic or not.

normalize()#

Normalize every sum node of this circuit in-place.

add_edges_and_nodes_from_circuit(other: typing_extensions.Self)#

Add all edges and nodes from another circuit to this circuit.

Parameters:

other – The other circuit to add.

add_weighted_edges_from(ebunch_to_add, weight='log_weight', **attr)#
subgraph_of(node: Unit) typing_extensions.Self#

Create a subgraph with a node as root.

Parameters:

node – The root of the subgraph.

Returns:

The subgraph.

fill_node_colors(node_colors: typing_extensions.Dict[Unit, str])#

Fill the node colors for the structure plot.

Parameters:

node_colors – The node colors to fill.

bfs_layout(scale: float = 1.0, align: PlotAlignment = PlotAlignment.VERTICAL) typing_extensions.Dict[int, numpy.array]#

Generate a bfs layout for this circuit.

Returns:

A dict mapping the node indices to 2d coordinates.

plot_structure(node_colors: typing_extensions.Optional[typing_extensions.Dict[Unit, str]] = None, variable_name_offset=0.2, plot_inference=False, inference_representation: typing_extensions.Callable = lambda node: ..., inference_result_offset: float = -0.25)#

Plot the structure of the circuit using matplotlib.

Parameters:

node_colors – Optionally specified colors of the node.

If nodes are not specified in the dictionary, they will be black. :param node_size: The size of the nodes :param variable_name_offset: The offset to the right of the variable names. :param plot_inference: If the results of the inference should be plotted. :param inference_representation: The representation of the inference results as a function from node to string. :param inference_result_offset: The vertical offset of the inference results.

nodes_weights() dict#
Returns:

dict with keys as nodes and values as list of all the log_weights for the node.

replace_discrete_distribution_with_deterministic_sum()#

splits the distribution into sum unit with all the discrete possibilities as leaf.

translate(translation: typing_extensions.Dict[random_events.variable.Variable, float])#

Translate the model in-place. Translation is done by adding the translation to the variable location influencing values. The translation can be viewed as what happens when you shift the numeric variables of the model by a constant vector.

Parameters:

translation – The variable value pairs to translate the model by.

scale(scale: typing_extensions.Dict[random_events.variable.Variable, float])#

Scale the model in-place. Scaling is done by multiplying the variable location influencing values. The scaling can be viewed as what happens when you multiply the numeric variables of the model by a constant vector.

Parameters:

scaling – The variable value pairs to scale the model by.

mount(other: Unit) typing_extensions.Dict[int, Unit]#

Mount another unit including its descendants. There will be no edge from self to other. This will also remove the nodes in other and their descendants from their circuit.

Parameters:

other – The other unit to mount.

__repr__()#
class probabilistic_model.probabilistic_circuit.jax.UnivariateContinuousLeaf#

Bases: UnivariateLeaf

Class for Leaf units.

distribution: typing_extensions.Optional[probabilistic_model.distributions.ContinuousDistribution]#

The distribution contained in this leaf unit.

__hash__#
log_truncated_of_simple_event_in_place(event: random_events.product_algebra.SimpleEvent)#
univariate_log_truncated_of_simple_event_in_place(event: random_events.interval.Interval)#

Condition this distribution on a simple event in-place but use sum units to create conditions on composite intervals. :param event: The simple event to condition on.

class probabilistic_model.probabilistic_circuit.jax.UniformDistribution(variable: probabilistic_model.distributions.distributions.Continuous, interval: probabilistic_model.distributions.distributions.SimpleInterval)#

Bases: probabilistic_model.distributions.distributions.ContinuousDistributionWithFiniteSupport

Class for uniform distributions over the half-open interval [lower, upper).

variable#
interval#

The interval of the distribution.

log_likelihood_without_bounds_check(x: probabilistic_model.distributions.distributions.np.array) probabilistic_model.distributions.distributions.np.array#

Evaluate the logarithmic likelihood function at x without checking the inclusion into the interval. :param x: x where p(x) > 0 :return: log(p(x))

cdf(x: probabilistic_model.distributions.distributions.np.array) probabilistic_model.distributions.distributions.np.array#

Calculate the cumulative distribution function at x. :param x: The data :return: The cumulative distribution function at x

univariate_log_mode() probabilistic_model.distributions.distributions.Tuple[probabilistic_model.distributions.distributions.AbstractCompositeSet, float]#
Returns:

The univariate mode of the distribution and its log-likelihood. The mode is not an Event.

log_conditional_from_simple_interval(interval: probabilistic_model.distributions.distributions.SimpleInterval) probabilistic_model.distributions.distributions.Tuple[probabilistic_model.distributions.distributions.Self, float]#

Calculate the truncated distribution given a simple interval.

Parameters:

interval – The simple interval

Returns:

The truncated distribution and the log-probability of the interval.

sample(amount: int) probabilistic_model.distributions.distributions.np.array#

Sample from the model.

Parameters:

amount – The number of samples to draw.

Returns:

The samples.

pdf_value() float#

Calculate the density of the uniform distribution.

log_pdf_value() float#

Calculate the log-density of the uniform distribution.

moment(order: probabilistic_model.distributions.distributions.OrderType, center: probabilistic_model.distributions.distributions.CenterType) probabilistic_model.distributions.distributions.MomentType#

Calculate the (centralized) moment of the distribution.

\[\int_{-\infty}^{\infty} (x - center)^{order} pdf(x) dx\]

Note

You can read more about queries of this class in Definition 22 in :cite:p:`choi2020probabilistic`_. [US20]

Parameters:
  • order – The orders of the moment as a variable map for every continuous and integer variable.

  • center – The center of the moment as a variable map for every continuous and integer variable.

Returns:

The moments of the variables in order.

__eq__(other)#
property drawio_label#

The label of the object as a drawio compatible string.

property representation#

The symbol used to represent this distribution.

property abbreviated_symbol: str#
__repr__()#
property image#
__copy__()#
__deepcopy__(memo=None)#
to_json() probabilistic_model.distributions.distributions.Dict[str, probabilistic_model.distributions.distributions.Any]#
classmethod _from_json(data: probabilistic_model.distributions.distributions.Dict[str, probabilistic_model.distributions.distributions.Any]) probabilistic_model.distributions.distributions.Self#

Create a variable from a json dict. This method is called from the from_json method after the correct subclass is determined and should be overwritten by the respective subclass.

Parameters:

data – The json dict

Returns:

The deserialized object

x_axis_points_for_plotly() probabilistic_model.distributions.distributions.List[probabilistic_model.distributions.distributions.Union[None, float]]#
pdf_trace() probabilistic_model.distributions.distributions.go.Scatter#
cdf_trace() probabilistic_model.distributions.distributions.go.Scatter#
plot(**kwargs) probabilistic_model.distributions.distributions.List#

Generate traces that can be plotted with plotly.

Parameters:
  • number_of_samples – The number of samples to draw.

  • surface – If True, plot the model as a surface plot.

  • mode – If True, plot the mode of the model.

Returns:

The traces.

__hash__()#
class probabilistic_model.probabilistic_circuit.jax.UniformLayer(variable: int, interval: jax.Array)#

Bases: probabilistic_model.probabilistic_circuit.jax.input_layer.ContinuousLayerWithFiniteSupport

A layer that represents uniform distributions over a single variable.

classmethod nx_classes() typing_extensions.Tuple[typing_extensions.Type, Ellipsis]#
Returns:

The tuple of matching classes of the layer in the probabilistic_model.probabilistic_circuit.rx package.

validate()#

Validate the parameters and their layouts.

property number_of_nodes: int#
Returns:

The number of nodes in the layer.

log_pdf_value() jax.numpy.array#

Calculate the log-density of the uniform distribution.

log_likelihood_of_nodes_single(x: jax.numpy.array) jax.numpy.array#

Calculate the log-likelihood of the distribution.

Parameters:

x – The input vector.

Returns:

The log-likelihood of every node in the layer for x.

log_likelihood_of_nodes(x: jax.numpy.array) jax.numpy.array#

Vectorized version of log_likelihood_of_nodes_single()

classmethod create_layer_from_nodes_with_same_type_and_scope(nodes: List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.UnivariateContinuousLeaf], child_layers: List[probabilistic_model.probabilistic_circuit.jax.inner_layer.NXConverterLayer], progress_bar: bool = True) probabilistic_model.probabilistic_circuit.jax.inner_layer.NXConverterLayer#

Create a layer from a list of nodes with the same type and scope.

classmethod _from_json(data: Dict[str, Any]) typing_extensions.Self#

Create a variable from a json dict. This method is called from the from_json method after the correct subclass is determined and should be overwritten by the respective subclass.

Parameters:

data – The json dict

Returns:

The deserialized object

to_nx(variables: sortedcontainers.SortedSet[random_events.variable.Variable], result: probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.ProbabilisticCircuit, progress_bar: tqdm.tqdm | None = None) List[probabilistic_model.probabilistic_circuit.rx.probabilistic_circuit.Unit]#

Convert the layer to a networkx circuit. For every node in this circuit, a corresponding node in the networkx circuit is created. The nodes all belong to the same circuit.

Parameters:
  • variables – The variables of the circuit.

  • result – The resulting circuit to write into

  • progress_bar – A progress bar to show the progress.

Returns:

The nodes of the networkx circuit.