Skip to content

PyAIF (pyaif-toolkit)

PyAIF is an active-inference toolkit for Python. It supports factorised discrete hidden states with categorical or continuous observations, and separates the generative model, likelihood, and temporal inference algorithm into reusable components.

Install PyAIF View source code

Capabilities

  • Categorical and continuous observation likelihoods
  • Shallow single-step inference
  • Deep temporal inference over policies
  • Expected-free-energy policy evaluation and action selection
  • Reusable categorical parameter-learning updates
  • Optional domain-specific continuous-likelihood learning hooks
  • Batched NumPy policy evaluation and bounded worker-thread support

Installation

PyAIF requires Python 3.9 or newer. Install the published pyaif-toolkit distribution from PyPI:

python -m pip install pyaif-toolkit

The distribution name is pyaif-toolkit; the Python import package is PyAIF.

Quick start

import numpy as np

from PyAIF import (
    ActiveInfAgent,
    CategoricalLikelihood,
    GenerativeModel,
    ShallowInference,
)


def object_array(*values):
    result = np.empty(len(values), dtype=object)
    for index, value in enumerate(values):
        result[index] = np.asarray(value, dtype=float)
    return result


A = object_array(np.array([[0.95, 0.05], [0.05, 0.95]]))

B_factor = np.zeros((2, 2, 2))
B_factor[:, :, 0] = np.eye(2)
B_factor[:, :, 1] = np.fliplr(np.eye(2))
B = object_array(B_factor)

D = object_array(np.array([0.5, 0.5]))
C = object_array(np.zeros(2))

model = GenerativeModel(
    B=B,
    D=D,
    controls_dim=[2],
    controllable_factors=[0],
)
likelihood = CategoricalLikelihood(
    A=A,
    preferences=C,
    modality_dependencies=[[0]],
)
agent = ActiveInfAgent(
    model=model,
    likelihood=likelihood,
    inference=ShallowInference(),
    action_selection="deterministic",
)

agent.reset()
agent.observe([0])
agent.infer_states()
expected_free_energy, policy_posterior = agent.infer_policies()
action = agent.select_action()

Use DeepTemporalInference(horizon=...) for a fixed temporal window. For a fresh planning window after every observation, use RecedingHorizonInference for policy-conditioned temporal message passing or FilteredRecedingHorizonInference for current-state filtering followed by future policy rollouts. See the public API and model-shape reference for component contracts and array dimensions.

Continuous observations

ContinuousLikelihood accepts a density function, observation grids, log preferences, and the hidden-state factors on which each modality depends. This lets applications supply domain-specific sensor models without changing the reusable agent implementation.

from PyAIF import ContinuousLikelihood

likelihood = ContinuousLikelihood(
    likelihood_fn=density,
    observation_grids=[observation_grid],
    log_preferences={0: log_preferences},
    modality_dependencies=[[0, 1]],
)