taf-agent / js /gamma_check.js
karlexmarin's picture
v0.6: TAF Card hero+accordion UI + γ_check + Lean+Mathlib badges
28ac122
// γ predicted-vs-observed diagnostic — Padé closed-form + regime classifier.
// Pure functions ported from tools/taf/diagnose/gamma_check.py.
// All math is browser-only (no backend, no Python).
const SQRT2 = Math.SQRT2;
export function gammaPade(theta, T) {
if (!Number.isFinite(theta) || theta <= 0 || !Number.isFinite(T) || T < 0) return NaN;
const z = (T * SQRT2) / theta;
return (2 - z) / (2 + z);
}
export function thetaEffPade(theta, T) {
if (!Number.isFinite(theta) || !Number.isFinite(T)) return NaN;
return theta + T / SQRT2;
}
export function thetaEffObserved(gObs, T) {
if (!Number.isFinite(gObs) || !Number.isFinite(T) || T < 0) return NaN;
if (Math.abs(1 - gObs) < 1e-12) return Infinity;
return (T * SQRT2) / (1 - gObs);
}
export function efficiency(thEffObs, thEffPade) {
if (!Number.isFinite(thEffObs) || !Number.isFinite(thEffPade) || thEffPade === 0) return NaN;
return thEffObs / thEffPade;
}
export function deltaHCardy(thEffObs, thetaNominal) {
if (!Number.isFinite(thEffObs) || thEffObs <= 0) return NaN;
if (!Number.isFinite(thetaNominal) || thetaNominal <= 0) return NaN;
return Math.log(thEffObs / thetaNominal);
}
export function classifyRegime(eff, gObs, isRandom) {
if (!Number.isFinite(gObs)) return "unknown";
if (gObs > 1.05) return isRandom ? "swa" : "unknown";
if (!Number.isFinite(eff)) return "unknown";
if (eff < 0.01) return "fraud";
if (eff < 0.50) return "compressed";
if (eff > 1.50) return "overpade";
if (eff >= 0.85 && eff <= 1.15) return "normal";
return "unknown";
}
export function gammaCheckAll({ theta, T, gObs, isRandom }) {
const gPade = gammaPade(theta, T);
const thEffPade = thetaEffPade(theta, T);
const thEffObs = thetaEffObserved(gObs, T);
const eff = efficiency(thEffObs, thEffPade);
const dH = deltaHCardy(thEffObs, theta);
const regime = classifyRegime(eff, gObs, !!isRandom);
return {
gammaPade: gPade,
thetaEffPade: thEffPade,
thetaEffObs: thEffObs,
efficiency: eff,
deltaHCardy: dH,
regime,
};
}
export const REGIME_META = {
normal: { emoji: "✅", cls: "v-yes" },
fraud: { emoji: "🚨", cls: "v-no" },
compressed: { emoji: "📉", cls: "v-deg" },
overpade: { emoji: "📈", cls: "v-deg" },
swa: { emoji: "🪟", cls: "v-deg" },
unknown: { emoji: "❓", cls: "v-deg" },
};