vega-statistics
Advanced tools
Comparing version
@@ -16,6 +16,4 @@ (function (global, factory) { | ||
let index = -1; | ||
for (let value of values) { | ||
value = valueof(value, ++index, values); | ||
if (value != null && value !== '' && (value = +value) >= value) { | ||
@@ -44,3 +42,2 @@ yield value; | ||
let index = -1; | ||
for (let value of values) { | ||
@@ -59,3 +56,2 @@ if ((value = valueof(value, ++index, values)) != null && (value = +value) >= value) { | ||
let sum = 0; | ||
if (valueof === undefined) { | ||
@@ -71,3 +67,2 @@ for (let value of values) { | ||
let index = -1; | ||
for (let value of values) { | ||
@@ -81,3 +76,2 @@ if ((value = valueof(value, ++index, values)) != null && (value = +value) >= value) { | ||
} | ||
if (count > 1) return sum / (count - 1); | ||
@@ -106,3 +100,2 @@ } | ||
let max; | ||
if (valueof === undefined) { | ||
@@ -116,3 +109,2 @@ for (const value of values) { | ||
let index = -1; | ||
for (let value of values) { | ||
@@ -124,3 +116,2 @@ if ((value = valueof(value, ++index, values)) != null && (max < value || max === undefined && value >= value)) { | ||
} | ||
return max; | ||
@@ -131,3 +122,2 @@ } | ||
let min; | ||
if (valueof === undefined) { | ||
@@ -141,3 +131,2 @@ for (const value of values) { | ||
let index = -1; | ||
for (let value of values) { | ||
@@ -149,11 +138,13 @@ if ((value = valueof(value, ++index, values)) != null && (min > value || min === undefined && value >= value)) { | ||
} | ||
return min; | ||
} | ||
// Based on https://github.com/mourner/quickselect | ||
// ISC license, Copyright 2018 Vladimir Agafonkin. | ||
function quickselect(array, k, left = 0, right = array.length - 1, compare) { | ||
function quickselect(array, k, left = 0, right = Infinity, compare) { | ||
k = Math.floor(k); | ||
left = Math.floor(Math.max(0, left)); | ||
right = Math.floor(Math.min(array.length - 1, right)); | ||
if (!(left <= k && k <= right)) return array; | ||
compare = compare === undefined ? ascendingDefined : compareDefined(compare); | ||
while (right > left) { | ||
@@ -170,3 +161,2 @@ if (right - left > 600) { | ||
} | ||
const t = array[k]; | ||
@@ -177,11 +167,7 @@ let i = left; | ||
if (compare(array[right], t) > 0) swap(array, left, right); | ||
while (i < j) { | ||
swap(array, i, j), ++i, --j; | ||
while (compare(array[i], t) < 0) ++i; | ||
while (compare(array[j], t) > 0) --j; | ||
} | ||
if (compare(array[left], t) === 0) swap(array, left, j);else ++j, swap(array, j, right); | ||
@@ -191,6 +177,4 @@ if (j <= k) left = j + 1; | ||
} | ||
return array; | ||
} | ||
function swap(array, i, j) { | ||
@@ -204,21 +188,21 @@ const t = array[i]; | ||
values = Float64Array.from(numbers(values, valueof)); | ||
if (!(n = values.length)) return; | ||
if ((p = +p) <= 0 || n < 2) return min(values); | ||
if (!(n = values.length) || isNaN(p = +p)) return; | ||
if (p <= 0 || n < 2) return min(values); | ||
if (p >= 1) return max(values); | ||
var n, | ||
i = (n - 1) * p, | ||
i0 = Math.floor(i), | ||
value0 = max(quickselect(values, i0).subarray(0, i0 + 1)), | ||
value1 = min(values.subarray(i0 + 1)); | ||
i = (n - 1) * p, | ||
i0 = Math.floor(i), | ||
value0 = max(quickselect(values, i0).subarray(0, i0 + 1)), | ||
value1 = min(values.subarray(i0 + 1)); | ||
return value0 + (value1 - value0) * (i - i0); | ||
} | ||
function quantileSorted(values, p, valueof = number) { | ||
if (!(n = values.length)) return; | ||
if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values); | ||
if (!(n = values.length) || isNaN(p = +p)) return; | ||
if (p <= 0 || n < 2) return +valueof(values[0], 0, values); | ||
if (p >= 1) return +valueof(values[n - 1], n - 1, values); | ||
var n, | ||
i = (n - 1) * p, | ||
i0 = Math.floor(i), | ||
value0 = +valueof(values[i0], i0, values), | ||
value1 = +valueof(values[i0 + 1], i0 + 1, values); | ||
i = (n - 1) * p, | ||
i0 = Math.floor(i), | ||
value0 = +valueof(values[i0], i0, values), | ||
value1 = +valueof(values[i0 + 1], i0 + 1, values); | ||
return value0 + (value1 - value0) * (i - i0); | ||
@@ -232,5 +216,6 @@ } | ||
function quantiles (array, p, f) { | ||
const values = Float64Array.from(numbers$1(array, f)); // don't depend on return value from typed array sort call | ||
const values = Float64Array.from(numbers$1(array, f)); | ||
// don't depend on return value from typed array sort call | ||
// protects against undefined sort results in Safari (vega/vega-lite#4964) | ||
values.sort(ascending); | ||
@@ -244,10 +229,10 @@ return p.map(_ => quantileSorted(values, _)); | ||
// Scott, D. W. (1992) Multivariate Density Estimation: | ||
// Theory, Practice, and Visualization. Wiley. | ||
function estimateBandwidth (array, f) { | ||
const n = array.length, | ||
d = deviation(array, f), | ||
q = quartiles(array, f), | ||
h = (q[2] - q[0]) / 1.34, | ||
v = Math.min(d, h) || d || Math.abs(q[0]) || 1; | ||
d = deviation(array, f), | ||
q = quartiles(array, f), | ||
h = (q[2] - q[0]) / 1.34, | ||
v = Math.min(d, h) || d || Math.abs(q[0]) || 1; | ||
return 1.06 * v * Math.pow(n, -0.2); | ||
@@ -259,15 +244,14 @@ } | ||
const maxb = _.maxbins || 20, | ||
base = _.base || 10, | ||
logb = Math.log(base), | ||
div = _.divide || [5, 2]; | ||
base = _.base || 10, | ||
logb = Math.log(base), | ||
div = _.divide || [5, 2]; | ||
let min = _.extent[0], | ||
max = _.extent[1], | ||
step, | ||
level, | ||
minstep, | ||
v, | ||
i, | ||
n; | ||
max = _.extent[1], | ||
step, | ||
level, | ||
minstep, | ||
v, | ||
i, | ||
n; | ||
const span = _.span || max - min || Math.abs(min) || 1; | ||
if (_.step) { | ||
@@ -279,5 +263,3 @@ // if step size is explicitly given, use that | ||
v = span / maxb; | ||
for (i = 0, n = _.steps.length; i < n && _.steps[i] < v; ++i); | ||
step = _.steps[Math.max(0, i - 1)]; | ||
@@ -288,9 +270,10 @@ } else { | ||
minstep = _.minstep || 0; | ||
step = Math.max(minstep, Math.pow(base, Math.round(Math.log(span) / logb) - level)); // increase step size if too many bins | ||
step = Math.max(minstep, Math.pow(base, Math.round(Math.log(span) / logb) - level)); | ||
// increase step size if too many bins | ||
while (Math.ceil(span / step) > maxb) { | ||
step *= base; | ||
} // decrease step size if allowed | ||
} | ||
// decrease step size if allowed | ||
for (i = 0, n = div.length; i < n; ++i) { | ||
@@ -300,9 +283,8 @@ v = step / div[i]; | ||
} | ||
} // update precision, min and max | ||
} | ||
// update precision, min and max | ||
v = Math.log(step); | ||
const precision = v >= 0 ? 0 : ~~(-v / logb) + 1, | ||
eps = Math.pow(base, -precision - 1); | ||
eps = Math.pow(base, -precision - 1); | ||
if (_.nice || _.nice === undefined) { | ||
@@ -313,3 +295,2 @@ v = Math.floor(min / step + eps) * step; | ||
} | ||
return { | ||
@@ -330,6 +311,5 @@ start: min, | ||
const values = Float64Array.from(numbers$1(array, f)), | ||
n = values.length, | ||
m = samples; | ||
n = values.length, | ||
m = samples; | ||
let a, i, j, mu; | ||
for (j = 0, mu = Array(m); j < m; ++j) { | ||
@@ -339,6 +319,4 @@ for (a = 0, i = 0; i < n; ++i) { | ||
} | ||
mu[j] = a / n; | ||
} | ||
mu.sort(ascending); | ||
@@ -353,66 +331,54 @@ return [quantile(mu, alpha / 2), quantile(mu, 1 - alpha / 2)]; | ||
f = f || (_ => _); | ||
const n = array.length, | ||
v = new Float64Array(n); | ||
v = new Float64Array(n); | ||
let i = 0, | ||
j = 1, | ||
a = f(array[0]), | ||
b = a, | ||
w = a + step, | ||
x; | ||
j = 1, | ||
a = f(array[0]), | ||
b = a, | ||
w = a + step, | ||
x; | ||
for (; j < n; ++j) { | ||
x = f(array[j]); | ||
if (x >= w) { | ||
b = (a + b) / 2; | ||
for (; i < j; ++i) v[i] = b; | ||
w = x + step; | ||
a = x; | ||
} | ||
b = x; | ||
} | ||
b = (a + b) / 2; | ||
for (; i < j; ++i) v[i] = b; | ||
return smooth ? smoothing(v, step + step / 4) : v; | ||
} | ||
return smooth ? smoothing(v, step + step / 4) : v; | ||
} // perform smoothing to reduce variance | ||
// perform smoothing to reduce variance | ||
// swap points between "adjacent" stacks | ||
// Wilkinson defines adjacent as within step/4 units | ||
function smoothing(v, thresh) { | ||
const n = v.length; | ||
let a = 0, | ||
b = 1, | ||
c, | ||
d; // get left stack | ||
b = 1, | ||
c, | ||
d; | ||
// get left stack | ||
while (v[a] === v[b]) ++b; | ||
while (b < n) { | ||
// get right stack | ||
c = b + 1; | ||
while (v[b] === v[c]) ++c; | ||
while (v[b] === v[c]) ++c; // are stacks adjacent? | ||
// are stacks adjacent? | ||
// if so, compare sizes and swap as needed | ||
if (v[b] - v[b - 1] < thresh) { | ||
d = b + (a + c - b - b >> 1); | ||
while (d < b) v[d++] = v[b]; | ||
while (d > b) v[d--] = v[a]; | ||
} // update left stack indices | ||
} | ||
// update left stack indices | ||
a = b; | ||
b = c; | ||
} | ||
return v; | ||
@@ -435,3 +401,2 @@ } | ||
} | ||
let a, b, d; | ||
@@ -448,3 +413,2 @@ const dist = { | ||
}, | ||
max(_) { | ||
@@ -459,11 +423,8 @@ if (arguments.length) { | ||
}, | ||
sample() { | ||
return a + Math.floor(d * exports.random()); | ||
}, | ||
pdf(x) { | ||
return x === Math.floor(x) && x >= a && x < b ? 1 / d : 0; | ||
}, | ||
cdf(x) { | ||
@@ -473,7 +434,5 @@ const v = Math.floor(x); | ||
}, | ||
icdf(p) { | ||
return p >= 0 && p <= 1 ? a - 1 + Math.floor(p * d) : NaN; | ||
} | ||
}; | ||
@@ -491,6 +450,5 @@ return dist.min(min).max(max); | ||
let x = 0, | ||
y = 0, | ||
rds, | ||
c; | ||
y = 0, | ||
rds, | ||
c; | ||
if (nextSample === nextSample) { | ||
@@ -505,9 +463,6 @@ x = nextSample; | ||
} while (rds === 0 || rds > 1); | ||
c = Math.sqrt(-2 * Math.log(rds) / rds); // Box-Muller transform | ||
x *= c; | ||
nextSample = y * c; | ||
} | ||
return mean + x * stdev; | ||
@@ -519,5 +474,6 @@ } | ||
return Math.exp(-0.5 * z * z) / (stdev * SQRT2PI); | ||
} // Approximation from West (2009) | ||
} | ||
// Approximation from West (2009) | ||
// Better Approximations to Cumulative Normal Functions | ||
function cumulativeNormal(value, mean, stdev) { | ||
@@ -527,5 +483,4 @@ mean = mean || 0; | ||
const z = (value - mean) / stdev, | ||
Z = Math.abs(z); | ||
Z = Math.abs(z); | ||
let cd; | ||
if (Z > 37) { | ||
@@ -536,3 +491,2 @@ cd = 0; | ||
let sum; | ||
if (Z < 7.07106781186547) { | ||
@@ -563,13 +517,14 @@ sum = 3.52624965998911e-02 * Z + 0.700383064443688; | ||
} | ||
return z > 0 ? 1 - cd : cd; | ||
} // Approximation of Probit function using inverse error function. | ||
} | ||
// Approximation of Probit function using inverse error function. | ||
function quantileNormal(p, mean, stdev) { | ||
if (p < 0 || p > 1) return NaN; | ||
return (mean || 0) + (stdev == null ? 1 : stdev) * SQRT2 * erfinv(2 * p - 1); | ||
} // Approximate inverse error function. Implementation from "Approximating | ||
} | ||
// Approximate inverse error function. Implementation from "Approximating | ||
// the erfinv function" by Mike Giles, GPU Computing Gems, volume 2, 2010. | ||
// Ported from Apache Commons Math, http://www.apache.org/licenses/LICENSE-2.0 | ||
function erfinv(x) { | ||
@@ -581,4 +536,3 @@ // beware that the logarithm argument must be | ||
let w = -Math.log((1 - x) * (1 + x)), | ||
p; | ||
p; | ||
if (w < 6.25) { | ||
@@ -652,6 +606,4 @@ w -= 3.125; | ||
} | ||
return p * x; | ||
} | ||
function gaussian (mean, stdev) { | ||
@@ -668,3 +620,2 @@ let mu, sigma; | ||
}, | ||
stdev(_) { | ||
@@ -678,3 +629,2 @@ if (arguments.length) { | ||
}, | ||
sample: () => sampleNormal(mu, sigma), | ||
@@ -701,3 +651,2 @@ pdf: value => densityNormal(value, mu, sigma), | ||
}, | ||
bandwidth(_) { | ||
@@ -709,33 +658,24 @@ if (!arguments.length) return bandwidth; | ||
}, | ||
sample() { | ||
return support[~~(exports.random() * n)] + bandwidth * kernel.sample(); | ||
}, | ||
pdf(x) { | ||
let y = 0, | ||
i = 0; | ||
i = 0; | ||
for (; i < n; ++i) { | ||
y += kernel.pdf((x - support[i]) / bandwidth); | ||
} | ||
return y / bandwidth / n; | ||
}, | ||
cdf(x) { | ||
let y = 0, | ||
i = 0; | ||
i = 0; | ||
for (; i < n; ++i) { | ||
y += kernel.cdf((x - support[i]) / bandwidth); | ||
} | ||
return y / n; | ||
}, | ||
icdf() { | ||
throw Error('KDE icdf not supported.'); | ||
} | ||
}; | ||
@@ -774,3 +714,2 @@ return dist.data(support); | ||
}, | ||
stdev(_) { | ||
@@ -784,3 +723,2 @@ if (arguments.length) { | ||
}, | ||
sample: () => sampleLogNormal(mu, sigma), | ||
@@ -796,20 +734,15 @@ pdf: value => densityLogNormal(value, mu, sigma), | ||
let m = 0, | ||
w; | ||
w; | ||
function normalize(x) { | ||
const w = []; | ||
let sum = 0, | ||
i; | ||
i; | ||
for (i = 0; i < m; ++i) { | ||
sum += w[i] = x[i] == null ? 1 : +x[i]; | ||
} | ||
for (i = 0; i < m; ++i) { | ||
w[i] /= sum; | ||
} | ||
return w; | ||
} | ||
const dist = { | ||
@@ -821,6 +754,4 @@ weights(_) { | ||
} | ||
return weights; | ||
}, | ||
distributions(_) { | ||
@@ -835,15 +766,13 @@ if (arguments.length) { | ||
} | ||
return dist.weights(weights); | ||
} | ||
return dists; | ||
}, | ||
sample() { | ||
const r = exports.random(); | ||
let d = dists[m - 1], | ||
v = w[0], | ||
i = 0; // first select distribution | ||
v = w[0], | ||
i = 0; | ||
// first select distribution | ||
for (; i < m - 1; v += w[++i]) { | ||
@@ -854,34 +783,25 @@ if (r < v) { | ||
} | ||
} // then sample from it | ||
} | ||
// then sample from it | ||
return d.sample(); | ||
}, | ||
pdf(x) { | ||
let p = 0, | ||
i = 0; | ||
i = 0; | ||
for (; i < m; ++i) { | ||
p += w[i] * dists[i].pdf(x); | ||
} | ||
return p; | ||
}, | ||
cdf(x) { | ||
let p = 0, | ||
i = 0; | ||
i = 0; | ||
for (; i < m; ++i) { | ||
p += w[i] * dists[i].cdf(x); | ||
} | ||
return p; | ||
}, | ||
icdf() { | ||
throw Error('Mixture icdf not supported.'); | ||
} | ||
}; | ||
@@ -896,3 +816,2 @@ return dist.distributions(dists).weights(weights); | ||
} | ||
return min + (max - min) * exports.random(); | ||
@@ -905,3 +824,2 @@ } | ||
} | ||
return value >= min && value <= max ? 1 / (max - min) : 0; | ||
@@ -914,3 +832,2 @@ } | ||
} | ||
return value < min ? 0 : value > max ? 1 : (value - min) / (max - min); | ||
@@ -923,3 +840,2 @@ } | ||
} | ||
return p >= 0 && p <= 1 ? min + p * (max - min) : NaN; | ||
@@ -938,3 +854,2 @@ } | ||
}, | ||
max(_) { | ||
@@ -948,3 +863,2 @@ if (arguments.length) { | ||
}, | ||
sample: () => sampleUniform(a, b), | ||
@@ -955,3 +869,2 @@ pdf: value => densityUniform(value, a, b), | ||
}; | ||
if (max == null) { | ||
@@ -961,3 +874,2 @@ max = min == null ? 1 : min; | ||
} | ||
return dist.min(min).max(max); | ||
@@ -969,4 +881,4 @@ } | ||
const delta = uX2 - uX * uX, | ||
slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, | ||
intercept = uY - slope * uX; | ||
slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, | ||
intercept = uY - slope * uX; | ||
return [intercept, slope]; | ||
@@ -978,21 +890,19 @@ } | ||
let u = x(d), | ||
v = y(d); | ||
v = y(d); | ||
return u != null && (u = +u) >= u && v != null && (v = +v) >= v; | ||
}); | ||
if (sort) { | ||
data.sort((a, b) => x(a) - x(b)); | ||
} | ||
const n = data.length, | ||
X = new Float64Array(n), | ||
Y = new Float64Array(n); // extract values, calculate means | ||
X = new Float64Array(n), | ||
Y = new Float64Array(n); | ||
// extract values, calculate means | ||
let i = 0, | ||
ux = 0, | ||
uy = 0, | ||
xv, | ||
yv, | ||
d; | ||
ux = 0, | ||
uy = 0, | ||
xv, | ||
yv, | ||
d; | ||
for (d of data) { | ||
@@ -1004,5 +914,5 @@ X[i] = xv = +x(d); | ||
uy += (yv - uy) / i; | ||
} // mean center the data | ||
} | ||
// mean center the data | ||
for (i = 0; i < n; ++i) { | ||
@@ -1012,3 +922,2 @@ X[i] -= ux; | ||
} | ||
return [X, Y, ux, uy]; | ||
@@ -1018,9 +927,7 @@ } | ||
let i = -1, | ||
u, | ||
v; | ||
u, | ||
v; | ||
for (const d of data) { | ||
u = x(d); | ||
v = y(d); | ||
if (u != null && (u = +u) >= u && v != null && (v = +v) >= v) { | ||
@@ -1032,10 +939,10 @@ callback(u, v, ++i); | ||
// Adapted from d3-regression by Harry Stevens | ||
// License: https://github.com/HarryStevens/d3-regression/blob/master/LICENSE | ||
function rSquared (data, x, y, uY, predict) { | ||
let SSE = 0, | ||
SST = 0; | ||
SST = 0; | ||
visitPoints(data, x, y, (dx, dy) => { | ||
const sse = dy - predict(dx), | ||
sst = dy - uY; | ||
sst = dy - uY; | ||
SSE += sse * sse; | ||
@@ -1047,10 +954,10 @@ SST += sst * sst; | ||
// Adapted from d3-regression by Harry Stevens | ||
// License: https://github.com/HarryStevens/d3-regression/blob/master/LICENSE | ||
function linear (data, x, y) { | ||
let X = 0, | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0, | ||
n = 0; | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0, | ||
n = 0; | ||
visitPoints(data, x, y, (dx, dy) => { | ||
@@ -1063,6 +970,4 @@ ++n; | ||
}); | ||
const coef = ols(X, Y, XY, X2), | ||
predict = x => coef[0] + coef[1] * x; | ||
predict = x => coef[0] + coef[1] * x; | ||
return { | ||
@@ -1075,10 +980,10 @@ coef: coef, | ||
// Adapted from d3-regression by Harry Stevens | ||
// License: https://github.com/HarryStevens/d3-regression/blob/master/LICENSE | ||
function log (data, x, y) { | ||
let X = 0, | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0, | ||
n = 0; | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0, | ||
n = 0; | ||
visitPoints(data, x, y, (dx, dy) => { | ||
@@ -1092,6 +997,4 @@ ++n; | ||
}); | ||
const coef = ols(X, Y, XY, X2), | ||
predict = x => coef[0] + coef[1] * Math.log(x); | ||
predict = x => coef[0] + coef[1] * Math.log(x); | ||
return { | ||
@@ -1108,9 +1011,9 @@ coef: coef, | ||
let YL = 0, | ||
XY = 0, | ||
XYL = 0, | ||
X2Y = 0, | ||
n = 0, | ||
dx, | ||
ly, | ||
xy; | ||
XY = 0, | ||
XYL = 0, | ||
X2Y = 0, | ||
n = 0, | ||
dx, | ||
ly, | ||
xy; | ||
visitPoints(data, x, y, (_, dy) => { | ||
@@ -1125,6 +1028,4 @@ dx = xv[n++]; | ||
}); | ||
const [c0, c1] = ols(XY / uy, YL / uy, XYL / uy, X2Y / uy), | ||
predict = x => Math.exp(c0 + c1 * (x - ux)); | ||
predict = x => Math.exp(c0 + c1 * (x - ux)); | ||
return { | ||
@@ -1137,14 +1038,14 @@ coef: [Math.exp(c0 - c1 * ux), c1], | ||
// Adapted from d3-regression by Harry Stevens | ||
// License: https://github.com/HarryStevens/d3-regression/blob/master/LICENSE | ||
function pow (data, x, y) { | ||
let X = 0, | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0, | ||
YS = 0, | ||
n = 0; | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0, | ||
YS = 0, | ||
n = 0; | ||
visitPoints(data, x, y, (dx, dy) => { | ||
const lx = Math.log(dx), | ||
ly = Math.log(dy); | ||
ly = Math.log(dy); | ||
++n; | ||
@@ -1157,6 +1058,4 @@ X += (lx - X) / n; | ||
}); | ||
const coef = ols(X, Y, XY, X2), | ||
predict = x => coef[0] * Math.pow(x, coef[1]); | ||
predict = x => coef[0] * Math.pow(x, coef[1]); | ||
coef[0] = Math.exp(coef[0]); | ||
@@ -1172,13 +1071,12 @@ return { | ||
const [xv, yv, ux, uy] = points(data, x, y), | ||
n = xv.length; | ||
n = xv.length; | ||
let X2 = 0, | ||
X3 = 0, | ||
X4 = 0, | ||
XY = 0, | ||
X2Y = 0, | ||
i, | ||
dx, | ||
dy, | ||
x2; | ||
X3 = 0, | ||
X4 = 0, | ||
XY = 0, | ||
X2Y = 0, | ||
i, | ||
dx, | ||
dy, | ||
x2; | ||
for (i = 0; i < n;) { | ||
@@ -1194,14 +1092,13 @@ dx = xv[i]; | ||
} | ||
const X2X2 = X4 - X2 * X2, | ||
d = X2 * X2X2 - X3 * X3, | ||
a = (X2Y * X2 - XY * X3) / d, | ||
b = (XY * X2X2 - X2Y * X3) / d, | ||
c = -a * X2, | ||
predict = x => { | ||
x = x - ux; | ||
return a * x * x + b * x + c + uy; | ||
}; // transform coefficients back from mean-centered space | ||
d = X2 * X2X2 - X3 * X3, | ||
a = (X2Y * X2 - XY * X3) / d, | ||
b = (XY * X2X2 - X2Y * X3) / d, | ||
c = -a * X2, | ||
predict = x => { | ||
x = x - ux; | ||
return a * x * x + b * x + c + uy; | ||
}; | ||
// transform coefficients back from mean-centered space | ||
return { | ||
@@ -1214,2 +1111,3 @@ coef: [c - b * ux + a * ux * ux + uy, b - 2 * a * ux, a], | ||
// Adapted from d3-regression by Harry Stevens | ||
// License: https://github.com/HarryStevens/d3-regression/blob/master/LICENSE | ||
@@ -1219,3 +1117,2 @@ // ... which was adapted from regression-js by Tom Alexander | ||
// License: https://github.com/Tom-Alexander/regression-js/blob/master/LICENSE | ||
function poly (data, x, y, order) { | ||
@@ -1226,8 +1123,7 @@ // use more efficient methods for lower orders | ||
const [xv, yv, ux, uy] = points(data, x, y), | ||
n = xv.length, | ||
lhs = [], | ||
rhs = [], | ||
k = order + 1; | ||
n = xv.length, | ||
lhs = [], | ||
rhs = [], | ||
k = order + 1; | ||
let i, j, l, v, c; | ||
for (i = 0; i < k; ++i) { | ||
@@ -1237,6 +1133,4 @@ for (l = 0, v = 0; l < n; ++l) { | ||
} | ||
lhs.push(v); | ||
c = new Float64Array(k); | ||
for (j = 0; j < k; ++j) { | ||
@@ -1246,21 +1140,14 @@ for (l = 0, v = 0; l < n; ++l) { | ||
} | ||
c[j] = v; | ||
} | ||
rhs.push(c); | ||
} | ||
rhs.push(lhs); | ||
const coef = gaussianElimination(rhs), | ||
predict = x => { | ||
x -= ux; | ||
let y = uy + coef[0] + coef[1] * x + coef[2] * x * x; | ||
for (i = 3; i < k; ++i) y += coef[i] * Math.pow(x, i); | ||
return y; | ||
}; | ||
predict = x => { | ||
x -= ux; | ||
let y = uy + coef[0] + coef[1] * x + coef[2] * x * x; | ||
for (i = 3; i < k; ++i) y += coef[i] * Math.pow(x, i); | ||
return y; | ||
}; | ||
return { | ||
@@ -1272,10 +1159,10 @@ coef: uncenter(k, coef, -ux, uy), | ||
} | ||
function uncenter(k, a, x, y) { | ||
const z = Array(k); | ||
let i, j, v, c; // initialize to zero | ||
let i, j, v, c; | ||
for (i = 0; i < k; ++i) z[i] = 0; // polynomial expansion | ||
// initialize to zero | ||
for (i = 0; i < k; ++i) z[i] = 0; | ||
// polynomial expansion | ||
for (i = k - 1; i >= 0; --i) { | ||
@@ -1285,25 +1172,21 @@ v = a[i]; | ||
z[i] += v; | ||
for (j = 1; j <= i; ++j) { | ||
c *= (i + 1 - j) / j; // binomial coefficent | ||
z[i - j] += v * Math.pow(x, j) * c; | ||
} | ||
} // bias term | ||
} | ||
// bias term | ||
z[0] += y; | ||
return z; | ||
} // Given an array for a two-dimensional matrix and the polynomial order, | ||
} | ||
// Given an array for a two-dimensional matrix and the polynomial order, | ||
// solve A * x = b using Gaussian elimination. | ||
function gaussianElimination(matrix) { | ||
const n = matrix.length - 1, | ||
coef = []; | ||
coef = []; | ||
let i, j, k, r, t; | ||
for (i = 0; i < n; ++i) { | ||
r = i; // max row | ||
for (j = i + 1; j < n; ++j) { | ||
@@ -1314,3 +1197,2 @@ if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { | ||
} | ||
for (k = i; k < n + 1; ++k) { | ||
@@ -1321,3 +1203,2 @@ t = matrix[k][i]; | ||
} | ||
for (j = i + 1; j < n; ++j) { | ||
@@ -1329,13 +1210,9 @@ for (k = n; k >= i; k--) { | ||
} | ||
for (j = n - 1; j >= 0; --j) { | ||
t = 0; | ||
for (k = j + 1; k < n; ++k) { | ||
t += matrix[k][j] * coef[k]; | ||
} | ||
coef[j] = (matrix[n][j] - t) / matrix[j][j]; | ||
} | ||
return coef; | ||
@@ -1345,28 +1222,27 @@ } | ||
const maxiters = 2, | ||
epsilon = 1e-12; // Adapted from science.js by Jason Davies | ||
epsilon = 1e-12; | ||
// Adapted from science.js by Jason Davies | ||
// Source: https://github.com/jasondavies/science.js/blob/master/src/stats/loess.js | ||
// License: https://github.com/jasondavies/science.js/blob/master/LICENSE | ||
function loess (data, x, y, bandwidth) { | ||
const [xv, yv, ux, uy] = points(data, x, y, true), | ||
n = xv.length, | ||
bw = Math.max(2, ~~(bandwidth * n)), | ||
// # nearest neighbors | ||
yhat = new Float64Array(n), | ||
residuals = new Float64Array(n), | ||
robustWeights = new Float64Array(n).fill(1); | ||
n = xv.length, | ||
bw = Math.max(2, ~~(bandwidth * n)), | ||
// # nearest neighbors | ||
yhat = new Float64Array(n), | ||
residuals = new Float64Array(n), | ||
robustWeights = new Float64Array(n).fill(1); | ||
for (let iter = -1; ++iter <= maxiters;) { | ||
const interval = [0, bw - 1]; | ||
for (let i = 0; i < n; ++i) { | ||
const dx = xv[i], | ||
i0 = interval[0], | ||
i1 = interval[1], | ||
edge = dx - xv[i0] > xv[i1] - dx ? i0 : i1; | ||
i0 = interval[0], | ||
i1 = interval[1], | ||
edge = dx - xv[i0] > xv[i1] - dx ? i0 : i1; | ||
let W = 0, | ||
X = 0, | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0; | ||
X = 0, | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0; | ||
const denom = 1 / Math.abs(xv[edge] - dx || 1); // avoid singularity! | ||
@@ -1376,5 +1252,5 @@ | ||
const xk = xv[k], | ||
yk = yv[k], | ||
w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k], | ||
xkw = xk * w; | ||
yk = yv[k], | ||
w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k], | ||
xkw = xk * w; | ||
W += w; | ||
@@ -1385,5 +1261,5 @@ X += xkw; | ||
X2 += xk * xkw; | ||
} // linear regression fit | ||
} | ||
// linear regression fit | ||
const [a, b] = ols(X / W, Y / W, XY / W, X2 / W); | ||
@@ -1394,33 +1270,31 @@ yhat[i] = a + b * dx; | ||
} | ||
if (iter === maxiters) { | ||
break; | ||
} | ||
const medianResidual = median(residuals); | ||
if (Math.abs(medianResidual) < epsilon) break; | ||
for (let i = 0, arg, w; i < n; ++i) { | ||
arg = residuals[i] / (6 * medianResidual); // default to epsilon (rather than zero) for large deviations | ||
arg = residuals[i] / (6 * medianResidual); | ||
// default to epsilon (rather than zero) for large deviations | ||
// keeping weights tiny but non-zero prevents singularites | ||
robustWeights[i] = arg >= 1 ? epsilon : (w = 1 - arg * arg) * w; | ||
} | ||
} | ||
return output(xv, yhat, ux, uy); | ||
} // weighting kernel for local regression | ||
} | ||
// weighting kernel for local regression | ||
function tricube(x) { | ||
return (x = 1 - x * x * x) * x * x; | ||
} // advance sliding window interval of nearest neighbors | ||
} | ||
// advance sliding window interval of nearest neighbors | ||
function updateInterval(xv, i, interval) { | ||
const val = xv[i]; | ||
let left = interval[0], | ||
right = interval[1] + 1; | ||
if (right >= xv.length) return; // step right if distance to new right edge is <= distance to old left edge | ||
right = interval[1] + 1; | ||
if (right >= xv.length) return; | ||
// step right if distance to new right edge is <= distance to old left edge | ||
// step when distance is equal to ensure movement over duplicate x values | ||
while (i > left && xv[right] - val <= val - xv[left]) { | ||
@@ -1431,17 +1305,15 @@ interval[0] = ++left; | ||
} | ||
} // generate smoothed output points | ||
} | ||
// generate smoothed output points | ||
// average points with repeated x values | ||
function output(xv, yhat, ux, uy) { | ||
const n = xv.length, | ||
out = []; | ||
out = []; | ||
let i = 0, | ||
cnt = 0, | ||
prev = [], | ||
v; | ||
cnt = 0, | ||
prev = [], | ||
v; | ||
for (; i < n; ++i) { | ||
v = xv[i] + ux; | ||
if (prev[0] === v) { | ||
@@ -1458,3 +1330,2 @@ // average output values via online update | ||
} | ||
prev[1] += uy; | ||
@@ -1465,16 +1336,15 @@ return out; | ||
// subdivide up to accuracy of 0.5 degrees | ||
const MIN_RADIANS = 0.5 * Math.PI / 180; // Adaptively sample an interpolated function over a domain extent | ||
const MIN_RADIANS = 0.5 * Math.PI / 180; | ||
// Adaptively sample an interpolated function over a domain extent | ||
function sampleCurve (f, extent, minSteps, maxSteps) { | ||
minSteps = minSteps || 25; | ||
maxSteps = Math.max(minSteps, maxSteps || 200); | ||
const point = x => [x, f(x)], | ||
minX = extent[0], | ||
maxX = extent[1], | ||
span = maxX - minX, | ||
stop = span / maxSteps, | ||
prev = [point(minX)], | ||
next = []; | ||
minX = extent[0], | ||
maxX = extent[1], | ||
span = maxX - minX, | ||
stop = span / maxSteps, | ||
prev = [point(minX)], | ||
next = []; | ||
if (minSteps === maxSteps) { | ||
@@ -1485,3 +1355,2 @@ // no adaptation, sample uniform grid directly and return | ||
} | ||
prev.push(point(maxX)); | ||
@@ -1493,3 +1362,2 @@ return prev; | ||
next.push(point(maxX)); | ||
for (let i = minSteps; --i > 0;) { | ||
@@ -1499,3 +1367,2 @@ next.push(point(minX + i / minSteps * span)); | ||
} | ||
let p0 = prev[0]; | ||
@@ -1505,3 +1372,2 @@ let p1 = next[next.length - 1]; | ||
const sy = scaleY(p0[1], next); | ||
while (p1) { | ||
@@ -1511,3 +1377,2 @@ // midpoint for potential curve subdivision | ||
const dx = pm[0] - p0[0] >= stop; | ||
if (dx && angleDelta(p0, pm, p1, sx, sy) > MIN_RADIANS) { | ||
@@ -1525,9 +1390,6 @@ // maximum resolution has not yet been met, and | ||
} | ||
p1 = next[next.length - 1]; | ||
} | ||
return prev; | ||
} | ||
function scaleY(init, points) { | ||
@@ -1537,3 +1399,2 @@ let ymin = init; | ||
const n = points.length; | ||
for (let i = 0; i < n; ++i) { | ||
@@ -1544,9 +1405,7 @@ const y = points[i][1]; | ||
} | ||
return 1 / (ymax - ymin); | ||
} | ||
function angleDelta(p, q, r, sx, sy) { | ||
const a0 = Math.atan2(sy * (r[1] - p[1]), sx * (r[0] - p[0])), | ||
a1 = Math.atan2(sy * (q[1] - p[1]), sx * (q[0] - p[0])); | ||
a1 = Math.atan2(sy * (q[1] - p[1]), sx * (q[0] - p[0])); | ||
return Math.abs(a0 - a1); | ||
@@ -1590,4 +1449,2 @@ } | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
})); |
@@ -1,2 +0,2 @@ | ||
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).vega={})}(this,(function(t){"use strict";function*n(t,n){if(null==n)for(let n of t)null!=n&&""!==n&&(n=+n)>=n&&(yield n);else{let e=-1;for(let r of t)r=n(r,++e,t),null!=r&&""!==r&&(r=+r)>=r&&(yield r)}}function e(t,n){return null==t||null==n?NaN:t<n?-1:t>n?1:t>=n?0:NaN}function r(t){return null===t?NaN:+t}function o(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:e;if(t===e)return l;if("function"!=typeof t)throw new TypeError("compare is not a function");return(n,e)=>{const r=t(n,e);return r||0===r?r:(0===t(e,e))-(0===t(n,n))}}function l(t,n){return(null==t||!(t>=t))-(null==n||!(n>=n))||(t<n?-1:t>n?1:0)}function u(t,n){let e;if(void 0===n)for(const n of t)null!=n&&(e<n||void 0===e&&n>=n)&&(e=n);else{let r=-1;for(let o of t)null!=(o=n(o,++r,t))&&(e<o||void 0===e&&o>=o)&&(e=o)}return e}function f(t,n){let e;if(void 0===n)for(const n of t)null!=n&&(e>n||void 0===e&&n>=n)&&(e=n);else{let r=-1;for(let o of t)null!=(o=n(o,++r,t))&&(e>o||void 0===e&&o>=o)&&(e=o)}return e}function a(t,n){let e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:t.length-1,u=arguments.length>4?arguments[4]:void 0;for(u=void 0===u?l:o(u);r>e;){if(r-e>600){const o=r-e+1,l=n-e+1,f=Math.log(o),i=.5*Math.exp(2*f/3),s=.5*Math.sqrt(f*i*(o-i)/o)*(l-o/2<0?-1:1);a(t,n,Math.max(e,Math.floor(n-l*i/o+s)),Math.min(r,Math.floor(n+(o-l)*i/o+s)),u)}const o=t[n];let l=e,f=r;for(i(t,e,n),u(t[r],o)>0&&i(t,e,r);l<f;){for(i(t,l,f),++l,--f;u(t[l],o)<0;)++l;for(;u(t[f],o)>0;)--f}0===u(t[e],o)?i(t,e,f):(++f,i(t,f,r)),f<=n&&(e=f+1),n<=f&&(r=f-1)}return t}function i(t,n,e){const r=t[n];t[n]=t[e],t[e]=r}function s(t,n,e){if(t=Float64Array.from(function*(t,n){if(void 0===n)for(let n of t)null!=n&&(n=+n)>=n&&(yield n);else{let e=-1;for(let r of t)null!=(r=n(r,++e,t))&&(r=+r)>=r&&(yield r)}}(t,e)),r=t.length){if((n=+n)<=0||r<2)return f(t);if(n>=1)return u(t);var r,o=(r-1)*n,l=Math.floor(o),i=u(a(t,l).subarray(0,l+1));return i+(f(t.subarray(l+1))-i)*(o-l)}}function c(t,o,l){const u=Float64Array.from(n(t,l));return u.sort(e),o.map((t=>function(t,n){let e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:r;if(o=t.length){if((n=+n)<=0||o<2)return+e(t[0],0,t);if(n>=1)return+e(t[o-1],o-1,t);var o,l=(o-1)*n,u=Math.floor(l),f=+e(t[u],u,t);return f+(+e(t[u+1],u+1,t)-f)*(l-u)}}(u,t)))}function h(t,n){return c(t,[.25,.5,.75],n)}function d(t,n){const e=t.length,r=function(t,n){const e=function(t,n){let e,r=0,o=0,l=0;if(void 0===n)for(let n of t)null!=n&&(n=+n)>=n&&(e=n-o,o+=e/++r,l+=e*(n-o));else{let u=-1;for(let f of t)null!=(f=n(f,++u,t))&&(f=+f)>=f&&(e=f-o,o+=e/++r,l+=e*(f-o))}if(r>1)return l/(r-1)}(t,n);return e?Math.sqrt(e):e}(t,n),o=h(t,n),l=(o[2]-o[0])/1.34;return 1.06*(Math.min(r,l)||r||Math.abs(o[0])||1)*Math.pow(e,-.2)}t.random=Math.random;const p=Math.sqrt(2*Math.PI),m=Math.SQRT2;let M=NaN;function g(n,e){n=n||0,e=null==e?1:e;let r,o,l=0,u=0;if(M==M)l=M,M=NaN;else{do{l=2*t.random()-1,u=2*t.random()-1,r=l*l+u*u}while(0===r||r>1);o=Math.sqrt(-2*Math.log(r)/r),l*=o,M=u*o}return n+l*e}function b(t,n,e){const r=(t-(n||0))/(e=null==e?1:e);return Math.exp(-.5*r*r)/(e*p)}function v(t,n,e){const r=(t-(n=n||0))/(e=null==e?1:e),o=Math.abs(r);let l;if(o>37)l=0;else{const t=Math.exp(-o*o/2);let n;o<7.07106781186547?(n=.0352624965998911*o+.700383064443688,n=n*o+6.37396220353165,n=n*o+33.912866078383,n=n*o+112.079291497871,n=n*o+221.213596169931,n=n*o+220.206867912376,l=t*n,n=.0883883476483184*o+1.75566716318264,n=n*o+16.064177579207,n=n*o+86.7807322029461,n=n*o+296.564248779674,n=n*o+637.333633378831,n=n*o+793.826512519948,n=n*o+440.413735824752,l/=n):(n=o+.65,n=o+4/n,n=o+3/n,n=o+2/n,n=o+1/n,l=t/n/2.506628274631)}return r>0?1-l:l}function y(t,n,e){return t<0||t>1?NaN:(n||0)+(null==e?1:e)*m*function(t){let n,e=-Math.log((1-t)*(1+t));e<6.25?(e-=3.125,n=-364441206401782e-35,n=n*e-16850591381820166e-35,n=128584807152564e-32+n*e,n=11157877678025181e-33+n*e,n=n*e-1333171662854621e-31,n=20972767875968562e-33+n*e,n=6637638134358324e-30+n*e,n=n*e-4054566272975207e-29,n=n*e-8151934197605472e-29,n=26335093153082323e-28+n*e,n=n*e-12975133253453532e-27,n=n*e-5415412054294628e-26,n=1.0512122733215323e-9+n*e,n=n*e-4.112633980346984e-9,n=n*e-2.9070369957882005e-8,n=4.2347877827932404e-7+n*e,n=n*e-13654692000834679e-22,n=n*e-13882523362786469e-21,n=.00018673420803405714+n*e,n=n*e-.000740702534166267,n=n*e-.006033670871430149,n=.24015818242558962+n*e,n=1.6536545626831027+n*e):e<16?(e=Math.sqrt(e)-3.25,n=2.2137376921775787e-9,n=9.075656193888539e-8+n*e,n=n*e-2.7517406297064545e-7,n=1.8239629214389228e-8+n*e,n=15027403968909828e-22+n*e,n=n*e-4013867526981546e-21,n=29234449089955446e-22+n*e,n=12475304481671779e-21+n*e,n=n*e-47318229009055734e-21,n=6828485145957318e-20+n*e,n=24031110387097894e-21+n*e,n=n*e-.0003550375203628475,n=.0009532893797373805+n*e,n=n*e-.0016882755560235047,n=.002491442096107851+n*e,n=n*e-.003751208507569241,n=.005370914553590064+n*e,n=1.0052589676941592+n*e,n=3.0838856104922208+n*e):Number.isFinite(e)?(e=Math.sqrt(e)-5,n=-27109920616438573e-27,n=n*e-2.555641816996525e-10,n=1.5076572693500548e-9+n*e,n=n*e-3.789465440126737e-9,n=7.61570120807834e-9+n*e,n=n*e-1.496002662714924e-8,n=2.914795345090108e-8+n*e,n=n*e-6.771199775845234e-8,n=2.2900482228026655e-7+n*e,n=n*e-9.9298272942317e-7,n=4526062597223154e-21+n*e,n=n*e-1968177810553167e-20,n=7599527703001776e-20+n*e,n=n*e-.00021503011930044477,n=n*e-.00013871931833623122,n=1.0103004648645344+n*e,n=4.849906401408584+n*e):n=1/0;return n*t}(2*t-1)}function N(t,n){let e,r;const o={mean(t){return arguments.length?(e=t||0,o):e},stdev(t){return arguments.length?(r=null==t?1:t,o):r},sample:()=>g(e,r),pdf:t=>b(t,e,r),cdf:t=>v(t,e,r),icdf:t=>y(t,e,r)};return o.mean(t).stdev(n)}function w(t,n){return t=t||0,n=null==n?1:n,Math.exp(t+g()*n)}function x(t,n,e){if(t<=0)return 0;n=n||0,e=null==e?1:e;const r=(Math.log(t)-n)/e;return Math.exp(-.5*r*r)/(e*p*t)}function q(t,n,e){return v(Math.log(t),n,e)}function A(t,n,e){return Math.exp(y(t,n,e))}function F(n,e){return null==e&&(e=null==n?1:n,n=0),n+(e-n)*t.random()}function L(t,n,e){return null==e&&(e=null==n?1:n,n=0),t>=n&&t<=e?1/(e-n):0}function S(t,n,e){return null==e&&(e=null==n?1:n,n=0),t<n?0:t>e?1:(t-n)/(e-n)}function E(t,n,e){return null==e&&(e=null==n?1:n,n=0),t>=0&&t<=1?n+t*(e-n):NaN}function P(t,n,e,r){const o=r-t*t,l=Math.abs(o)<1e-24?0:(e-t*n)/o;return[n-l*t,l]}function U(t,n,e,r){t=t.filter((t=>{let r=n(t),o=e(t);return null!=r&&(r=+r)>=r&&null!=o&&(o=+o)>=o})),r&&t.sort(((t,e)=>n(t)-n(e)));const o=t.length,l=new Float64Array(o),u=new Float64Array(o);let f,a,i,s=0,c=0,h=0;for(i of t)l[s]=f=+n(i),u[s]=a=+e(i),++s,c+=(f-c)/s,h+=(a-h)/s;for(s=0;s<o;++s)l[s]-=c,u[s]-=h;return[l,u,c,h]}function I(t,n,e,r){let o,l,u=-1;for(const f of t)o=n(f),l=e(f),null!=o&&(o=+o)>=o&&null!=l&&(l=+l)>=l&&r(o,l,++u)}function T(t,n,e,r,o){let l=0,u=0;return I(t,n,e,((t,n)=>{const e=n-o(t),f=n-r;l+=e*e,u+=f*f})),1-l/u}function k(t,n,e){let r=0,o=0,l=0,u=0,f=0;I(t,n,e,((t,n)=>{++f,r+=(t-r)/f,o+=(n-o)/f,l+=(t*n-l)/f,u+=(t*t-u)/f}));const a=P(r,o,l,u),i=t=>a[0]+a[1]*t;return{coef:a,predict:i,rSquared:T(t,n,e,o,i)}}function C(t,n,e){const[r,o,l,u]=U(t,n,e),f=r.length;let a,i,s,c,h=0,d=0,p=0,m=0,M=0;for(a=0;a<f;)i=r[a],s=o[a++],c=i*i,h+=(c-h)/a,d+=(c*i-d)/a,p+=(c*c-p)/a,m+=(i*s-m)/a,M+=(c*s-M)/a;const g=p-h*h,b=h*g-d*d,v=(M*h-m*d)/b,y=(m*g-M*d)/b,N=-v*h,w=t=>v*(t-=l)*t+y*t+N+u;return{coef:[N-y*l+v*l*l+u,y-2*v*l,v],predict:w,rSquared:T(t,n,e,u,w)}}function D(t,n,e,r){const o=Array(t);let l,u,f,a;for(l=0;l<t;++l)o[l]=0;for(l=t-1;l>=0;--l)for(f=n[l],a=1,o[l]+=f,u=1;u<=l;++u)a*=(l+1-u)/u,o[l-u]+=f*Math.pow(e,u)*a;return o[0]+=r,o}function R(t){return(t=1-t*t*t)*t*t}function j(t,n,e){const r=t[n];let o=e[0],l=e[1]+1;if(!(l>=t.length))for(;n>o&&t[l]-r<=r-t[o];)e[0]=++o,e[1]=l,++l}const K=.5*Math.PI/180;function Q(t,n,e,r,o){const l=Math.atan2(o*(e[1]-t[1]),r*(e[0]-t[0])),u=Math.atan2(o*(n[1]-t[1]),r*(n[0]-t[0]));return Math.abs(l-u)}t.bandwidthNRD=d,t.bin=function(t){const n=t.maxbins||20,e=t.base||10,r=Math.log(e),o=t.divide||[5,2];let l,u,f,a,i,s,c=t.extent[0],h=t.extent[1];const d=t.span||h-c||Math.abs(c)||1;if(t.step)l=t.step;else if(t.steps){for(a=d/n,i=0,s=t.steps.length;i<s&&t.steps[i]<a;++i);l=t.steps[Math.max(0,i-1)]}else{for(u=Math.ceil(Math.log(n)/r),f=t.minstep||0,l=Math.max(f,Math.pow(e,Math.round(Math.log(d)/r)-u));Math.ceil(d/l)>n;)l*=e;for(i=0,s=o.length;i<s;++i)a=l/o[i],a>=f&&d/a<=n&&(l=a)}a=Math.log(l);const p=a>=0?0:1+~~(-a/r),m=Math.pow(e,-p-1);return(t.nice||void 0===t.nice)&&(a=Math.floor(c/l+m)*l,c=c<a?a-l:a,h=Math.ceil(h/l)*l),{start:c,stop:h===c?c+l:h,step:l}},t.bootstrapCI=function(r,o,l,u){if(!r.length)return[void 0,void 0];const f=Float64Array.from(n(r,u)),a=f.length,i=o;let c,h,d,p;for(d=0,p=Array(i);d<i;++d){for(c=0,h=0;h<a;++h)c+=f[~~(t.random()*a)];p[d]=c/a}return p.sort(e),[s(p,l/2),s(p,1-l/2)]},t.cumulativeLogNormal=q,t.cumulativeNormal=v,t.cumulativeUniform=S,t.densityLogNormal=x,t.densityNormal=b,t.densityUniform=L,t.dotbin=function(t,n,e,r){r=r||(t=>t);const o=t.length,l=new Float64Array(o);let u,f=0,a=1,i=r(t[0]),s=i,c=i+n;for(;a<o;++a){if(u=r(t[a]),u>=c){for(s=(i+s)/2;f<a;++f)l[f]=s;c=u+n,i=u}s=u}for(s=(i+s)/2;f<a;++f)l[f]=s;return e?function(t,n){const e=t.length;let r,o,l=0,u=1;for(;t[l]===t[u];)++u;for(;u<e;){for(r=u+1;t[u]===t[r];)++r;if(t[u]-t[u-1]<n){for(o=u+(l+r-u-u>>1);o<u;)t[o++]=t[u];for(;o>u;)t[o--]=t[l]}l=u,u=r}return t}(l,n+n/4):l},t.quantileLogNormal=A,t.quantileNormal=y,t.quantileUniform=E,t.quantiles=c,t.quartiles=h,t.randomInteger=function(n,e){let r,o,l;null==e&&(e=n,n=0);const u={min(t){return arguments.length?(r=t||0,l=o-r,u):r},max(t){return arguments.length?(o=t||0,l=o-r,u):o},sample:()=>r+Math.floor(l*t.random()),pdf:t=>t===Math.floor(t)&&t>=r&&t<o?1/l:0,cdf(t){const n=Math.floor(t);return n<r?0:n>=o?1:(n-r+1)/l},icdf:t=>t>=0&&t<=1?r-1+Math.floor(t*l):NaN};return u.min(n).max(e)},t.randomKDE=function(n,e){const r=N();let o=0;const l={data(t){return arguments.length?(n=t,o=t?t.length:0,l.bandwidth(e)):n},bandwidth(t){return arguments.length?(!(e=t)&&n&&(e=d(n)),l):e},sample:()=>n[~~(t.random()*o)]+e*r.sample(),pdf(t){let l=0,u=0;for(;u<o;++u)l+=r.pdf((t-n[u])/e);return l/e/o},cdf(t){let l=0,u=0;for(;u<o;++u)l+=r.cdf((t-n[u])/e);return l/o},icdf(){throw Error("KDE icdf not supported.")}};return l.data(n)},t.randomLCG=function(t){return function(){return(t=(1103515245*t+12345)%2147483647)/2147483647}},t.randomLogNormal=function(t,n){let e,r;const o={mean(t){return arguments.length?(e=t||0,o):e},stdev(t){return arguments.length?(r=null==t?1:t,o):r},sample:()=>w(e,r),pdf:t=>x(t,e,r),cdf:t=>q(t,e,r),icdf:t=>A(t,e,r)};return o.mean(t).stdev(n)},t.randomMixture=function(n,e){let r,o=0;const l={weights(t){return arguments.length?(r=function(t){const n=[];let e,r=0;for(e=0;e<o;++e)r+=n[e]=null==t[e]?1:+t[e];for(e=0;e<o;++e)n[e]/=r;return n}(e=t||[]),l):e},distributions(t){return arguments.length?(t?(o=t.length,n=t):(o=0,n=[]),l.weights(e)):n},sample(){const e=t.random();let l=n[o-1],u=r[0],f=0;for(;f<o-1;u+=r[++f])if(e<u){l=n[f];break}return l.sample()},pdf(t){let e=0,l=0;for(;l<o;++l)e+=r[l]*n[l].pdf(t);return e},cdf(t){let e=0,l=0;for(;l<o;++l)e+=r[l]*n[l].cdf(t);return e},icdf(){throw Error("Mixture icdf not supported.")}};return l.distributions(n).weights(e)},t.randomNormal=N,t.randomUniform=function(t,n){let e,r;const o={min(t){return arguments.length?(e=t||0,o):e},max(t){return arguments.length?(r=null==t?1:t,o):r},sample:()=>F(e,r),pdf:t=>L(t,e,r),cdf:t=>S(t,e,r),icdf:t=>E(t,e,r)};return null==n&&(n=null==t?1:t,t=0),o.min(t).max(n)},t.regressionExp=function(t,n,e){const[r,o,l,u]=U(t,n,e);let f,a,i,s=0,c=0,h=0,d=0,p=0;I(t,n,e,((t,n)=>{f=r[p++],a=Math.log(n),i=f*n,s+=(n*a-s)/p,c+=(i-c)/p,h+=(i*a-h)/p,d+=(f*i-d)/p}));const[m,M]=P(c/u,s/u,h/u,d/u),g=t=>Math.exp(m+M*(t-l));return{coef:[Math.exp(m-M*l),M],predict:g,rSquared:T(t,n,e,u,g)}},t.regressionLinear=k,t.regressionLoess=function(t,n,e,r){const[o,l,u,f]=U(t,n,e,!0),a=o.length,i=Math.max(2,~~(r*a)),c=new Float64Array(a),h=new Float64Array(a),d=new Float64Array(a).fill(1);for(let t=-1;++t<=2;){const n=[0,i-1];for(let t=0;t<a;++t){const e=o[t],r=n[0],u=n[1],f=e-o[r]>o[u]-e?r:u;let a=0,i=0,s=0,p=0,m=0;const M=1/Math.abs(o[f]-e||1);for(let t=r;t<=u;++t){const n=o[t],r=l[t],u=R(Math.abs(e-n)*M)*d[t],f=n*u;a+=u,i+=f,s+=r*u,p+=r*f,m+=n*f}const[g,b]=P(i/a,s/a,p/a,m/a);c[t]=g+b*e,h[t]=Math.abs(l[t]-c[t]),j(o,t+1,n)}if(2===t)break;const e=s(h,.5,void 0);if(Math.abs(e)<1e-12)break;for(let t,n,r=0;r<a;++r)t=h[r]/(6*e),d[r]=t>=1?1e-12:(n=1-t*t)*n}return function(t,n,e,r){const o=t.length,l=[];let u,f=0,a=0,i=[];for(;f<o;++f)u=t[f]+e,i[0]===u?i[1]+=(n[f]-i[1])/++a:(a=0,i[1]+=r,i=[u,n[f]],l.push(i));return i[1]+=r,l}(o,c,u,f)},t.regressionLog=function(t,n,e){let r=0,o=0,l=0,u=0,f=0;I(t,n,e,((t,n)=>{++f,t=Math.log(t),r+=(t-r)/f,o+=(n-o)/f,l+=(t*n-l)/f,u+=(t*t-u)/f}));const a=P(r,o,l,u),i=t=>a[0]+a[1]*Math.log(t);return{coef:a,predict:i,rSquared:T(t,n,e,o,i)}},t.regressionPoly=function(t,n,e,r){if(1===r)return k(t,n,e);if(2===r)return C(t,n,e);const[o,l,u,f]=U(t,n,e),a=o.length,i=[],s=[],c=r+1;let h,d,p,m,M;for(h=0;h<c;++h){for(p=0,m=0;p<a;++p)m+=Math.pow(o[p],h)*l[p];for(i.push(m),M=new Float64Array(c),d=0;d<c;++d){for(p=0,m=0;p<a;++p)m+=Math.pow(o[p],h+d);M[d]=m}s.push(M)}s.push(i);const g=function(t){const n=t.length-1,e=[];let r,o,l,u,f;for(r=0;r<n;++r){for(u=r,o=r+1;o<n;++o)Math.abs(t[r][o])>Math.abs(t[r][u])&&(u=o);for(l=r;l<n+1;++l)f=t[l][r],t[l][r]=t[l][u],t[l][u]=f;for(o=r+1;o<n;++o)for(l=n;l>=r;l--)t[l][o]-=t[l][r]*t[r][o]/t[r][r]}for(o=n-1;o>=0;--o){for(f=0,l=o+1;l<n;++l)f+=t[l][o]*e[l];e[o]=(t[n][o]-f)/t[o][o]}return e}(s),b=t=>{t-=u;let n=f+g[0]+g[1]*t+g[2]*t*t;for(h=3;h<c;++h)n+=g[h]*Math.pow(t,h);return n};return{coef:D(c,g,-u,f),predict:b,rSquared:T(t,n,e,f,b)}},t.regressionPow=function(t,n,e){let r=0,o=0,l=0,u=0,f=0,a=0;I(t,n,e,((t,n)=>{const e=Math.log(t),i=Math.log(n);++a,r+=(e-r)/a,o+=(i-o)/a,l+=(e*i-l)/a,u+=(e*e-u)/a,f+=(n-f)/a}));const i=P(r,o,l,u),s=t=>i[0]*Math.pow(t,i[1]);return i[0]=Math.exp(i[0]),{coef:i,predict:s,rSquared:T(t,n,e,f,s)}},t.regressionQuad=C,t.sampleCurve=function(t,n,e,r){e=e||25,r=Math.max(e,r||200);const o=n=>[n,t(n)],l=n[0],u=n[1],f=u-l,a=f/r,i=[o(l)],s=[];if(e===r){for(let t=1;t<r;++t)i.push(o(l+t/e*f));return i.push(o(u)),i}s.push(o(u));for(let t=e;--t>0;)s.push(o(l+t/e*f));let c=i[0],h=s[s.length-1];const d=1/f,p=function(t,n){let e=t,r=t;const o=n.length;for(let t=0;t<o;++t){const o=n[t][1];o<e&&(e=o),o>r&&(r=o)}return 1/(r-e)}(c[1],s);for(;h;){const t=o((c[0]+h[0])/2);t[0]-c[0]>=a&&Q(c,t,h,d,p)>K?s.push(t):(c=h,i.push(h),s.pop()),h=s[s.length-1]}return i},t.sampleLogNormal=w,t.sampleNormal=g,t.sampleUniform=F,t.setRandom=function(n){t.random=n},Object.defineProperty(t,"__esModule",{value:!0})})); | ||
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).vega={})}(this,(function(t){"use strict";function*n(t,n){if(null==n)for(let n of t)null!=n&&""!==n&&(n=+n)>=n&&(yield n);else{let e=-1;for(let r of t)r=n(r,++e,t),null!=r&&""!==r&&(r=+r)>=r&&(yield r)}}function e(t,n){return null==t||null==n?NaN:t<n?-1:t>n?1:t>=n?0:NaN}function r(t){return null===t?NaN:+t}function o(t,n){return(null==t||!(t>=t))-(null==n||!(n>=n))||(t<n?-1:t>n?1:0)}function l(t,n){let e;if(void 0===n)for(const n of t)null!=n&&(e<n||void 0===e&&n>=n)&&(e=n);else{let r=-1;for(let o of t)null!=(o=n(o,++r,t))&&(e<o||void 0===e&&o>=o)&&(e=o)}return e}function u(t,n){let e;if(void 0===n)for(const n of t)null!=n&&(e>n||void 0===e&&n>=n)&&(e=n);else{let r=-1;for(let o of t)null!=(o=n(o,++r,t))&&(e>o||void 0===e&&o>=o)&&(e=o)}return e}function f(t,n){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,l=arguments.length>3&&void 0!==arguments[3]?arguments[3]:1/0,u=arguments.length>4?arguments[4]:void 0;if(n=Math.floor(n),r=Math.floor(Math.max(0,r)),l=Math.floor(Math.min(t.length-1,l)),!(r<=n&&n<=l))return t;for(u=void 0===u?o:function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:e;if(t===e)return o;if("function"!=typeof t)throw new TypeError("compare is not a function");return(n,e)=>{const r=t(n,e);return r||0===r?r:(0===t(e,e))-(0===t(n,n))}}(u);l>r;){if(l-r>600){const e=l-r+1,o=n-r+1,a=Math.log(e),i=.5*Math.exp(2*a/3),s=.5*Math.sqrt(a*i*(e-i)/e)*(o-e/2<0?-1:1);f(t,n,Math.max(r,Math.floor(n-o*i/e+s)),Math.min(l,Math.floor(n+(e-o)*i/e+s)),u)}const e=t[n];let o=r,i=l;for(a(t,r,n),u(t[l],e)>0&&a(t,r,l);o<i;){for(a(t,o,i),++o,--i;u(t[o],e)<0;)++o;for(;u(t[i],e)>0;)--i}0===u(t[r],e)?a(t,r,i):(++i,a(t,i,l)),i<=n&&(r=i+1),n<=i&&(l=i-1)}return t}function a(t,n,e){const r=t[n];t[n]=t[e],t[e]=r}function i(t,n,e){if(t=Float64Array.from(function*(t,n){if(void 0===n)for(let n of t)null!=n&&(n=+n)>=n&&(yield n);else{let e=-1;for(let r of t)null!=(r=n(r,++e,t))&&(r=+r)>=r&&(yield r)}}(t,e)),(r=t.length)&&!isNaN(n=+n)){if(n<=0||r<2)return u(t);if(n>=1)return l(t);var r,o=(r-1)*n,a=Math.floor(o),i=l(f(t,a).subarray(0,a+1));return i+(u(t.subarray(a+1))-i)*(o-a)}}function s(t,o,l){const u=Float64Array.from(n(t,l));return u.sort(e),o.map((t=>function(t,n){let e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:r;if((o=t.length)&&!isNaN(n=+n)){if(n<=0||o<2)return+e(t[0],0,t);if(n>=1)return+e(t[o-1],o-1,t);var o,l=(o-1)*n,u=Math.floor(l),f=+e(t[u],u,t);return f+(+e(t[u+1],u+1,t)-f)*(l-u)}}(u,t)))}function c(t,n){return s(t,[.25,.5,.75],n)}function h(t,n){const e=t.length,r=function(t,n){const e=function(t,n){let e,r=0,o=0,l=0;if(void 0===n)for(let n of t)null!=n&&(n=+n)>=n&&(e=n-o,o+=e/++r,l+=e*(n-o));else{let u=-1;for(let f of t)null!=(f=n(f,++u,t))&&(f=+f)>=f&&(e=f-o,o+=e/++r,l+=e*(f-o))}if(r>1)return l/(r-1)}(t,n);return e?Math.sqrt(e):e}(t,n),o=c(t,n),l=(o[2]-o[0])/1.34;return 1.06*(Math.min(r,l)||r||Math.abs(o[0])||1)*Math.pow(e,-.2)}t.random=Math.random;const d=Math.sqrt(2*Math.PI),p=Math.SQRT2;let M=NaN;function m(n,e){n=n||0,e=null==e?1:e;let r,o,l=0,u=0;if(M==M)l=M,M=NaN;else{do{l=2*t.random()-1,u=2*t.random()-1,r=l*l+u*u}while(0===r||r>1);o=Math.sqrt(-2*Math.log(r)/r),l*=o,M=u*o}return n+l*e}function g(t,n,e){const r=(t-(n||0))/(e=null==e?1:e);return Math.exp(-.5*r*r)/(e*d)}function N(t,n,e){const r=(t-(n=n||0))/(e=null==e?1:e),o=Math.abs(r);let l;if(o>37)l=0;else{const t=Math.exp(-o*o/2);let n;o<7.07106781186547?(n=.0352624965998911*o+.700383064443688,n=n*o+6.37396220353165,n=n*o+33.912866078383,n=n*o+112.079291497871,n=n*o+221.213596169931,n=n*o+220.206867912376,l=t*n,n=.0883883476483184*o+1.75566716318264,n=n*o+16.064177579207,n=n*o+86.7807322029461,n=n*o+296.564248779674,n=n*o+637.333633378831,n=n*o+793.826512519948,n=n*o+440.413735824752,l/=n):(n=o+.65,n=o+4/n,n=o+3/n,n=o+2/n,n=o+1/n,l=t/n/2.506628274631)}return r>0?1-l:l}function b(t,n,e){return t<0||t>1?NaN:(n||0)+(null==e?1:e)*p*function(t){let n,e=-Math.log((1-t)*(1+t));e<6.25?(e-=3.125,n=-364441206401782e-35,n=n*e-16850591381820166e-35,n=128584807152564e-32+n*e,n=11157877678025181e-33+n*e,n=n*e-1333171662854621e-31,n=20972767875968562e-33+n*e,n=6637638134358324e-30+n*e,n=n*e-4054566272975207e-29,n=n*e-8151934197605472e-29,n=26335093153082323e-28+n*e,n=n*e-12975133253453532e-27,n=n*e-5415412054294628e-26,n=1.0512122733215323e-9+n*e,n=n*e-4.112633980346984e-9,n=n*e-2.9070369957882005e-8,n=4.2347877827932404e-7+n*e,n=n*e-13654692000834679e-22,n=n*e-13882523362786469e-21,n=.00018673420803405714+n*e,n=n*e-.000740702534166267,n=n*e-.006033670871430149,n=.24015818242558962+n*e,n=1.6536545626831027+n*e):e<16?(e=Math.sqrt(e)-3.25,n=2.2137376921775787e-9,n=9.075656193888539e-8+n*e,n=n*e-2.7517406297064545e-7,n=1.8239629214389228e-8+n*e,n=15027403968909828e-22+n*e,n=n*e-4013867526981546e-21,n=29234449089955446e-22+n*e,n=12475304481671779e-21+n*e,n=n*e-47318229009055734e-21,n=6828485145957318e-20+n*e,n=24031110387097894e-21+n*e,n=n*e-.0003550375203628475,n=.0009532893797373805+n*e,n=n*e-.0016882755560235047,n=.002491442096107851+n*e,n=n*e-.003751208507569241,n=.005370914553590064+n*e,n=1.0052589676941592+n*e,n=3.0838856104922208+n*e):Number.isFinite(e)?(e=Math.sqrt(e)-5,n=-27109920616438573e-27,n=n*e-2.555641816996525e-10,n=1.5076572693500548e-9+n*e,n=n*e-3.789465440126737e-9,n=7.61570120807834e-9+n*e,n=n*e-1.496002662714924e-8,n=2.914795345090108e-8+n*e,n=n*e-6.771199775845234e-8,n=2.2900482228026655e-7+n*e,n=n*e-9.9298272942317e-7,n=4526062597223154e-21+n*e,n=n*e-1968177810553167e-20,n=7599527703001776e-20+n*e,n=n*e-.00021503011930044477,n=n*e-.00013871931833623122,n=1.0103004648645344+n*e,n=4.849906401408584+n*e):n=1/0;return n*t}(2*t-1)}function v(t,n){let e,r;const o={mean(t){return arguments.length?(e=t||0,o):e},stdev(t){return arguments.length?(r=null==t?1:t,o):r},sample:()=>m(e,r),pdf:t=>g(t,e,r),cdf:t=>N(t,e,r),icdf:t=>b(t,e,r)};return o.mean(t).stdev(n)}function x(t,n){return t=t||0,n=null==n?1:n,Math.exp(t+m()*n)}function y(t,n,e){if(t<=0)return 0;n=n||0,e=null==e?1:e;const r=(Math.log(t)-n)/e;return Math.exp(-.5*r*r)/(e*d*t)}function w(t,n,e){return N(Math.log(t),n,e)}function q(t,n,e){return Math.exp(b(t,n,e))}function A(n,e){return null==e&&(e=null==n?1:n,n=0),n+(e-n)*t.random()}function F(t,n,e){return null==e&&(e=null==n?1:n,n=0),t>=n&&t<=e?1/(e-n):0}function L(t,n,e){return null==e&&(e=null==n?1:n,n=0),t<n?0:t>e?1:(t-n)/(e-n)}function S(t,n,e){return null==e&&(e=null==n?1:n,n=0),t>=0&&t<=1?n+t*(e-n):NaN}function E(t,n,e,r){const o=r-t*t,l=Math.abs(o)<1e-24?0:(e-t*n)/o;return[n-l*t,l]}function U(t,n,e,r){t=t.filter((t=>{let r=n(t),o=e(t);return null!=r&&(r=+r)>=r&&null!=o&&(o=+o)>=o})),r&&t.sort(((t,e)=>n(t)-n(e)));const o=t.length,l=new Float64Array(o),u=new Float64Array(o);let f,a,i,s=0,c=0,h=0;for(i of t)l[s]=f=+n(i),u[s]=a=+e(i),++s,c+=(f-c)/s,h+=(a-h)/s;for(s=0;s<o;++s)l[s]-=c,u[s]-=h;return[l,u,c,h]}function I(t,n,e,r){let o,l,u=-1;for(const f of t)o=n(f),l=e(f),null!=o&&(o=+o)>=o&&null!=l&&(l=+l)>=l&&r(o,l,++u)}function P(t,n,e,r,o){let l=0,u=0;return I(t,n,e,((t,n)=>{const e=n-o(t),f=n-r;l+=e*e,u+=f*f})),1-l/u}function T(t,n,e){let r=0,o=0,l=0,u=0,f=0;I(t,n,e,((t,n)=>{++f,r+=(t-r)/f,o+=(n-o)/f,l+=(t*n-l)/f,u+=(t*t-u)/f}));const a=E(r,o,l,u),i=t=>a[0]+a[1]*t;return{coef:a,predict:i,rSquared:P(t,n,e,o,i)}}function k(t,n,e){const[r,o,l,u]=U(t,n,e),f=r.length;let a,i,s,c,h=0,d=0,p=0,M=0,m=0;for(a=0;a<f;)i=r[a],s=o[a++],c=i*i,h+=(c-h)/a,d+=(c*i-d)/a,p+=(c*c-p)/a,M+=(i*s-M)/a,m+=(c*s-m)/a;const g=p-h*h,N=h*g-d*d,b=(m*h-M*d)/N,v=(M*g-m*d)/N,x=-b*h,y=t=>b*(t-=l)*t+v*t+x+u;return{coef:[x-v*l+b*l*l+u,v-2*b*l,b],predict:y,rSquared:P(t,n,e,u,y)}}function C(t,n,e,r){const o=Array(t);let l,u,f,a;for(l=0;l<t;++l)o[l]=0;for(l=t-1;l>=0;--l)for(f=n[l],a=1,o[l]+=f,u=1;u<=l;++u)a*=(l+1-u)/u,o[l-u]+=f*Math.pow(e,u)*a;return o[0]+=r,o}const D=2,R=1e-12;function K(t){return(t=1-t*t*t)*t*t}function Q(t,n,e){const r=t[n];let o=e[0],l=e[1]+1;if(!(l>=t.length))for(;n>o&&t[l]-r<=r-t[o];)e[0]=++o,e[1]=l,++l}const j=.5*Math.PI/180;function G(t,n,e,r,o){const l=Math.atan2(o*(e[1]-t[1]),r*(e[0]-t[0])),u=Math.atan2(o*(n[1]-t[1]),r*(n[0]-t[0]));return Math.abs(l-u)}t.bandwidthNRD=h,t.bin=function(t){const n=t.maxbins||20,e=t.base||10,r=Math.log(e),o=t.divide||[5,2];let l,u,f,a,i,s,c=t.extent[0],h=t.extent[1];const d=t.span||h-c||Math.abs(c)||1;if(t.step)l=t.step;else if(t.steps){for(a=d/n,i=0,s=t.steps.length;i<s&&t.steps[i]<a;++i);l=t.steps[Math.max(0,i-1)]}else{for(u=Math.ceil(Math.log(n)/r),f=t.minstep||0,l=Math.max(f,Math.pow(e,Math.round(Math.log(d)/r)-u));Math.ceil(d/l)>n;)l*=e;for(i=0,s=o.length;i<s;++i)a=l/o[i],a>=f&&d/a<=n&&(l=a)}a=Math.log(l);const p=a>=0?0:1+~~(-a/r),M=Math.pow(e,-p-1);return(t.nice||void 0===t.nice)&&(a=Math.floor(c/l+M)*l,c=c<a?a-l:a,h=Math.ceil(h/l)*l),{start:c,stop:h===c?c+l:h,step:l}},t.bootstrapCI=function(r,o,l,u){if(!r.length)return[void 0,void 0];const f=Float64Array.from(n(r,u)),a=f.length,s=o;let c,h,d,p;for(d=0,p=Array(s);d<s;++d){for(c=0,h=0;h<a;++h)c+=f[~~(t.random()*a)];p[d]=c/a}return p.sort(e),[i(p,l/2),i(p,1-l/2)]},t.cumulativeLogNormal=w,t.cumulativeNormal=N,t.cumulativeUniform=L,t.densityLogNormal=y,t.densityNormal=g,t.densityUniform=F,t.dotbin=function(t,n,e,r){r=r||(t=>t);const o=t.length,l=new Float64Array(o);let u,f=0,a=1,i=r(t[0]),s=i,c=i+n;for(;a<o;++a){if(u=r(t[a]),u>=c){for(s=(i+s)/2;f<a;++f)l[f]=s;c=u+n,i=u}s=u}for(s=(i+s)/2;f<a;++f)l[f]=s;return e?function(t,n){const e=t.length;let r,o,l=0,u=1;for(;t[l]===t[u];)++u;for(;u<e;){for(r=u+1;t[u]===t[r];)++r;if(t[u]-t[u-1]<n){for(o=u+(l+r-u-u>>1);o<u;)t[o++]=t[u];for(;o>u;)t[o--]=t[l]}l=u,u=r}return t}(l,n+n/4):l},t.quantileLogNormal=q,t.quantileNormal=b,t.quantileUniform=S,t.quantiles=s,t.quartiles=c,t.randomInteger=function(n,e){let r,o,l;null==e&&(e=n,n=0);const u={min(t){return arguments.length?(r=t||0,l=o-r,u):r},max(t){return arguments.length?(o=t||0,l=o-r,u):o},sample:()=>r+Math.floor(l*t.random()),pdf:t=>t===Math.floor(t)&&t>=r&&t<o?1/l:0,cdf(t){const n=Math.floor(t);return n<r?0:n>=o?1:(n-r+1)/l},icdf:t=>t>=0&&t<=1?r-1+Math.floor(t*l):NaN};return u.min(n).max(e)},t.randomKDE=function(n,e){const r=v();let o=0;const l={data(t){return arguments.length?(n=t,o=t?t.length:0,l.bandwidth(e)):n},bandwidth(t){return arguments.length?(!(e=t)&&n&&(e=h(n)),l):e},sample:()=>n[~~(t.random()*o)]+e*r.sample(),pdf(t){let l=0,u=0;for(;u<o;++u)l+=r.pdf((t-n[u])/e);return l/e/o},cdf(t){let l=0,u=0;for(;u<o;++u)l+=r.cdf((t-n[u])/e);return l/o},icdf(){throw Error("KDE icdf not supported.")}};return l.data(n)},t.randomLCG=function(t){return function(){return(t=(1103515245*t+12345)%2147483647)/2147483647}},t.randomLogNormal=function(t,n){let e,r;const o={mean(t){return arguments.length?(e=t||0,o):e},stdev(t){return arguments.length?(r=null==t?1:t,o):r},sample:()=>x(e,r),pdf:t=>y(t,e,r),cdf:t=>w(t,e,r),icdf:t=>q(t,e,r)};return o.mean(t).stdev(n)},t.randomMixture=function(n,e){let r,o=0;const l={weights(t){return arguments.length?(r=function(t){const n=[];let e,r=0;for(e=0;e<o;++e)r+=n[e]=null==t[e]?1:+t[e];for(e=0;e<o;++e)n[e]/=r;return n}(e=t||[]),l):e},distributions(t){return arguments.length?(t?(o=t.length,n=t):(o=0,n=[]),l.weights(e)):n},sample(){const e=t.random();let l=n[o-1],u=r[0],f=0;for(;f<o-1;u+=r[++f])if(e<u){l=n[f];break}return l.sample()},pdf(t){let e=0,l=0;for(;l<o;++l)e+=r[l]*n[l].pdf(t);return e},cdf(t){let e=0,l=0;for(;l<o;++l)e+=r[l]*n[l].cdf(t);return e},icdf(){throw Error("Mixture icdf not supported.")}};return l.distributions(n).weights(e)},t.randomNormal=v,t.randomUniform=function(t,n){let e,r;const o={min(t){return arguments.length?(e=t||0,o):e},max(t){return arguments.length?(r=null==t?1:t,o):r},sample:()=>A(e,r),pdf:t=>F(t,e,r),cdf:t=>L(t,e,r),icdf:t=>S(t,e,r)};return null==n&&(n=null==t?1:t,t=0),o.min(t).max(n)},t.regressionExp=function(t,n,e){const[r,o,l,u]=U(t,n,e);let f,a,i,s=0,c=0,h=0,d=0,p=0;I(t,n,e,((t,n)=>{f=r[p++],a=Math.log(n),i=f*n,s+=(n*a-s)/p,c+=(i-c)/p,h+=(i*a-h)/p,d+=(f*i-d)/p}));const[M,m]=E(c/u,s/u,h/u,d/u),g=t=>Math.exp(M+m*(t-l));return{coef:[Math.exp(M-m*l),m],predict:g,rSquared:P(t,n,e,u,g)}},t.regressionLinear=T,t.regressionLoess=function(t,n,e,r){const[o,l,u,f]=U(t,n,e,!0),a=o.length,s=Math.max(2,~~(r*a)),c=new Float64Array(a),h=new Float64Array(a),d=new Float64Array(a).fill(1);for(let t=-1;++t<=D;){const n=[0,s-1];for(let t=0;t<a;++t){const e=o[t],r=n[0],u=n[1],f=e-o[r]>o[u]-e?r:u;let a=0,i=0,s=0,p=0,M=0;const m=1/Math.abs(o[f]-e||1);for(let t=r;t<=u;++t){const n=o[t],r=l[t],u=K(Math.abs(e-n)*m)*d[t],f=n*u;a+=u,i+=f,s+=r*u,p+=r*f,M+=n*f}const[g,N]=E(i/a,s/a,p/a,M/a);c[t]=g+N*e,h[t]=Math.abs(l[t]-c[t]),Q(o,t+1,n)}if(t===D)break;const e=i(h,.5,void 0);if(Math.abs(e)<R)break;for(let t,n,r=0;r<a;++r)t=h[r]/(6*e),d[r]=t>=1?R:(n=1-t*t)*n}return function(t,n,e,r){const o=t.length,l=[];let u,f=0,a=0,i=[];for(;f<o;++f)u=t[f]+e,i[0]===u?i[1]+=(n[f]-i[1])/++a:(a=0,i[1]+=r,i=[u,n[f]],l.push(i));return i[1]+=r,l}(o,c,u,f)},t.regressionLog=function(t,n,e){let r=0,o=0,l=0,u=0,f=0;I(t,n,e,((t,n)=>{++f,t=Math.log(t),r+=(t-r)/f,o+=(n-o)/f,l+=(t*n-l)/f,u+=(t*t-u)/f}));const a=E(r,o,l,u),i=t=>a[0]+a[1]*Math.log(t);return{coef:a,predict:i,rSquared:P(t,n,e,o,i)}},t.regressionPoly=function(t,n,e,r){if(1===r)return T(t,n,e);if(2===r)return k(t,n,e);const[o,l,u,f]=U(t,n,e),a=o.length,i=[],s=[],c=r+1;let h,d,p,M,m;for(h=0;h<c;++h){for(p=0,M=0;p<a;++p)M+=Math.pow(o[p],h)*l[p];for(i.push(M),m=new Float64Array(c),d=0;d<c;++d){for(p=0,M=0;p<a;++p)M+=Math.pow(o[p],h+d);m[d]=M}s.push(m)}s.push(i);const g=function(t){const n=t.length-1,e=[];let r,o,l,u,f;for(r=0;r<n;++r){for(u=r,o=r+1;o<n;++o)Math.abs(t[r][o])>Math.abs(t[r][u])&&(u=o);for(l=r;l<n+1;++l)f=t[l][r],t[l][r]=t[l][u],t[l][u]=f;for(o=r+1;o<n;++o)for(l=n;l>=r;l--)t[l][o]-=t[l][r]*t[r][o]/t[r][r]}for(o=n-1;o>=0;--o){for(f=0,l=o+1;l<n;++l)f+=t[l][o]*e[l];e[o]=(t[n][o]-f)/t[o][o]}return e}(s),N=t=>{t-=u;let n=f+g[0]+g[1]*t+g[2]*t*t;for(h=3;h<c;++h)n+=g[h]*Math.pow(t,h);return n};return{coef:C(c,g,-u,f),predict:N,rSquared:P(t,n,e,f,N)}},t.regressionPow=function(t,n,e){let r=0,o=0,l=0,u=0,f=0,a=0;I(t,n,e,((t,n)=>{const e=Math.log(t),i=Math.log(n);++a,r+=(e-r)/a,o+=(i-o)/a,l+=(e*i-l)/a,u+=(e*e-u)/a,f+=(n-f)/a}));const i=E(r,o,l,u),s=t=>i[0]*Math.pow(t,i[1]);return i[0]=Math.exp(i[0]),{coef:i,predict:s,rSquared:P(t,n,e,f,s)}},t.regressionQuad=k,t.sampleCurve=function(t,n,e,r){e=e||25,r=Math.max(e,r||200);const o=n=>[n,t(n)],l=n[0],u=n[1],f=u-l,a=f/r,i=[o(l)],s=[];if(e===r){for(let t=1;t<r;++t)i.push(o(l+t/e*f));return i.push(o(u)),i}s.push(o(u));for(let t=e;--t>0;)s.push(o(l+t/e*f));let c=i[0],h=s[s.length-1];const d=1/f,p=function(t,n){let e=t,r=t;const o=n.length;for(let t=0;t<o;++t){const o=n[t][1];o<e&&(e=o),o>r&&(r=o)}return 1/(r-e)}(c[1],s);for(;h;){const t=o((c[0]+h[0])/2);t[0]-c[0]>=a&&G(c,t,h,d,p)>j?s.push(t):(c=h,i.push(h),s.pop()),h=s[s.length-1]}return i},t.sampleLogNormal=x,t.sampleNormal=m,t.sampleUniform=A,t.setRandom=function(n){t.random=n}})); | ||
//# sourceMappingURL=vega-statistics.min.js.map |
@@ -12,6 +12,4 @@ import { ascending, quantileSorted, deviation, quantile, median } from 'd3-array'; | ||
let index = -1; | ||
for (let value of values) { | ||
value = valueof(value, ++index, values); | ||
if (value != null && value !== '' && (value = +value) >= value) { | ||
@@ -25,5 +23,6 @@ yield value; | ||
function quantiles (array, p, f) { | ||
const values = Float64Array.from(numbers(array, f)); // don't depend on return value from typed array sort call | ||
const values = Float64Array.from(numbers(array, f)); | ||
// don't depend on return value from typed array sort call | ||
// protects against undefined sort results in Safari (vega/vega-lite#4964) | ||
values.sort(ascending); | ||
@@ -37,10 +36,10 @@ return p.map(_ => quantileSorted(values, _)); | ||
// Scott, D. W. (1992) Multivariate Density Estimation: | ||
// Theory, Practice, and Visualization. Wiley. | ||
function estimateBandwidth (array, f) { | ||
const n = array.length, | ||
d = deviation(array, f), | ||
q = quartiles(array, f), | ||
h = (q[2] - q[0]) / 1.34, | ||
v = Math.min(d, h) || d || Math.abs(q[0]) || 1; | ||
d = deviation(array, f), | ||
q = quartiles(array, f), | ||
h = (q[2] - q[0]) / 1.34, | ||
v = Math.min(d, h) || d || Math.abs(q[0]) || 1; | ||
return 1.06 * v * Math.pow(n, -0.2); | ||
@@ -52,15 +51,14 @@ } | ||
const maxb = _.maxbins || 20, | ||
base = _.base || 10, | ||
logb = Math.log(base), | ||
div = _.divide || [5, 2]; | ||
base = _.base || 10, | ||
logb = Math.log(base), | ||
div = _.divide || [5, 2]; | ||
let min = _.extent[0], | ||
max = _.extent[1], | ||
step, | ||
level, | ||
minstep, | ||
v, | ||
i, | ||
n; | ||
max = _.extent[1], | ||
step, | ||
level, | ||
minstep, | ||
v, | ||
i, | ||
n; | ||
const span = _.span || max - min || Math.abs(min) || 1; | ||
if (_.step) { | ||
@@ -72,5 +70,3 @@ // if step size is explicitly given, use that | ||
v = span / maxb; | ||
for (i = 0, n = _.steps.length; i < n && _.steps[i] < v; ++i); | ||
step = _.steps[Math.max(0, i - 1)]; | ||
@@ -81,9 +77,10 @@ } else { | ||
minstep = _.minstep || 0; | ||
step = Math.max(minstep, Math.pow(base, Math.round(Math.log(span) / logb) - level)); // increase step size if too many bins | ||
step = Math.max(minstep, Math.pow(base, Math.round(Math.log(span) / logb) - level)); | ||
// increase step size if too many bins | ||
while (Math.ceil(span / step) > maxb) { | ||
step *= base; | ||
} // decrease step size if allowed | ||
} | ||
// decrease step size if allowed | ||
for (i = 0, n = div.length; i < n; ++i) { | ||
@@ -93,9 +90,8 @@ v = step / div[i]; | ||
} | ||
} // update precision, min and max | ||
} | ||
// update precision, min and max | ||
v = Math.log(step); | ||
const precision = v >= 0 ? 0 : ~~(-v / logb) + 1, | ||
eps = Math.pow(base, -precision - 1); | ||
eps = Math.pow(base, -precision - 1); | ||
if (_.nice || _.nice === undefined) { | ||
@@ -106,3 +102,2 @@ v = Math.floor(min / step + eps) * step; | ||
} | ||
return { | ||
@@ -123,6 +118,5 @@ start: min, | ||
const values = Float64Array.from(numbers(array, f)), | ||
n = values.length, | ||
m = samples; | ||
n = values.length, | ||
m = samples; | ||
let a, i, j, mu; | ||
for (j = 0, mu = Array(m); j < m; ++j) { | ||
@@ -132,6 +126,4 @@ for (a = 0, i = 0; i < n; ++i) { | ||
} | ||
mu[j] = a / n; | ||
} | ||
mu.sort(ascending); | ||
@@ -146,66 +138,54 @@ return [quantile(mu, alpha / 2), quantile(mu, 1 - alpha / 2)]; | ||
f = f || (_ => _); | ||
const n = array.length, | ||
v = new Float64Array(n); | ||
v = new Float64Array(n); | ||
let i = 0, | ||
j = 1, | ||
a = f(array[0]), | ||
b = a, | ||
w = a + step, | ||
x; | ||
j = 1, | ||
a = f(array[0]), | ||
b = a, | ||
w = a + step, | ||
x; | ||
for (; j < n; ++j) { | ||
x = f(array[j]); | ||
if (x >= w) { | ||
b = (a + b) / 2; | ||
for (; i < j; ++i) v[i] = b; | ||
w = x + step; | ||
a = x; | ||
} | ||
b = x; | ||
} | ||
b = (a + b) / 2; | ||
for (; i < j; ++i) v[i] = b; | ||
return smooth ? smoothing(v, step + step / 4) : v; | ||
} | ||
return smooth ? smoothing(v, step + step / 4) : v; | ||
} // perform smoothing to reduce variance | ||
// perform smoothing to reduce variance | ||
// swap points between "adjacent" stacks | ||
// Wilkinson defines adjacent as within step/4 units | ||
function smoothing(v, thresh) { | ||
const n = v.length; | ||
let a = 0, | ||
b = 1, | ||
c, | ||
d; // get left stack | ||
b = 1, | ||
c, | ||
d; | ||
// get left stack | ||
while (v[a] === v[b]) ++b; | ||
while (b < n) { | ||
// get right stack | ||
c = b + 1; | ||
while (v[b] === v[c]) ++c; | ||
while (v[b] === v[c]) ++c; // are stacks adjacent? | ||
// are stacks adjacent? | ||
// if so, compare sizes and swap as needed | ||
if (v[b] - v[b - 1] < thresh) { | ||
d = b + (a + c - b - b >> 1); | ||
while (d < b) v[d++] = v[b]; | ||
while (d > b) v[d--] = v[a]; | ||
} // update left stack indices | ||
} | ||
// update left stack indices | ||
a = b; | ||
b = c; | ||
} | ||
return v; | ||
@@ -228,3 +208,2 @@ } | ||
} | ||
let a, b, d; | ||
@@ -241,3 +220,2 @@ const dist = { | ||
}, | ||
max(_) { | ||
@@ -252,11 +230,8 @@ if (arguments.length) { | ||
}, | ||
sample() { | ||
return a + Math.floor(d * random()); | ||
}, | ||
pdf(x) { | ||
return x === Math.floor(x) && x >= a && x < b ? 1 / d : 0; | ||
}, | ||
cdf(x) { | ||
@@ -266,7 +241,5 @@ const v = Math.floor(x); | ||
}, | ||
icdf(p) { | ||
return p >= 0 && p <= 1 ? a - 1 + Math.floor(p * d) : NaN; | ||
} | ||
}; | ||
@@ -284,6 +257,5 @@ return dist.min(min).max(max); | ||
let x = 0, | ||
y = 0, | ||
rds, | ||
c; | ||
y = 0, | ||
rds, | ||
c; | ||
if (nextSample === nextSample) { | ||
@@ -298,9 +270,6 @@ x = nextSample; | ||
} while (rds === 0 || rds > 1); | ||
c = Math.sqrt(-2 * Math.log(rds) / rds); // Box-Muller transform | ||
x *= c; | ||
nextSample = y * c; | ||
} | ||
return mean + x * stdev; | ||
@@ -312,5 +281,6 @@ } | ||
return Math.exp(-0.5 * z * z) / (stdev * SQRT2PI); | ||
} // Approximation from West (2009) | ||
} | ||
// Approximation from West (2009) | ||
// Better Approximations to Cumulative Normal Functions | ||
function cumulativeNormal(value, mean, stdev) { | ||
@@ -320,5 +290,4 @@ mean = mean || 0; | ||
const z = (value - mean) / stdev, | ||
Z = Math.abs(z); | ||
Z = Math.abs(z); | ||
let cd; | ||
if (Z > 37) { | ||
@@ -329,3 +298,2 @@ cd = 0; | ||
let sum; | ||
if (Z < 7.07106781186547) { | ||
@@ -356,13 +324,14 @@ sum = 3.52624965998911e-02 * Z + 0.700383064443688; | ||
} | ||
return z > 0 ? 1 - cd : cd; | ||
} // Approximation of Probit function using inverse error function. | ||
} | ||
// Approximation of Probit function using inverse error function. | ||
function quantileNormal(p, mean, stdev) { | ||
if (p < 0 || p > 1) return NaN; | ||
return (mean || 0) + (stdev == null ? 1 : stdev) * SQRT2 * erfinv(2 * p - 1); | ||
} // Approximate inverse error function. Implementation from "Approximating | ||
} | ||
// Approximate inverse error function. Implementation from "Approximating | ||
// the erfinv function" by Mike Giles, GPU Computing Gems, volume 2, 2010. | ||
// Ported from Apache Commons Math, http://www.apache.org/licenses/LICENSE-2.0 | ||
function erfinv(x) { | ||
@@ -374,4 +343,3 @@ // beware that the logarithm argument must be | ||
let w = -Math.log((1 - x) * (1 + x)), | ||
p; | ||
p; | ||
if (w < 6.25) { | ||
@@ -445,6 +413,4 @@ w -= 3.125; | ||
} | ||
return p * x; | ||
} | ||
function gaussian (mean, stdev) { | ||
@@ -461,3 +427,2 @@ let mu, sigma; | ||
}, | ||
stdev(_) { | ||
@@ -471,3 +436,2 @@ if (arguments.length) { | ||
}, | ||
sample: () => sampleNormal(mu, sigma), | ||
@@ -494,3 +458,2 @@ pdf: value => densityNormal(value, mu, sigma), | ||
}, | ||
bandwidth(_) { | ||
@@ -502,33 +465,24 @@ if (!arguments.length) return bandwidth; | ||
}, | ||
sample() { | ||
return support[~~(random() * n)] + bandwidth * kernel.sample(); | ||
}, | ||
pdf(x) { | ||
let y = 0, | ||
i = 0; | ||
i = 0; | ||
for (; i < n; ++i) { | ||
y += kernel.pdf((x - support[i]) / bandwidth); | ||
} | ||
return y / bandwidth / n; | ||
}, | ||
cdf(x) { | ||
let y = 0, | ||
i = 0; | ||
i = 0; | ||
for (; i < n; ++i) { | ||
y += kernel.cdf((x - support[i]) / bandwidth); | ||
} | ||
return y / n; | ||
}, | ||
icdf() { | ||
throw Error('KDE icdf not supported.'); | ||
} | ||
}; | ||
@@ -567,3 +521,2 @@ return dist.data(support); | ||
}, | ||
stdev(_) { | ||
@@ -577,3 +530,2 @@ if (arguments.length) { | ||
}, | ||
sample: () => sampleLogNormal(mu, sigma), | ||
@@ -589,20 +541,15 @@ pdf: value => densityLogNormal(value, mu, sigma), | ||
let m = 0, | ||
w; | ||
w; | ||
function normalize(x) { | ||
const w = []; | ||
let sum = 0, | ||
i; | ||
i; | ||
for (i = 0; i < m; ++i) { | ||
sum += w[i] = x[i] == null ? 1 : +x[i]; | ||
} | ||
for (i = 0; i < m; ++i) { | ||
w[i] /= sum; | ||
} | ||
return w; | ||
} | ||
const dist = { | ||
@@ -614,6 +561,4 @@ weights(_) { | ||
} | ||
return weights; | ||
}, | ||
distributions(_) { | ||
@@ -628,15 +573,13 @@ if (arguments.length) { | ||
} | ||
return dist.weights(weights); | ||
} | ||
return dists; | ||
}, | ||
sample() { | ||
const r = random(); | ||
let d = dists[m - 1], | ||
v = w[0], | ||
i = 0; // first select distribution | ||
v = w[0], | ||
i = 0; | ||
// first select distribution | ||
for (; i < m - 1; v += w[++i]) { | ||
@@ -647,34 +590,25 @@ if (r < v) { | ||
} | ||
} // then sample from it | ||
} | ||
// then sample from it | ||
return d.sample(); | ||
}, | ||
pdf(x) { | ||
let p = 0, | ||
i = 0; | ||
i = 0; | ||
for (; i < m; ++i) { | ||
p += w[i] * dists[i].pdf(x); | ||
} | ||
return p; | ||
}, | ||
cdf(x) { | ||
let p = 0, | ||
i = 0; | ||
i = 0; | ||
for (; i < m; ++i) { | ||
p += w[i] * dists[i].cdf(x); | ||
} | ||
return p; | ||
}, | ||
icdf() { | ||
throw Error('Mixture icdf not supported.'); | ||
} | ||
}; | ||
@@ -689,3 +623,2 @@ return dist.distributions(dists).weights(weights); | ||
} | ||
return min + (max - min) * random(); | ||
@@ -698,3 +631,2 @@ } | ||
} | ||
return value >= min && value <= max ? 1 / (max - min) : 0; | ||
@@ -707,3 +639,2 @@ } | ||
} | ||
return value < min ? 0 : value > max ? 1 : (value - min) / (max - min); | ||
@@ -716,3 +647,2 @@ } | ||
} | ||
return p >= 0 && p <= 1 ? min + p * (max - min) : NaN; | ||
@@ -731,3 +661,2 @@ } | ||
}, | ||
max(_) { | ||
@@ -741,3 +670,2 @@ if (arguments.length) { | ||
}, | ||
sample: () => sampleUniform(a, b), | ||
@@ -748,3 +676,2 @@ pdf: value => densityUniform(value, a, b), | ||
}; | ||
if (max == null) { | ||
@@ -754,3 +681,2 @@ max = min == null ? 1 : min; | ||
} | ||
return dist.min(min).max(max); | ||
@@ -762,4 +688,4 @@ } | ||
const delta = uX2 - uX * uX, | ||
slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, | ||
intercept = uY - slope * uX; | ||
slope = Math.abs(delta) < 1e-24 ? 0 : (uXY - uX * uY) / delta, | ||
intercept = uY - slope * uX; | ||
return [intercept, slope]; | ||
@@ -771,21 +697,19 @@ } | ||
let u = x(d), | ||
v = y(d); | ||
v = y(d); | ||
return u != null && (u = +u) >= u && v != null && (v = +v) >= v; | ||
}); | ||
if (sort) { | ||
data.sort((a, b) => x(a) - x(b)); | ||
} | ||
const n = data.length, | ||
X = new Float64Array(n), | ||
Y = new Float64Array(n); // extract values, calculate means | ||
X = new Float64Array(n), | ||
Y = new Float64Array(n); | ||
// extract values, calculate means | ||
let i = 0, | ||
ux = 0, | ||
uy = 0, | ||
xv, | ||
yv, | ||
d; | ||
ux = 0, | ||
uy = 0, | ||
xv, | ||
yv, | ||
d; | ||
for (d of data) { | ||
@@ -797,5 +721,5 @@ X[i] = xv = +x(d); | ||
uy += (yv - uy) / i; | ||
} // mean center the data | ||
} | ||
// mean center the data | ||
for (i = 0; i < n; ++i) { | ||
@@ -805,3 +729,2 @@ X[i] -= ux; | ||
} | ||
return [X, Y, ux, uy]; | ||
@@ -811,9 +734,7 @@ } | ||
let i = -1, | ||
u, | ||
v; | ||
u, | ||
v; | ||
for (const d of data) { | ||
u = x(d); | ||
v = y(d); | ||
if (u != null && (u = +u) >= u && v != null && (v = +v) >= v) { | ||
@@ -825,10 +746,10 @@ callback(u, v, ++i); | ||
// Adapted from d3-regression by Harry Stevens | ||
// License: https://github.com/HarryStevens/d3-regression/blob/master/LICENSE | ||
function rSquared (data, x, y, uY, predict) { | ||
let SSE = 0, | ||
SST = 0; | ||
SST = 0; | ||
visitPoints(data, x, y, (dx, dy) => { | ||
const sse = dy - predict(dx), | ||
sst = dy - uY; | ||
sst = dy - uY; | ||
SSE += sse * sse; | ||
@@ -840,10 +761,10 @@ SST += sst * sst; | ||
// Adapted from d3-regression by Harry Stevens | ||
// License: https://github.com/HarryStevens/d3-regression/blob/master/LICENSE | ||
function linear (data, x, y) { | ||
let X = 0, | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0, | ||
n = 0; | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0, | ||
n = 0; | ||
visitPoints(data, x, y, (dx, dy) => { | ||
@@ -856,6 +777,4 @@ ++n; | ||
}); | ||
const coef = ols(X, Y, XY, X2), | ||
predict = x => coef[0] + coef[1] * x; | ||
predict = x => coef[0] + coef[1] * x; | ||
return { | ||
@@ -868,10 +787,10 @@ coef: coef, | ||
// Adapted from d3-regression by Harry Stevens | ||
// License: https://github.com/HarryStevens/d3-regression/blob/master/LICENSE | ||
function log (data, x, y) { | ||
let X = 0, | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0, | ||
n = 0; | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0, | ||
n = 0; | ||
visitPoints(data, x, y, (dx, dy) => { | ||
@@ -885,6 +804,4 @@ ++n; | ||
}); | ||
const coef = ols(X, Y, XY, X2), | ||
predict = x => coef[0] + coef[1] * Math.log(x); | ||
predict = x => coef[0] + coef[1] * Math.log(x); | ||
return { | ||
@@ -901,9 +818,9 @@ coef: coef, | ||
let YL = 0, | ||
XY = 0, | ||
XYL = 0, | ||
X2Y = 0, | ||
n = 0, | ||
dx, | ||
ly, | ||
xy; | ||
XY = 0, | ||
XYL = 0, | ||
X2Y = 0, | ||
n = 0, | ||
dx, | ||
ly, | ||
xy; | ||
visitPoints(data, x, y, (_, dy) => { | ||
@@ -918,6 +835,4 @@ dx = xv[n++]; | ||
}); | ||
const [c0, c1] = ols(XY / uy, YL / uy, XYL / uy, X2Y / uy), | ||
predict = x => Math.exp(c0 + c1 * (x - ux)); | ||
predict = x => Math.exp(c0 + c1 * (x - ux)); | ||
return { | ||
@@ -930,14 +845,14 @@ coef: [Math.exp(c0 - c1 * ux), c1], | ||
// Adapted from d3-regression by Harry Stevens | ||
// License: https://github.com/HarryStevens/d3-regression/blob/master/LICENSE | ||
function pow (data, x, y) { | ||
let X = 0, | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0, | ||
YS = 0, | ||
n = 0; | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0, | ||
YS = 0, | ||
n = 0; | ||
visitPoints(data, x, y, (dx, dy) => { | ||
const lx = Math.log(dx), | ||
ly = Math.log(dy); | ||
ly = Math.log(dy); | ||
++n; | ||
@@ -950,6 +865,4 @@ X += (lx - X) / n; | ||
}); | ||
const coef = ols(X, Y, XY, X2), | ||
predict = x => coef[0] * Math.pow(x, coef[1]); | ||
predict = x => coef[0] * Math.pow(x, coef[1]); | ||
coef[0] = Math.exp(coef[0]); | ||
@@ -965,13 +878,12 @@ return { | ||
const [xv, yv, ux, uy] = points(data, x, y), | ||
n = xv.length; | ||
n = xv.length; | ||
let X2 = 0, | ||
X3 = 0, | ||
X4 = 0, | ||
XY = 0, | ||
X2Y = 0, | ||
i, | ||
dx, | ||
dy, | ||
x2; | ||
X3 = 0, | ||
X4 = 0, | ||
XY = 0, | ||
X2Y = 0, | ||
i, | ||
dx, | ||
dy, | ||
x2; | ||
for (i = 0; i < n;) { | ||
@@ -987,14 +899,13 @@ dx = xv[i]; | ||
} | ||
const X2X2 = X4 - X2 * X2, | ||
d = X2 * X2X2 - X3 * X3, | ||
a = (X2Y * X2 - XY * X3) / d, | ||
b = (XY * X2X2 - X2Y * X3) / d, | ||
c = -a * X2, | ||
predict = x => { | ||
x = x - ux; | ||
return a * x * x + b * x + c + uy; | ||
}; // transform coefficients back from mean-centered space | ||
d = X2 * X2X2 - X3 * X3, | ||
a = (X2Y * X2 - XY * X3) / d, | ||
b = (XY * X2X2 - X2Y * X3) / d, | ||
c = -a * X2, | ||
predict = x => { | ||
x = x - ux; | ||
return a * x * x + b * x + c + uy; | ||
}; | ||
// transform coefficients back from mean-centered space | ||
return { | ||
@@ -1007,2 +918,3 @@ coef: [c - b * ux + a * ux * ux + uy, b - 2 * a * ux, a], | ||
// Adapted from d3-regression by Harry Stevens | ||
// License: https://github.com/HarryStevens/d3-regression/blob/master/LICENSE | ||
@@ -1012,3 +924,2 @@ // ... which was adapted from regression-js by Tom Alexander | ||
// License: https://github.com/Tom-Alexander/regression-js/blob/master/LICENSE | ||
function poly (data, x, y, order) { | ||
@@ -1019,8 +930,7 @@ // use more efficient methods for lower orders | ||
const [xv, yv, ux, uy] = points(data, x, y), | ||
n = xv.length, | ||
lhs = [], | ||
rhs = [], | ||
k = order + 1; | ||
n = xv.length, | ||
lhs = [], | ||
rhs = [], | ||
k = order + 1; | ||
let i, j, l, v, c; | ||
for (i = 0; i < k; ++i) { | ||
@@ -1030,6 +940,4 @@ for (l = 0, v = 0; l < n; ++l) { | ||
} | ||
lhs.push(v); | ||
c = new Float64Array(k); | ||
for (j = 0; j < k; ++j) { | ||
@@ -1039,21 +947,14 @@ for (l = 0, v = 0; l < n; ++l) { | ||
} | ||
c[j] = v; | ||
} | ||
rhs.push(c); | ||
} | ||
rhs.push(lhs); | ||
const coef = gaussianElimination(rhs), | ||
predict = x => { | ||
x -= ux; | ||
let y = uy + coef[0] + coef[1] * x + coef[2] * x * x; | ||
for (i = 3; i < k; ++i) y += coef[i] * Math.pow(x, i); | ||
return y; | ||
}; | ||
predict = x => { | ||
x -= ux; | ||
let y = uy + coef[0] + coef[1] * x + coef[2] * x * x; | ||
for (i = 3; i < k; ++i) y += coef[i] * Math.pow(x, i); | ||
return y; | ||
}; | ||
return { | ||
@@ -1065,10 +966,10 @@ coef: uncenter(k, coef, -ux, uy), | ||
} | ||
function uncenter(k, a, x, y) { | ||
const z = Array(k); | ||
let i, j, v, c; // initialize to zero | ||
let i, j, v, c; | ||
for (i = 0; i < k; ++i) z[i] = 0; // polynomial expansion | ||
// initialize to zero | ||
for (i = 0; i < k; ++i) z[i] = 0; | ||
// polynomial expansion | ||
for (i = k - 1; i >= 0; --i) { | ||
@@ -1078,25 +979,21 @@ v = a[i]; | ||
z[i] += v; | ||
for (j = 1; j <= i; ++j) { | ||
c *= (i + 1 - j) / j; // binomial coefficent | ||
z[i - j] += v * Math.pow(x, j) * c; | ||
} | ||
} // bias term | ||
} | ||
// bias term | ||
z[0] += y; | ||
return z; | ||
} // Given an array for a two-dimensional matrix and the polynomial order, | ||
} | ||
// Given an array for a two-dimensional matrix and the polynomial order, | ||
// solve A * x = b using Gaussian elimination. | ||
function gaussianElimination(matrix) { | ||
const n = matrix.length - 1, | ||
coef = []; | ||
coef = []; | ||
let i, j, k, r, t; | ||
for (i = 0; i < n; ++i) { | ||
r = i; // max row | ||
for (j = i + 1; j < n; ++j) { | ||
@@ -1107,3 +1004,2 @@ if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][r])) { | ||
} | ||
for (k = i; k < n + 1; ++k) { | ||
@@ -1114,3 +1010,2 @@ t = matrix[k][i]; | ||
} | ||
for (j = i + 1; j < n; ++j) { | ||
@@ -1122,13 +1017,9 @@ for (k = n; k >= i; k--) { | ||
} | ||
for (j = n - 1; j >= 0; --j) { | ||
t = 0; | ||
for (k = j + 1; k < n; ++k) { | ||
t += matrix[k][j] * coef[k]; | ||
} | ||
coef[j] = (matrix[n][j] - t) / matrix[j][j]; | ||
} | ||
return coef; | ||
@@ -1138,28 +1029,27 @@ } | ||
const maxiters = 2, | ||
epsilon = 1e-12; // Adapted from science.js by Jason Davies | ||
epsilon = 1e-12; | ||
// Adapted from science.js by Jason Davies | ||
// Source: https://github.com/jasondavies/science.js/blob/master/src/stats/loess.js | ||
// License: https://github.com/jasondavies/science.js/blob/master/LICENSE | ||
function loess (data, x, y, bandwidth) { | ||
const [xv, yv, ux, uy] = points(data, x, y, true), | ||
n = xv.length, | ||
bw = Math.max(2, ~~(bandwidth * n)), | ||
// # nearest neighbors | ||
yhat = new Float64Array(n), | ||
residuals = new Float64Array(n), | ||
robustWeights = new Float64Array(n).fill(1); | ||
n = xv.length, | ||
bw = Math.max(2, ~~(bandwidth * n)), | ||
// # nearest neighbors | ||
yhat = new Float64Array(n), | ||
residuals = new Float64Array(n), | ||
robustWeights = new Float64Array(n).fill(1); | ||
for (let iter = -1; ++iter <= maxiters;) { | ||
const interval = [0, bw - 1]; | ||
for (let i = 0; i < n; ++i) { | ||
const dx = xv[i], | ||
i0 = interval[0], | ||
i1 = interval[1], | ||
edge = dx - xv[i0] > xv[i1] - dx ? i0 : i1; | ||
i0 = interval[0], | ||
i1 = interval[1], | ||
edge = dx - xv[i0] > xv[i1] - dx ? i0 : i1; | ||
let W = 0, | ||
X = 0, | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0; | ||
X = 0, | ||
Y = 0, | ||
XY = 0, | ||
X2 = 0; | ||
const denom = 1 / Math.abs(xv[edge] - dx || 1); // avoid singularity! | ||
@@ -1169,5 +1059,5 @@ | ||
const xk = xv[k], | ||
yk = yv[k], | ||
w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k], | ||
xkw = xk * w; | ||
yk = yv[k], | ||
w = tricube(Math.abs(dx - xk) * denom) * robustWeights[k], | ||
xkw = xk * w; | ||
W += w; | ||
@@ -1178,5 +1068,5 @@ X += xkw; | ||
X2 += xk * xkw; | ||
} // linear regression fit | ||
} | ||
// linear regression fit | ||
const [a, b] = ols(X / W, Y / W, XY / W, X2 / W); | ||
@@ -1187,33 +1077,31 @@ yhat[i] = a + b * dx; | ||
} | ||
if (iter === maxiters) { | ||
break; | ||
} | ||
const medianResidual = median(residuals); | ||
if (Math.abs(medianResidual) < epsilon) break; | ||
for (let i = 0, arg, w; i < n; ++i) { | ||
arg = residuals[i] / (6 * medianResidual); // default to epsilon (rather than zero) for large deviations | ||
arg = residuals[i] / (6 * medianResidual); | ||
// default to epsilon (rather than zero) for large deviations | ||
// keeping weights tiny but non-zero prevents singularites | ||
robustWeights[i] = arg >= 1 ? epsilon : (w = 1 - arg * arg) * w; | ||
} | ||
} | ||
return output(xv, yhat, ux, uy); | ||
} // weighting kernel for local regression | ||
} | ||
// weighting kernel for local regression | ||
function tricube(x) { | ||
return (x = 1 - x * x * x) * x * x; | ||
} // advance sliding window interval of nearest neighbors | ||
} | ||
// advance sliding window interval of nearest neighbors | ||
function updateInterval(xv, i, interval) { | ||
const val = xv[i]; | ||
let left = interval[0], | ||
right = interval[1] + 1; | ||
if (right >= xv.length) return; // step right if distance to new right edge is <= distance to old left edge | ||
right = interval[1] + 1; | ||
if (right >= xv.length) return; | ||
// step right if distance to new right edge is <= distance to old left edge | ||
// step when distance is equal to ensure movement over duplicate x values | ||
while (i > left && xv[right] - val <= val - xv[left]) { | ||
@@ -1224,17 +1112,15 @@ interval[0] = ++left; | ||
} | ||
} // generate smoothed output points | ||
} | ||
// generate smoothed output points | ||
// average points with repeated x values | ||
function output(xv, yhat, ux, uy) { | ||
const n = xv.length, | ||
out = []; | ||
out = []; | ||
let i = 0, | ||
cnt = 0, | ||
prev = [], | ||
v; | ||
cnt = 0, | ||
prev = [], | ||
v; | ||
for (; i < n; ++i) { | ||
v = xv[i] + ux; | ||
if (prev[0] === v) { | ||
@@ -1251,3 +1137,2 @@ // average output values via online update | ||
} | ||
prev[1] += uy; | ||
@@ -1258,16 +1143,15 @@ return out; | ||
// subdivide up to accuracy of 0.5 degrees | ||
const MIN_RADIANS = 0.5 * Math.PI / 180; // Adaptively sample an interpolated function over a domain extent | ||
const MIN_RADIANS = 0.5 * Math.PI / 180; | ||
// Adaptively sample an interpolated function over a domain extent | ||
function sampleCurve (f, extent, minSteps, maxSteps) { | ||
minSteps = minSteps || 25; | ||
maxSteps = Math.max(minSteps, maxSteps || 200); | ||
const point = x => [x, f(x)], | ||
minX = extent[0], | ||
maxX = extent[1], | ||
span = maxX - minX, | ||
stop = span / maxSteps, | ||
prev = [point(minX)], | ||
next = []; | ||
minX = extent[0], | ||
maxX = extent[1], | ||
span = maxX - minX, | ||
stop = span / maxSteps, | ||
prev = [point(minX)], | ||
next = []; | ||
if (minSteps === maxSteps) { | ||
@@ -1278,3 +1162,2 @@ // no adaptation, sample uniform grid directly and return | ||
} | ||
prev.push(point(maxX)); | ||
@@ -1286,3 +1169,2 @@ return prev; | ||
next.push(point(maxX)); | ||
for (let i = minSteps; --i > 0;) { | ||
@@ -1292,3 +1174,2 @@ next.push(point(minX + i / minSteps * span)); | ||
} | ||
let p0 = prev[0]; | ||
@@ -1298,3 +1179,2 @@ let p1 = next[next.length - 1]; | ||
const sy = scaleY(p0[1], next); | ||
while (p1) { | ||
@@ -1304,3 +1184,2 @@ // midpoint for potential curve subdivision | ||
const dx = pm[0] - p0[0] >= stop; | ||
if (dx && angleDelta(p0, pm, p1, sx, sy) > MIN_RADIANS) { | ||
@@ -1318,9 +1197,6 @@ // maximum resolution has not yet been met, and | ||
} | ||
p1 = next[next.length - 1]; | ||
} | ||
return prev; | ||
} | ||
function scaleY(init, points) { | ||
@@ -1330,3 +1206,2 @@ let ymin = init; | ||
const n = points.length; | ||
for (let i = 0; i < n; ++i) { | ||
@@ -1337,9 +1212,7 @@ const y = points[i][1]; | ||
} | ||
return 1 / (ymax - ymin); | ||
} | ||
function angleDelta(p, q, r, sx, sy) { | ||
const a0 = Math.atan2(sy * (r[1] - p[1]), sx * (r[0] - p[0])), | ||
a1 = Math.atan2(sy * (q[1] - p[1]), sx * (q[0] - p[0])); | ||
a1 = Math.atan2(sy * (q[1] - p[1]), sx * (q[0] - p[0])); | ||
return Math.abs(a0 - a1); | ||
@@ -1346,0 +1219,0 @@ } |
{ | ||
"name": "vega-statistics", | ||
"version": "1.8.0", | ||
"version": "1.8.1", | ||
"description": "Statistical routines and probability distributions.", | ||
@@ -19,3 +19,3 @@ "keywords": [ | ||
"prebuild": "rimraf build", | ||
"build": "rollup -c", | ||
"build": "rollup -c rollup.config.mjs", | ||
"pretest": "yarn build --config-test", | ||
@@ -26,5 +26,5 @@ "test": "tape 'test/**/*-test.js'", | ||
"dependencies": { | ||
"d3-array": "^3.1.1" | ||
"d3-array": "^3.2.2" | ||
}, | ||
"gitHead": "9a3faca4395cade9ecdfde90af98f1c53e9916b2" | ||
"gitHead": "fb1092f6b931d450f9c210b67ae4752bd3dd461b" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
214966
0.88%3530
2.08%Updated