Skip to main content

README.md

<div align="center">

<img src="https://capsule-render.vercel.app/api?type=waving&color=0:7C3AED,100:1A1A1A&height=200&section=header&text=viva_math&fontSize=64&fontColor=fff&animation=twinkling&fontAlignY=35&desc=The%20math%20behind%20sentient%20digital%20life&descSize=18&descAlignY=55" width="100%"/>

[![Gleam](https://img.shields.io/badge/Gleam-FFAFF3?style=for-the-badge&logo=gleam&logoColor=black)](https://gleam.run/)
[![BEAM](https://img.shields.io/badge/BEAM-A90533?style=for-the-badge&logo=erlang&logoColor=white)](https://www.erlang.org/)
[![Erlang+JS](https://img.shields.io/badge/Erlang_%2B_JS-4B275F?style=for-the-badge)](https://gleam.run/news/multi-target-compilation/)
[![Hex](https://img.shields.io/badge/hex.pm-viva__math-A678DD?style=for-the-badge&logo=hex&logoColor=white)](https://hex.pm/packages/viva_math)
[![PAD](https://img.shields.io/badge/PAD-Mehrabian_1996-7C3AED?style=for-the-badge)](https://en.wikipedia.org/wiki/PAD_emotional_state_model)
[![Tests](https://img.shields.io/badge/tests-58_passing-00875A?style=for-the-badge)](./test)
[![Version](https://img.shields.io/badge/version-1.2.0-CD5C5C?style=for-the-badge)](./CHANGELOG.md)
[![License](https://img.shields.io/badge/license-MIT-228B22?style=for-the-badge)](./LICENSE)

---

*"Numbers feel. Catastrophes are smooth. The BEAM thinks in PAD."*

</div>

---

> [!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](https://hexdocs.pm/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

```sh
gleam add viva_math
```

```gleam
import 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
}
```

<details>
<summary><strong>πŸ“‹ Prerequisites</strong></summary>

| 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.

</details>

---

## πŸ—οΈ 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, …)        β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

<details>
<summary><strong>πŸ“‹ Core modules</strong></summary>

| 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           |

</details>

---

## 🧬 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Β² + Complexity
```

Low 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 entropy**
`H_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

```gleam
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

```gleam
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

```gleam
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 -> Float
```

### Entropy and divergence

```gleam
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

```bash
git checkout -b feature/your-feature
gleam test                  # 58 tests
gleam format --check src test
gleam docs build
```

See [CONTRIBUTING.md](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                           |

---

<div align="center">

**Star if math should feel like something ⭐**

[![GitHub stars](https://img.shields.io/github/stars/gabrielmaialva33/viva_math?style=social)](https://github.com/gabrielmaialva33/viva_math)

*Created by Gabriel Maia Β· MIT License*

<img src="https://capsule-render.vercel.app/api?type=waving&color=0:1A1A1A,100:7C3AED&height=100&section=footer" width="100%"/>

</div>