Source code for qmlhc.predictors.projector

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Deterministic Projectors
------------------------
Mappings from a compact present state ``S_t`` to a set of K candidate futures
``{S_{t+1}^{(k)}}``.

This module defines:

- ``Projector``: protocol/contract for deterministic future projection.
- ``LinearProjector``: affine projector that generates evenly spaced
  perturbations around a base prediction, followed by ``tanh`` stabilization.
"""

from __future__ import annotations

from typing import Protocol

import numpy as np

from ..core.types import Array, TensorLike


[docs] class Projector(Protocol): """ Contract for deterministic future projection from a present compact state. """
[docs] def project(self, s_t: TensorLike, branches: int = 2) -> Array: """ Produce K candidate futures from the current state. Parameters ---------- s_t : TensorLike Current compact state vector ``(D,)``. branches : int, optional Number of candidate futures (K), by default ``2``. Returns ------- Array Matrix of candidate futures with shape ``(K, D)``. """ ...
[docs] class LinearProjector: """ Affine projector with evenly spaced perturbations around the base prediction. The projector computes a base prediction ``base = w * x + b`` and then generates ``K`` values by adding linearly spaced deltas in ``[-span, span]``; each result is passed through ``tanh`` for numerical stability. Parameters ---------- weight : float, optional Scalar weight ``w`` used in the affine base prediction, by default ``1.0``. bias : float, optional Scalar bias ``b`` used in the affine base prediction, by default ``0.0``. span : float, optional Half-width of the linear delta range, by default ``0.2``. """ def __init__(self, weight: float = 1.0, bias: float = 0.0, span: float = 0.2): self._w = float(weight) self._b = float(bias) self._span = float(span)
[docs] def project(self, s_t: TensorLike, branches: int = 2) -> Array: """ Generate K candidate futures via affine transform + evenly spaced deltas. Parameters ---------- s_t : TensorLike Current compact state vector ``(D,)``. branches : int, optional Number of candidate futures (K), by default ``2`` (clamped to ``>= 2``). Returns ------- Array Matrix of candidate futures with shape ``(K, D)``. Notes ----- The final futures are computed as: ``tanh(w * s_t + b + delta_k)`` for ``delta_k`` in evenly spaced values across ``[-span, span]``. """ x = np.asarray(s_t, dtype=float).reshape(-1) k = max(2, int(branches)) base = self._w * x + self._b deltas = np.linspace(-self._span, self._span, k, dtype=float) fut = np.stack([np.tanh(base + d) for d in deltas], axis=0) return fut