random – Random number functionality#
The pytensor.tensor.random module provides random-number drawing functionality
that closely resembles the numpy.random module.
High-level API#
PyTensor uses RandomGeneratorVariables (symbolic equivalent to NumPy random Generators) to define graphs with pseudo-random draws.
Unlike NumPy, each random-draw definition returns a tuple of (next_rng, draws), containing the symbolic draws and updated random Generator state.
Users should use next_rng for subsequent random draw operations, and for the final update expression.
For an example of how to use random numbers, see Using Random Numbers.
For a technical explanation of how PyTensor implements random variables see Pseudo random number generation in PyTensor.
Using RNG variables#
If a user prefers to work with non-shared RNG variables, they can do so with
- pytensor.tensor.random.variable.rng(name=None)[source]#
Create a symbolic random number generator variable.
This creates a root variable with no data attached, suitable for use as a function input. When compiling a function, use
pytensor.In(rng, mutable=True)to allow in-place RNG updates.- Parameters:
name (str, optional) – Name for the variable.
- Returns:
A symbolic random number generator variable.
- Return type:
Examples
>>> import numpy as np >>> import pytensor >>> import pytensor.tensor.random as ptr
>>> rng = ptr.rng("rng") >>> next_rng, x = rng.normal() >>> fn = pytensor.function([pytensor.In(rng, mutable=True)], [next_rng, x]) >>> rng_val = np.random.default_rng(153) >>> rng_val, draw = fn(rng_val) >>> draw array(1.45769255) >>> rng_val, draw = fn(rng_val) >>> draw array(0.44383835)
RandomGeneratorVariable objects have distribution methods that mirror
pytensor.tensor.random functions. Each method returns a tuple of
(next_rng, draw):
init_rng = pt.random.rng()
next_rng, x = init_rng.uniform(-1, 1)
final_rng, y = next_rng.normal(0, 1)
fn = pytensor.function([pytensor.In(init_rng, mutable=True)], [final_rng, x, y])
rng_np = np.random.default_rng(123)
rng_np, x_draw1, y_draw1 = fn(rng_np)
x_draw2, y_draw2 = fn(rng_np)
assert x_draw1 != y_draw1 != x_draw2 != y_draw2
rng_np = np.random.default_rng(123)
_, x_draw3, y_draw3 = fn(rng_np)
assert x_draw3 == x_draw1
assert y_draw3 == y_draw1
Note
Use pytensor.In(..., mutable=True) on initial rng variables to allow direct inplace use by PyTensor. Otherwise a costly deepcopy will be perfomed on the node that first uses it. Alternatively using shared_rng and working with updates grants the same inplace permissions.
See also
Using Random Numbers for a tutorial with practical examples.
Pseudo random number generation in PyTensor for a deeper look at how PyTensor implements RNG state threading, inplace optimizations, and backend support.
Distributions#
All distributions are available as methods on RandomGeneratorVariable
(e.g. rng.normal()) and as module-level functions in pytensor.tensor.random.