CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-stheno

Implementation of Gaussian processes in Python with support for AutoGrad, TensorFlow, PyTorch, and JAX

Overview
Eval results
Files

gp-operations.mddocs/

GP Arithmetic and Transformations

Mathematical operations for combining and transforming Gaussian processes. This includes arithmetic operations like addition and multiplication, input transformations such as shifting and stretching, differentiation, and dimension selection for multi-dimensional inputs.

Capabilities

GP Arithmetic Operations

Combine Gaussian processes using arithmetic operations. Addition creates independent sums while multiplication can represent products of functions or scaling operations.

class GP:
    def __add__(self, other):
        """
        Add GP with another GP, function, or scalar.
        
        Parameters:
        - other: GP, function, or numeric value
        
        Returns:
        - GP: Sum of the processes
        """

    def __mul__(self, other):
        """
        Multiply GP by another GP, function, or scalar.
        
        Parameters:
        - other: GP, function, or numeric value
        
        Returns:
        - GP: Product/scaled process
        """

    def __radd__(self, other):
        """Right addition (other + self)."""

    def __rmul__(self, other):  
        """Right multiplication (other * self)."""

    def __neg__(self):
        """Negation (-self)."""

    def __sub__(self, other):
        """Subtraction (self - other)."""

    def __rsub__(self, other):
        """Right subtraction (other - self)."""

Input Transformations

Transform the input space of Gaussian processes through shifting, stretching, or arbitrary transformations. These operations modify how the GP responds to input coordinates.

class GP:
    def shift(self, shift):
        """
        Shift GP inputs by constant offset.
        
        Parameters:
        - shift: Shift amount (scalar or vector)
        
        Returns:
        - GP: Shifted process
        """

    def stretch(self, stretch):
        """
        Stretch GP inputs by scaling factor.
        
        Parameters:
        - stretch: Stretch factor (scalar or vector)
        
        Returns:
        - GP: Stretched process
        """

    def transform(self, f):
        """
        Apply arbitrary transformation to GP inputs.
        
        Parameters:
        - f: Transformation function
        
        Returns:
        - GP: Transformed process
        """

Dimension Selection

Select specific dimensions from multi-dimensional input spaces, enabling creation of lower-dimensional views of higher-dimensional processes.

class GP:
    def select(self, *dims):
        """
        Select input dimensions from multi-dimensional GP.
        
        Parameters:
        - *dims: Dimension indices to select
        
        Returns:
        - GP: Process with selected dimensions
        """

Differentiation

Compute derivatives of Gaussian processes either analytically (when supported by the kernel) or through finite difference approximations.

class GP:
    def diff(self, dim=0):
        """
        Differentiate GP with respect to specified dimension.
        
        Parameters:
        - dim: Dimension to differentiate along (default: 0)
        
        Returns:
        - GP: Differentiated process
        """

    def diff_approx(self, deriv=1, order=6):
        """
        Approximate derivative using finite differences.
        
        Parameters:
        - deriv: Derivative order (default: 1)
        - order: Finite difference order (default: 6)
        
        Returns:
        - GP: Approximately differentiated process
        """

Cross Products

Create Cartesian products of multiple Gaussian processes, useful for multi-output modeling and vector-valued processes.

def cross(*ps) -> GP:
    """
    Construct Cartesian product of processes.
    
    Parameters:
    - *ps: Gaussian processes to combine
    
    Returns:
    - GP: Cross product process
    """

Usage Examples

Basic Arithmetic Operations

import stheno
import numpy as np

# Create base processes
gp1 = stheno.GP(kernel=stheno.EQ())
gp2 = stheno.GP(kernel=stheno.Matern52())

# Addition
sum_gp = gp1 + gp2
sum_gp = gp1 + np.sin  # Add a function
sum_gp = gp1 + 2.5     # Add a constant

# Multiplication  
scaled_gp = 2.0 * gp1  # Scale by constant
product_gp = gp1 * gp2 # Product of processes
modulated_gp = gp1 * np.cos  # Modulate by function

# Other operations
neg_gp = -gp1          # Negation
diff_gp = gp1 - gp2    # Subtraction

Input Transformations

# Create base GP
gp = stheno.GP(kernel=stheno.EQ())

# Shift inputs
shifted_gp = gp.shift(1.0)  # Shift by constant
shifted_gp = gp.shift([1.0, 2.0])  # Shift each dimension

# Stretch inputs
stretched_gp = gp.stretch(2.0)  # Stretch by factor
stretched_gp = gp.stretch([2.0, 0.5])  # Different stretch per dimension

# Custom transformation
def custom_transform(x):
    return x**2  # Square the inputs

transformed_gp = gp.transform(custom_transform)

# Combined transformations
complex_gp = gp.shift(1.0).stretch(2.0).transform(np.log)

Dimension Selection

# Create 3D GP
gp_3d = stheno.GP(kernel=stheno.EQ())

# Select specific dimensions
gp_x = gp_3d.select(0)        # Only x dimension
gp_xy = gp_3d.select(0, 1)    # x and y dimensions  
gp_xz = gp_3d.select(0, 2)    # x and z dimensions

# Use for evaluation
x_3d = np.random.randn(50, 3)  # 3D inputs
x_2d = x_3d[:, [0, 1]]         # 2D projection

fdd_3d = gp_3d(x_3d)
fdd_2d = gp_xy(x_2d)  # Equivalent to gp_3d.select(0,1)(x_2d)

Differentiation

# Create smooth GP
gp = stheno.GP(kernel=stheno.EQ())

# Analytical differentiation
dgp_dx = gp.diff(dim=0)  # First derivative w.r.t. dimension 0

# Second derivative
d2gp_dx2 = gp.diff(dim=0).diff(dim=0)

# Mixed partial derivatives (for multi-dimensional inputs)
gp_2d = stheno.GP(kernel=stheno.EQ())
dgp_dx = gp_2d.diff(dim=0)  # ∂f/∂x
dgp_dy = gp_2d.diff(dim=1)  # ∂f/∂y
d2gp_dxdy = gp_2d.diff(dim=0).diff(dim=1)  # ∂²f/∂x∂y

# Approximate differentiation
approx_deriv = gp.diff_approx(deriv=1, order=6)  # First derivative
approx_deriv2 = gp.diff_approx(deriv=2, order=8)  # Second derivative

Cross Products for Multi-Output GPs

# Create individual processes
temp_gp = stheno.GP(kernel=stheno.EQ(), name="temperature")
pressure_gp = stheno.GP(kernel=stheno.Matern52(), name="pressure")
humidity_gp = stheno.GP(kernel=stheno.Linear(), name="humidity")

# Create multi-output process
multi_output_gp = stheno.cross(temp_gp, pressure_gp, humidity_gp)

# Evaluate at same input points
x = np.linspace(0, 10, 100)
multi_fdd = multi_output_gp(x)

# Sample from multi-output process
samples = multi_fdd.sample()  # Shape: (300, 1) for 3 outputs × 100 points

Complex Compositions

# Build complex GP through composition
base_gp = stheno.GP(kernel=stheno.EQ())

# Create trend + seasonal + noise model
trend = stheno.GP(kernel=stheno.Linear()).stretch(10.0)
seasonal = (stheno.GP(kernel=stheno.EQ()) * np.sin).stretch(0.5)  
noise = 0.1 * stheno.GP(kernel=stheno.Delta())

complex_model = trend + seasonal + noise

# Transform for non-stationary behavior
nonstationary = base_gp.transform(lambda x: x**0.5).stretch(2.0).shift(1.0)

Install with Tessl CLI

npx tessl i tessl/pypi-stheno

docs

core-gp.md

gp-operations.md

index.md

lazy.md

measure.md

multi-output.md

observations.md

random.md

tile.json