Abstract Model Component API Reference

Abstract base classes for SciStanPy model components.

This module defines the foundational abstract class that forms the core architecture of SciStanPy model components, including parameters, constants, and transformations. Users typically do not interact with this module directly; instead, they use the concrete implementations provided in the scistanpy.model.components.constants and scistanpy.model.components.parameters submodules.

The module establishes the common functionality that all model components must implement.

Core Abstractions:
  • Component Hierarchy: Parent-child relationships between model elements

  • Stan Code Generation: Automatic translation to Stan programming language

  • Shape Broadcasting: Automatic handling of multi-dimensional parameters

  • Dependency Management: Tracking and validation of component relationships

Key Responsibilities:
  • Define abstract interfaces for model component behavior

  • Implement common functionality for shape handling and validation

  • Provide Stan code generation template

  • Manage component relationships and dependency graphs

  • Handle parameter bounds and constraints

  • Support sampling and drawing from component distributions

Stan Integration: The abstract base provides core Stan code generation capabilities including:
  • Variable declarations with appropriate types and constraints

  • Index management for multi-dimensional arrays

  • Target increment and transformation assignment generation

  • Support function inclusion for custom distributions

Component Relationships: The hierarchy system enables complex model construction through:
  • Parent-child linkage for dependency tracking

  • Parameter name resolution and validation

  • Automatic shape broadcasting across related components

  • Tree traversal for model analysis and code generation

This foundational layer enables the construction of sophisticated probabilistic models while maintaining type safety and automatic Stan code generation.

AbstractModelComponent

class scistanpy.model.components.abstract_model_component.AbstractModelComponent(
*,
shape: tuple['custom_types.Integer', ...] | 'custom_types.Integer' = (),
**model_params: custom_types.CombinableParameterType,
)[source]

Bases: ABC

Abstract base class for all SciStanPy model components.

This class defines the fundamental interface and common functionality for all elements in a SciStanPy probabilistic model. It provides the foundation for parameters, constants, transformed_parameters, and other model components.

Parameters:
  • shape (Union[tuple[custom_types.Integer, ...], custom_types.Integer]) – Shape of the component array. Defaults to scalar ().

  • model_params (custom_types.CombinableParameterType) – Named parameters that this component depends on

Variables:
  • POSITIVE_PARAMS – Set of parameter names that must be positive

  • NEGATIVE_PARAMS – Set of parameter names that must be negative

  • SIMPLEX_PARAMS – Set of parameter names that must be simplexes

  • LOG_SIMPLEX_PARAMS – Set of parameter names that must be log-simplexes

  • BASE_STAN_DTYPE – Base Stan data type for this component

  • LOWER_BOUND – Lower bound constraint for component values

  • UPPER_BOUND – Upper bound constraint for component values

  • IS_SIMPLEX – Whether this component represents a simplex

  • IS_LOG_SIMPLEX – Whether this component represents a log-simplex

  • FORCE_PARENT_NAME – Whether to force naming of parent variables in Stan code

  • FORCE_LOOP_RESET – Whether to force loop reset in Stan code

The class provides core functionality for:
  • Component relationship management (parents and children)

  • Shape validation and broadcasting

  • Stan code generation for variable declarations and operations

  • Sampling and drawing from component distributions

  • Tree traversal for model analysis

All model components must implement the abstract methods for drawing samples and generating Stan code appropriate to their type.

BASE_STAN_DTYPE: Literal['real', 'int', 'simplex'] = 'real'

Class variable giving the base Stan data type for this component.

FORCE_LOOP_RESET: bool = False

Class variable noting whether to force loop reset in Stan code. This is useful where this parameter’s shape makes it appear nestable with another inside the same loop, but it actually is not.

FORCE_PARENT_NAME: bool = False

Class variable noting whether to force naming of parent variables in Stan code. If True and not provided by the user, parent parameters will be assigned names automatically in the Stan code.

IS_LOG_SIMPLEX: bool = False

Class variable giving whether this component represents a log-simplex (exponentials over last dim sum to 1).

IS_SIMPLEX: bool = False

Class variable giving whether this component represents a simplex (elements over last dim sum to 1).

LOG_SIMPLEX_PARAMS: set[str] = {}

Class variable giving the set of parent parameter names that must be log-simplexes. The sum of exponentials over the last dimension for any parent parameter named here must equal 1

LOWER_BOUND: 'custom_types.Float' | 'custom_types.Integer' | None = None

Class variable giving the lower bound constraint for component values. None if unbounded.

NEGATIVE_PARAMS: set[str] = {}

Class variable giving the set of parent parameter names that must be negative.

POSITIVE_PARAMS: set[str] = {}

Class variable giving the set of parent parameter names that must be positive.

SIMPLEX_PARAMS: set[str] = {}

Class variable giving the set of parent parameter names that must be simplexes. The sum over the last dimension for any parent parameter named here must equal 1.

UPPER_BOUND: 'custom_types.Float' | 'custom_types.Integer' | None = None

Class variable giving the upper bound constraint for component values. None if unbounded.

property assign_depth: custom_types.Integer

Get the assignment depth for Stan loop nesting.

Returns:

Loop nesting level for this component

Return type:

custom_types.Integer

This is the property form of get_assign_depth() and provides convenient access to the assignment depth. It determines how deeply nested this component should be in Stan’s loop structure.

property children: list[AbstractModelComponent]

Get all child components that depend on this component.

Returns:

Copy of the children list

Return type:

list[AbstractModelComponent]

Returns a shallow copy to prevent external modification of the internal _children list while allowing iteration and inspection.

property constants

Get all constant-valued parent components.

Returns:

Dictionary mapping parameter names to constant components

Return type:

dict[str, Constant]

This property filters parent components to return only those that are Constant instances, useful for identifying fixed values in the model hierarchy.

declare_stan_variable(varname: str, force_basetype: bool = False) str[source]

Generate Stan variable declaration with appropriate type and bounds.

Parameters:
  • varname (str) – Variable name to declare

  • force_basetype (bool) – Whether to force array[…] basetype format. Defaults to False.

Returns:

Complete Stan variable declaration

Return type:

str

This method combines the Stan data type (from get_stan_dtype()) with the variable name to create a complete variable declaration suitable for use in Stan data, parameters, or other blocks.

draw(
n: custom_types.Integer,
*,
_drawn: dict['AbstractModelComponent', npt.NDArray] | None = None,
seed: 'custom_types.Integer' | None = None,
) tuple[npt.NDArray, dict['AbstractModelComponent', npt.NDArray]][source]

Recursively draw samples from this component and its dependency tree.

Parameters:
  • n (custom_types.Integer) – Number of samples to draw

  • _drawn (Optional[dict[AbstractModelComponent, npt.NDArray]]) – Cache of previously drawn samples. Auto-created if None. Defaults to None. Internal use only. Used to cache draws throughout recursion.

  • seed (Optional[custom_types.Integer]) – Random seed for reproducible sampling. Defaults to None.

Returns:

Tuple of (samples_from_this_component, all_drawn_samples)

Return type:

tuple[npt.NDArray, dict[AbstractModelComponent, npt.NDArray]]

Raises:
  • NumpySampleError – If sampling fails due to parameter issues

  • AssertionError – If drawn values violate component bounds or constraints

This method implements the complete sampling workflow:
  1. Recursively draws from parent components if not already drawn

  2. Collects parent samples for the current level

  3. Draws n samples from this component using parent values

  4. Validates drawn samples against bounds and constraints

  5. Returns samples and updates the global draw cache

The method enforces constraint validation including:
  • Lower and upper bound checking

  • Simplex sum-to-one validation

  • Parameter type constraint validation

property force_name: bool

Check whether this component should be explicitly named in Stan code.

Returns:

True if any child forces parent naming

Return type:

bool

This property returns True if any child component has FORCE_PARENT_NAME set to True, indicating that this component should be given an explicit variable name in the generated Stan code rather than being inlined.

get_assign_depth() int[source]

Calculate the assignment depth for Stan loop structure.

Returns:

Loop nesting level for this component’s assignment

Return type:

int

This method determines the appropriate loop nesting level for defining this component in Stan code. The depth is calculated as:

  • Number of dimensions minus one (last dimension is vectorized)

  • Minus trailing singleton dimensions (except the last)

  • Clipped to a minimum of zero

Assignment depth affects:
  • Loop structure in generated Stan code

  • Index variable management

  • Vectorization opportunities

get_child_paramnames() dict[AbstractModelComponent, str][source]

Get parameter names that this component defines in its children.

Returns:

Mapping from child components to parameter names they use for this component

Return type:

dict[AbstractModelComponent, str]

Raises:

AssertionError – If a child references this component with multiple parameter names

This method analyzes the dependency graph to determine how child components reference this component. Each child should reference this component through exactly one parameter name.

get_index_offset(
query: str | AbstractModelComponent,
offset_adjustment: int = 0,
) int[source]

Calculate index offset for multi-dimensional variable access.

Parameters:
  • query (Union[str, AbstractModelComponent]) – Component or parameter name to calculate offset for

  • offset_adjustment (int) – Additional offset to apply. Defaults to 0.

Returns:

Number of leading indices to skip

Return type:

int

Raises:

KeyError – If query string doesn’t match any parent parameter

This method calculates the appropriate index offset when accessing parent components that have different numbers of dimensions. The offset accounts for implicit singleton dimensions that are added during broadcasting operations (e.g., the offset between x with shape (10,) and y with shape (2, 10) would be “1”).

Index offsets are essential for:
  • Proper multi-dimensional array indexing in Stan code

  • Handling broadcasting between components of different shapes

  • Maintaining correct dimension alignment in generated code

get_indexed_varname(
index_opts: tuple[str, ...] | None,
offset: custom_types.Integer = 0,
start_dim: custom_types.Integer = 0,
end_dim: 'custom_types.Integer' | None = -1,
_name_override: str = '',
) str[source]

Generate Stan variable name with appropriate indexing.

Parameters:
  • index_opts (Optional[tuple[str, ...]]) – Index variable names to choose from.

  • offset (custom_types.Integer) – Number of leading indices to skip. Defaults to 0.

  • start_dim (custom_types.Integer) – First dimension to include in indexing. Defaults to 0.

  • end_dim (Optional[custom_types.Integer]) – Last dimension to include in indexing. Defaults to -1.

  • _name_override (str) – Override for base variable name. Defaults to “”. Internal use only.

Returns:

Stan variable name with proper indexing

Return type:

str

This method generates proper Stan variable names for multi-dimensional components, handling:

  • Singleton dimension skipping

  • Index offset management for broadcasting

  • Dimension range selection

  • Automatic vectorization of the last dimension

The offset parameter accounts for implicit singleton dimensions prepended during broadcasting between parent and child components.

abstractmethod get_right_side(
index_opts: tuple[str, ...] | None,
start_dims: dict[str, 'custom_types.Integer'] | None = None,
end_dims: dict[str, 'custom_types.Integer'] | None = None,
offset_adjustment: int = 0,
) dict[str, str][source]

Generate Stan code for the right-hand side of statements.

Parameters:
  • index_opts (Optional[tuple[str, ...]]) – Index variable names for multi-dimensional access

  • start_dims (Optional[dict[str, custom_types.Integer]]) – First indexable dimension for each parent parameter. Defaults to None.

  • end_dims (Optional[dict[str, custom_types.Integer]]) – Last indexable dimension for each parent parameter. Defaults to None.

  • offset_adjustment (int) – Index offset adjustment. Defaults to 0.

Returns:

Dictionary mapping parameter names to Stan code strings

Return type:

dict[str, str]

This abstract method must be implemented by all model components to generate appropriate Stan code for probability statements, transformations, and assignments. The method processes parent components and returns properly formatted Stan expressions.

The base implementation in this abstract class provides common functionality for:

  • Processing parent component relationships

  • Handling index offsets and dimension slicing

  • Determining when to use variable names vs. inline expressions

  • Managing transformed parameter code generation

Subclasses extend this foundation to generate component-specific Stan code patterns.

get_shared_leading(other: AbstractModelComponent) custom_types.Integer[source]

Determine the number of compatible leading dimensions with another component.

Parameters:

other (AbstractModelComponent) – Component to compare shapes with

Returns:

Number of shared leading dimensions

Return type:

custom_types.Integer

This method analyzes shape compatibility between components by counting the number of leading dimensions that are compatible according to broadcasting rules. Dimensions are compatible if they are equal or if at least one of them is 1 (singleton).

Shape compatibility is important for:
  • Determining indexing strategies

  • Validating broadcasting operations

  • Optimizing Stan code generation

get_stan_dtype(force_basetype: bool = False) str[source]

Generate Stan data type declaration for this component.

Parameters:

force_basetype (bool) – Whether to force array[…] format instead of vectors. Defaults to False.

Returns:

Stan data type string with bounds

Return type:

str

Raises:

AssertionError – If unknown data type is encountered

This method generates appropriate Stan data type declarations based on:
  • Base data type (real, int, simplex)

  • Component dimensionality

  • Bound constraints

  • Whether vector/array format is preferred

get_stan_parameter_declaration(force_basetype: bool = False) str[source]

Generate Stan parameter declaration for this component.

Parameters:

force_basetype (bool) – Whether to force array[…] format. Defaults to False.

Returns:

Complete Stan parameter declaration

Return type:

str

This convenience method generates a parameter declaration using the component’s Stan model variable name and appropriate data type.

get_supporting_functions() list[str][source]

Get Stan function definitions required by this component.

Returns:

List of Stan function definition strings

Return type:

list[str]

This method returns Stan function definitions or include statements that must be added to the Stan program to support this component. The default implementation returns an empty list.

Custom components may override this method to include:
  • Custom distribution definitions

  • Helper function implementations

  • Include statements for external function libraries

get_target_incrementation(index_opts: tuple[str, ...]) str[source]

Generate Stan code for log-probability target increments. This is the statement that appears in the model block of the Stan program.

Parameters:

index_opts (tuple[str, ...]) – Index variable names for multi-dimensional access

Returns:

Stan code for target increment (empty by default)

Return type:

str

This method generates Stan code for the model block, where log-probability contributions are added to the target density. The default implementation returns an empty string.

Probabilistic components should override this method to provide appropriate target increment statements for their distributions.

get_transformation_assignment(index_opts: tuple[str, ...]) str[source]

Generate Stan code for parameter transformation assignments. This is the statement that appears in the transformed parameters block of the Stan program.

Parameters:

index_opts (tuple[str, ...]) – Index variable names for multi-dimensional access

Returns:

Stan code for transformation assignment (empty by default)

Return type:

str

This method generates Stan code for the transformed parameters block, where deterministic transformations of parameters are computed. The default implementation returns an empty string.

Components that require parameter transformations (such as non-centered parameterizations) should override this method to provide appropriate Stan transformation code.

property is_named: bool

Check whether this component has an assigned variable name.

Returns:

True if component has been assigned a model variable name

Return type:

bool

Examples:
# Example model with named and unnamed parameters
class MyModel(Model):
    def __init__(self):
        super().__init__()
        self.param1 = Parameter(...)  # is_named is True
        param2 = Parameter(...)       # is_named is False

# Outside of a model, is_named is always False
param = Parameter(...)
assert not param.is_named
property model_varname: str

Get or generate the SciStanPy variable name for this component. Only valid within a SciStanPy Model.

Returns:

Variable name for this component

Return type:

str

If a variable name has been explicitly assigned, returns that name. Otherwise, automatically generates a name based on child component relationships using dot notation for hierarchical names.

Examples:
class MyModel(Model):
    def __init__(self):
        super().__init__()

        # Parameter without explicit name has auto-generated name
        # Name is "param2.mu" based on child relationship
        param1 = Parameter(...)  # model_varname is "param2.mu"

        # Explicitly named parameter
        param2 = Parameter(mu = self.param1) # model_varname is "param2"
property ndim: custom_types.Integer

Get the number of dimensions of this component.

Returns:

Number of dimensions

Return type:

custom_types.Integer

property observable: bool

Check whether this component represents observed data.

Returns:

False by default (most components are not observable)

Return type:

bool

Observable components represent known data values rather than parameters to be inferred. The default implementation returns False; subclasses may override for specific behavior.

property parents: list[AbstractModelComponent]

Get all parent components that this component depends on.

Returns:

List of parent components

Return type:

list[AbstractModelComponent]

property shape: tuple[int, ...]

Get the shape of this component.

Returns:

Shape tuple for this component

Return type:

tuple[int, …]

property stan_bounds: str

Generate Stan bounds specification string.

Returns:

Stan bounds specification (empty if no bounds)

Return type:

str

This property formats LOWER_BOUND and UPPER_BOUND into Stan’s bound format. Returns an empty string if no bounds are specified.

property stan_model_varname: str

Get the Stan-compatible variable name for this component. This is identical to model_varname, but with dots replaced by double underscores.

Returns:

Stan variable name with dots replaced by double underscores

Return type:

str

abstract property torch_parametrization: torch.Tensor
walk_tree(
walk_down: bool = True,
_recursion_depth: custom_types.Integer = 1,
) list[tuple[int, 'AbstractModelComponent', 'AbstractModelComponent']][source]

Traverse the model component dependency tree.

Parameters:
  • walk_down (bool) – Whether to walk toward children (True) or parents (False). Defaults to True.

  • _recursion_depth (custom_types.Integer) – Current recursion depth (internal parameter). Defaults to 1.

Returns:

List of (depth, current_component, relative_component) tuples

Return type:

list[tuple[int, AbstractModelComponent, AbstractModelComponent]]

This method enables systematic traversal of the model dependency graph in either direction. Each tuple contains:

  • Recursion depth relative to the starting component

  • The current component in the traversal

  • The relative component (child if walking down, parent if walking up)

Tree traversal is useful for:
  • Model structure analysis and visualization

  • Dependency validation and cycle detection

  • Code generation ordering

  • Model component discovery