squiggle/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res
2022-10-06 00:02:10 +04:00

34 lines
1.3 KiB
Plaintext

//The math here was taken from https://github.com/jasondavies/science.js/blob/master/src/stats/SampleSetDist_Bandwidth.js
let {iqr_percentile, nrd0_lo_denominator, one, nrd0_coef, nrd_coef, nrd_fractionalPower} = module(
MagicNumbers.SampleSetBandwidth
)
let len = x => E.FloatArray.length(x)->float_of_int
let iqr = x => {
let xArr = x->E.FloatArray.toArray
Jstat.percentile(xArr, iqr_percentile, true) -.
Jstat.percentile(xArr, 1.0 -. iqr_percentile, true)
}
// Silverman, B. W. (1986) Density Estimation. London: Chapman and Hall.
let nrd0 = x => {
let hi = Js_math.sqrt(Stdlib.Base.variance(x))
let lo = Js_math.minMany_float([hi, iqr(x) /. nrd0_lo_denominator])
let e = Js_math.abs_float(x->E.FloatArray.unsafe_get(1))
let lo' = switch (lo, hi, e) {
| (lo, _, _) if !Js.Float.isNaN(lo) => lo
| (_, hi, _) if !Js.Float.isNaN(hi) => hi
| (_, _, e) if !Js.Float.isNaN(e) => e
| _ => one
}
nrd0_coef *. lo' *. Js.Math.pow_float(~base=len(x), ~exp=nrd_fractionalPower)
}
// Scott, D. W. (1992) Multivariate Density Estimation: Theory, Practice, and Visualization. Wiley.
let nrd = x => {
let h = iqr(x) /. nrd0_lo_denominator
nrd_coef *.
Js.Math.min_float(Js.Math.sqrt(Stdlib.Base.variance(x)), h) *.
Js.Math.pow_float(~base=len(x), ~exp=nrd_fractionalPower)
}