time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

kde.js (1505B)


      1 import { nrd0 } from "./bandwidth.js";
      2 export const kde = ({ samples, outputLength, weight, kernelWidth, }) => {
      3     let xWidth = kernelWidth ?? nrd0(samples);
      4     samples = samples.filter((v) => Number.isFinite(v));
      5     const len = samples.length;
      6     if (len === 0 || xWidth === 0)
      7         return { usedWidth: xWidth, xs: [], ys: [] };
      8     const smin = samples[0];
      9     const srange = samples[len - 1] - smin;
     10     const wantedWidth = ((outputLength - 1) * xWidth) / (srange + 2 * xWidth);
     11     const width = Math.max(1, Math.floor(wantedWidth));
     12     const stepsInside = outputLength - 1 - 2 * width;
     13     const dx = srange / stepsInside;
     14     xWidth = width * dx;
     15     const min = smin - xWidth;
     16     const ysum = Array(outputLength + 2 * width).fill(0);
     17     const dxInv = 1 / dx;
     18     samples.forEach((x) => {
     19         const off = x - min;
     20         const index = Math.floor(off * dxInv);
     21         const leftWeight = off - index * dx;
     22         const rightWeight = dx - leftWeight;
     23         ysum[width + index + 1] += rightWeight;
     24         ysum[width + index + 2] += leftWeight;
     25     });
     26     const normalizer = weight / (xWidth * xWidth);
     27     const xs = Array(outputLength)
     28         .fill(0)
     29         .map((_, i) => min + i * dx);
     30     let dy = 0;
     31     let y = 0;
     32     const ys = xs.map((_, i) => {
     33         const ddy = ysum[i] - 2 * ysum[i + width] + ysum[i + 2 * width];
     34         dy += ddy;
     35         y += dy;
     36         return normalizer * y;
     37     });
     38     return { usedWidth: xWidth, xs, ys };
     39 };
     40 //# sourceMappingURL=kde.js.map