@visactor/vutils 1.0.25 → 1.0.26

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 (70) hide show
  1. package/REGRESSION.md +36 -0
  2. package/cjs/common/ascending.js +2 -1
  3. package/cjs/common/deviation.js +1 -2
  4. package/cjs/common/getType.js +2 -1
  5. package/cjs/common/index.d.ts +1 -0
  6. package/cjs/common/index.js +2 -1
  7. package/cjs/common/index.js.map +1 -1
  8. package/cjs/common/isFunction.js +1 -2
  9. package/cjs/common/isObject.js +2 -1
  10. package/cjs/common/isPrototype.js +1 -1
  11. package/cjs/common/isRegExp.js +1 -1
  12. package/cjs/common/isShallowEqual.js +1 -1
  13. package/cjs/common/isString.js +1 -1
  14. package/cjs/common/isType.js +1 -1
  15. package/cjs/common/regression-bootstrap.d.ts +14 -0
  16. package/cjs/common/regression-bootstrap.js +37 -0
  17. package/cjs/common/regression-bootstrap.js.map +1 -0
  18. package/cjs/common/regression-linear.d.ts +1 -0
  19. package/cjs/common/regression-linear.js +11 -29
  20. package/cjs/common/regression-linear.js.map +1 -1
  21. package/cjs/common/regression-lowess.d.ts +9 -8
  22. package/cjs/common/regression-lowess.js +109 -130
  23. package/cjs/common/regression-lowess.js.map +1 -1
  24. package/cjs/common/regression-polynomial.d.ts +1 -0
  25. package/cjs/common/regression-polynomial.js +11 -92
  26. package/cjs/common/regression-polynomial.js.map +1 -1
  27. package/cjs/common/regression-solver.d.ts +26 -0
  28. package/cjs/common/regression-solver.js +180 -0
  29. package/cjs/common/regression-solver.js.map +1 -0
  30. package/cjs/data-structure/bounds.js +1 -1
  31. package/cjs/data-structure/hashTable.js +1 -2
  32. package/cjs/data-structure/index.js +1 -1
  33. package/cjs/data-structure/matrix.js +1 -1
  34. package/cjs/data-structure/point.js +1 -1
  35. package/dist/index.js +471 -340
  36. package/dist/index.min.js +16 -16
  37. package/es/common/ascending.js +2 -1
  38. package/es/common/deviation.js +1 -2
  39. package/es/common/getType.js +2 -1
  40. package/es/common/index.d.ts +1 -0
  41. package/es/common/index.js +2 -0
  42. package/es/common/index.js.map +1 -1
  43. package/es/common/isFunction.js +1 -2
  44. package/es/common/isObject.js +2 -1
  45. package/es/common/isPrototype.js +1 -1
  46. package/es/common/isRegExp.js +1 -1
  47. package/es/common/isShallowEqual.js +1 -1
  48. package/es/common/isString.js +1 -1
  49. package/es/common/isType.js +1 -1
  50. package/es/common/regression-bootstrap.d.ts +14 -0
  51. package/es/common/regression-bootstrap.js +31 -0
  52. package/es/common/regression-bootstrap.js.map +1 -0
  53. package/es/common/regression-linear.d.ts +1 -0
  54. package/es/common/regression-linear.js +9 -27
  55. package/es/common/regression-linear.js.map +1 -1
  56. package/es/common/regression-lowess.d.ts +9 -8
  57. package/es/common/regression-lowess.js +106 -130
  58. package/es/common/regression-lowess.js.map +1 -1
  59. package/es/common/regression-polynomial.d.ts +1 -0
  60. package/es/common/regression-polynomial.js +9 -86
  61. package/es/common/regression-polynomial.js.map +1 -1
  62. package/es/common/regression-solver.d.ts +26 -0
  63. package/es/common/regression-solver.js +168 -0
  64. package/es/common/regression-solver.js.map +1 -0
  65. package/es/data-structure/bounds.js +1 -1
  66. package/es/data-structure/hashTable.js +1 -2
  67. package/es/data-structure/index.js +1 -1
  68. package/es/data-structure/matrix.js +1 -1
  69. package/es/data-structure/point.js +1 -1
  70. package/package.json +5 -4
package/REGRESSION.md ADDED
@@ -0,0 +1,36 @@
1
+ # 一元回归与成对 bootstrap 契约
2
+
3
+ 本轮修正面向 VUtil 1.0.25 的回归工具;正式 npm 1.0.25 不包含这些修复和新 API。
4
+
5
+ - regressionLinear:使用中心化/缩放的一元 OLS,预测在稳定坐标中求值,保留 coef.a/b。增加 rank;常量 x 的历史常数估计继续有定义,图表需要可识别斜率时由输入边界拒绝。
6
+ - regressionPolynomial:以归一化设计矩阵做增量 Givens QR;秩不足时对小型 R 做 Jacobi SVD 得到最小范数解,增加 rank,不再返回伪造零系数。coef 保持升幂的原始 x 坐标含义,predict 用稳定基底。degree 为非负整数,默认仍为 0。原始系数不能有限表示时明确报 RangeError。
7
+ - regressionLowess:默认 span 从 0.3 改为 2/3、iterations 从 2 改为 3,使用全部有效观测;不再隐藏抽样或按 N 关闭稳健迭代。拟合时固定稳健状态,predict/evaluateGrid/fitted 节点一致。显式 maxSamples 保留历史抽样用途,并包含端点;delta 默认为 0,正值以观测锚点插值加速,全量观测仍参与局部权重与稳健残差。fitted 按 x 排序,保留重复样本。此默认行为调整会改变旧 LOWESS 曲线,调用方需要明确选择参数。
8
+ - LOWESS 使用查询点附近的局部 x/y 坐标,避免远处观测压缩近邻精度;只有距离或插值区间溢出时才改用归一化 x 距离。
9
+ - 等距离邻域选择较小 x,再按 y 排序,不依赖调用方行顺序。相同 x 的零半径邻域包含所有相同 x 观测。零核权重时用最近有效观测的加权常数,等距离取均值;没有有效稳健观测时明确报错。median=0 时保留数值精度内零残差点的权重,对明显非零残差赋零权重。
10
+ - regressionBootstrap 从包根导出,仅 linear/polynomial。options 为 method/degree?/grid/level/resamples/seed,完整 (x,y) 成对有放回抽样,每次拟合一次。原始组须有满秩设计及正残差自由度,退化重采样在原始固定归一化基底中取最小范数解,不删抽样或重抽。每个 grid 位置按线性插值分位数生成 lower/upper,表示均值响应的逐点 percentile CI,不是预测区间。
11
+
12
+ 既有 confidenceInterval 的正态临界值与旧区间用途没有在本轮改成 bootstrap。尤其旧多项式/LOWESS 区间近似不能用来声称符合新的回归置信带契约;完整整理独立处理。
13
+
14
+ 缺失 accessor 的既有排除行为保留;无穷大不参与拟合,StatPlots 另有更严格的有限原始观测边界。新增求解器不修改输入。bootstrap 在内部对配对排序,同组同 seed 可复现;不承诺与 NumPy RNG 相同。
15
+
16
+ 独立数值对照使用 __tests__/fixtures/regression-python.json 的固定参考数据,文件记录参考环境的 Python、NumPy 和 statsmodels 版本;TypeScript 测试直接读取 JSON,无需 Python 运行环境。LOWESS 正常非退化数据对照 statsmodels,bootstrap 重放同一抽样索引后对照 NumPy 最小二乘与分位数。退化/ties 行为及坐标基底差异单独声明,不承诺全部参数逐位相同。
17
+
18
+ 性能在真实 Node 构建产物测量,避免 Jest VM 对 Math 属性代理的显著额外成本;先 npm run build,再运行 lowess-performance.test.ts 或 node benchmarks/lowess.cjs。保留原 100/150/200ms 预算,使用显式 delta 并断言所有节点保留,精确路径另由数值测试和浏览器实测覆盖。VUtils 的 Jest 配置使用单 worker,CI 的 Rush test 使用 --parallelism 1,避免同包或其他包并发测试影响墙钟预算;所有单元与性能用例均执行。
19
+
20
+ ## 调用示例
21
+
22
+ ```ts
23
+ import { regressionLinear, regressionBootstrap, regressionLowess } from '@visactor/vutils';
24
+
25
+ const samples = [{ x: 0, y: 1 }, { x: 1, y: 3 }, { x: 2, y: 4 }, { x: 3, y: 7 }];
26
+ const model = regressionLinear(samples);
27
+ const curve = model.evaluateGrid(100);
28
+ const bounds = regressionBootstrap(samples, {
29
+ method: 'linear', grid: curve.map(p => p.x), level: 0.95, resamples: 1000, seed: 0
30
+ });
31
+ const smooth = regressionLowess(samples, undefined, undefined, { span: 2 / 3, iterations: 3, delta: 0 });
32
+ // bounds 与 curve 使用相同 x;LOWESS 的 fitted 保留排序后的全部有效观测。
33
+ const prediction = smooth.predict(1);
34
+ ```
35
+
36
+ bootstrap 的 level 严格在 (0,1),resamples 为正整数,seed 为 uint32;grid 为有限数字数组。主模型不满秩或没有残差自由度时抛出 RangeError。bootstrap 的多项式使用 method='polynomial' 和正整数 degree。图表层可采用更严格的次数和预算上限,不改变通用求解器契约。
@@ -6,4 +6,5 @@ function ascending(a, b) {
6
6
 
7
7
  Object.defineProperty(exports, "__esModule", {
8
8
  value: !0
9
- }), exports.ascending = void 0, exports.ascending = ascending;
9
+ }), exports.ascending = void 0, exports.ascending = ascending;
10
+ //# sourceMappingURL=ascending.js.map
@@ -11,5 +11,4 @@ function deviation(values, valueof) {
11
11
  return v ? Math.sqrt(v) : v;
12
12
  }
13
13
 
14
- exports.deviation = deviation;
15
- //# sourceMappingURL=deviation.js.map
14
+ exports.deviation = deviation;
@@ -6,4 +6,5 @@ Object.defineProperty(exports, "__esModule", {
6
6
 
7
7
  const getType = value => ({}.toString.call(value).replace(/^\[object /, "").replace(/]$/, ""));
8
8
 
9
- exports.default = getType;
9
+ exports.default = getType;
10
+ //# sourceMappingURL=getType.js.map
@@ -71,3 +71,4 @@ export * from './ecdf';
71
71
  export * from './correlation';
72
72
  export * from './mean';
73
73
  export * from './bootstrap';
74
+ export * from './regression-bootstrap';
@@ -551,5 +551,6 @@ __exportStar(require("./extent"), exports), __exportStar(require("./regression-l
551
551
  __exportStar(require("./regression-logistic"), exports), __exportStar(require("./regression-lowess"), exports),
552
552
  __exportStar(require("./regression-polynomial"), exports), __exportStar(require("./kde"), exports),
553
553
  __exportStar(require("./ecdf"), exports), __exportStar(require("./correlation"), exports),
554
- __exportStar(require("./mean"), exports), __exportStar(require("./bootstrap"), exports);
554
+ __exportStar(require("./mean"), exports), __exportStar(require("./bootstrap"), exports),
555
+ __exportStar(require("./regression-bootstrap"), exports);
555
556
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/common/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// type check\nexport { default as isBoolean } from './isBoolean';\nexport { default as isFunction } from './isFunction';\nexport { default as isNil } from './isNil';\nexport { default as isNull } from './isNull';\nexport { default as isValid } from './isValid';\nexport { default as isObject } from './isObject';\nexport { default as isObjectLike } from './isObjectLike';\nexport { default as isPlainObject } from './isPlainObject';\nexport { default as isType } from './isType';\nexport { default as isUndefined } from './isUndefined';\nexport { default as isString } from './isString';\nexport { default as isArray } from './isArray';\nexport { default as isArrayLike } from './isArrayLike';\nexport { default as isDate } from './isDate';\nexport { default as isNumber } from './isNumber';\nexport { default as isNumeric } from './isNumeric';\nexport { default as isValidNumber } from './isValidNumber';\nexport { default as isValidUrl } from './isValidUrl';\nexport { default as isRegExp } from './isRegExp';\nexport { default as isBase64 } from './isBase64';\n\nexport { default as isEmpty } from './isEmpty';\n\n// object\nexport { default as get } from './get';\nexport { default as has } from './has';\nexport { default as clone } from './clone';\nexport { default as cloneDeep } from './cloneDeep';\nexport { default as merge, baseMerge } from './merge';\nexport { default as pick } from './pick';\nexport { default as pickWithout } from './pickWithout';\nexport { isEqual } from './isEqual';\nexport { isShallowEqual } from './isShallowEqual';\nexport * from './mixin';\n\n// array\nexport * from './array';\nexport { range } from './range';\nexport { ascending } from './ascending';\nexport * from './quantileSorted';\nexport { normalQuantile } from './normalQuantile';\nexport { bisect, findZeroOfFunction, binaryFuzzySearch, binaryFuzzySearchInNumberRange } from './bisect';\nexport { deviation } from './deviation';\nexport { median } from './median';\nexport { variance } from './variance';\n\n// tick\nexport { tickStep } from './tickStep';\n\n// number\nexport * from './number';\n\n// function\nexport { default as constant } from './constant';\nexport { memoize } from './memoize';\n\n// pad\nexport { default as pad } from './pad';\nexport { default as truncate } from './truncate';\n\n// uuid\nexport { default as uuid } from './uuid';\n\n// clamp\nexport { default as clamp } from './clamp';\nexport { default as clampRange } from './clampRange';\nexport { clamper } from './clamper';\n\n// debounce & throttle\nexport { default as debounce } from './debounce';\nexport { default as throttle } from './throttle';\n\n// interpolate\nexport * from './interpolate';\n\n// type convert\nexport { toDate } from './toDate';\nexport { toNumber } from './toNumber';\nexport { toValidNumber } from './toValidNumber';\n\n// string\nexport { default as lowerFirst } from './lowerFirst';\nexport { default as upperFirst } from './upperFirst';\n\n// string format\nexport { default as substitute } from './substitute';\n\nexport * from './random';\nexport * from './field';\nexport * from './toPercent';\nexport * from './zero';\nexport * from './extent';\nexport * from './regression-linear';\nexport * from './regression-logistic';\nexport * from './regression-lowess';\nexport * from './regression-polynomial';\nexport * from './kde';\nexport * from './ecdf';\n\nexport * from './correlation';\nexport * from './mean';\nexport * from './bootstrap';\n"]}
1
+ {"version":3,"sources":["../src/common/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// type check\nexport { default as isBoolean } from './isBoolean';\nexport { default as isFunction } from './isFunction';\nexport { default as isNil } from './isNil';\nexport { default as isNull } from './isNull';\nexport { default as isValid } from './isValid';\nexport { default as isObject } from './isObject';\nexport { default as isObjectLike } from './isObjectLike';\nexport { default as isPlainObject } from './isPlainObject';\nexport { default as isType } from './isType';\nexport { default as isUndefined } from './isUndefined';\nexport { default as isString } from './isString';\nexport { default as isArray } from './isArray';\nexport { default as isArrayLike } from './isArrayLike';\nexport { default as isDate } from './isDate';\nexport { default as isNumber } from './isNumber';\nexport { default as isNumeric } from './isNumeric';\nexport { default as isValidNumber } from './isValidNumber';\nexport { default as isValidUrl } from './isValidUrl';\nexport { default as isRegExp } from './isRegExp';\nexport { default as isBase64 } from './isBase64';\n\nexport { default as isEmpty } from './isEmpty';\n\n// object\nexport { default as get } from './get';\nexport { default as has } from './has';\nexport { default as clone } from './clone';\nexport { default as cloneDeep } from './cloneDeep';\nexport { default as merge, baseMerge } from './merge';\nexport { default as pick } from './pick';\nexport { default as pickWithout } from './pickWithout';\nexport { isEqual } from './isEqual';\nexport { isShallowEqual } from './isShallowEqual';\nexport * from './mixin';\n\n// array\nexport * from './array';\nexport { range } from './range';\nexport { ascending } from './ascending';\nexport * from './quantileSorted';\nexport { normalQuantile } from './normalQuantile';\nexport { bisect, findZeroOfFunction, binaryFuzzySearch, binaryFuzzySearchInNumberRange } from './bisect';\nexport { deviation } from './deviation';\nexport { median } from './median';\nexport { variance } from './variance';\n\n// tick\nexport { tickStep } from './tickStep';\n\n// number\nexport * from './number';\n\n// function\nexport { default as constant } from './constant';\nexport { memoize } from './memoize';\n\n// pad\nexport { default as pad } from './pad';\nexport { default as truncate } from './truncate';\n\n// uuid\nexport { default as uuid } from './uuid';\n\n// clamp\nexport { default as clamp } from './clamp';\nexport { default as clampRange } from './clampRange';\nexport { clamper } from './clamper';\n\n// debounce & throttle\nexport { default as debounce } from './debounce';\nexport { default as throttle } from './throttle';\n\n// interpolate\nexport * from './interpolate';\n\n// type convert\nexport { toDate } from './toDate';\nexport { toNumber } from './toNumber';\nexport { toValidNumber } from './toValidNumber';\n\n// string\nexport { default as lowerFirst } from './lowerFirst';\nexport { default as upperFirst } from './upperFirst';\n\n// string format\nexport { default as substitute } from './substitute';\n\nexport * from './random';\nexport * from './field';\nexport * from './toPercent';\nexport * from './zero';\nexport * from './extent';\nexport * from './regression-linear';\nexport * from './regression-logistic';\nexport * from './regression-lowess';\nexport * from './regression-polynomial';\nexport * from './kde';\nexport * from './ecdf';\n\nexport * from './correlation';\nexport * from './mean';\nexport * from './bootstrap';\nexport * from './regression-bootstrap';\n"]}
@@ -32,5 +32,4 @@ Object.defineProperty(exports, "__esModule", {
32
32
  // eslint-disable-next-line @typescript-eslint/ban-types
33
33
  const isFunction = value => "function" == typeof value;
34
34
 
35
- exports.default = isFunction;
36
- //# sourceMappingURL=isFunction.js.map
35
+ exports.default = isFunction;
@@ -31,4 +31,5 @@ const isObject = value => {
31
31
  return null !== value && "object" === type || "function" === type;
32
32
  };
33
33
 
34
- exports.default = isObject;
34
+ exports.default = isObject;
35
+ //# sourceMappingURL=isObject.js.map
@@ -10,4 +10,4 @@ const objectProto = Object.prototype, isPrototype = function(value) {
10
10
  };
11
11
 
12
12
  exports.default = isPrototype;
13
- //# sourceMappingURL=isPrototype.js.map
13
+ //# sourceMappingURL=isPrototype.js.map
@@ -13,4 +13,4 @@ Object.defineProperty(exports, "__esModule", {
13
13
  const isType_1 = __importDefault(require("./isType")), isRegExp = value => (0, isType_1.default)(value, "RegExp");
14
14
 
15
15
  exports.default = isRegExp;
16
- //# sourceMappingURL=isRegExp.js.map
16
+ //# sourceMappingURL=isRegExp.js.map
@@ -32,4 +32,4 @@ function isShallowEqual(objA, objB) {
32
32
  }
33
33
 
34
34
  exports.isShallowEqual = isShallowEqual;
35
- //# sourceMappingURL=isShallowEqual.js.map
35
+ //# sourceMappingURL=isShallowEqual.js.map
@@ -28,4 +28,4 @@ const isType_1 = __importDefault(require("./isType")), isString = (value, fuzzy
28
28
  * isString(1)
29
29
  * // => false
30
30
  */ exports.default = isString;
31
- //# sourceMappingURL=isString.js.map
31
+ //# sourceMappingURL=isString.js.map
@@ -13,4 +13,4 @@ Object.defineProperty(exports, "__esModule", {
13
13
  const isType = (value, type) => Object.prototype.toString.call(value) === `[object ${type}]`;
14
14
 
15
15
  exports.default = isType;
16
- //# sourceMappingURL=isType.js.map
16
+ //# sourceMappingURL=isType.js.map
@@ -0,0 +1,14 @@
1
+ import { type RegressionPoint } from './regression-solver';
2
+ /** 成对 percentile bootstrap;每次重采样仅拟合一次,固定原始坐标基底。 */
3
+ export declare function regressionBootstrap(data: readonly RegressionPoint[], options: {
4
+ method: 'linear' | 'polynomial';
5
+ degree?: number;
6
+ grid: readonly number[];
7
+ level: number;
8
+ resamples: number;
9
+ seed: number;
10
+ }): {
11
+ x: number;
12
+ lower: number;
13
+ upper: number;
14
+ }[];
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: !0
5
+ }), exports.regressionBootstrap = void 0;
6
+
7
+ const random_1 = require("./random"), quantileSorted_1 = require("./quantileSorted"), regression_solver_1 = require("./regression-solver");
8
+
9
+ /** 成对 percentile bootstrap;每次重采样仅拟合一次,固定原始坐标基底。 */
10
+ function regressionBootstrap(data, options) {
11
+ var _a;
12
+ const degree = "linear" === options.method ? 1 : null !== (_a = options.degree) && void 0 !== _a ? _a : NaN;
13
+ if ("linear" !== options.method && "polynomial" !== options.method || !Number.isInteger(degree) || degree < 1 || !data.length || data.some((p => !Number.isFinite(p.x) || !Number.isFinite(p.y))) || options.grid.some((x => !Number.isFinite(x))) || !(options.level > 0 && options.level < 1) || !Number.isInteger(options.resamples) || options.resamples < 1 || !Number.isInteger(options.seed) || options.seed < 0 || options.seed > 4294967295) throw new RangeError("Invalid paired regression bootstrap inputs");
14
+ if (data.length <= degree + 1) throw new RangeError("Regression bootstrap requires positive residual degrees of freedom");
15
+ const sorted = data.slice().sort(((a, b) => a.x - b.x || a.y - b.y)), basis = (0,
16
+ regression_solver_1.regressionBasis)(sorted);
17
+ if ((0, regression_solver_1.fitRegression)(sorted, degree, basis).rank < degree + 1) throw new RangeError("Original regression design is rank deficient");
18
+ const random = (0, random_1.randomLCG)(options.seed), sample = new Array(sorted.length), values = options.grid.map((() => new Array(options.resamples)));
19
+ for (let b = 0; b < options.resamples; b++) {
20
+ for (let i = 0; i < sample.length; i++) sample[i] = sorted[Math.floor(random() * sorted.length)];
21
+ const model = (0, regression_solver_1.fitRegression)(sample, degree, basis);
22
+ for (let j = 0; j < options.grid.length; j++) {
23
+ const value = (0, regression_solver_1.regressionPrediction)(model, options.grid[j]);
24
+ if (!Number.isFinite(value)) throw new RangeError("Regression bootstrap prediction is not finite");
25
+ values[j][b] = value;
26
+ }
27
+ }
28
+ const tail = (1 - options.level) / 2;
29
+ return options.grid.map(((x, j) => (values[j].sort(((a, b) => a - b)), {
30
+ x: x,
31
+ lower: (0, quantileSorted_1.quantileSorted)(values[j], tail),
32
+ upper: (0, quantileSorted_1.quantileSorted)(values[j], 1 - tail)
33
+ })));
34
+ }
35
+
36
+ exports.regressionBootstrap = regressionBootstrap;
37
+ //# sourceMappingURL=regression-bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/common/regression-bootstrap.ts"],"names":[],"mappings":"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","file":"regression-bootstrap.js","sourcesContent":["import { randomLCG } from './random';\nimport { quantileSorted } from './quantileSorted';\nimport { fitRegression, regressionBasis, regressionPrediction, type RegressionPoint } from './regression-solver';\n\n/** 成对 percentile bootstrap;每次重采样仅拟合一次,固定原始坐标基底。 */\nexport function regressionBootstrap(\n data: readonly RegressionPoint[],\n options: {\n method: 'linear' | 'polynomial';\n degree?: number;\n grid: readonly number[];\n level: number;\n resamples: number;\n seed: number;\n }\n) {\n const degree = options.method === 'linear' ? 1 : options.degree ?? NaN;\n if (\n (options.method !== 'linear' && options.method !== 'polynomial') ||\n !Number.isInteger(degree) ||\n degree < 1 ||\n !data.length ||\n data.some(p => !Number.isFinite(p.x) || !Number.isFinite(p.y)) ||\n options.grid.some(x => !Number.isFinite(x)) ||\n !(options.level > 0 && options.level < 1) ||\n !Number.isInteger(options.resamples) ||\n options.resamples < 1 ||\n !Number.isInteger(options.seed) ||\n options.seed < 0 ||\n options.seed > 0xffffffff\n ) {\n throw new RangeError('Invalid paired regression bootstrap inputs');\n }\n if (data.length <= degree + 1) {\n throw new RangeError('Regression bootstrap requires positive residual degrees of freedom');\n }\n const sorted = data.slice().sort((a, b) => a.x - b.x || a.y - b.y);\n const basis = regressionBasis(sorted);\n if (fitRegression(sorted, degree, basis).rank < degree + 1) {\n throw new RangeError('Original regression design is rank deficient');\n }\n const random = randomLCG(options.seed);\n const sample = new Array<RegressionPoint>(sorted.length);\n const values = options.grid.map(() => new Array<number>(options.resamples));\n for (let b = 0; b < options.resamples; b++) {\n for (let i = 0; i < sample.length; i++) {\n sample[i] = sorted[Math.floor(random() * sorted.length)];\n }\n const model = fitRegression(sample, degree, basis);\n for (let j = 0; j < options.grid.length; j++) {\n const value = regressionPrediction(model, options.grid[j]);\n if (!Number.isFinite(value)) {\n throw new RangeError('Regression bootstrap prediction is not finite');\n }\n values[j][b] = value;\n }\n }\n const tail = (1 - options.level) / 2;\n return options.grid.map((x, j) => {\n values[j].sort((a, b) => a - b);\n return { x, lower: quantileSorted(values[j], tail), upper: quantileSorted(values[j], 1 - tail) };\n });\n}\n"]}
@@ -15,6 +15,7 @@ export declare function regressionLinear(data: any[], x?: (d: any) => number, y?
15
15
  a: number;
16
16
  b: number;
17
17
  };
18
+ rank: number;
18
19
  predict: (xx: number) => number;
19
20
  rSquared: number;
20
21
  evaluateGrid: (N: number) => {
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "__esModule", {
10
10
  value: !0
11
11
  }), exports.regressionLinear = exports.rSquared = exports.visitPoints = exports.ordinaryLeastSquares = void 0;
12
12
 
13
- const isNil_1 = __importDefault(require("./isNil")), regression_utils_1 = require("./regression-utils");
13
+ const isNil_1 = __importDefault(require("./isNil")), regression_solver_1 = require("./regression-solver"), regression_utils_1 = require("./regression-utils");
14
14
 
15
15
  /**
16
16
  * Linear regression utilities (single clean implementation).
@@ -54,41 +54,23 @@ function rSquared(data, x, y, uY, predict) {
54
54
 
55
55
  function regressionLinear(data, x = (d => d.x), y = (d => d.y), options) {
56
56
  var _a;
57
- const alpha = null !== (_a = null == options ? void 0 : options.alpha) && void 0 !== _a ? _a : .05;
58
- // accumulate online means (sufficient statistics)
59
- let n = 0, meanX = 0, meanY = 0, meanXY = 0, meanX2 = 0;
60
- visitPoints(data, x, y, ((xi, yi) => {
61
- n++, meanX += (xi - meanX) / n, meanY += (yi - meanY) / n, meanXY += (xi * yi - meanXY) / n,
62
- meanX2 += (xi * xi - meanX2) / n;
63
- }));
64
- const {a: a, b: b} = ordinaryLeastSquares(meanX, meanY, meanXY, meanX2), predict = xx => a + b * xx, comps = (0,
65
- regression_utils_1.computeLinearCIComponents)(data, x, y, predict);
66
- return {
57
+ const alpha = null !== (_a = null == options ? void 0 : options.alpha) && void 0 !== _a ? _a : .05, points = (0,
58
+ regression_solver_1.regressionPoints)(data, x, y), model = (0, regression_solver_1.fitRegression)(points, 1), coef = (0,
59
+ regression_solver_1.regressionCoefficients)(model), a = coef[0], b = coef[1], predict = xx => (0,
60
+ regression_solver_1.regressionPrediction)(model, xx), comps = (0, regression_utils_1.computeLinearCIComponents)(data, x, y, predict);
61
+ let meanY = 0;
62
+ return points.forEach(((p, i) => {
63
+ meanY += (p.y - meanY) / (i + 1);
64
+ })), {
67
65
  coef: {
68
66
  a: a,
69
67
  b: b
70
68
  },
69
+ rank: model.rank,
71
70
  predict: predict,
72
71
  rSquared: rSquared(data, x, y, meanY, predict),
73
72
  evaluateGrid: function(N) {
74
- const out = [];
75
- if (0 === comps.n || N <= 0) return out;
76
- if (comps.min === comps.max) {
77
- for (let i = 0; i < N; i++) out.push({
78
- x: comps.min,
79
- y: predict(comps.min)
80
- });
81
- return out;
82
- }
83
- const step = (comps.max - comps.min) / (N - 1);
84
- for (let i = 0; i < N; i++) {
85
- const px = i === N - 1 ? comps.max : comps.min + step * i;
86
- out.push({
87
- x: px,
88
- y: predict(px)
89
- });
90
- }
91
- return out;
73
+ return (0, regression_solver_1.regressionGrid)(comps.min, comps.max, N, predict);
92
74
  },
93
75
  confidenceInterval: function(N = 50) {
94
76
  const out = [];
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/common/regression-linear.ts"],"names":[],"mappings":"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","file":"regression-linear.js","sourcesContent":["import isNil from './isNil';\nimport {\n computeLinearCIComponents,\n confidenceCriticalValue,\n confidenceHalfWidth,\n stdErrorsAt\n} from './regression-utils';\n\n/**\n * Linear regression utilities (single clean implementation).\n * Exports: ordinaryLeastSquares, visitPoints, rSquared, regressionLinear\n */\n\nexport function ordinaryLeastSquares(uX: number, uY: number, uXY: number, uX2: number) {\n const denom = uX2 - uX * uX;\n if (Math.abs(denom) < Number.EPSILON) {\n return { a: uY, b: 0 };\n }\n const b = (uXY - uX * uY) / denom;\n const a = uY - b * uX;\n return { a, b };\n}\n\nexport function visitPoints(\n data: any[],\n x: (d: any) => number,\n y: (d: any) => number,\n callback: (x: number, y: number, index: number) => void\n) {\n for (let i = 0; i < data.length; i++) {\n const d = data[i];\n let xi = x(d);\n let yi = y(d);\n if (!isNil(xi) && (xi = +xi) >= xi && !isNil(yi) && (yi = +yi) >= yi) {\n callback(xi, yi, i);\n }\n }\n}\n\nexport function rSquared(\n data: any[],\n x: (d: any) => number,\n y: (d: any) => number,\n uY: number,\n predict: (x: number) => number\n) {\n let ssr = 0;\n let sst = 0;\n for (let i = 0; i < data.length; i++) {\n const d = data[i];\n let yi = y(d);\n if (!isNil(yi) && (yi = +yi) >= yi) {\n const p = predict(x(d));\n const r = yi - p;\n ssr += r * r;\n const t = yi - uY;\n sst += t * t;\n }\n }\n return sst === 0 ? 0 : 1 - ssr / sst;\n}\n\nexport function regressionLinear(\n data: any[],\n x: (d: any) => number = d => d.x,\n y: (d: any) => number = d => d.y,\n options?: {\n alpha?: number;\n }\n) {\n const alpha = options?.alpha ?? 0.05;\n // accumulate online means (sufficient statistics)\n let n = 0;\n let meanX = 0;\n let meanY = 0;\n let meanXY = 0;\n let meanX2 = 0;\n\n visitPoints(data, x, y, (xi, yi) => {\n n++;\n meanX += (xi - meanX) / n;\n meanY += (yi - meanY) / n;\n meanXY += (xi * yi - meanXY) / n;\n meanX2 += (xi * xi - meanX2) / n;\n });\n\n const { a, b } = ordinaryLeastSquares(meanX, meanY, meanXY, meanX2);\n const predict = (xx: number) => a + b * xx;\n\n const comps = computeLinearCIComponents(data, x, y, predict);\n\n function evaluateGrid(N: number) {\n const out: { x: number; y: number }[] = [];\n if (comps.n === 0 || N <= 0) {\n return out;\n }\n if (comps.min === comps.max) {\n for (let i = 0; i < N; i++) {\n out.push({ x: comps.min, y: predict(comps.min) });\n }\n return out;\n }\n const step = (comps.max - comps.min) / (N - 1);\n for (let i = 0; i < N; i++) {\n const px = i === N - 1 ? comps.max : comps.min + step * i;\n out.push({ x: px, y: predict(px) });\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 if (comps.n === 0 || N <= 0) {\n return out;\n }\n const z = confidenceCriticalValue(alpha);\n if (comps.min === comps.max) {\n const m = predict(comps.min);\n const errs = stdErrorsAt(comps.min, comps);\n const meanHalfWidth = confidenceHalfWidth(z, errs.seMean);\n const predHalfWidth = confidenceHalfWidth(z, errs.sePred);\n for (let i = 0; i < N; i++) {\n out.push({\n x: comps.min,\n mean: m,\n lower: m - meanHalfWidth,\n upper: m + meanHalfWidth,\n predLower: m - predHalfWidth,\n predUpper: m + predHalfWidth\n });\n }\n return out;\n }\n const step = (comps.max - comps.min) / (N - 1);\n for (let i = 0; i < N; i++) {\n const px = i === N - 1 ? comps.max : comps.min + step * i;\n const m = predict(px);\n const errs = stdErrorsAt(px, comps);\n const meanHalfWidth = confidenceHalfWidth(z, errs.seMean);\n const predHalfWidth = confidenceHalfWidth(z, errs.sePred);\n out.push({\n x: px,\n mean: m,\n lower: m - meanHalfWidth,\n upper: m + meanHalfWidth,\n predLower: m - predHalfWidth,\n predUpper: m + predHalfWidth\n });\n }\n return out;\n }\n\n return {\n coef: { a, b },\n predict,\n rSquared: rSquared(data, x, y, meanY, predict),\n evaluateGrid,\n confidenceInterval\n };\n}\n\nexport default {\n ordinaryLeastSquares,\n visitPoints,\n rSquared,\n regressionLinear\n};\n"]}
1
+ {"version":3,"sources":["../src/common/regression-linear.ts"],"names":[],"mappings":"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","file":"regression-linear.js","sourcesContent":["import isNil from './isNil';\nimport {\n regressionPoints,\n fitRegression,\n regressionPrediction,\n regressionCoefficients,\n regressionGrid\n} from './regression-solver';\nimport {\n computeLinearCIComponents,\n confidenceCriticalValue,\n confidenceHalfWidth,\n stdErrorsAt\n} from './regression-utils';\n\n/**\n * Linear regression utilities (single clean implementation).\n * Exports: ordinaryLeastSquares, visitPoints, rSquared, regressionLinear\n */\n\nexport function ordinaryLeastSquares(uX: number, uY: number, uXY: number, uX2: number) {\n const denom = uX2 - uX * uX;\n if (Math.abs(denom) < Number.EPSILON) {\n return { a: uY, b: 0 };\n }\n const b = (uXY - uX * uY) / denom;\n const a = uY - b * uX;\n return { a, b };\n}\n\nexport function visitPoints(\n data: any[],\n x: (d: any) => number,\n y: (d: any) => number,\n callback: (x: number, y: number, index: number) => void\n) {\n for (let i = 0; i < data.length; i++) {\n const d = data[i];\n let xi = x(d);\n let yi = y(d);\n if (!isNil(xi) && (xi = +xi) >= xi && !isNil(yi) && (yi = +yi) >= yi) {\n callback(xi, yi, i);\n }\n }\n}\n\nexport function rSquared(\n data: any[],\n x: (d: any) => number,\n y: (d: any) => number,\n uY: number,\n predict: (x: number) => number\n) {\n let ssr = 0;\n let sst = 0;\n for (let i = 0; i < data.length; i++) {\n const d = data[i];\n let yi = y(d);\n if (!isNil(yi) && (yi = +yi) >= yi) {\n const p = predict(x(d));\n const r = yi - p;\n ssr += r * r;\n const t = yi - uY;\n sst += t * t;\n }\n }\n return sst === 0 ? 0 : 1 - ssr / sst;\n}\n\nexport function regressionLinear(\n data: any[],\n x: (d: any) => number = d => d.x,\n y: (d: any) => number = d => d.y,\n options?: {\n alpha?: number;\n }\n) {\n const alpha = options?.alpha ?? 0.05;\n const points = regressionPoints(data, x, y);\n const model = fitRegression(points, 1);\n const coef = regressionCoefficients(model);\n const a = coef[0];\n const b = coef[1];\n const predict = (xx: number) => regressionPrediction(model, xx);\n const comps = computeLinearCIComponents(data, x, y, predict);\n let meanY = 0;\n points.forEach((p, i) => {\n meanY += (p.y - meanY) / (i + 1);\n });\n\n function evaluateGrid(N: number) {\n return regressionGrid(comps.min, comps.max, N, predict);\n }\n\n function confidenceInterval(N: number = 50) {\n const out: { x: number; mean: number; lower: number; upper: number; predLower: number; predUpper: number }[] = [];\n if (comps.n === 0 || N <= 0) {\n return out;\n }\n const z = confidenceCriticalValue(alpha);\n if (comps.min === comps.max) {\n const m = predict(comps.min);\n const errs = stdErrorsAt(comps.min, comps);\n const meanHalfWidth = confidenceHalfWidth(z, errs.seMean);\n const predHalfWidth = confidenceHalfWidth(z, errs.sePred);\n for (let i = 0; i < N; i++) {\n out.push({\n x: comps.min,\n mean: m,\n lower: m - meanHalfWidth,\n upper: m + meanHalfWidth,\n predLower: m - predHalfWidth,\n predUpper: m + predHalfWidth\n });\n }\n return out;\n }\n const step = (comps.max - comps.min) / (N - 1);\n for (let i = 0; i < N; i++) {\n const px = i === N - 1 ? comps.max : comps.min + step * i;\n const m = predict(px);\n const errs = stdErrorsAt(px, comps);\n const meanHalfWidth = confidenceHalfWidth(z, errs.seMean);\n const predHalfWidth = confidenceHalfWidth(z, errs.sePred);\n out.push({\n x: px,\n mean: m,\n lower: m - meanHalfWidth,\n upper: m + meanHalfWidth,\n predLower: m - predHalfWidth,\n predUpper: m + predHalfWidth\n });\n }\n return out;\n }\n\n return {\n coef: { a, b },\n rank: model.rank,\n predict,\n rSquared: rSquared(data, x, y, meanY, predict),\n evaluateGrid,\n confidenceInterval\n };\n}\n\nexport default {\n ordinaryLeastSquares,\n visitPoints,\n rSquared,\n regressionLinear\n};\n"]}
@@ -1,11 +1,7 @@
1
1
  /**
2
- * Simple lowess implementation (univariate x)
3
- * options:
4
- * - span: fraction of points used in local regression (0,1]
5
- * - degree: 0 (constant) or 1 (linear)
6
- * - iterations: number of robustifying iterations
7
- * - alpha: confidence level for CI
8
- * - maxSamples: maximum number of points to use (default: 1000 for fast processing)
2
+ * 局部线性 LOWESS。默认全量观测、span=2/3、三次稳健重加权。
3
+ * delta 显式插值加速;maxSamples 仅保留显式选择的历史抽样用途。
4
+ * predict 与 evaluateGrid 查询构建时固定的同一模型,不触发再拟合。
9
5
  */
10
6
  export declare function regressionLowess(data: any[], x?: (d: any) => number, y?: (d: any) => number, options?: {
11
7
  span?: number;
@@ -13,9 +9,10 @@ export declare function regressionLowess(data: any[], x?: (d: any) => number, y?
13
9
  iterations?: number;
14
10
  alpha?: number;
15
11
  maxSamples?: number;
12
+ delta?: number;
16
13
  }): {
17
14
  predict: (x0: number | number[]) => number | number[];
18
- evaluate: any;
15
+ evaluate: (x0: number | number[]) => number | number[];
19
16
  evaluateGrid: (N: number) => {
20
17
  x: number;
21
18
  y: number;
@@ -28,5 +25,9 @@ export declare function regressionLowess(data: any[], x?: (d: any) => number, y?
28
25
  predLower: number;
29
26
  predUpper: number;
30
27
  }[];
28
+ fitted: {
29
+ x: number;
30
+ y: number;
31
+ }[];
31
32
  };
32
33
  export default regressionLowess;