MHRN-Space / src /playground /pan /hypervector.py
ThomasHeisig's picture
Sync GitHub main e8a04aea24121d15707238534e635cf0ceee8eaf (part 8)
250836c verified
Raw History Blame Contribute Delete
3.65 kB
"""Hypervector operations for exploratory PAN state representations."""
from __future__ import annotations
import math
from collections.abc import Sequence
BASE_AXES: tuple[tuple[str, str, str, str], ...] = (
(
"intrinsic_time",
"t",
"Intrinsic simulation time; never wall-clock time.",
"R+",
),
(
"excitability",
"E",
"Normalized membrane excitability proxy.",
"[0,1]",
),
(
"plasticity",
"P",
"Current exploratory plasticity activity.",
"[0,1]",
),
(
"information_proxy",
"I*",
"Local surprise proxy; not a validated PID quantity.",
"[0,1]",
),
(
"health",
"H",
"Exploratory health / survival state.",
"[0,1]",
),
(
"neuromodulation",
"N",
"Bounded exploratory neuromodulatory state.",
"[0,1]",
),
(
"energy",
"ATP*",
"Normalized exploratory energy budget.",
"[0,1]",
),
(
"embodied_position",
"R",
"Scalar projection of the assigned topology coordinate.",
"[0,1]",
),
(
"consolidation",
"C",
"Activity-history consolidation proxy.",
"[0,1]",
),
(
"network_coupling",
"S",
"Normalized local coupling / degree proxy.",
"[0,1]",
),
)
def axis_schema(dimensions: int) -> list[dict[str, object]]:
"""Return neutral metadata for a PAN hyperstate with D >= 5."""
if not 5 <= dimensions <= 32:
raise ValueError("PAN hypervector dimensions must be between 5 and 32")
axes: list[dict[str, object]] = []
for index in range(dimensions):
if index < len(BASE_AXES):
name, symbol, meaning, value_range = BASE_AXES[index]
else:
name = f"latent_{index + 1}"
symbol = f"L{index + 1}"
meaning = "Unassigned exploratory latent axis."
value_range = "R"
axes.append(
{
"dimension": index + 1,
"name": name,
"symbol": symbol,
"meaning": meaning,
"range": value_range,
}
)
return axes
def _same_width(a: Sequence[float], b: Sequence[float]) -> None:
if len(a) != len(b):
raise ValueError("hypervectors must have equal dimensions")
def bind(
a: Sequence[float],
b: Sequence[float],
*,
method: str = "hadamard",
) -> list[float]:
"""Bind two equal-width hypervectors without scientific interpretation."""
_same_width(a, b)
if method == "hadamard":
return [float(left) * float(right) for left, right in zip(a, b)]
if method == "circular_convolution":
width = len(a)
if width == 0:
return []
return [
sum(
float(a[index]) * float(b[(out - index) % width])
for index in range(width)
)
for out in range(width)
]
raise ValueError(f"unknown PAN binding method: {method}")
def bundle(vectors: Sequence[Sequence[float]]) -> list[float]:
"""Bundle hypervectors by the sign of their component-wise sum."""
if not vectors:
return []
width = len(vectors[0])
if any(len(vector) != width for vector in vectors):
raise ValueError("all hypervectors must have equal dimensions")
sums = [sum(float(vector[index]) for vector in vectors) for index in range(width)]
return [0.0 if value == 0.0 else math.copysign(1.0, value) for value in sums]