@visactor/vutils 1.0.20 → 1.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/cjs/common/ascending.js +1 -2
  2. package/cjs/common/extent.js +2 -1
  3. package/cjs/common/index.js +1 -2
  4. package/cjs/common/isNull.js +2 -1
  5. package/cjs/common/isPlainObject.js +1 -2
  6. package/cjs/common/isShallowEqual.js +1 -1
  7. package/cjs/common/isString.js +1 -1
  8. package/cjs/common/isType.js +1 -1
  9. package/cjs/common/isUndefined.js +1 -1
  10. package/cjs/common/isValid.js +1 -1
  11. package/cjs/common/regression-lowess.d.ts +1 -0
  12. package/cjs/common/regression-lowess.js +57 -39
  13. package/cjs/common/regression-lowess.js.map +1 -1
  14. package/cjs/data-structure/bounds.js +1 -1
  15. package/cjs/data-structure/hashTable.js +2 -1
  16. package/cjs/data-structure/index.js +1 -1
  17. package/cjs/data-structure/matrix.js +1 -1
  18. package/cjs/data-structure/point.js +1 -1
  19. package/dist/index.js +94 -70
  20. package/dist/index.min.js +1 -1
  21. package/es/common/ascending.js +1 -2
  22. package/es/common/extent.js +2 -1
  23. package/es/common/index.js +1 -2
  24. package/es/common/isNull.js +2 -1
  25. package/es/common/isPlainObject.js +1 -2
  26. package/es/common/isShallowEqual.js +1 -1
  27. package/es/common/isString.js +1 -1
  28. package/es/common/isType.js +1 -1
  29. package/es/common/isUndefined.js +1 -1
  30. package/es/common/isValid.js +1 -1
  31. package/es/common/regression-lowess.d.ts +1 -0
  32. package/es/common/regression-lowess.js +57 -39
  33. package/es/common/regression-lowess.js.map +1 -1
  34. package/es/data-structure/bounds.js +1 -1
  35. package/es/data-structure/hashTable.js +2 -1
  36. package/es/data-structure/index.js +1 -1
  37. package/es/data-structure/matrix.js +1 -1
  38. package/es/data-structure/point.js +1 -1
  39. package/package.json +2 -2
@@ -6,5 +6,4 @@ function ascending(a, b) {
6
6
 
7
7
  Object.defineProperty(exports, "__esModule", {
8
8
  value: !0
9
- }), exports.ascending = void 0, exports.ascending = ascending;
10
- //# sourceMappingURL=ascending.js.map
9
+ }), exports.ascending = void 0, exports.ascending = ascending;
@@ -26,4 +26,5 @@ const isFunction_1 = __importDefault(require("./isFunction")), isNil_1 = __impor
26
26
  return [ min, max ];
27
27
  };
28
28
 
29
- exports.extent = extent;
29
+ exports.extent = extent;
30
+ //# sourceMappingURL=extent.js.map
@@ -524,5 +524,4 @@ __exportStar(require("./toPercent"), exports), __exportStar(require("./zero"), e
524
524
  __exportStar(require("./extent"), exports), __exportStar(require("./regression-linear"), exports),
525
525
  __exportStar(require("./regression-logistic"), exports), __exportStar(require("./regression-lowess"), exports),
526
526
  __exportStar(require("./regression-polynomial"), exports), __exportStar(require("./kde"), exports),
527
- __exportStar(require("./ecdf"), exports);
528
- //# sourceMappingURL=index.js.map
527
+ __exportStar(require("./ecdf"), exports);
@@ -6,4 +6,5 @@ Object.defineProperty(exports, "__esModule", {
6
6
 
7
7
  const isNull = value => null === value;
8
8
 
9
- exports.default = isNull;
9
+ exports.default = isNull;
10
+ //# sourceMappingURL=isNull.js.map
@@ -18,5 +18,4 @@ const isObjectLike_1 = __importDefault(require("./isObjectLike")), isType_1 = __
18
18
  return Object.getPrototypeOf(value) === proto;
19
19
  };
20
20
 
21
- exports.default = isPlainObject;
22
- //# sourceMappingURL=isPlainObject.js.map
21
+ exports.default = isPlainObject;
@@ -31,4 +31,4 @@ function isShallowEqual(objA, objB) {
31
31
  }
32
32
 
33
33
  exports.isShallowEqual = isShallowEqual;
34
- //# sourceMappingURL=isShallowEqual.js.map
34
+ //# sourceMappingURL=isShallowEqual.js.map
@@ -16,4 +16,4 @@ const isType_1 = __importDefault(require("./isType")), isString = (value, fuzzy
16
16
  };
17
17
 
18
18
  exports.default = isString;
19
- //# sourceMappingURL=isString.js.map
19
+ //# sourceMappingURL=isString.js.map
@@ -7,4 +7,4 @@ Object.defineProperty(exports, "__esModule", {
7
7
  const isType = (value, type) => Object.prototype.toString.call(value) === `[object ${type}]`;
8
8
 
9
9
  exports.default = isType;
10
- //# sourceMappingURL=isType.js.map
10
+ //# sourceMappingURL=isType.js.map
@@ -7,4 +7,4 @@ Object.defineProperty(exports, "__esModule", {
7
7
  const isUndefined = value => void 0 === value;
8
8
 
9
9
  exports.default = isUndefined;
10
- //# sourceMappingURL=isUndefined.js.map
10
+ //# sourceMappingURL=isUndefined.js.map
@@ -7,4 +7,4 @@ Object.defineProperty(exports, "__esModule", {
7
7
  const isValid = value => null != value;
8
8
 
9
9
  exports.default = isValid;
10
- //# sourceMappingURL=isValid.js.map
10
+ //# sourceMappingURL=isValid.js.map
@@ -3,6 +3,7 @@ export declare function regressionLowess(data: any[], x?: (d: any) => number, y?
3
3
  degree?: 1 | 0;
4
4
  iterations?: number;
5
5
  alpha?: number;
6
+ maxSamples?: number;
6
7
  }): {
7
8
  predict: (x0: number | number[]) => number | number[];
8
9
  evaluate: any;
@@ -13,38 +13,60 @@ function tricube(u) {
13
13
  return t * t * t;
14
14
  }
15
15
 
16
+ function stratifiedSample(sortedData, maxSamples) {
17
+ const n = sortedData.length;
18
+ if (n <= maxSamples) return sortedData;
19
+ const sampled = [], step = n / maxSamples;
20
+ for (let i = 0; i < maxSamples; i++) {
21
+ const idx = Math.min(Math.floor(i * step), n - 1);
22
+ sampled.push(sortedData[idx]);
23
+ }
24
+ return sampled;
25
+ }
26
+
16
27
  function regressionLowess(data, x = (d => d.x), y = (d => d.y), options = {}) {
17
28
  var _a;
18
- const span = options.span || .3, degree = 0 === options.degree ? 0 : 1, alpha = null !== (_a = null == options ? void 0 : options.alpha) && void 0 !== _a ? _a : .05, iterations = null == options.iterations ? 2 : options.iterations, ptsX = [], ptsY = [];
29
+ const span = options.span || .3, degree = 0 === options.degree ? 0 : 1, alpha = null !== (_a = options.alpha) && void 0 !== _a ? _a : .05, iterations = null == options.iterations ? 2 : options.iterations, maxSamples = options.maxSamples || 1e3, rawPoints = [];
19
30
  (0, regression_linear_1.visitPoints)(data, x, y, ((dx, dy) => {
20
- ptsX.push(dx), ptsY.push(dy);
21
- }));
22
- const n = ptsX.length;
31
+ rawPoints.push({
32
+ x: dx,
33
+ y: dy
34
+ });
35
+ })), rawPoints.sort(((a, b) => a.x - b.x));
36
+ const sampledPoints = stratifiedSample(rawPoints, maxSamples), n = sampledPoints.length, ptsX = new Array(n), ptsY = new Array(n);
37
+ for (let i = 0; i < n; i++) ptsX[i] = sampledPoints[i].x, ptsY[i] = sampledPoints[i].y;
23
38
  function predictSingle(x0, robustWeights) {
24
39
  if (0 === n) return 0;
25
- const dists = [];
26
- for (let i = 0; i < n; i++) dists.push({
27
- idx: i,
28
- dist: Math.abs(ptsX[i] - x0)
29
- });
30
- dists.sort(((a, b) => a.dist - b.dist));
31
- const m = Math.max(2, Math.min(n, Math.floor(span * n))), maxDist = dists[m - 1].dist || 0, w = new Array(m);
40
+ let left = 0, right = n;
41
+ for (;left < right; ) {
42
+ const mid = left + right >> 1;
43
+ ptsX[mid] < x0 ? left = mid + 1 : right = mid;
44
+ }
45
+ const m = Math.max(2, Math.min(n, Math.floor(span * n))), start = Math.max(0, left - Math.floor(m / 2)), end = Math.min(n, start + m), actualStart = Math.max(0, end - m);
46
+ let maxDist = 0;
47
+ const windowSize = end - actualStart, distances = new Array(windowSize);
48
+ for (let i = actualStart; i < end; i++) {
49
+ const dist = Math.abs(ptsX[i] - x0);
50
+ distances[i - actualStart] = dist, dist > maxDist && (maxDist = dist);
51
+ }
32
52
  let sumw = 0;
33
- for (let i = 0; i < m; i++) {
34
- const idx = dists[i].idx;
35
- let wi = tricube(0 === maxDist ? 0 : dists[i].dist / maxDist);
36
- robustWeights && null != robustWeights[idx] && (wi *= robustWeights[idx]), w[i] = wi,
37
- sumw += wi;
53
+ const w = new Array(windowSize);
54
+ for (let i = 0; i < windowSize; i++) {
55
+ let wi = tricube(0 === maxDist ? 0 : distances[i] / maxDist);
56
+ robustWeights && null != robustWeights[actualStart + i] && (wi *= robustWeights[actualStart + i]),
57
+ w[i] = wi, sumw += wi;
58
+ }
59
+ if (0 === sumw) {
60
+ return ptsY[left < n ? left : n - 1];
38
61
  }
39
- if (0 === sumw) return ptsY[dists[0].idx];
40
62
  if (0 === degree) {
41
63
  let s = 0;
42
- for (let i = 0; i < m; i++) s += w[i] * ptsY[dists[i].idx];
64
+ for (let i = 0; i < w.length; i++) s += w[i] * ptsY[actualStart + i];
43
65
  return s / sumw;
44
66
  }
45
67
  let sw = 0, sx = 0, sy = 0, sxx = 0, sxy = 0;
46
- for (let i = 0; i < m; i++) {
47
- const idx = dists[i].idx, xi = ptsX[idx], yi = ptsY[idx], wi = w[i];
68
+ for (let i = actualStart; i < end; i++) {
69
+ const idx = i - actualStart, xi = ptsX[i], yi = ptsY[i], wi = w[idx];
48
70
  sw += wi, sx += wi * xi, sy += wi * yi, sxx += wi * xi * xi, sxy += wi * xi * yi;
49
71
  }
50
72
  const meanX = sx / sw, meanY = sy / sw, denom = sxx - sx * meanX, slope = Math.abs(denom) < 1e-12 ? 0 : (sxy - sx * meanY) / denom;
@@ -52,8 +74,8 @@ function regressionLowess(data, x = (d => d.x), y = (d => d.y), options = {}) {
52
74
  }
53
75
  function predict(x0) {
54
76
  if (Array.isArray(x0)) {
55
- const out = [];
56
- for (let i = 0; i < x0.length; i++) out.push(predictSingle(x0[i]));
77
+ const len = x0.length, out = new Array(len);
78
+ for (let i = 0; i < len; i++) out[i] = predictSingle(x0[i]);
57
79
  return out;
58
80
  }
59
81
  return predictSingle(x0);
@@ -62,26 +84,23 @@ function regressionLowess(data, x = (d => d.x), y = (d => d.y), options = {}) {
62
84
  predict: predict,
63
85
  evaluate: predict,
64
86
  evaluateGrid: function(N) {
65
- const out = [];
66
- if (N <= 0) return out;
67
- if (0 === n) return out;
68
- let min = 1 / 0, max = -1 / 0;
69
- for (let i = 0; i < n; i++) ptsX[i] < min && (min = ptsX[i]), ptsX[i] > max && (max = ptsX[i]);
87
+ if (N <= 0) return [];
88
+ if (0 === n) return [];
89
+ const out = new Array(N), min = ptsX[0], max = ptsX[n - 1];
70
90
  if (min === max) {
71
91
  const v = predictSingle(min);
72
- for (let i = 0; i < N; i++) out.push({
92
+ for (let i = 0; i < N; i++) out[i] = {
73
93
  x: min,
74
94
  y: v
75
- });
95
+ };
76
96
  return out;
77
97
  }
78
98
  const step = (max - min) / (N - 1);
79
99
  let robustWeights;
80
- for (let iter = 0; iter < iterations; iter++) {
81
- const fits = [];
82
- for (let i = 0; i < n; i++) fits.push(predictSingle(ptsX[i], robustWeights));
83
- const res = [];
84
- for (let i = 0; i < n; i++) res.push(Math.abs(ptsY[i] - fits[i]));
100
+ const effectiveIterations = null != options.iterations ? iterations : n > 500 ? 0 : iterations;
101
+ if (effectiveIterations > 0) for (let iter = 0; iter < effectiveIterations; iter++) {
102
+ const fits = new Array(n), res = new Array(n);
103
+ for (let i = 0; i < n; i++) fits[i] = predictSingle(ptsX[i], robustWeights), res[i] = Math.abs(ptsY[i] - fits[i]);
85
104
  const med = res.slice().sort(((a, b) => a - b))[Math.floor(n / 2)] || 0;
86
105
  robustWeights = new Array(n);
87
106
  for (let i = 0; i < n; i++) {
@@ -91,10 +110,10 @@ function regressionLowess(data, x = (d => d.x), y = (d => d.y), options = {}) {
91
110
  }
92
111
  for (let i = 0; i < N; i++) {
93
112
  const px = i === N - 1 ? max : min + step * i;
94
- out.push({
113
+ out[i] = {
95
114
  x: px,
96
115
  y: predictSingle(px, robustWeights)
97
- });
116
+ };
98
117
  }
99
118
  return out;
100
119
  },
@@ -102,9 +121,8 @@ function regressionLowess(data, x = (d => d.x), y = (d => d.y), options = {}) {
102
121
  const out = [];
103
122
  if (N <= 0) return out;
104
123
  if (0 === n) return out;
105
- let min = 1 / 0, max = -1 / 0;
106
- for (let i = 0; i < n; i++) ptsX[i] < min && (min = ptsX[i]), ptsX[i] > max && (max = ptsX[i]);
107
- if (min === 1 / 0 || max === -1 / 0) return out;
124
+ const min = ptsX[0], max = ptsX[n - 1];
125
+ if (void 0 === min || void 0 === max || min === 1 / 0 || max === -1 / 0) return out;
108
126
  const comps = (0, regression_utils_1.computeLinearCIComponents)(data, x, y, (xx => predictSingle(xx)));
109
127
  if (0 === comps.n) return out;
110
128
  const z = Math.abs((0, regression_utils_1.invNorm)(1 - alpha / 2));
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/common/regression-lowess.ts"],"names":[],"mappings":"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","file":"regression-lowess.js","sourcesContent":["import { visitPoints } from './regression-linear';\nimport { computeLinearCIComponents, invNorm, stdErrorsAt } from './regression-utils';\n\nfunction tricube(u: number) {\n const uu = Math.abs(u);\n if (uu >= 1) {\n return 0;\n }\n const t = 1 - uu * uu * uu;\n return t * t * t;\n}\n\n/**\n * Simple lowess implementation (univariate x)\n * options:\n * - span: fraction of points used in local regression (0,1]\n * - degree: 0 (constant) or 1 (linear)\n * - iterations: number of robustifying iterations\n */\nexport function regressionLowess(\n data: any[],\n x: (d: any) => number = d => d.x,\n y: (d: any) => number = d => d.y,\n options: { span?: number; degree?: 1 | 0; iterations?: number; alpha?: number } = {}\n) {\n const span = options.span || 0.3;\n const degree = options.degree === 0 ? 0 : 1;\n const alpha = options?.alpha ?? 0.05;\n const iterations = options.iterations == null ? 2 : options.iterations;\n\n const ptsX: number[] = [];\n const ptsY: number[] = [];\n visitPoints(data, x, y, (dx, dy) => {\n ptsX.push(dx);\n ptsY.push(dy);\n });\n\n const n = ptsX.length;\n function predictSingle(x0: number, robustWeights?: number[]) {\n if (n === 0) {\n return 0;\n }\n // compute distances and select nearest m points\n const dists: { idx: number; dist: number }[] = [];\n for (let i = 0; i < n; i++) {\n dists.push({ idx: i, dist: Math.abs(ptsX[i] - x0) });\n }\n dists.sort((a, b) => a.dist - b.dist);\n const m = Math.max(2, Math.min(n, Math.floor(span * n)));\n const maxDist = dists[m - 1].dist || 0;\n\n // compute weights\n const w: number[] = new Array(m);\n let sumw = 0;\n for (let i = 0; i < m; i++) {\n const idx = dists[i].idx;\n const u = maxDist === 0 ? 0 : dists[i].dist / maxDist;\n let wi = tricube(u);\n if (robustWeights && robustWeights[idx] != null) {\n wi *= robustWeights[idx];\n }\n w[i] = wi;\n sumw += wi;\n }\n\n if (sumw === 0) {\n // fallback to nearest y\n return ptsY[dists[0].idx];\n }\n\n if (degree === 0) {\n let s = 0;\n for (let i = 0; i < m; i++) {\n s += w[i] * ptsY[dists[i].idx];\n }\n return s / sumw;\n }\n\n // weighted linear regression on local points\n let sw = 0;\n let sx = 0;\n let sy = 0;\n let sxx = 0;\n let sxy = 0;\n for (let i = 0; i < m; i++) {\n const idx = dists[i].idx;\n const xi = ptsX[idx];\n const yi = ptsY[idx];\n const wi = w[i];\n sw += wi;\n sx += wi * xi;\n sy += wi * yi;\n sxx += wi * xi * xi;\n sxy += wi * xi * yi;\n }\n\n const meanX = sx / sw;\n const meanY = sy / sw;\n const denom = sxx - sx * meanX;\n const slope = Math.abs(denom) < 1e-12 ? 0 : (sxy - sx * meanY) / denom;\n const intercept = meanY - slope * meanX;\n return intercept + slope * x0;\n }\n\n function predict(x0: number | number[]) {\n if (Array.isArray(x0)) {\n const out: number[] = [];\n for (let i = 0; i < x0.length; i++) {\n out.push(predictSingle(x0[i]));\n }\n return out;\n }\n return predictSingle(x0 as number);\n }\n\n function evaluateGrid(N: number) {\n const out: { x: number; y: number }[] = [];\n if (N <= 0) {\n return out;\n }\n if (n === 0) {\n return out;\n }\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < n; i++) {\n if (ptsX[i] < min) {\n min = ptsX[i];\n }\n if (ptsX[i] > max) {\n max = ptsX[i];\n }\n }\n if (min === max) {\n const v = predictSingle(min);\n for (let i = 0; i < N; i++) {\n out.push({ x: min, y: v });\n }\n return out;\n }\n const step = (max - min) / (N - 1);\n\n // optionally add robust iterations\n let robustWeights: number[] | undefined;\n for (let iter = 0; iter < iterations; iter++) {\n // compute fits\n const fits: number[] = [];\n for (let i = 0; i < n; i++) {\n fits.push(predictSingle(ptsX[i], robustWeights));\n }\n // compute residuals\n const res: number[] = [];\n for (let i = 0; i < n; i++) {\n res.push(Math.abs(ptsY[i] - fits[i]));\n }\n // median absolute deviation\n const sortedRes = res.slice().sort((a, b) => a - b);\n const med = sortedRes[Math.floor(n / 2)] || 0;\n robustWeights = new Array(n);\n for (let i = 0; i < n; i++) {\n const u = med === 0 ? 0 : res[i] / (6 * med);\n const w = Math.abs(u) >= 1 ? 0 : (1 - u * u) * (1 - u * u);\n robustWeights[i] = w;\n }\n }\n\n for (let i = 0; i < N; i++) {\n const px = i === N - 1 ? max : min + step * i;\n out.push({ x: px, y: predictSingle(px, robustWeights) });\n }\n return out;\n }\n\n function confidenceInterval(N: number = 50) {\n const out: { x: number; mean: number; lower: number; upper: number; predLower: number; predUpper: number }[] = [];\n\n if (N <= 0) {\n return out;\n }\n if (n === 0) {\n return out;\n }\n\n // use data x-range\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < n; i++) {\n if (ptsX[i] < min) {\n min = ptsX[i];\n }\n if (ptsX[i] > max) {\n max = ptsX[i];\n }\n }\n if (min === Infinity || max === -Infinity) {\n return out;\n }\n\n const comps = computeLinearCIComponents(data, x, y, (xx: number) => predictSingle(xx));\n if (comps.n === 0) {\n return out;\n }\n\n const z = Math.abs(invNorm(1 - alpha / 2));\n if (comps.min === comps.max) {\n const v = predictSingle(comps.min);\n const errs = stdErrorsAt(comps.min, comps);\n for (let i = 0; i < N; i++) {\n out.push({\n x: comps.min,\n mean: v,\n lower: v - z * errs.seMean,\n upper: v + z * errs.seMean,\n predLower: v - z * errs.sePred,\n predUpper: v + z * errs.sePred\n });\n }\n return out;\n }\n\n const step = (max - min) / (N - 1);\n for (let i = 0; i < N; i++) {\n const px = i === N - 1 ? max : min + step * i;\n const yh = predictSingle(px);\n const errs = stdErrorsAt(px, comps);\n out.push({\n x: px,\n mean: yh,\n lower: yh - z * errs.seMean,\n upper: yh + z * errs.seMean,\n predLower: yh - z * errs.sePred,\n predUpper: yh + z * errs.sePred\n });\n }\n return out;\n }\n\n return {\n predict,\n evaluate: predict as any,\n evaluateGrid,\n confidenceInterval\n };\n}\n\nexport default regressionLowess;\n"]}
1
+ {"version":3,"sources":["../src/common/regression-lowess.ts"],"names":[],"mappings":"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","file":"regression-lowess.js","sourcesContent":["import { visitPoints } from './regression-linear';\nimport { computeLinearCIComponents, invNorm, stdErrorsAt } from './regression-utils';\n\nfunction tricube(u: number) {\n const uu = Math.abs(u);\n if (uu >= 1) {\n return 0;\n }\n const t = 1 - uu * uu * uu;\n return t * t * t;\n}\n\n/**\n * Stratified sampling to reduce data size while preserving distribution\n */\nfunction stratifiedSample(sortedData: { x: number; y: number }[], maxSamples: number) {\n const n = sortedData.length;\n if (n <= maxSamples) {\n return sortedData;\n }\n\n const sampled: { x: number; y: number }[] = [];\n\n // More aggressive sampling - use exact step size\n const step = n / maxSamples;\n\n for (let i = 0; i < maxSamples; i++) {\n const idx = Math.min(Math.floor(i * step), n - 1);\n sampled.push(sortedData[idx]);\n }\n\n return sampled;\n}\n\n/**\n * Simple lowess implementation (univariate x)\n * options:\n * - span: fraction of points used in local regression (0,1]\n * - degree: 0 (constant) or 1 (linear)\n * - iterations: number of robustifying iterations\n * - alpha: confidence level for CI\n * - maxSamples: maximum number of points to use (default: 1000 for fast processing)\n */\nexport function regressionLowess(\n data: any[],\n x: (d: any) => number = d => d.x,\n y: (d: any) => number = d => d.y,\n options: { span?: number; degree?: 1 | 0; iterations?: number; alpha?: number; maxSamples?: number } = {}\n) {\n const span = options.span || 0.3;\n const degree = options.degree === 0 ? 0 : 1;\n const alpha = options.alpha ?? 0.05;\n const iterations = options.iterations == null ? 2 : options.iterations;\n const maxSamples = options.maxSamples || 1000;\n\n // Collect and sort data by x\n const rawPoints: { x: number; y: number }[] = [];\n visitPoints(data, x, y, (dx, dy) => {\n rawPoints.push({ x: dx, y: dy });\n });\n\n rawPoints.sort((a, b) => a.x - b.x);\n\n // Apply sampling if needed\n const sampledPoints = stratifiedSample(rawPoints, maxSamples);\n\n const n = sampledPoints.length;\n const ptsX: number[] = new Array(n);\n const ptsY: number[] = new Array(n);\n\n for (let i = 0; i < n; i++) {\n ptsX[i] = sampledPoints[i].x;\n ptsY[i] = sampledPoints[i].y;\n }\n\n /**\n * Optimized predictSingle using binary search on pre-sorted data\n */\n function predictSingle(x0: number, robustWeights?: number[]) {\n if (n === 0) {\n return 0;\n }\n\n // Binary search to find insertion point\n let left = 0;\n let right = n;\n while (left < right) {\n const mid = (left + right) >> 1;\n if (ptsX[mid] < x0) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n\n const m = Math.max(2, Math.min(n, Math.floor(span * n)));\n\n // Calculate range around insertion point\n const start = Math.max(0, left - Math.floor(m / 2));\n const end = Math.min(n, start + m);\n const actualStart = Math.max(0, end - m);\n\n // Find max distance and compute weights in single pass\n let maxDist = 0;\n const windowSize = end - actualStart;\n const distances: number[] = new Array(windowSize);\n\n for (let i = actualStart; i < end; i++) {\n const dist = Math.abs(ptsX[i] - x0);\n distances[i - actualStart] = dist;\n if (dist > maxDist) {\n maxDist = dist;\n }\n }\n\n // Compute weights using pre-calculated distances\n let sumw = 0;\n const w: number[] = new Array(windowSize);\n for (let i = 0; i < windowSize; i++) {\n const u = maxDist === 0 ? 0 : distances[i] / maxDist;\n let wi = tricube(u);\n if (robustWeights && robustWeights[actualStart + i] != null) {\n wi *= robustWeights[actualStart + i];\n }\n w[i] = wi;\n sumw += wi;\n }\n\n if (sumw === 0) {\n // fallback to nearest y\n const nearestIdx = left < n ? left : n - 1;\n return ptsY[nearestIdx];\n }\n\n if (degree === 0) {\n let s = 0;\n for (let i = 0; i < w.length; i++) {\n s += w[i] * ptsY[actualStart + i];\n }\n return s / sumw;\n }\n\n // weighted linear regression on local points\n let sw = 0;\n let sx = 0;\n let sy = 0;\n let sxx = 0;\n let sxy = 0;\n for (let i = actualStart; i < end; i++) {\n const idx = i - actualStart;\n const xi = ptsX[i];\n const yi = ptsY[i];\n const wi = w[idx];\n sw += wi;\n sx += wi * xi;\n sy += wi * yi;\n sxx += wi * xi * xi;\n sxy += wi * xi * yi;\n }\n\n const meanX = sx / sw;\n const meanY = sy / sw;\n const denom = sxx - sx * meanX;\n const slope = Math.abs(denom) < 1e-12 ? 0 : (sxy - sx * meanY) / denom;\n const intercept = meanY - slope * meanX;\n return intercept + slope * x0;\n }\n\n function predict(x0: number | number[]) {\n if (Array.isArray(x0)) {\n const len = x0.length;\n const out: number[] = new Array(len);\n for (let i = 0; i < len; i++) {\n out[i] = predictSingle(x0[i]);\n }\n return out;\n }\n return predictSingle(x0 as number);\n }\n\n function evaluateGrid(N: number) {\n if (N <= 0) {\n return [];\n }\n if (n === 0) {\n return [];\n }\n\n const out: { x: number; y: number }[] = new Array(N);\n const min = ptsX[0];\n const max = ptsX[n - 1];\n\n if (min === max) {\n const v = predictSingle(min);\n for (let i = 0; i < N; i++) {\n out[i] = { x: min, y: v };\n }\n return out;\n }\n const step = (max - min) / (N - 1);\n\n // optionally add robust iterations\n let robustWeights: number[] | undefined;\n\n // Disable robustness iterations for large datasets to improve performance\n // Users can override by setting iterations explicitly\n const effectiveIterations = options.iterations != null ? iterations : n > 500 ? 0 : iterations;\n\n if (effectiveIterations > 0) {\n for (let iter = 0; iter < effectiveIterations; iter++) {\n // compute fits - pre-allocate arrays\n const fits: number[] = new Array(n);\n const res: number[] = new Array(n);\n\n for (let i = 0; i < n; i++) {\n fits[i] = predictSingle(ptsX[i], robustWeights);\n res[i] = Math.abs(ptsY[i] - fits[i]);\n }\n\n // median absolute deviation\n const sortedRes = res.slice().sort((a, b) => a - b);\n const med = sortedRes[Math.floor(n / 2)] || 0;\n robustWeights = new Array(n);\n for (let i = 0; i < n; i++) {\n const u = med === 0 ? 0 : res[i] / (6 * med);\n const w = Math.abs(u) >= 1 ? 0 : (1 - u * u) * (1 - u * u);\n robustWeights[i] = w;\n }\n }\n }\n\n for (let i = 0; i < N; i++) {\n const px = i === N - 1 ? max : min + step * i;\n out[i] = { x: px, y: predictSingle(px, robustWeights) };\n }\n return out;\n }\n\n function confidenceInterval(N: number = 50) {\n const out: { x: number; mean: number; lower: number; upper: number; predLower: number; predUpper: number }[] = [];\n\n if (N <= 0) {\n return out;\n }\n if (n === 0) {\n return out;\n }\n\n // use data x-range (already sorted)\n const min = ptsX[0];\n const max = ptsX[n - 1];\n\n if (min === undefined || max === undefined || min === Infinity || max === -Infinity) {\n return out;\n }\n\n const comps = computeLinearCIComponents(data, x, y, (xx: number) => predictSingle(xx));\n if (comps.n === 0) {\n return out;\n }\n\n const z = Math.abs(invNorm(1 - alpha / 2));\n if (comps.min === comps.max) {\n const v = predictSingle(comps.min);\n const errs = stdErrorsAt(comps.min, comps);\n for (let i = 0; i < N; i++) {\n out.push({\n x: comps.min,\n mean: v,\n lower: v - z * errs.seMean,\n upper: v + z * errs.seMean,\n predLower: v - z * errs.sePred,\n predUpper: v + z * errs.sePred\n });\n }\n return out;\n }\n\n const step = (max - min) / (N - 1);\n for (let i = 0; i < N; i++) {\n const px = i === N - 1 ? max : min + step * i;\n const yh = predictSingle(px);\n const errs = stdErrorsAt(px, comps);\n out.push({\n x: px,\n mean: yh,\n lower: yh - z * errs.seMean,\n upper: yh + z * errs.seMean,\n predLower: yh - z * errs.sePred,\n predUpper: yh + z * errs.sePred\n });\n }\n return out;\n }\n\n return {\n predict,\n evaluate: predict as any,\n evaluateGrid,\n confidenceInterval\n };\n}\n\nexport default regressionLowess;\n"]}
@@ -169,4 +169,4 @@ class OBBBounds extends Bounds {
169
169
  }
170
170
 
171
171
  exports.OBBBounds = OBBBounds;
172
- //# sourceMappingURL=bounds.js.map
172
+ //# sourceMappingURL=bounds.js.map
@@ -111,4 +111,5 @@ class HashTable {
111
111
  toImmutableMap() {}
112
112
  }
113
113
 
114
- exports.HashTable = HashTable;
114
+ exports.HashTable = HashTable;
115
+ //# sourceMappingURL=hashTable.js.map
@@ -19,4 +19,4 @@ Object.defineProperty(exports, "__esModule", {
19
19
  value: !0
20
20
  }), __exportStar(require("./hashTable"), exports), __exportStar(require("./point"), exports),
21
21
  __exportStar(require("./bounds"), exports), __exportStar(require("./matrix"), exports);
22
- //# sourceMappingURL=index.js.map
22
+ //# sourceMappingURL=index.js.map
@@ -110,4 +110,4 @@ function normalTransform(out, origin, x, y, scaleX, scaleY, angle, rotateCenter)
110
110
  }
111
111
 
112
112
  exports.Matrix = Matrix, exports.normalTransform = normalTransform;
113
- //# sourceMappingURL=matrix.js.map
113
+ //# sourceMappingURL=matrix.js.map
@@ -78,4 +78,4 @@ class PolarPoint {
78
78
  }
79
79
 
80
80
  exports.PolarPoint = PolarPoint;
81
- //# sourceMappingURL=point.js.map
81
+ //# sourceMappingURL=point.js.map
package/dist/index.js CHANGED
@@ -2074,49 +2074,87 @@
2074
2074
  const t = 1 - uu * uu * uu;
2075
2075
  return t * t * t;
2076
2076
  }
2077
+ function stratifiedSample(sortedData, maxSamples) {
2078
+ const n = sortedData.length;
2079
+ if (n <= maxSamples) {
2080
+ return sortedData;
2081
+ }
2082
+ const sampled = [];
2083
+ const step = n / maxSamples;
2084
+ for (let i = 0; i < maxSamples; i++) {
2085
+ const idx = Math.min(Math.floor(i * step), n - 1);
2086
+ sampled.push(sortedData[idx]);
2087
+ }
2088
+ return sampled;
2089
+ }
2077
2090
  function regressionLowess(data, x = d => d.x, y = d => d.y, options = {}) {
2078
2091
  var _a;
2079
2092
  const span = options.span || 0.3;
2080
2093
  const degree = options.degree === 0 ? 0 : 1;
2081
- const alpha = (_a = options === null || options === void 0 ? void 0 : options.alpha) !== null && _a !== void 0 ? _a : 0.05;
2094
+ const alpha = (_a = options.alpha) !== null && _a !== void 0 ? _a : 0.05;
2082
2095
  const iterations = options.iterations == null ? 2 : options.iterations;
2083
- const ptsX = [];
2084
- const ptsY = [];
2096
+ const maxSamples = options.maxSamples || 1000;
2097
+ const rawPoints = [];
2085
2098
  visitPoints(data, x, y, (dx, dy) => {
2086
- ptsX.push(dx);
2087
- ptsY.push(dy);
2099
+ rawPoints.push({ x: dx, y: dy });
2088
2100
  });
2089
- const n = ptsX.length;
2101
+ rawPoints.sort((a, b) => a.x - b.x);
2102
+ const sampledPoints = stratifiedSample(rawPoints, maxSamples);
2103
+ const n = sampledPoints.length;
2104
+ const ptsX = new Array(n);
2105
+ const ptsY = new Array(n);
2106
+ for (let i = 0; i < n; i++) {
2107
+ ptsX[i] = sampledPoints[i].x;
2108
+ ptsY[i] = sampledPoints[i].y;
2109
+ }
2090
2110
  function predictSingle(x0, robustWeights) {
2091
2111
  if (n === 0) {
2092
2112
  return 0;
2093
2113
  }
2094
- const dists = [];
2095
- for (let i = 0; i < n; i++) {
2096
- dists.push({ idx: i, dist: Math.abs(ptsX[i] - x0) });
2114
+ let left = 0;
2115
+ let right = n;
2116
+ while (left < right) {
2117
+ const mid = (left + right) >> 1;
2118
+ if (ptsX[mid] < x0) {
2119
+ left = mid + 1;
2120
+ }
2121
+ else {
2122
+ right = mid;
2123
+ }
2097
2124
  }
2098
- dists.sort((a, b) => a.dist - b.dist);
2099
2125
  const m = Math.max(2, Math.min(n, Math.floor(span * n)));
2100
- const maxDist = dists[m - 1].dist || 0;
2101
- const w = new Array(m);
2126
+ const start = Math.max(0, left - Math.floor(m / 2));
2127
+ const end = Math.min(n, start + m);
2128
+ const actualStart = Math.max(0, end - m);
2129
+ let maxDist = 0;
2130
+ const windowSize = end - actualStart;
2131
+ const distances = new Array(windowSize);
2132
+ for (let i = actualStart; i < end; i++) {
2133
+ const dist = Math.abs(ptsX[i] - x0);
2134
+ distances[i - actualStart] = dist;
2135
+ if (dist > maxDist) {
2136
+ maxDist = dist;
2137
+ }
2138
+ }
2102
2139
  let sumw = 0;
2103
- for (let i = 0; i < m; i++) {
2104
- const idx = dists[i].idx;
2105
- const u = maxDist === 0 ? 0 : dists[i].dist / maxDist;
2140
+ const w = new Array(windowSize);
2141
+ for (let i = 0; i < windowSize; i++) {
2142
+ const u = maxDist === 0 ? 0 : distances[i] / maxDist;
2106
2143
  let wi = tricube(u);
2107
- if (robustWeights && robustWeights[idx] != null) {
2108
- wi *= robustWeights[idx];
2144
+ if (robustWeights && robustWeights[actualStart + i] != null) {
2145
+ wi *= robustWeights[actualStart + i];
2109
2146
  }
2110
2147
  w[i] = wi;
2111
2148
  sumw += wi;
2112
2149
  }
2113
2150
  if (sumw === 0) {
2114
- return ptsY[dists[0].idx];
2151
+ const nearestIdx = left < n ? left : n - 1;
2152
+ return ptsY[nearestIdx];
2115
2153
  }
2116
2154
  if (degree === 0) {
2117
2155
  let s = 0;
2118
- for (let i = 0; i < m; i++) {
2119
- s += w[i] * ptsY[dists[i].idx];
2156
+ for (let i = 0; i < w.length; i++) {
2157
+ s += w[i] * ptsY[actualStart + i];
2120
2158
  }
2121
2159
  return s / sumw;
2122
2160
  }
@@ -2125,11 +2163,11 @@
2125
2163
  let sy = 0;
2126
2164
  let sxx = 0;
2127
2165
  let sxy = 0;
2128
- for (let i = 0; i < m; i++) {
2129
- const idx = dists[i].idx;
2130
- const xi = ptsX[idx];
2131
- const yi = ptsY[idx];
2132
- const wi = w[i];
2166
+ for (let i = actualStart; i < end; i++) {
2167
+ const idx = i - actualStart;
2168
+ const xi = ptsX[i];
2169
+ const yi = ptsY[i];
2170
+ const wi = w[idx];
2133
2171
  sw += wi;
2134
2172
  sx += wi * xi;
2135
2173
  sy += wi * yi;
@@ -2145,62 +2183,56 @@
2145
2183
  }
2146
2184
  function predict(x0) {
2147
2185
  if (Array.isArray(x0)) {
2148
- const out = [];
2149
- for (let i = 0; i < x0.length; i++) {
2150
- out.push(predictSingle(x0[i]));
2186
+ const len = x0.length;
2187
+ const out = new Array(len);
2188
+ for (let i = 0; i < len; i++) {
2189
+ out[i] = predictSingle(x0[i]);
2151
2190
  }
2152
2191
  return out;
2153
2192
  }
2154
2193
  return predictSingle(x0);
2155
2194
  }
2156
2195
  function evaluateGrid(N) {
2157
- const out = [];
2158
2196
  if (N <= 0) {
2159
- return out;
2197
+ return [];
2160
2198
  }
2161
2199
  if (n === 0) {
2162
- return out;
2163
- }
2164
- let min = Infinity;
2165
- let max = -Infinity;
2166
- for (let i = 0; i < n; i++) {
2167
- if (ptsX[i] < min) {
2168
- min = ptsX[i];
2169
- }
2170
- if (ptsX[i] > max) {
2171
- max = ptsX[i];
2172
- }
2200
+ return [];
2173
2201
  }
2202
+ const out = new Array(N);
2203
+ const min = ptsX[0];
2204
+ const max = ptsX[n - 1];
2174
2205
  if (min === max) {
2175
2206
  const v = predictSingle(min);
2176
2207
  for (let i = 0; i < N; i++) {
2177
- out.push({ x: min, y: v });
2208
+ out[i] = { x: min, y: v };
2178
2209
  }
2179
2210
  return out;
2180
2211
  }
2181
2212
  const step = (max - min) / (N - 1);
2182
2213
  let robustWeights;
2183
- for (let iter = 0; iter < iterations; iter++) {
2184
- const fits = [];
2185
- for (let i = 0; i < n; i++) {
2186
- fits.push(predictSingle(ptsX[i], robustWeights));
2187
- }
2188
- const res = [];
2189
- for (let i = 0; i < n; i++) {
2190
- res.push(Math.abs(ptsY[i] - fits[i]));
2191
- }
2192
- const sortedRes = res.slice().sort((a, b) => a - b);
2193
- const med = sortedRes[Math.floor(n / 2)] || 0;
2194
- robustWeights = new Array(n);
2195
- for (let i = 0; i < n; i++) {
2196
- const u = med === 0 ? 0 : res[i] / (6 * med);
2197
- const w = Math.abs(u) >= 1 ? 0 : (1 - u * u) * (1 - u * u);
2198
- robustWeights[i] = w;
2214
+ const effectiveIterations = options.iterations != null ? iterations : n > 500 ? 0 : iterations;
2215
+ if (effectiveIterations > 0) {
2216
+ for (let iter = 0; iter < effectiveIterations; iter++) {
2217
+ const fits = new Array(n);
2218
+ const res = new Array(n);
2219
+ for (let i = 0; i < n; i++) {
2220
+ fits[i] = predictSingle(ptsX[i], robustWeights);
2221
+ res[i] = Math.abs(ptsY[i] - fits[i]);
2222
+ }
2223
+ const sortedRes = res.slice().sort((a, b) => a - b);
2224
+ const med = sortedRes[Math.floor(n / 2)] || 0;
2225
+ robustWeights = new Array(n);
2226
+ for (let i = 0; i < n; i++) {
2227
+ const u = med === 0 ? 0 : res[i] / (6 * med);
2228
+ const w = Math.abs(u) >= 1 ? 0 : (1 - u * u) * (1 - u * u);
2229
+ robustWeights[i] = w;
2230
+ }
2199
2231
  }
2200
2232
  }
2201
2233
  for (let i = 0; i < N; i++) {
2202
2234
  const px = i === N - 1 ? max : min + step * i;
2203
- out.push({ x: px, y: predictSingle(px, robustWeights) });
2235
+ out[i] = { x: px, y: predictSingle(px, robustWeights) };
2204
2236
  }
2205
2237
  return out;
2206
2238
  }
@@ -2212,17 +2244,9 @@
2212
2244
  if (n === 0) {
2213
2245
  return out;
2214
2246
  }
2215
- let min = Infinity;
2216
- let max = -Infinity;
2217
- for (let i = 0; i < n; i++) {
2218
- if (ptsX[i] < min) {
2219
- min = ptsX[i];
2220
- }
2221
- if (ptsX[i] > max) {
2222
- max = ptsX[i];
2223
- }
2224
- }
2225
- if (min === Infinity || max === -Infinity) {
2247
+ const min = ptsX[0];
2248
+ const max = ptsX[n - 1];
2249
+ if (min === undefined || max === undefined || min === Infinity || max === -Infinity) {
2226
2250
  return out;
2227
2251
  }
2228
2252
  const comps = computeLinearCIComponents(data, x, y, (xx) => predictSingle(xx));