Research-Stack/0-Core-Formalism/lean/external/OTOM/MISignal.lean

93 lines
3.5 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
MISignal.lean - Mutual Information Signal Processing Bindings
Ports rows 72-76 from MATH_MODEL_MAP.tsv (Python → Lean).
All values are Q16.16. Bits-per-byte range [0, 8] maps to [0, 8·65536].
-/
import Semantics.Bind
import Semantics.FixedPoint
namespace Semantics.MISignal
open Q16_16
def epsilon : Q16_16 := ⟨1⟩
-- Scale constant: 8.0 in Q16.16 = 8 * 65536
def bitsPerByteMax : Q16_16 := ⟨8 * 65536⟩
structure MIRecord where
baselineBpb : Q16_16 -- baseline bits-per-byte (uncompressed context)
actualBpb : Q16_16 -- actual bits-per-byte achieved
miPredicted : Q16_16 -- kNN-predicted MI value
deriving Repr, Inhabited, DecidableEq
-- Row 72: MI(x) = baseline_bpb - actual_bpb
-- Mutual information extracted through compression improvement
def mutualInformationSignal (r : MIRecord) : Q16_16 :=
if r.baselineBpb.val ≥ r.actualBpb.val
then sub r.baselineBpb r.actualBpb
else zero
-- Row 73: MI_pred = Σ(w_i · MI_i · S_i) / Σ(w_i · S_i)
-- kNN weighted MI prediction; w_i = 1/(d_i + ε)
-- distances, mis, similarities are parallel arrays
def knnMIPrediction (distances mis similarities : Array Q16_16) : Q16_16 :=
let n := distances.size
if n == 0 || mis.size != n || similarities.size != n then zero
else
let num := Array.foldl (fun acc i =>
let w := div one (add distances[i]! epsilon)
add acc (mul (mul w mis[i]!) similarities[i]!)
) zero (Array.range n)
let den := Array.foldl (fun acc i =>
let w := div one (add distances[i]! epsilon)
add acc (mul w similarities[i]!)
) zero (Array.range n)
if den.val == 0 then zero else div num den
-- Row 74: surprise = log(1 + |MI_actual - MI_predicted|)
-- Approximated in Q16.16: surprise ≈ |diff| (natural log not available in integer—use diff directly as ordinal surprise)
def surpriseMetric (r : MIRecord) : Q16_16 :=
let miActual := mutualInformationSignal r
let diff := abs (sub miActual r.miPredicted)
-- log(1+x) ≈ x for small x; represent as direct delta in Q16.16
add one diff
-- Row 75: ρ(x) = MI(x) / (cost(x) + ε)
-- Structure yield: information per unit compute cost
def structureYield (mi cost : Q16_16) : Q16_16 :=
div mi (add cost epsilon)
-- Row 76: d(z₁, z₂) = √( Σ w_i · ((z₁_i - z₂_i) / s_i)² )
-- Weighted feature distance over 9-dim vector
-- Uses integer arithmetic: no float sqrt; return squared distance as cost proxy
def weightedFeatureDistanceSq (z1 z2 weights scales : Array Q16_16) : Q16_16 :=
let n := z1.size
if n == 0 then zero
else
Array.foldl (fun acc i =>
if i < z2.size && i < weights.size && i < scales.size then
let diff := abs (sub z1[i]! z2[i]!)
let scaled := div diff (add scales[i]! epsilon)
let sq := mul scaled scaled
add acc (mul weights[i]! sq)
else acc
) zero (Array.range n)
def miInvariant (r : MIRecord) : String :=
s!"mi:baseline={r.baselineBpb.val},actual={r.actualBpb.val}"
def miCost (a b : MIRecord) (_m : Metric) : UInt32 :=
let ma := mutualInformationSignal a
let mb := mutualInformationSignal b
(abs (sub ma mb)).val
def miSignalBind (a b : MIRecord) (m : Metric) : Bind MIRecord MIRecord :=
informationalBind a b m miCost miInvariant miInvariant
-- Verify
#eval mutualInformationSignal { baselineBpb := ⟨5 * 65536⟩, actualBpb := ⟨3 * 65536⟩, miPredicted := ⟨2 * 65536⟩ }
#eval surpriseMetric { baselineBpb := ⟨5 * 65536⟩, actualBpb := ⟨3 * 65536⟩, miPredicted := ⟨65536⟩ }
end Semantics.MISignal