Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // js/jitter.js
- /**
- * Ultra-sensitive jitter detector.
- *
- * Strategy:
- * 1) Normalize inputs to numbers, drop NaNs.
- * 2) Quantize values by a large base (default 65535, adjustable).
- * 3) Compute first-difference signs only when |Δq| >= minStep (default 1 tick).
- * 4) Jitter = fraction of sign flips between consecutive significant diffs.
- *
- * Tunables (via window.defaults.jitter):
- * - base: number (default 65535) // larger base => detect tinier wiggles
- * - minStep: int (default 1) // minimum quantized tick to count as movement
- *
- * Returns:
- * { jitter, jitterStr, flips, n, center, consideredSteps }
- */
- window.calculateJitter = function calculateJitter(history) {
- if (!Array.isArray(history) || history.length === 0) {
- return { jitter: 0, jitterStr: "0.0000", flips: 0, n: 0, center: NaN, consideredSteps: 0 };
- }
- // 1) Normalize to numeric values
- const values = [];
- for (const item of history) {
- const v = (item && typeof item === 'object' && 'floatValue' in item)
- ? Number(item.floatValue)
- : Number(item);
- if (Number.isFinite(v)) values.push(v);
- }
- const n = values.length;
- if (n < 2) {
- return { jitter: 0, jitterStr: "0.0000", flips: 0, n, center: n ? values[0] : NaN, consideredSteps: 0 };
- }
- // 2) Quantization settings (tune these to catch tiny wiggles)
- const base = Math.max(1, Math.floor(Number(window?.defaults?.jitter?.base ?? 65535)));
- const minStep = Math.max(1, Math.floor(Number(window?.defaults?.jitter?.minStep ?? 1)));
- // Quantize to integers so sub-float wiggles become detectable ticks
- const q = new Array(n);
- for (let i = 0; i < n; i++) q[i] = Math.round(values[i] * base);
- // 3) Significant first-difference signs (±1) when |Δq| >= minStep
- const signs = [];
- for (let i = 1; i < n; i++) {
- const dq = q[i] - q[i - 1];
- if (Math.abs(dq) >= minStep) {
- // Math.sign(dq) is ±1 here (never 0 because |dq| >= minStep >= 1)
- signs.push(Math.sign(dq));
- }
- }
- // If there were fewer than 2 significant steps, jitter is 0 by definition
- if (signs.length < 2) {
- const center0 = values.reduce((a, b) => a + b, 0) / n;
- return { jitter: 0, jitterStr: "0.0000", flips: 0, n, center: center0, consideredSteps: 0 };
- }
- // 4) Count sign flips between consecutive significant steps
- let flips = 0;
- for (let i = 1; i < signs.length; i++) {
- if (signs[i] !== signs[i - 1]) {
- flips++;
- }
- }
- const consideredSteps = signs.length - 1;
- const jitter = flips / consideredSteps;
- // Mean center (original units)
- const center = values.reduce((a, b) => a + b, 0) / n;
- const jitterStr = jitter.toFixed(4);
- return { jitter, jitterStr, flips, n, center, consideredSteps };
- };
Advertisement
Add Comment
Please, Sign In to add comment