Operations¶
Structural operations for combining, splitting, and factorizing features in probabilistic circuits.
Cat¶
Concatenates multiple modules along the feature or channel dimension.
- class spflow.modules.ops.Cat(inputs, dim=-1)[source]¶
Bases:
Module- log_likelihood(data, cache=None)[source]¶
Compute log likelihood by concatenating input log-likelihoods.
- marginalize(marg_rvs, prune=True, cache=None)[source]¶
Marginalize out specified random variables.
- Parameters:
- Returns:
Marginalized module or None if fully marginalized.
- Return type:
Optional[Module]
- sample(num_samples=None, data=None, is_mpe=False, cache=None, sampling_ctx=None)[source]¶
Generate samples by delegating to concatenated inputs.
- Parameters:
- Returns:
Generated samples tensor.
- Return type:
Tensor
Split¶
Abstract base class for feature splitting operations.
- class spflow.modules.ops.split.Split(inputs, dim=1, num_splits=2)[source]¶
-
Abstract base class for tensor splitting operations.
Splits input tensors along specified dimensions. Concrete implementations must provide feature_to_scope property.
- inputs¶
Single input module to split.
- Type:
nn.ModuleList
- scope¶
Variable scope inherited from input.
- Type:
Scope
- get_out_shapes(event_shape)[source]¶
Get output shapes for each split based on input event shape.
- Parameters:
event_shape – Shape of the input event tensor.
- Returns:
List of tuples representing output shapes for each split.
- marginalize(marg_rvs, prune=True, cache=None)[source]¶
Marginalize out specified random variables.
- Parameters:
- Return type:
- Returns:
Marginalized module or None if fully marginalized.
- abstractmethod merge_split_indices(*split_indices)[source]¶
Merge per-split channel indices back to original feature layout.
This method takes channel indices for each split and combines them into indices matching the original (unsplit) feature layout. Used by parent modules (like EinsumLayer) during sampling.
- sample(num_samples=None, data=None, is_mpe=False, cache=None, sampling_ctx=None)[source]¶
Generate samples by delegating to input module.
- Parameters:
- Return type:
- Returns:
Tensor containing the generated samples.
SplitMode¶
Factory class for creating split configurations.
- class spflow.modules.ops.split.SplitMode(split_type, num_splits=2, indices=None)[source]¶
Bases:
objectConfiguration for split operations.
Factory class for creating split configurations. Use the class methods to create split configurations that can be passed to modules.
Example
>>> layer = EinsumLayer(inputs=leaf, num_repetitions=3, out_channels=10, split_mode=SplitMode.interleaved(num_splits=3)) >>> layer = LinsumLayer(inputs=leaf, out_channels=10, split_mode=SplitMode.consecutive(num_splits=2)) >>> layer = LinsumLayer(inputs=leaf, out_channels=10, split_mode=SplitMode.by_index(indices=[[0,1], [2,3]]))
- classmethod by_index(indices)[source]¶
Create a split configuration with explicit feature indices.
Splits features according to specified indices. Each inner list contains the feature indices for that split.
Example
>>> SplitMode.by_index([[0, 1, 4], [2, 3, 5, 6, 7]]) SplitMode.by_index(indices=[[0, 1, 4], [2, 3, 5, 6, 7]])
- classmethod consecutive(num_splits=2)[source]¶
Create a consecutive split configuration.
Splits features into consecutive chunks: [0,1,2,3] -> [0,1], [2,3].
- classmethod interleaved(num_splits=2)[source]¶
Create an interleaved split configuration.
Splits features using modulo: [0,1,2,3] -> [0,2], [1,3].
SplitConsecutive¶
Splits features into consecutive halves (or n parts).
- class spflow.modules.ops.SplitConsecutive(inputs, dim=1, num_splits=2)[source]¶
Bases:
SplitSplit operation using consecutive feature distribution.
Splits features into consecutive chunks: feature i goes to split i // (num_features / num_splits).
Example
With num_splits=2: [0,1,2,3] -> [0,1], [2,3] With num_splits=3: [0,1,2,3,4,5] -> [0,1], [2,3], [4,5]
- merge_split_indices(*split_indices)[source]¶
Merge split indices back to original layout (consecutive).
SplitConsecutive splits features consecutively: [0,1,2,3] -> [0,1], [2,3]. So we concatenate: left_indices, right_indices.
- Return type:
- sample(num_samples=None, data=None, is_mpe=False, cache=None, sampling_ctx=None)[source]¶
Generate samples by delegating to input module.
SplitConsecutive splits features consecutively: [0,1,2,3,4,5,6,7] -> left=[0,1,2,3], right=[4,5,6,7]. When sampling, we may need to expand the channel indices by repeating them for each split if they come from a parent that operates on the split output features.
- Parameters:
- Return type:
- Returns:
Tensor containing the generated samples.
SplitInterleaved¶
Splits features in alternating fashion.
- class spflow.modules.ops.SplitInterleaved(inputs, dim=1, num_splits=2)[source]¶
Bases:
SplitSplit operation using interleaved feature distribution.
Distributes features using modulo arithmetic: feature i goes to split i % num_splits. Optimized for common cases (2 and 3 splits).
Example
With num_splits=2: [0,1,2,3] -> [0,2], [1,3] With num_splits=3: [0,1,2,3,4,5] -> [0,3], [1,4], [2,5]
- split_masks¶
Boolean masks for each split.
- Type:
list[Tensor]
SplitByIndex¶
Splits features according to user-specified indices.
- class spflow.modules.ops.SplitByIndex(inputs, indices=None, dim=1)[source]¶
Bases:
SplitSplit operation using explicit feature indices.
Allows full control over which features go into which split by specifying exact indices for each split.
Example
With indices=[[0, 1, 4], [2, 3, 5, 6, 7]]: features are split into group 1: [0, 1, 4] and group 2: [2, 3, 5, 6, 7]
- indices¶
List of lists specifying feature indices for each split.
- inverse_indices¶
Tensor mapping original positions to split outputs.
- __init__(inputs, indices=None, dim=1)[source]¶
Initialize index-based split operation.
- Parameters:
inputs (
Module) – Input module to split.indices (
Optional[Sequence[Sequence[int]]]) – List of lists specifying feature indices for each split. Each inner list contains the feature indices for that split. All features must be covered exactly once (no overlap, no gaps).dim (
int) – Dimension along which to split (0=batch, 1=feature, 2=channel).
- Raises:
ValueError – If indices are invalid (overlap, gaps, out of bounds).
- merge_split_indices(*split_indices)[source]¶
Merge split indices back to original layout.
Takes channel indices for each split and combines them into indices matching the original (unsplit) feature layout.
- sample(num_samples=None, data=None, is_mpe=False, cache=None, sampling_ctx=None)[source]¶
Generate samples by delegating to input module.
SplitByIndex may receive channel indices for split features that need to be expanded to the full input feature count.
- Parameters:
- Return type:
- Returns:
Tensor containing the generated samples.