Broadcasting with Vector Parameters

PyHS3 supports broadcasting operations by allowing parameters to be vectors instead of scalars. This is useful when you want to evaluate the same model at multiple parameter points simultaneously.

Basic Usage

By default, all parameters are scalar tensors:

Converting Parameters to Vectors

To enable broadcasting, you need to modify the parameter’s kind before creating the model:

>>> # Get the parameter set
>>> parameterset = ws.parameter_points[0]
>>> # Convert 'x' parameter to vector
>>> parameterset["x"].kind = pt.vector
>>> # Create new model with vector parameter
>>> new_model = ws.model(parameter_set=parameterset)

Now you can pass vector values for the x parameter:

>>> # Vector evaluation - multiple x values at once
>>> parameters = {"x": [0.0, 1.0, 2.0], "mu": 0.0, "sigma": 1.0}
>>> results = new_model.logpdf_unsafe("model", **parameters)
>>> print(f"Vector results: {results}")
Vector results: [-0.91893853 -1.41893853 -2.91893853]

Understanding the Model Structure

You can inspect the model to understand its parameter structure:

>>> print(model)
Model(
    mode: FAST_RUN
    parameters: 3 (...)
    distributions: 1 (model)
    functions: 0 ()
)
>>> # Check parameter types
>>> print(f"Parameters: {sorted(model.parameters)}")
Parameters: ['mu', 'sigma', 'x']
>>> print(f"x parameter type: {type(model.parameters['x'])}")
x parameter type: <class 'pytensor.tensor.variable.TensorVariable'>
>>> # Check parameter set configuration
>>> print(f"Parameter set: {model.parameterset}")
Parameter set: ...
>>> print(f"x parameter config: {model.parameterset['x']}")
x parameter config: name='x'

Behavior Difference: Scalar vs Vector Parameters

When you pass vector values to a scalar parameter model, it will only use the first element:

>>> # Scalar model with vector input - only uses first element
>>> parameters = {"x": [0.0, 1.0, 2.0], "mu": 0.0, "sigma": 1.0}
>>> result = model.pdf_unsafe("model", **parameters)
>>> print(f"Result with scalar model: {result}")
Result with scalar model: 0.3989422804014327
>>> # Compare with vector model - processes all elements
>>> result_vector = new_model.pdf_unsafe("model", **parameters)
>>> print(f"Result with vector model: {result_vector}")
Result with vector model: [0.39894228 0.24197072 0.05399097]

Complete Example

Here’s a complete working example:

Current Limitations

  • Users must manually specify which parameters should be vectors

  • The kind must be set before creating the model

  • No automatic inference of parameter dimensionality

Note

A more user-friendly API for automatic broadcasting detection is planned for future releases.