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,
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,
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:
Recursively draws from parent components if not already drawn
Collects parent samples for the current level
Draws n samples from this component using parent values
Validates drawn samples against bounds and constraints
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 hasFORCE_PARENT_NAME
set toTrue
, 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,
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,) andy
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 = '',
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,
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.
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
andUPPER_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,
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