viva_emotion/dynamics

Dynamics - How emotions evolve over time

Ornstein-Uhlenbeck Process

Based on Oravecz et al. (2009, 2011) for affective dynamics:

dX(t) = θ(μ - X(t))dt + σdW(t)

Where:

Asymptotic variance: Var_∞ = σ²/(2θ) With θ=0.1, σ=0.02: Var_∞ ≈ 0.002, fluctuations ≈ ±0.045

Cusp Catastrophe

Based on Thom (1975) catastrophe theory, using viva_math/cusp:

V(x) = x⁴/4 + αx²/2 + βx

Bistability region: Δ = -4α³ - 27β² > 0 (validated by DeepSeek R1)

Mapping to PAD:

References

Types

Configuration for emotional dynamics

pub type DynamicsConfig {
  DynamicsConfig(
    decay_rate: Float,
    baseline: pad.Pad,
    volatility: Float,
    cusp_threshold: Float,
    cusp_dominance_trigger: Float,
    cusp_pleasure_trigger: Float,
    cusp_flip_pleasure_damp: Float,
    cusp_flip_arousal_damp: Float,
    cusp_flip_dominance_boost: Float,
    coupling_pa: Float,
    coupling_pd: Float,
    coupling_ap: Float,
    coupling_da: Float,
  )
}

Constructors

  • DynamicsConfig(
      decay_rate: Float,
      baseline: pad.Pad,
      volatility: Float,
      cusp_threshold: Float,
      cusp_dominance_trigger: Float,
      cusp_pleasure_trigger: Float,
      cusp_flip_pleasure_damp: Float,
      cusp_flip_arousal_damp: Float,
      cusp_flip_dominance_boost: Float,
      coupling_pa: Float,
      coupling_pd: Float,
      coupling_ap: Float,
      coupling_da: Float,
    )

    Arguments

    decay_rate

    Base decay rate (theta in O-U)

    baseline

    Target state (mu in O-U) - personality baseline

    volatility

    Volatility scale (sigma in O-U) - multiplied with injected noise

    cusp_threshold

    Cusp alpha threshold for bistability

    cusp_dominance_trigger

    Dominance threshold for cusp trigger (default -0.3)

    cusp_pleasure_trigger

    Pleasure threshold for cusp trigger (default -0.5)

    cusp_flip_pleasure_damp

    Dampening factor for pleasure flip (default 0.7)

    cusp_flip_arousal_damp

    Dampening factor for arousal after flip (default 0.8)

    cusp_flip_dominance_boost

    Dominance recovery after flip (default 0.2)

    coupling_pa

    P-A coupling: arousal influence on pleasure dynamics (default 0.0) Positive = high arousal amplifies pleasure change

    coupling_pd

    P-D coupling: dominance influence on pleasure dynamics (default 0.05) Based on Bakker et al. (2014) P-D correlation ≈ 0.85

    coupling_ap

    A-P coupling: pleasure influence on arousal dynamics (default 0.0)

    coupling_da

    D-A coupling: arousal influence on dominance dynamics (default -0.03) High arousal reduces dominance (feeling less in control) Based on Yik (2011) arousal-dominance interaction

Values

pub fn check_cusp(
  state: pad.Pad,
  config: DynamicsConfig,
) -> #(pad.Pad, Bool)

Check for cusp catastrophe and apply if triggered Returns new state (possibly jumped) and whether jump occurred

pub fn cusp_potential(
  x: Float,
  alpha: Float,
  beta: Float,
) -> Float

Cusp catastrophe potential (delegated to viva_math/cusp) V(x) = x^4/4 + alphax^2/2 + betax

pub fn default_config() -> DynamicsConfig

Default dynamics configuration

pub fn evolve(
  state: pad.Pad,
  config: DynamicsConfig,
  dt: Float,
) -> pad.Pad

Evolve PAD state using coupled Ornstein-Uhlenbeck process

Extended model with inter-dimensional coupling:

dP = θ(μ_p - P)dt + c_pa × A × dt + c_pd × D × dt
dA = θ(μ_a - A)dt + c_ap × P × dt
dD = θ(μ_d - D)dt + c_da × A × dt

Where c_da = -0.03 (Yik 2011): high arousal reduces dominance

Higher arousal = slower decay (emotions persist when excited)

pub fn evolve_with_noise(
  state: pad.Pad,
  config: DynamicsConfig,
  dt: Float,
  noise: pad.Pad,
) -> pad.Pad

Evolve with injected noise (stochastic O-U process)

Noise Requirements

For mathematically correct Euler-Maruyama discretization, each component of noise should be sampled from N(0,1):

noise.pleasure  ~ N(0, 1)
noise.arousal   ~ N(0, 1)
noise.dominance ~ N(0, 1)

The scaling σ × √dt is applied internally.

Deterministic Mode

For testing/replay, pass pad.neutral() (all zeros) as noise. This gives fully deterministic mean-reversion behavior.

Warning

If noise has non-Gaussian distribution (e.g., uniform [-1,1]), the statistical properties of the O-U process will be incorrect. The asymptotic variance Var_∞ = σ²/(2θ) assumes Gaussian noise.

pub fn is_bistable(alpha: Float, beta: Float) -> Bool

Check if system is in bistable region (delegated to viva_math/cusp) Uses validated formula: Δ = -4α³ - 27β² > 0

pub fn tick(
  state: pad.Pad,
  config: DynamicsConfig,
  dt: Float,
) -> #(pad.Pad, Bool)

Full dynamics tick: evolve + check cusp (deterministic)

pub fn tick_with_noise(
  state: pad.Pad,
  config: DynamicsConfig,
  dt: Float,
  noise: pad.Pad,
) -> #(pad.Pad, Bool)

Full dynamics tick with noise injection Pass pad.neutral() as noise for deterministic/reproducible behavior

Search Document