[!IMPORTANT] viva_math IS NOT JUST A MATH LIB. It is the kernel of VIVA's affective computing stack β PAD emotional space, Cusp catastrophe for mood transitions, Friston's Free Energy Principle, attractor dynamics, and information theory β all expressed as small, type-safe Gleam functions.
Built on gleam_community_maths, targeting Erlang + JavaScript.
π― Overview
Core mathematical foundations for VIVA β a sentient digital life research project. The library models emotional dynamics as a dynamical system: PAD state vectors, Cusp catastrophe for sudden mood shifts, Free Energy for interoception, and Shannon-family entropy for affective complexity.
The math is small, deliberate, and grounded in real papers (Mehrabian 1996, Thom 1972, Friston 2010, Shannon 1948).
| Property | Value |
|---|---|
| Language | Pure Gleam (type-safe functional) |
| Targets | Erlang (BEAM) + JavaScript |
| Built on | gleam_community_maths β₯ 2.0 |
| Tests | 58 passing |
| Domain | Affective computing, dynamical systems, info theory |
| Public API | viva_math/{common,vector,cusp,free_energy,attractor,entropy} |
β‘ Quick Start
gleam add viva_mathimport viva_math/attractor
import viva_math/cusp
import viva_math/free_energy
import viva_math/vector
pub fn main() {
// PAD emotional state: Pleasure / Arousal / Dominance
let state = vector.pad(-0.3, 0.7, -0.2)
// Nearest discrete emotion
let emotion = attractor.classify_emotion(state)
// -> "fear"
// Bistability check (sudden mood shift possible?)
let params = cusp.from_arousal_dominance(0.7, -0.2)
let volatile = cusp.is_bistable(params)
// -> True
// Prediction error vs expected state
let expected = vector.pad(0.0, 0.0, 0.0)
let fe = free_energy.compute_state(expected, state, expected, 0.1)
// fe.feeling -> Surprised | Alarmed
}π Prerequisites
| Tool | Version | Required for | |:-----------|:---------|:-----------------| | Gleam | `>= 1.4` | Build / runtime | | Erlang/OTP | `>= 26` | BEAM target | | Node.js | `>= 18` | JS target (opt.) | Zero NIFs. Zero C dependencies. Pure functional.ποΈ Architecture
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Gleam application code β
β viva_math/{common,vector,...} β
ββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββ
β viva_math modules β
β β
β ββββββββββ ββββββββββ ββββββββββ ββββββββββββββββ β
β β common β β vector β β cusp β β free_energy β β
β β clamp β β Vec3 β β Thom β β Friston β β
β β sigmoidβ β PAD βΒ³ β β 1972 β β 2010 β β
β β noise β β ops β β stoch. β β homeostasis β β
β ββββββββββ ββββββββββ ββββββββββ ββββββββββββββββ β
β β
β ββββββββββββββ ββββββββββββββββββββ β
β β attractor β β entropy β β
β β Mehrabian β β Shannon Β· KL β β
β β 1996 β β JS Β· RΓ©nyi β β
β β 8 emotions β β hybrid affect. β β
β ββββββββββββββ ββββββββββββββββββββ β
ββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββ
β gleam_community_maths (trig, stats, β¦) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββπ Core modules
| Module | Purpose | |:------------------------|:--------------------------------------------------------------------------| | `viva_math/common` | `clamp`, `sigmoid`, `softmax`, `lerp`, `smoothstep`, Wiener noise, decays | | `viva_math/vector` | `Vec3` PAD type β Pleasure / Arousal / Dominance space | | `viva_math/cusp` | Cusp catastrophe (Thom 1972) + Stochastic Cusp (Euler-Maruyama) | | `viva_math/free_energy` | Free Energy Principle (Friston 2010) β interoception | | `viva_math/attractor` | 8 basic-emotion attractors in PAD space (Mehrabian 1996) | | `viva_math/entropy` | Shannon, KL divergence, Jensen-Shannon, RΓ©nyi, hybrid affective |𧬠Theoretical Background
PAD Model β Mehrabian (1996)
Emotions live as points in 3D vector space:
- Pleasure
[-1, 1]β sadness β joy - Arousal
[-1, 1]β calm β excitement - Dominance
[-1, 1]β submission β control
Cusp Catastrophe β Thom (1972)
Sudden mood transitions modeled by the potential:
V(x) = xβ΄/4 + Ξ±xΒ²/2 + Ξ²x
When arousal pushes Ξ± < 0 and the discriminant Ξ > 0, the system goes
bistable β tiny perturbations trigger discrete mood jumps. The stochastic
variant adds Wiener noise (dV/dx + ΟΞΎ(t)) integrated via Euler-Maruyama.
Free Energy Principle β Friston (2010)
Agents minimize "surprise" via prediction:
F β Prediction_ErrorΒ² + ComplexityLow free energy β predictions match reality (homeostasis). High free energy β significant mismatch (alarm).
Attractor Dynamics
Eight basic emotions form attractors in PAD space:
| Emotion | P | A | D |
|---|---|---|---|
| Joy | +0.76 | +0.48 | +0.35 |
| Sadness | -0.63 | -0.27 | -0.33 |
| Fear | -0.64 | +0.60 | -0.43 |
| Anger | -0.51 | +0.59 | +0.25 |
| Trust | +0.58 | -0.23 | +0.42 |
| Disgust | -0.60 | +0.35 | +0.11 |
| Serenity | +0.45 | -0.42 | +0.21 |
| Excitement | +0.62 | +0.75 | +0.38 |
Information Theory β Shannon (1948) + extensions
Shannon entropy H(p), KL divergence D(pβq), Jensen-Shannon JS(p,q),
RΓ©nyi H_Ξ±, and a hybrid affective entropyH_hybrid = Ξ±Hβ + (1-Ξ±)Hβ for mixed emotional states.
π¨ Design Principles
| Principle | Description |
|---|---|
| Math grounded in papers | Every function cites the source (Thom, Friston, Mehrabian, β¦) |
| Type-safe affect | Vec3 constructor enforces PAD axis order at compile time |
| Multi-target | Same code runs on BEAM and in the browser via JS target |
| Small surface, deep meaning | 6 modules, ~60 public functions β nothing speculative |
| Zero runtime deps |
Builds only on gleam_stdlib + gleam_community_maths |
π Public API Highlights
Vec3 / PAD space
import viva_math/vector
let v = vector.pad(0.5, -0.2, 0.7)
let mag = vector.magnitude(v)
let unit = vector.normalize(v)
let dist = vector.euclidean(v, vector.pad(0.0, 0.0, 0.0))Cusp catastrophe β deterministic + stochastic
import viva_math/cusp
let params = cusp.from_arousal_dominance(0.7, -0.2)
let v = cusp.potential(params, 0.3) // V(x)
let g = cusp.gradient(params, 0.3) // dV/dx
// Stochastic mood walk
let trajectory =
cusp.simulate_stochastic(
cusp.StochasticCuspParams(params, sigma: 0.05, seed: 42),
start: 0.0,
steps: 1000,
dt: 0.01,
)Free Energy
import viva_math/free_energy
import viva_math/vector
let expected = vector.pad(0.0, 0.0, 0.0)
let actual = vector.pad(-0.3, 0.7, -0.2)
let state = free_energy.compute_state(expected, actual, expected, 0.1)
// state.feeling -> Calm | Surprised | Alarmed
// state.free_energy -> FloatEntropy and divergence
import viva_math/entropy
let h = entropy.shannon([0.2, 0.3, 0.5])
let d = entropy.kl_divergence([0.2, 0.8], [0.5, 0.5])
let js = entropy.jensen_shannon([0.2, 0.8], [0.5, 0.5])
let r = entropy.renyi([0.2, 0.3, 0.5], alpha: 2.0)πΊοΈ Roadmap
| Phase | Status |
|---|---|
| PAD vector space + emotion attractors | β |
| Deterministic Cusp catastrophe | β |
| Stochastic Cusp (Wiener + Euler-Maruyama) | β |
| Free Energy Principle (basic interoception) | β |
| Shannon / KL / Jensen-Shannon / RΓ©nyi entropy | β |
| Hybrid affective entropy | β |
| Arousal-weighted KL sensitivity | β |
| Multi-target build (Erlang + JS) | β |
| Ornstein-Uhlenbeck mood dynamics | β³ |
| Variational Free Energy (deeper Bayesian model) | β³ |
| Wasserstein distance between affective distributions | β³ |
| Property-based tests on every closed form | β³ |
π€ Contributing
git checkout -b feature/your-feature
gleam test # 58 tests
gleam format --check src test
gleam docs buildSee CONTRIBUTING.md for guidelines.
π References
- Mehrabian (1996) β Pleasure-arousal-dominance: A general framework
- Thom (1972) β Structural Stability and Morphogenesis
- Friston (2010) β The free-energy principle: a unified brain theory?
- Grasman et al. (2009) β Fitting the Cusp Catastrophe in R
- Oravecz et al. (2009) β Ornstein-Uhlenbeck Process in Affective Dynamics
- Shannon (1948) β A Mathematical Theory of Communication
π VIVA Ecosystem
| Package | Purpose |
|---|---|
viva_math | Mathematical foundations (this package) |
viva_emotion | PAD emotional dynamics |
viva_tensor | FP8 LLM inference on the BEAM |
viva_telemetry | Observability suite |
viva_aion | Time perception |
viva_glyph | Symbolic language |