jargon

Jitter.js

Aug 15th, 2025
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // js/jitter.js
  2.  
  3. /**
  4.  * Ultra-sensitive jitter detector.
  5.  *
  6.  * Strategy:
  7.  *  1) Normalize inputs to numbers, drop NaNs.
  8.  *  2) Quantize values by a large base (default 65535, adjustable).
  9.  *  3) Compute first-difference signs only when |Δq| >= minStep (default 1 tick).
  10.  *  4) Jitter = fraction of sign flips between consecutive significant diffs.
  11.  *
  12.  * Tunables (via window.defaults.jitter):
  13.  *   - base: number  (default 65535)  // larger base => detect tinier wiggles
  14.  *   - minStep: int  (default 1)      // minimum quantized tick to count as movement
  15.  *
  16.  * Returns:
  17.  *   { jitter, jitterStr, flips, n, center, consideredSteps }
  18.  */
  19. window.calculateJitter = function calculateJitter(history) {
  20.   if (!Array.isArray(history) || history.length === 0) {
  21.     return { jitter: 0, jitterStr: "0.0000", flips: 0, n: 0, center: NaN, consideredSteps: 0 };
  22.   }
  23.  
  24.   // 1) Normalize to numeric values
  25.   const values = [];
  26.   for (const item of history) {
  27.     const v = (item && typeof item === 'object' && 'floatValue' in item)
  28.       ? Number(item.floatValue)
  29.       : Number(item);
  30.     if (Number.isFinite(v)) values.push(v);
  31.   }
  32.   const n = values.length;
  33.   if (n < 2) {
  34.     return { jitter: 0, jitterStr: "0.0000", flips: 0, n, center: n ? values[0] : NaN, consideredSteps: 0 };
  35.   }
  36.  
  37.   // 2) Quantization settings (tune these to catch tiny wiggles)
  38.   const base    = Math.max(1, Math.floor(Number(window?.defaults?.jitter?.base ?? 65535)));
  39.   const minStep = Math.max(1, Math.floor(Number(window?.defaults?.jitter?.minStep ?? 1)));
  40.  
  41.   // Quantize to integers so sub-float wiggles become detectable ticks
  42.   const q = new Array(n);
  43.   for (let i = 0; i < n; i++) q[i] = Math.round(values[i] * base);
  44.  
  45.   // 3) Significant first-difference signs (±1) when |Δq| >= minStep
  46.   const signs = [];
  47.   for (let i = 1; i < n; i++) {
  48.     const dq = q[i] - q[i - 1];
  49.     if (Math.abs(dq) >= minStep) {
  50.       // Math.sign(dq) is ±1 here (never 0 because |dq| >= minStep >= 1)
  51.       signs.push(Math.sign(dq));
  52.     }
  53.   }
  54.  
  55.   // If there were fewer than 2 significant steps, jitter is 0 by definition
  56.   if (signs.length < 2) {
  57.     const center0 = values.reduce((a, b) => a + b, 0) / n;
  58.     return { jitter: 0, jitterStr: "0.0000", flips: 0, n, center: center0, consideredSteps: 0 };
  59.   }
  60.  
  61.   // 4) Count sign flips between consecutive significant steps
  62.   let flips = 0;
  63.   for (let i = 1; i < signs.length; i++) {
  64.     if (signs[i] !== signs[i - 1]) {
  65.       flips++;
  66.     }
  67.   }
  68.  
  69.   const consideredSteps = signs.length - 1;
  70.   const jitter = flips / consideredSteps;
  71.  
  72.   // Mean center (original units)
  73.   const center = values.reduce((a, b) => a + b, 0) / n;
  74.   const jitterStr = jitter.toFixed(4);
  75.  
  76.   return { jitter, jitterStr, flips, n, center, consideredSteps };
  77. };
  78.  
Advertisement
Add Comment
Please, Sign In to add comment