Mahault
Initial commit: MindSphere Coach — ToM-powered coaching agent
157b149
"""
Numerical utilities for Active Inference computations.
Adapted from empathy-prisonner-dilemma inference utilities.
Pure numpy, no numba dependency.
"""
from __future__ import annotations
import numpy as np
def normalize(x: np.ndarray) -> np.ndarray:
"""Normalize array to sum to 1 (probability distribution)."""
total = np.sum(x)
if total <= 0.0:
return np.ones_like(x) / x.size
return x / total
def softmax(x: np.ndarray, temperature: float = 1.0) -> np.ndarray:
"""Softmax with temperature scaling. Lower temp = more deterministic."""
if temperature <= 0.0:
out = np.zeros_like(x, dtype=np.float64)
out[np.argmax(x)] = 1.0
return out
scaled = x / temperature
shifted = scaled - np.max(scaled)
exp_vals = np.exp(shifted)
return exp_vals / np.sum(exp_vals)
def entropy(p: np.ndarray) -> float:
"""Shannon entropy H(p) = -sum(p * log(p))."""
p_safe = p[p > 1e-12]
return -float(np.sum(p_safe * np.log(p_safe)))
def kl_divergence(p: np.ndarray, q: np.ndarray) -> float:
"""KL divergence D_KL(p || q) = sum(p * log(p/q))."""
mask = p > 1e-12
q_safe = np.maximum(q[mask], 1e-12)
return float(np.sum(p[mask] * np.log(p[mask] / q_safe)))
def sigmoid(x: float, center: float = 0.0, scale: float = 1.0) -> float:
"""Sigmoid function with configurable center and scale."""
z = (x - center) / max(scale, 1e-12)
z = np.clip(z, -500, 500)
return 1.0 / (1.0 + np.exp(-z))
def expected_value(belief: np.ndarray, values: np.ndarray) -> float:
"""Compute expected value under a belief distribution."""
return float(np.dot(belief, values))