viva_glyph/encoder
Encoder - PAD to Latent Space transformation
Expands 3D PAD state into 6D latent space optimized for emotional quantization (Johnson-Lindenstrauss optimal).
Architecture
PAD (3D) ──▶ Expand ──▶ Latent (6D) ──▶ RVQ ──▶ Glyph
Expansion includes:
- Raw PAD values (P, A, D)
- Derived features (intensity, valence_sign, activation)
Validated (DeepSeek R1 671B - 2025-01-24)
- 6D sufficient for 3D PAD (Johnson-Lindenstrauss lemma)
- activation = A × D (preserves dominance sign)
- intensity essential for magnitude metric
Types
Context for encoding (optional metadata)
pub type Context {
Context(situation: Int, temporal: Float)
}
Constructors
-
Context(situation: Int, temporal: Float)Arguments
- situation
-
Situation identifier (0 = no context)
- temporal
-
Time-based feature (0.0-1.0, e.g., circadian)
Encoder configuration
pub type EncoderConfig {
EncoderConfig(latent_dim: Int, use_derived: Bool)
}
Constructors
-
EncoderConfig(latent_dim: Int, use_derived: Bool)Arguments
- latent_dim
-
Latent space dimension (default 6, optimal per Johnson-Lindenstrauss)
- use_derived
-
Whether to include derived features
PAD state (matches viva_emotion)
pub type Pad {
Pad(pleasure: Float, arousal: Float, dominance: Float)
}
Constructors
-
Pad(pleasure: Float, arousal: Float, dominance: Float)
Values
pub fn decode(rvq: rvq.RvqEncoder, glyph: glyph.Glyph) -> Pad
Full decoding pipeline: Glyph → PAD
pub fn decode_batch(
rvq: rvq.RvqEncoder,
glyphs: List(glyph.Glyph),
) -> List(Pad)
Batch decode multiple glyphs
pub fn encode(
rvq: rvq.RvqEncoder,
pad: Pad,
context: Context,
) -> glyph.Glyph
Full encoding pipeline: PAD → Glyph
pub fn encode_batch(
rvq: rvq.RvqEncoder,
pads: List(Pad),
context: Context,
) -> List(glyph.Glyph)
Batch encode multiple PAD states
pub fn latent_to_pad(latent: List(Float)) -> Pad
Contract latent vector back to PAD Only uses first 3 components (ignores derived features)
pub fn pad_to_latent(pad: Pad, context: Context) -> List(Float)
Expand PAD to latent vector
Latent layout (6D) - validated by DeepSeek R1: [0] pleasure [1] arousal [2] dominance [3] intensity = sqrt(P² + A² + D²) / sqrt(3) - magnitude metric [4] valence_sign = sign(P) * |P|^0.5 - emphasizes valence direction [5] activation = A × D - preserves dominance sign (Yik 2011)
Note: temporal/reserved removed per Johnson-Lindenstrauss optimization
pub fn round_trip(
rvq: rvq.RvqEncoder,
pad: Pad,
context: Context,
) -> #(Pad, Float)
Round-trip with error measurement