@visactor/vutils 1.0.24 → 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.
- package/README.zh-CN.md +12 -0
- package/REGRESSION.md +36 -0
- package/cjs/angle.d.ts +61 -0
- package/cjs/angle.js +73 -7
- package/cjs/angle.js.map +1 -1
- package/cjs/color/Color.d.ts +3 -0
- package/cjs/color/Color.js +64 -10
- package/cjs/color/Color.js.map +1 -1
- package/cjs/color/hexToRgb.d.ts +5 -0
- package/cjs/color/hexToRgb.js +5 -0
- package/cjs/color/hexToRgb.js.map +1 -1
- package/cjs/color/rgbToHsl.js +5 -1
- package/cjs/color/rgbToHsl.js.map +1 -1
- package/cjs/common/array.d.ts +43 -0
- package/cjs/common/array.js +44 -0
- package/cjs/common/array.js.map +1 -1
- package/cjs/common/bisect.d.ts +21 -0
- package/cjs/common/bisect.js +29 -0
- package/cjs/common/bisect.js.map +1 -1
- package/cjs/common/bootstrap.d.ts +5 -0
- package/cjs/common/bootstrap.js +22 -0
- package/cjs/common/bootstrap.js.map +1 -0
- package/cjs/common/clone.js +6 -0
- package/cjs/common/clone.js.map +1 -1
- package/cjs/common/cloneDeep.js +4 -1
- package/cjs/common/cloneDeep.js.map +1 -1
- package/cjs/common/correlation.d.ts +3 -0
- package/cjs/common/correlation.js +83 -0
- package/cjs/common/correlation.js.map +1 -0
- package/cjs/common/debounce.js +22 -4
- package/cjs/common/debounce.js.map +1 -1
- package/cjs/common/deviation.js +1 -2
- package/cjs/common/ecdf.d.ts +8 -0
- package/cjs/common/ecdf.js +11 -2
- package/cjs/common/ecdf.js.map +1 -1
- package/cjs/common/extent.d.ts +4 -0
- package/cjs/common/extent.js +4 -2
- package/cjs/common/extent.js.map +1 -1
- package/cjs/common/field.d.ts +6 -0
- package/cjs/common/field.js +3 -0
- package/cjs/common/field.js.map +1 -1
- package/cjs/common/has.d.ts +17 -0
- package/cjs/common/has.js +18 -1
- package/cjs/common/has.js.map +1 -1
- package/cjs/common/index.d.ts +5 -0
- package/cjs/common/index.js +34 -6
- package/cjs/common/index.js.map +1 -1
- package/cjs/common/interpolate.js +16 -3
- package/cjs/common/interpolate.js.map +1 -1
- package/cjs/common/isBase64.d.ts +6 -0
- package/cjs/common/isBase64.js +6 -0
- package/cjs/common/isBase64.js.map +1 -1
- package/cjs/common/isBoolean.d.ts +13 -0
- package/cjs/common/isBoolean.js +13 -1
- package/cjs/common/isBoolean.js.map +1 -1
- package/cjs/common/isEmpty.js +11 -1
- package/cjs/common/isEmpty.js.map +1 -1
- package/cjs/common/isEqual.js +19 -7
- package/cjs/common/isEqual.js.map +1 -1
- package/cjs/common/isFunction.d.ts +25 -0
- package/cjs/common/isFunction.js +27 -2
- package/cjs/common/isFunction.js.map +1 -1
- package/cjs/common/isNull.js +2 -1
- package/cjs/common/isNumber.d.ts +23 -0
- package/cjs/common/isNumber.js +23 -1
- package/cjs/common/isNumber.js.map +1 -1
- package/cjs/common/isNumeric.d.ts +25 -0
- package/cjs/common/isNumeric.js +25 -0
- package/cjs/common/isNumeric.js.map +1 -1
- package/cjs/common/isObject.d.ts +21 -0
- package/cjs/common/isObject.js +22 -0
- package/cjs/common/isObject.js.map +1 -1
- package/cjs/common/isObjectLike.d.ts +20 -0
- package/cjs/common/isObjectLike.js +21 -0
- package/cjs/common/isObjectLike.js.map +1 -1
- package/cjs/common/isPlainObject.d.ts +25 -0
- package/cjs/common/isPlainObject.js.map +1 -1
- package/cjs/common/isPrototype.js +1 -1
- package/cjs/common/isRegExp.js +1 -1
- package/cjs/common/isShallowEqual.js +1 -0
- package/cjs/common/isShallowEqual.js.map +1 -1
- package/cjs/common/isString.d.ts +13 -0
- package/cjs/common/isString.js +13 -1
- package/cjs/common/isString.js.map +1 -1
- package/cjs/common/isType.d.ts +6 -0
- package/cjs/common/isType.js +6 -0
- package/cjs/common/isType.js.map +1 -1
- package/cjs/common/isValidNumber.js.map +1 -1
- package/cjs/common/isValidUrl.js.map +1 -1
- package/cjs/common/kde.d.ts +28 -0
- package/cjs/common/kde.js +29 -5
- package/cjs/common/kde.js.map +1 -1
- package/cjs/common/mean.d.ts +2 -0
- package/cjs/common/mean.js +25 -0
- package/cjs/common/mean.js.map +1 -0
- package/cjs/common/merge.js +20 -4
- package/cjs/common/merge.js.map +1 -1
- package/cjs/common/mixin.js +14 -3
- package/cjs/common/mixin.js.map +1 -1
- package/cjs/common/normalQuantile.d.ts +5 -0
- package/cjs/common/normalQuantile.js +21 -0
- package/cjs/common/normalQuantile.js.map +1 -0
- package/cjs/common/number.d.ts +24 -0
- package/cjs/common/number.js +24 -1
- package/cjs/common/number.js.map +1 -1
- package/cjs/common/pad.d.ts +21 -0
- package/cjs/common/pad.js +21 -1
- package/cjs/common/pad.js.map +1 -1
- package/cjs/common/random.d.ts +3 -0
- package/cjs/common/random.js +13 -0
- package/cjs/common/random.js.map +1 -1
- package/cjs/common/regression-bootstrap.d.ts +14 -0
- package/cjs/common/regression-bootstrap.js +37 -0
- package/cjs/common/regression-bootstrap.js.map +1 -0
- package/cjs/common/regression-linear.d.ts +5 -0
- package/cjs/common/regression-linear.js +28 -39
- package/cjs/common/regression-linear.js.map +1 -1
- package/cjs/common/regression-logistic.d.ts +6 -0
- package/cjs/common/regression-logistic.js +25 -14
- package/cjs/common/regression-logistic.js.map +1 -1
- package/cjs/common/regression-lowess.d.ts +11 -1
- package/cjs/common/regression-lowess.js +125 -118
- package/cjs/common/regression-lowess.js.map +1 -1
- package/cjs/common/regression-polynomial.d.ts +1 -0
- package/cjs/common/regression-polynomial.js +24 -94
- package/cjs/common/regression-polynomial.js.map +1 -1
- package/cjs/common/regression-solver.d.ts +26 -0
- package/cjs/common/regression-solver.js +180 -0
- package/cjs/common/regression-solver.js.map +1 -0
- package/cjs/common/regression-utils.d.ts +13 -1
- package/cjs/common/regression-utils.js +27 -12
- package/cjs/common/regression-utils.js.map +1 -1
- package/cjs/common/throttle.js +3 -0
- package/cjs/common/throttle.js.map +1 -1
- package/cjs/common/toDate.js +22 -3
- package/cjs/common/toDate.js.map +1 -1
- package/cjs/common/uuid.d.ts +7 -0
- package/cjs/common/uuid.js +15 -1
- package/cjs/common/uuid.js.map +1 -1
- package/cjs/data-structure/bounds.d.ts +101 -0
- package/cjs/data-structure/bounds.js +74 -7
- package/cjs/data-structure/bounds.js.map +1 -1
- package/cjs/data-structure/hashTable.d.ts +4 -0
- package/cjs/data-structure/hashTable.js +11 -2
- package/cjs/data-structure/hashTable.js.map +1 -1
- package/cjs/data-structure/index.js +6 -2
- package/cjs/data-structure/index.js.map +1 -1
- package/cjs/data-structure/matrix.d.ts +91 -0
- package/cjs/data-structure/matrix.js +52 -4
- package/cjs/data-structure/matrix.js.map +1 -1
- package/cjs/data-structure/point.d.ts +3 -0
- package/cjs/data-structure/point.js +5 -1
- package/cjs/data-structure/point.js.map +1 -1
- package/cjs/dom.d.ts +36 -0
- package/cjs/dom.js +43 -1
- package/cjs/dom.js.map +1 -1
- package/cjs/fmin/blas1.js +10 -1
- package/cjs/fmin/blas1.js.map +1 -1
- package/cjs/fmin/conjugate-gradient.js +18 -3
- package/cjs/fmin/conjugate-gradient.js.map +1 -1
- package/cjs/fmin/linesearch.js +15 -1
- package/cjs/fmin/linesearch.js.map +1 -1
- package/cjs/fmin/nelder-mead.d.ts +1 -0
- package/cjs/fmin/nelder-mead.js +30 -10
- package/cjs/fmin/nelder-mead.js.map +1 -1
- package/cjs/format/number/formatDecimal.js +9 -1
- package/cjs/format/number/formatDecimal.js.map +1 -1
- package/cjs/format/number/formatGroup.js +7 -0
- package/cjs/format/number/formatGroup.js.map +1 -1
- package/cjs/format/number/formatPrefixAuto.js +8 -0
- package/cjs/format/number/formatPrefixAuto.js.map +1 -1
- package/cjs/format/number/formatRounded.js +7 -0
- package/cjs/format/number/formatRounded.js.map +1 -1
- package/cjs/format/number/formatTrim.js +7 -0
- package/cjs/format/number/formatTrim.js.map +1 -1
- package/cjs/format/number/number.js +39 -9
- package/cjs/format/number/number.js.map +1 -1
- package/cjs/format/time.js +23 -6
- package/cjs/format/time.js.map +1 -1
- package/cjs/geo/circle-intersection.d.ts +12 -0
- package/cjs/geo/circle-intersection.js +54 -9
- package/cjs/geo/circle-intersection.js.map +1 -1
- package/cjs/geo/constant.js +8 -1
- package/cjs/geo/constant.js.map +1 -1
- package/cjs/geo/invariant.d.ts +22 -0
- package/cjs/geo/invariant.js +24 -1
- package/cjs/geo/invariant.js.map +1 -1
- package/cjs/graphics/algorithm/aabb.js +7 -3
- package/cjs/graphics/algorithm/aabb.js.map +1 -1
- package/cjs/graphics/algorithm/intersect.d.ts +48 -0
- package/cjs/graphics/algorithm/intersect.js +75 -7
- package/cjs/graphics/algorithm/intersect.js.map +1 -1
- package/cjs/graphics/bounds-util.js +4 -2
- package/cjs/graphics/bounds-util.js.map +1 -1
- package/cjs/graphics/graph-util.js +4 -0
- package/cjs/graphics/graph-util.js.map +1 -1
- package/cjs/graphics/index.js +7 -4
- package/cjs/graphics/index.js.map +1 -1
- package/cjs/graphics/polygon.d.ts +12 -0
- package/cjs/graphics/polygon.js +28 -5
- package/cjs/graphics/polygon.js.map +1 -1
- package/cjs/graphics/text/measure/interface.d.ts +12 -0
- package/cjs/graphics/text/measure/textMeasure.d.ts +23 -0
- package/cjs/graphics/text/measure/textMeasure.js +50 -22
- package/cjs/graphics/text/measure/textMeasure.js.map +1 -1
- package/cjs/graphics/text/measure/util.js +1 -0
- package/cjs/graphics/text/measure/util.js.map +1 -1
- package/cjs/graphics/text/stringWidth.js +7 -3
- package/cjs/graphics/text/stringWidth.js.map +1 -1
- package/cjs/index.d.ts +6 -0
- package/cjs/index.js +19 -4
- package/cjs/index.js.map +1 -1
- package/cjs/logger.js +12 -2
- package/cjs/logger.js.map +1 -1
- package/cjs/lru.js +14 -6
- package/cjs/lru.js.map +1 -1
- package/cjs/math.d.ts +9 -0
- package/cjs/math.js +10 -0
- package/cjs/math.js.map +1 -1
- package/cjs/padding.d.ts +5 -0
- package/cjs/padding.js +5 -0
- package/cjs/padding.js.map +1 -1
- package/cjs/time/formatUtils.d.ts +6 -0
- package/cjs/time/formatUtils.js +7 -0
- package/cjs/time/formatUtils.js.map +1 -1
- package/dist/index.js +2035 -411
- package/dist/index.min.js +128 -1
- package/es/angle.d.ts +61 -0
- package/es/angle.js +66 -10
- package/es/angle.js.map +1 -1
- package/es/color/Color.d.ts +3 -0
- package/es/color/Color.js +64 -9
- package/es/color/Color.js.map +1 -1
- package/es/color/hexToRgb.d.ts +5 -0
- package/es/color/hexToRgb.js +5 -0
- package/es/color/hexToRgb.js.map +1 -1
- package/es/color/rgbToHsl.js +5 -1
- package/es/color/rgbToHsl.js.map +1 -1
- package/es/common/array.d.ts +43 -0
- package/es/common/array.js +44 -8
- package/es/common/array.js.map +1 -1
- package/es/common/bisect.d.ts +21 -0
- package/es/common/bisect.js +29 -4
- package/es/common/bisect.js.map +1 -1
- package/es/common/bootstrap.d.ts +5 -0
- package/es/common/bootstrap.js +14 -0
- package/es/common/bootstrap.js.map +1 -0
- package/es/common/clone.js +6 -0
- package/es/common/clone.js.map +1 -1
- package/es/common/cloneDeep.js +4 -1
- package/es/common/cloneDeep.js.map +1 -1
- package/es/common/correlation.d.ts +3 -0
- package/es/common/correlation.js +77 -0
- package/es/common/correlation.js.map +1 -0
- package/es/common/debounce.js +22 -4
- package/es/common/debounce.js.map +1 -1
- package/es/common/deviation.js +1 -2
- package/es/common/ecdf.d.ts +8 -0
- package/es/common/ecdf.js +11 -1
- package/es/common/ecdf.js.map +1 -1
- package/es/common/extent.d.ts +4 -0
- package/es/common/extent.js +8 -3
- package/es/common/extent.js.map +1 -1
- package/es/common/field.d.ts +6 -0
- package/es/common/field.js +3 -1
- package/es/common/field.js.map +1 -1
- package/es/common/has.d.ts +17 -0
- package/es/common/has.js +18 -1
- package/es/common/has.js.map +1 -1
- package/es/common/index.d.ts +5 -0
- package/es/common/index.js +24 -0
- package/es/common/index.js.map +1 -1
- package/es/common/interpolate.js +16 -3
- package/es/common/interpolate.js.map +1 -1
- package/es/common/isBase64.d.ts +6 -0
- package/es/common/isBase64.js +6 -0
- package/es/common/isBase64.js.map +1 -1
- package/es/common/isBoolean.d.ts +13 -0
- package/es/common/isBoolean.js +13 -1
- package/es/common/isBoolean.js.map +1 -1
- package/es/common/isEmpty.js +11 -1
- package/es/common/isEmpty.js.map +1 -1
- package/es/common/isEqual.js +19 -7
- package/es/common/isEqual.js.map +1 -1
- package/es/common/isFunction.d.ts +25 -0
- package/es/common/isFunction.js +27 -2
- package/es/common/isFunction.js.map +1 -1
- package/es/common/isNull.js +2 -1
- package/es/common/isNumber.d.ts +23 -0
- package/es/common/isNumber.js +23 -1
- package/es/common/isNumber.js.map +1 -1
- package/es/common/isNumeric.d.ts +25 -0
- package/es/common/isNumeric.js +25 -0
- package/es/common/isNumeric.js.map +1 -1
- package/es/common/isObject.d.ts +21 -0
- package/es/common/isObject.js +22 -0
- package/es/common/isObject.js.map +1 -1
- package/es/common/isObjectLike.d.ts +20 -0
- package/es/common/isObjectLike.js +21 -0
- package/es/common/isObjectLike.js.map +1 -1
- package/es/common/isPlainObject.d.ts +25 -0
- package/es/common/isPlainObject.js +26 -0
- package/es/common/isPlainObject.js.map +1 -1
- package/es/common/isPrototype.js +1 -1
- package/es/common/isRegExp.js +1 -1
- package/es/common/isShallowEqual.js +1 -0
- package/es/common/isShallowEqual.js.map +1 -1
- package/es/common/isString.d.ts +13 -0
- package/es/common/isString.js +13 -1
- package/es/common/isString.js.map +1 -1
- package/es/common/isType.d.ts +6 -0
- package/es/common/isType.js +6 -0
- package/es/common/isType.js.map +1 -1
- package/es/common/isValidNumber.js.map +1 -1
- package/es/common/isValidUrl.js.map +1 -1
- package/es/common/kde.d.ts +28 -0
- package/es/common/kde.js +29 -7
- package/es/common/kde.js.map +1 -1
- package/es/common/mean.d.ts +2 -0
- package/es/common/mean.js +19 -0
- package/es/common/mean.js.map +1 -0
- package/es/common/merge.js +22 -5
- package/es/common/merge.js.map +1 -1
- package/es/common/mixin.js +14 -3
- package/es/common/mixin.js.map +1 -1
- package/es/common/normalQuantile.d.ts +5 -0
- package/es/common/normalQuantile.js +15 -0
- package/es/common/normalQuantile.js.map +1 -0
- package/es/common/number.d.ts +24 -0
- package/es/common/number.js +24 -2
- package/es/common/number.js.map +1 -1
- package/es/common/pad.d.ts +21 -0
- package/es/common/pad.js +21 -1
- package/es/common/pad.js.map +1 -1
- package/es/common/random.d.ts +3 -0
- package/es/common/random.js +13 -1
- package/es/common/random.js.map +1 -1
- package/es/common/regression-bootstrap.d.ts +14 -0
- package/es/common/regression-bootstrap.js +31 -0
- package/es/common/regression-bootstrap.js.map +1 -0
- package/es/common/regression-linear.d.ts +5 -0
- package/es/common/regression-linear.js +25 -39
- package/es/common/regression-linear.js.map +1 -1
- package/es/common/regression-logistic.d.ts +6 -0
- package/es/common/regression-logistic.js +24 -16
- package/es/common/regression-logistic.js.map +1 -1
- package/es/common/regression-lowess.d.ts +11 -1
- package/es/common/regression-lowess.js +120 -118
- package/es/common/regression-lowess.js.map +1 -1
- package/es/common/regression-polynomial.d.ts +1 -0
- package/es/common/regression-polynomial.js +21 -89
- package/es/common/regression-polynomial.js.map +1 -1
- package/es/common/regression-solver.d.ts +26 -0
- package/es/common/regression-solver.js +168 -0
- package/es/common/regression-solver.js.map +1 -0
- package/es/common/regression-utils.d.ts +13 -1
- package/es/common/regression-utils.js +18 -9
- package/es/common/regression-utils.js.map +1 -1
- package/es/common/throttle.js +3 -0
- package/es/common/throttle.js.map +1 -1
- package/es/common/toDate.js +23 -3
- package/es/common/toDate.js.map +1 -1
- package/es/common/uuid.d.ts +7 -0
- package/es/common/uuid.js +15 -1
- package/es/common/uuid.js.map +1 -1
- package/es/data-structure/bounds.d.ts +101 -0
- package/es/data-structure/bounds.js +74 -8
- package/es/data-structure/bounds.js.map +1 -1
- package/es/data-structure/hashTable.d.ts +4 -0
- package/es/data-structure/hashTable.js +11 -2
- package/es/data-structure/hashTable.js.map +1 -1
- package/es/data-structure/index.js +2 -0
- package/es/data-structure/index.js.map +1 -1
- package/es/data-structure/matrix.d.ts +91 -0
- package/es/data-structure/matrix.js +52 -5
- package/es/data-structure/matrix.js.map +1 -1
- package/es/data-structure/point.d.ts +3 -0
- package/es/data-structure/point.js +5 -1
- package/es/data-structure/point.js.map +1 -1
- package/es/dom.d.ts +36 -0
- package/es/dom.js +43 -8
- package/es/dom.js.map +1 -1
- package/es/fmin/blas1.js +10 -0
- package/es/fmin/blas1.js.map +1 -1
- package/es/fmin/conjugate-gradient.js +18 -2
- package/es/fmin/conjugate-gradient.js.map +1 -1
- package/es/fmin/linesearch.js +15 -0
- package/es/fmin/linesearch.js.map +1 -1
- package/es/fmin/nelder-mead.d.ts +1 -0
- package/es/fmin/nelder-mead.js +29 -9
- package/es/fmin/nelder-mead.js.map +1 -1
- package/es/format/number/formatDecimal.js +9 -1
- package/es/format/number/formatDecimal.js.map +1 -1
- package/es/format/number/formatGroup.js +7 -0
- package/es/format/number/formatGroup.js.map +1 -1
- package/es/format/number/formatPrefixAuto.js +8 -0
- package/es/format/number/formatPrefixAuto.js.map +1 -1
- package/es/format/number/formatRounded.js +7 -0
- package/es/format/number/formatRounded.js.map +1 -1
- package/es/format/number/formatTrim.js +7 -0
- package/es/format/number/formatTrim.js.map +1 -1
- package/es/format/number/number.js +40 -8
- package/es/format/number/number.js.map +1 -1
- package/es/format/time.js +23 -5
- package/es/format/time.js.map +1 -1
- package/es/geo/circle-intersection.d.ts +12 -0
- package/es/geo/circle-intersection.js +54 -14
- package/es/geo/circle-intersection.js.map +1 -1
- package/es/geo/constant.js +8 -0
- package/es/geo/constant.js.map +1 -1
- package/es/geo/invariant.d.ts +22 -0
- package/es/geo/invariant.js +24 -0
- package/es/geo/invariant.js.map +1 -1
- package/es/graphics/algorithm/aabb.js +7 -3
- package/es/graphics/algorithm/aabb.js.map +1 -1
- package/es/graphics/algorithm/intersect.d.ts +48 -0
- package/es/graphics/algorithm/intersect.js +75 -12
- package/es/graphics/algorithm/intersect.js.map +1 -1
- package/es/graphics/bounds-util.js +4 -2
- package/es/graphics/bounds-util.js.map +1 -1
- package/es/graphics/graph-util.js +4 -0
- package/es/graphics/graph-util.js.map +1 -1
- package/es/graphics/index.js +2 -0
- package/es/graphics/index.js.map +1 -1
- package/es/graphics/polygon.d.ts +12 -0
- package/es/graphics/polygon.js +28 -6
- package/es/graphics/polygon.js.map +1 -1
- package/es/graphics/text/measure/interface.d.ts +12 -0
- package/es/graphics/text/measure/textMeasure.d.ts +23 -0
- package/es/graphics/text/measure/textMeasure.js +46 -21
- package/es/graphics/text/measure/textMeasure.js.map +1 -1
- package/es/graphics/text/measure/util.js +1 -0
- package/es/graphics/text/measure/util.js.map +1 -1
- package/es/graphics/text/stringWidth.js +7 -3
- package/es/graphics/text/stringWidth.js.map +1 -1
- package/es/index.d.ts +6 -0
- package/es/index.js +15 -1
- package/es/index.js.map +1 -1
- package/es/logger.js +12 -1
- package/es/logger.js.map +1 -1
- package/es/lru.js +14 -6
- package/es/lru.js.map +1 -1
- package/es/math.d.ts +9 -0
- package/es/math.js +10 -1
- package/es/math.js.map +1 -1
- package/es/padding.d.ts +5 -0
- package/es/padding.js +5 -1
- package/es/padding.js.map +1 -1
- package/es/time/formatUtils.d.ts +6 -0
- package/es/time/formatUtils.js +7 -1
- package/es/time/formatUtils.js.map +1 -1
- package/package.json +4 -3
|
@@ -1,163 +1,165 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { regressionPoints, regressionGrid, regressionBasis, normalizeRegression } from "./regression-solver";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { median } from "./median";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
const uu = Math.abs(u);
|
|
7
|
-
if (uu >= 1) return 0;
|
|
8
|
-
const t = 1 - uu * uu * uu;
|
|
9
|
-
return t * t * t;
|
|
10
|
-
}
|
|
5
|
+
import { computeLinearCIComponents, confidenceCriticalValue, confidenceHalfWidth, stdErrorsAt } from "./regression-utils";
|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
/**
|
|
8
|
+
* 局部线性 LOWESS。默认全量观测、span=2/3、三次稳健重加权。
|
|
9
|
+
* delta 显式插值加速;maxSamples 仅保留显式选择的历史抽样用途。
|
|
10
|
+
* predict 与 evaluateGrid 查询构建时固定的同一模型,不触发再拟合。
|
|
11
|
+
*/ export function regressionLowess(data, x = (d => d.x), y = (d => d.y), options = {}) {
|
|
12
|
+
var _a, _b, _c, _d, _e;
|
|
13
|
+
const span = null !== (_a = options.span) && void 0 !== _a ? _a : 2 / 3, degree = null !== (_b = options.degree) && void 0 !== _b ? _b : 1, iterations = null !== (_c = options.iterations) && void 0 !== _c ? _c : 3, delta = null !== (_d = options.delta) && void 0 !== _d ? _d : 0, alpha = null !== (_e = options.alpha) && void 0 !== _e ? _e : .05;
|
|
14
|
+
if (!(span > 0 && span <= 1) || !Number.isInteger(iterations) || iterations < 0 || !Number.isFinite(delta) || delta < 0 || 0 !== degree && 1 !== degree || null != options.maxSamples && (!Number.isInteger(options.maxSamples) || options.maxSamples < 2)) throw new RangeError("Invalid LOWESS span, degree, iterations, delta or maxSamples");
|
|
15
|
+
let pts = regressionPoints(data, x, y).sort(((a, b) => a.x - b.x || a.y - b.y));
|
|
16
|
+
if (null != options.maxSamples && pts.length > options.maxSamples) {
|
|
17
|
+
const full = pts, count = options.maxSamples;
|
|
18
|
+
pts = Array.from({
|
|
19
|
+
length: count
|
|
20
|
+
}, ((_, i) => full[Math.floor(i * (full.length - 1) / (count - 1))]));
|
|
19
21
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
rawPoints.push({
|
|
28
|
-
x: dx,
|
|
29
|
-
y: dy,
|
|
30
|
-
index: index
|
|
31
|
-
});
|
|
32
|
-
})), rawPoints.sort(((a, b) => a.x - b.x));
|
|
33
|
-
const sampledPoints = stratifiedSample(rawPoints, maxSamples), n = sampledPoints.length, ptsX = new Array(n), ptsY = new Array(n);
|
|
34
|
-
for (let i = 0; i < n; i++) ptsX[i] = sampledPoints[i].x, ptsY[i] = sampledPoints[i].y;
|
|
35
|
-
function predictSingle(x0, robustWeights) {
|
|
36
|
-
if (0 === n) return 0;
|
|
37
|
-
let left = 0, right = n;
|
|
22
|
+
const n = pts.length, ptsX = pts.map((p => p.x)), ptsY = pts.map((p => p.y)), basis = regressionBasis(pts), normalizedX = ptsX.map((v => normalizeRegression(v, basis.xCenter, basis.xScale))), normalizedY = ptsY.map((v => normalizeRegression(v, basis.yCenter, basis.yScale))), count = Math.min(n, Math.max(2, Math.floor(span * n + 1e-10)));
|
|
23
|
+
let robustWeights;
|
|
24
|
+
function exact(x0) {
|
|
25
|
+
if (!n) return 0;
|
|
26
|
+
const query = normalizeRegression(x0, basis.xCenter, basis.xScale);
|
|
27
|
+
// 找到连续的最近邻窗口;相等距离选择较小的 x(ties 的 y 已排序)。
|
|
28
|
+
let left = 0, right = n - count;
|
|
38
29
|
for (;left < right; ) {
|
|
39
|
-
const mid = left + right
|
|
40
|
-
|
|
30
|
+
const mid = left + right >>> 1, lowerDistance = x0 - ptsX[mid], upperDistance = ptsX[mid + count] - x0;
|
|
31
|
+
(Number.isFinite(lowerDistance) && Number.isFinite(upperDistance) ? lowerDistance > upperDistance : query - normalizedX[mid] > normalizedX[mid + count] - query) ? left = mid + 1 : right = mid;
|
|
41
32
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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);
|
|
33
|
+
let start = left, end = left + count;
|
|
34
|
+
if (ptsX[start] === ptsX[end - 1]) {
|
|
35
|
+
for (;start > 0 && ptsX[start - 1] === ptsX[start]; ) start--;
|
|
36
|
+
for (;end < n && ptsX[end] === ptsX[start]; ) end++;
|
|
51
37
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
38
|
+
const rawRadius = Math.max(Math.abs(ptsX[start] - x0), Math.abs(ptsX[end - 1] - x0)), scaled = !Number.isFinite(rawRadius), radius = scaled ? Math.max(Math.abs(normalizedX[start] - query), Math.abs(normalizedX[end - 1] - query)) : rawRadius;
|
|
39
|
+
// 局部响应坐标不能由远处、未参与该邻域的观测决定精度。
|
|
40
|
+
let yMin = 1 / 0, yMax = -1 / 0;
|
|
41
|
+
for (let i = start; i < end; i++) yMin = Math.min(yMin, ptsY[i]), yMax = Math.max(yMax, ptsY[i]);
|
|
42
|
+
const yCenter = yMin / 2 + yMax / 2, yScale = Math.max(Math.abs(yMin - yCenter), Math.abs(yMax - yCenter)) || 1;
|
|
43
|
+
let sw = 0, sx = 0, sy = 0, sxx = 0, sxy = 0;
|
|
44
|
+
for (let i = start; i < end; i++) {
|
|
45
|
+
const z = 0 === radius ? 0 : (scaled ? normalizedX[i] - query : ptsX[i] - x0) / radius, u = Math.abs(z), t = u >= 1 ? 0 : 1 - u * u * u, w = t * t * t * (robustWeights ? robustWeights[i] : 1);
|
|
46
|
+
sw += w, sx += w * z;
|
|
47
|
+
const response = normalizeRegression(ptsY[i], yCenter, yScale);
|
|
48
|
+
sy += w * response, sxx += w * z * z, sxy += w * z * response;
|
|
58
49
|
}
|
|
59
|
-
if (0 ===
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
50
|
+
if (0 === sw) {
|
|
51
|
+
// 核边界零权重时使用最近有效观测的加权常数;等距离取均值。
|
|
52
|
+
let distance = 1 / 0, weight = 0, value = 0;
|
|
53
|
+
for (let i = 0; i < n; i++) {
|
|
54
|
+
const w = robustWeights ? robustWeights[i] : 1;
|
|
55
|
+
if (0 === w) continue;
|
|
56
|
+
const d = Math.abs(scaled ? normalizedX[i] - query : ptsX[i] - x0);
|
|
57
|
+
d < distance ? (distance = d, weight = w, value = ptsY[i]) : d === distance && (value = value * (weight / (weight + w)) + ptsY[i] * (w / (weight + w)),
|
|
58
|
+
weight += w);
|
|
65
59
|
}
|
|
66
|
-
|
|
60
|
+
if (0 === weight) throw new RangeError("LOWESS has no effective local observations");
|
|
61
|
+
return value;
|
|
67
62
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
const mx = sx / sw, my = sy / sw, variance = sxx / sw - mx * mx;
|
|
64
|
+
return yCenter + yScale * (my - (0 === degree || variance <= 32 * Number.EPSILON ? 0 : (sxy / sw - mx * my) / variance) * mx);
|
|
65
|
+
}
|
|
66
|
+
// delta 不删除观测。只减少局部回归求值位置,全部残差参与重加权。
|
|
67
|
+
const anchors = [];
|
|
68
|
+
for (let i = 0; i < n && (anchors.push(i), i !== n - 1); ) {
|
|
69
|
+
let next = i + 1;
|
|
70
|
+
if (delta > 0) for (;next + 1 < n && ptsX[next + 1] - ptsX[i] <= delta; ) next++;
|
|
71
|
+
// 重复 x 一起使用同一预测;端点不能丢失。
|
|
72
|
+
for (;next + 1 < n && ptsX[next + 1] === ptsX[next]; ) next++;
|
|
73
|
+
i = next;
|
|
74
|
+
}
|
|
75
|
+
let fits = new Array(n);
|
|
76
|
+
function fitObservations() {
|
|
77
|
+
const out = new Array(n);
|
|
78
|
+
for (let a = 0; a < anchors.length; a++) {
|
|
79
|
+
const index = anchors[a];
|
|
80
|
+
if (out[index] = exact(ptsX[index]), 0 === a) continue;
|
|
81
|
+
const previous = anchors[a - 1], rawWidth = ptsX[index] - ptsX[previous], width = Number.isFinite(rawWidth) ? rawWidth : normalizedX[index] - normalizedX[previous];
|
|
82
|
+
for (let i = previous + 1; i < index; i++) {
|
|
83
|
+
const t = 0 === width ? 0 : (Number.isFinite(rawWidth) ? ptsX[i] - ptsX[previous] : normalizedX[i] - normalizedX[previous]) / width;
|
|
84
|
+
out[i] = out[previous] * (1 - t) + out[index] * t;
|
|
85
|
+
}
|
|
72
86
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
for (let iteration = 0; iteration <= iterations && (fits = fitObservations(), iteration !== iterations); iteration++) {
|
|
90
|
+
const residuals = fits.map(((v, i) => {
|
|
91
|
+
const residual = ptsY[i] - v;
|
|
92
|
+
return Number.isFinite(residual) ? Math.abs(residual / basis.yScale) : Math.abs(normalizedY[i] - normalizeRegression(v, basis.yCenter, basis.yScale));
|
|
93
|
+
})), med = median(residuals.slice()), currentFits = fits;
|
|
94
|
+
robustWeights = residuals.map(((r, i) => {
|
|
95
|
+
if (0 === med) {
|
|
96
|
+
return r <= 64 * Number.EPSILON * (Math.max(Math.abs(ptsY[i]), Math.abs(currentFits[i])) / basis.yScale) ? 1 : 0;
|
|
97
|
+
}
|
|
98
|
+
const u = r / (6 * med);
|
|
99
|
+
return u >= 1 ? 0 : (1 - u * u) ** 2;
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
function predictSingle(x0) {
|
|
103
|
+
if (0 === delta || n < 2 || x0 < ptsX[0] || x0 > ptsX[n - 1]) return exact(x0);
|
|
104
|
+
let lo = 0, hi = n - 1;
|
|
105
|
+
for (;hi - lo > 1; ) {
|
|
106
|
+
const mid = lo + hi >>> 1;
|
|
107
|
+
ptsX[mid] <= x0 ? lo = mid : hi = mid;
|
|
77
108
|
}
|
|
78
|
-
|
|
79
|
-
|
|
109
|
+
if (ptsX[hi] === ptsX[lo]) return fits[lo];
|
|
110
|
+
const width = ptsX[hi] - ptsX[lo], t = Number.isFinite(width) ? (x0 - ptsX[lo]) / width : (normalizeRegression(x0, basis.xCenter, basis.xScale) - normalizedX[lo]) / (normalizedX[hi] - normalizedX[lo]);
|
|
111
|
+
return fits[lo] * (1 - t) + fits[hi] * t;
|
|
80
112
|
}
|
|
81
113
|
function predict(x0) {
|
|
82
|
-
|
|
83
|
-
const len = x0.length, out = new Array(len);
|
|
84
|
-
for (let i = 0; i < len; i++) out[i] = predictSingle(x0[i]);
|
|
85
|
-
return out;
|
|
86
|
-
}
|
|
87
|
-
return predictSingle(x0);
|
|
114
|
+
return Array.isArray(x0) ? x0.map(predictSingle) : predictSingle(x0);
|
|
88
115
|
}
|
|
89
116
|
return {
|
|
90
117
|
predict: predict,
|
|
91
118
|
evaluate: predict,
|
|
92
119
|
evaluateGrid: function(N) {
|
|
93
|
-
|
|
94
|
-
if (0 === n) return [];
|
|
95
|
-
const out = new Array(N), min = ptsX[0], max = ptsX[n - 1];
|
|
96
|
-
if (min === max) {
|
|
97
|
-
const v = predictSingle(min);
|
|
98
|
-
for (let i = 0; i < N; i++) out[i] = {
|
|
99
|
-
x: min,
|
|
100
|
-
y: v
|
|
101
|
-
};
|
|
102
|
-
return out;
|
|
103
|
-
}
|
|
104
|
-
const step = (max - min) / (N - 1);
|
|
105
|
-
let robustWeights;
|
|
106
|
-
const effectiveIterations = null != options.iterations ? iterations : n > 500 ? 0 : iterations;
|
|
107
|
-
if (effectiveIterations > 0) for (let iter = 0; iter < effectiveIterations; iter++) {
|
|
108
|
-
const fits = new Array(n), res = new Array(n);
|
|
109
|
-
for (let i = 0; i < n; i++) fits[i] = predictSingle(ptsX[i], robustWeights), res[i] = Math.abs(ptsY[i] - fits[i]);
|
|
110
|
-
const med = res.slice().sort(((a, b) => a - b))[Math.floor(n / 2)] || 0;
|
|
111
|
-
robustWeights = new Array(n);
|
|
112
|
-
for (let i = 0; i < n; i++) {
|
|
113
|
-
const u = 0 === med ? 0 : res[i] / (6 * med), w = Math.abs(u) >= 1 ? 0 : (1 - u * u) * (1 - u * u);
|
|
114
|
-
robustWeights[i] = w;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
for (let i = 0; i < N; i++) {
|
|
118
|
-
const px = i === N - 1 ? max : min + step * i;
|
|
119
|
-
out[i] = {
|
|
120
|
-
x: px,
|
|
121
|
-
y: predictSingle(px, robustWeights)
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
return out;
|
|
120
|
+
return regressionGrid(ptsX[0], ptsX[n - 1], N, predictSingle);
|
|
125
121
|
},
|
|
126
122
|
confidenceInterval: function(N = 50) {
|
|
127
123
|
const out = [];
|
|
128
124
|
if (N <= 0) return out;
|
|
129
125
|
if (0 === n) return out;
|
|
130
|
-
|
|
126
|
+
// use data x-range (already sorted)
|
|
127
|
+
const min = ptsX[0], max = ptsX[n - 1];
|
|
131
128
|
if (void 0 === min || void 0 === max || min === 1 / 0 || max === -1 / 0) return out;
|
|
132
129
|
const comps = computeLinearCIComponents(data, x, y, (xx => predictSingle(xx)));
|
|
133
130
|
if (0 === comps.n) return out;
|
|
134
|
-
const z =
|
|
131
|
+
const z = confidenceCriticalValue(alpha);
|
|
135
132
|
if (comps.min === comps.max) {
|
|
136
|
-
const v = predictSingle(comps.min), errs = stdErrorsAt(comps.min, comps);
|
|
133
|
+
const v = predictSingle(comps.min), errs = stdErrorsAt(comps.min, comps), meanHalfWidth = confidenceHalfWidth(z, errs.seMean), predHalfWidth = confidenceHalfWidth(z, errs.sePred);
|
|
137
134
|
for (let i = 0; i < N; i++) out.push({
|
|
138
135
|
x: comps.min,
|
|
139
136
|
mean: v,
|
|
140
|
-
lower: v -
|
|
141
|
-
upper: v +
|
|
142
|
-
predLower: v -
|
|
143
|
-
predUpper: v +
|
|
137
|
+
lower: v - meanHalfWidth,
|
|
138
|
+
upper: v + meanHalfWidth,
|
|
139
|
+
predLower: v - predHalfWidth,
|
|
140
|
+
predUpper: v + predHalfWidth
|
|
144
141
|
});
|
|
145
142
|
return out;
|
|
146
143
|
}
|
|
147
144
|
const step = (max - min) / (N - 1);
|
|
148
145
|
for (let i = 0; i < N; i++) {
|
|
149
|
-
const px = i === N - 1 ? max : min + step * i, yh = predictSingle(px), errs = stdErrorsAt(px, comps);
|
|
146
|
+
const px = i === N - 1 ? max : min + step * i, yh = predictSingle(px), errs = stdErrorsAt(px, comps), meanHalfWidth = confidenceHalfWidth(z, errs.seMean), predHalfWidth = confidenceHalfWidth(z, errs.sePred);
|
|
150
147
|
out.push({
|
|
151
148
|
x: px,
|
|
152
149
|
mean: yh,
|
|
153
|
-
lower: yh -
|
|
154
|
-
upper: yh +
|
|
155
|
-
predLower: yh -
|
|
156
|
-
predUpper: yh +
|
|
150
|
+
lower: yh - meanHalfWidth,
|
|
151
|
+
upper: yh + meanHalfWidth,
|
|
152
|
+
predLower: yh - predHalfWidth,
|
|
153
|
+
predUpper: yh + predHalfWidth
|
|
157
154
|
});
|
|
158
155
|
}
|
|
159
156
|
return out;
|
|
160
|
-
}
|
|
157
|
+
},
|
|
158
|
+
// 节点值按 x 排序,重复观测仍保持其统计权重。
|
|
159
|
+
fitted: pts.map(((p, i) => ({
|
|
160
|
+
x: p.x,
|
|
161
|
+
y: fits[i]
|
|
162
|
+
})))
|
|
161
163
|
};
|
|
162
164
|
}
|
|
163
165
|
|
|
@@ -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\ninterface LowessPoint {\n x: number;\n y: number;\n index: number;\n}\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: LowessPoint[], maxSamples: number) {\n const n = sortedData.length;\n if (n <= maxSamples) {\n return sortedData;\n }\n\n const sampled: LowessPoint[] = [];\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: LowessPoint[] = [];\n visitPoints(data, x, y, (dx, dy, index) => {\n rawPoints.push({ x: dx, y: dy, index });\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.min(n, Math.max(2, Math.floor(span * n)));\n\n // Expand by distance: equal numbers on either side need not be the nearest points.\n let lo = left - 1;\n let hi = left;\n for (let count = 0; count < m; count++) {\n if (lo >= 0 && (hi >= n || x0 - ptsX[lo] <= ptsX[hi] - x0)) {\n lo--;\n } else {\n hi++;\n }\n }\n const actualStart = lo + 1;\n const end = hi;\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 // Fall back to the nearest y, preserving input order for equal distances.\n let nearestIdx = 0;\n let nearestDistance = Math.abs(ptsX[0] - x0);\n for (let i = 1; i < n; i++) {\n const distance = Math.abs(ptsX[i] - x0);\n if (\n distance < nearestDistance ||\n (distance === nearestDistance && sampledPoints[i].index < sampledPoints[nearestIdx].index)\n ) {\n nearestIdx = i;\n nearestDistance = distance;\n }\n }\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/common/regression-lowess.ts"],"names":[],"mappings":"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","file":"regression-lowess.js","sourcesContent":["import { regressionPoints, regressionGrid, regressionBasis, normalizeRegression } from './regression-solver';\nimport { median } from './median';\nimport {\n computeLinearCIComponents,\n confidenceCriticalValue,\n confidenceHalfWidth,\n stdErrorsAt\n} from './regression-utils';\n\n/**\n * 局部线性 LOWESS。默认全量观测、span=2/3、三次稳健重加权。\n * delta 显式插值加速;maxSamples 仅保留显式选择的历史抽样用途。\n * predict 与 evaluateGrid 查询构建时固定的同一模型,不触发再拟合。\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: {\n span?: number;\n degree?: 1 | 0;\n iterations?: number;\n alpha?: number;\n maxSamples?: number;\n delta?: number;\n } = {}\n) {\n const span = options.span ?? 2 / 3;\n const degree = options.degree ?? 1;\n const iterations = options.iterations ?? 3;\n const delta = options.delta ?? 0;\n const alpha = options.alpha ?? 0.05;\n if (\n !(span > 0 && span <= 1) ||\n !Number.isInteger(iterations) ||\n iterations < 0 ||\n !Number.isFinite(delta) ||\n delta < 0 ||\n (degree !== 0 && degree !== 1) ||\n (options.maxSamples != null && (!Number.isInteger(options.maxSamples) || options.maxSamples < 2))\n ) {\n throw new RangeError('Invalid LOWESS span, degree, iterations, delta or maxSamples');\n }\n let pts = regressionPoints(data, x, y).sort((a, b) => a.x - b.x || a.y - b.y);\n if (options.maxSamples != null && pts.length > options.maxSamples) {\n const full = pts;\n const count = options.maxSamples;\n pts = Array.from({ length: count }, (_, i) => full[Math.floor((i * (full.length - 1)) / (count - 1))]);\n }\n const n = pts.length;\n const ptsX = pts.map(p => p.x);\n const ptsY = pts.map(p => p.y);\n const basis = regressionBasis(pts);\n const normalizedX = ptsX.map(v => normalizeRegression(v, basis.xCenter, basis.xScale));\n const normalizedY = ptsY.map(v => normalizeRegression(v, basis.yCenter, basis.yScale));\n const count = Math.min(n, Math.max(2, Math.floor(span * n + 1e-10)));\n let robustWeights: number[] | undefined;\n\n function exact(x0: number) {\n if (!n) {\n return 0;\n }\n const query = normalizeRegression(x0, basis.xCenter, basis.xScale);\n // 找到连续的最近邻窗口;相等距离选择较小的 x(ties 的 y 已排序)。\n let left = 0;\n let right = n - count;\n while (left < right) {\n const mid = (left + right) >>> 1;\n const lowerDistance = x0 - ptsX[mid];\n const upperDistance = ptsX[mid + count] - x0;\n if (\n Number.isFinite(lowerDistance) && Number.isFinite(upperDistance)\n ? lowerDistance > upperDistance\n : query - normalizedX[mid] > normalizedX[mid + count] - query\n ) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n let start = left;\n let end = left + count;\n if (ptsX[start] === ptsX[end - 1]) {\n while (start > 0 && ptsX[start - 1] === ptsX[start]) {\n start--;\n }\n while (end < n && ptsX[end] === ptsX[start]) {\n end++;\n }\n }\n const rawRadius = Math.max(Math.abs(ptsX[start] - x0), Math.abs(ptsX[end - 1] - x0));\n const scaled = !Number.isFinite(rawRadius);\n const radius = scaled\n ? Math.max(Math.abs(normalizedX[start] - query), Math.abs(normalizedX[end - 1] - query))\n : rawRadius;\n // 局部响应坐标不能由远处、未参与该邻域的观测决定精度。\n let yMin = Infinity;\n let yMax = -Infinity;\n for (let i = start; i < end; i++) {\n yMin = Math.min(yMin, ptsY[i]);\n yMax = Math.max(yMax, ptsY[i]);\n }\n const yCenter = yMin / 2 + yMax / 2;\n const yScale = Math.max(Math.abs(yMin - yCenter), Math.abs(yMax - yCenter)) || 1;\n let sw = 0;\n let sx = 0;\n let sy = 0;\n let sxx = 0;\n let sxy = 0;\n for (let i = start; i < end; i++) {\n const z = radius === 0 ? 0 : (scaled ? normalizedX[i] - query : ptsX[i] - x0) / radius;\n const u = Math.abs(z);\n const t = u >= 1 ? 0 : 1 - u * u * u;\n const w = t * t * t * (robustWeights ? robustWeights[i] : 1);\n sw += w;\n sx += w * z;\n const response = normalizeRegression(ptsY[i], yCenter, yScale);\n sy += w * response;\n sxx += w * z * z;\n sxy += w * z * response;\n }\n if (sw === 0) {\n // 核边界零权重时使用最近有效观测的加权常数;等距离取均值。\n let distance = Infinity;\n let weight = 0;\n let value = 0;\n for (let i = 0; i < n; i++) {\n const w = robustWeights ? robustWeights[i] : 1;\n if (w === 0) {\n continue;\n }\n const d = Math.abs(scaled ? normalizedX[i] - query : ptsX[i] - x0);\n if (d < distance) {\n distance = d;\n weight = w;\n value = ptsY[i];\n } else if (d === distance) {\n value = value * (weight / (weight + w)) + ptsY[i] * (w / (weight + w));\n weight += w;\n }\n }\n if (weight === 0) {\n throw new RangeError('LOWESS has no effective local observations');\n }\n return value;\n }\n const mx = sx / sw;\n const my = sy / sw;\n const variance = sxx / sw - mx * mx;\n const slope = degree === 0 || variance <= Number.EPSILON * 32 ? 0 : (sxy / sw - mx * my) / variance;\n return yCenter + yScale * (my - slope * mx);\n }\n\n // delta 不删除观测。只减少局部回归求值位置,全部残差参与重加权。\n const anchors: number[] = [];\n for (let i = 0; i < n; ) {\n anchors.push(i);\n if (i === n - 1) {\n break;\n }\n let next = i + 1;\n if (delta > 0) {\n while (next + 1 < n && ptsX[next + 1] - ptsX[i] <= delta) {\n next++;\n }\n }\n // 重复 x 一起使用同一预测;端点不能丢失。\n while (next + 1 < n && ptsX[next + 1] === ptsX[next]) {\n next++;\n }\n i = next;\n }\n let fits = new Array<number>(n);\n function fitObservations() {\n const out = new Array<number>(n);\n for (let a = 0; a < anchors.length; a++) {\n const index = anchors[a];\n out[index] = exact(ptsX[index]);\n if (a === 0) {\n continue;\n }\n const previous = anchors[a - 1];\n const rawWidth = ptsX[index] - ptsX[previous];\n const width = Number.isFinite(rawWidth) ? rawWidth : normalizedX[index] - normalizedX[previous];\n for (let i = previous + 1; i < index; i++) {\n const t =\n width === 0\n ? 0\n : (Number.isFinite(rawWidth) ? ptsX[i] - ptsX[previous] : normalizedX[i] - normalizedX[previous]) / width;\n out[i] = out[previous] * (1 - t) + out[index] * t;\n }\n }\n return out;\n }\n for (let iteration = 0; iteration <= iterations; iteration++) {\n fits = fitObservations();\n if (iteration === iterations) {\n break;\n }\n const residuals = fits.map((v, i) => {\n const residual = ptsY[i] - v;\n return Number.isFinite(residual)\n ? Math.abs(residual / basis.yScale)\n : Math.abs(normalizedY[i] - normalizeRegression(v, basis.yCenter, basis.yScale));\n });\n const med = median(residuals.slice());\n const currentFits = fits;\n robustWeights = residuals.map((r, i) => {\n if (med === 0) {\n const tolerance = Number.EPSILON * 64 * (Math.max(Math.abs(ptsY[i]), Math.abs(currentFits[i])) / basis.yScale);\n return r <= tolerance ? 1 : 0;\n }\n const u = r / (6 * med);\n return u >= 1 ? 0 : (1 - u * u) ** 2;\n });\n }\n function predictSingle(x0: number): number {\n if (delta === 0 || n < 2 || x0 < ptsX[0] || x0 > ptsX[n - 1]) {\n return exact(x0);\n }\n let lo = 0;\n let hi = n - 1;\n while (hi - lo > 1) {\n const mid = (lo + hi) >>> 1;\n if (ptsX[mid] <= x0) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n if (ptsX[hi] === ptsX[lo]) {\n return fits[lo];\n }\n const width = ptsX[hi] - ptsX[lo];\n const t = Number.isFinite(width)\n ? (x0 - ptsX[lo]) / width\n : (normalizeRegression(x0, basis.xCenter, basis.xScale) - normalizedX[lo]) / (normalizedX[hi] - normalizedX[lo]);\n return fits[lo] * (1 - t) + fits[hi] * t;\n }\n function predict(x0: number | number[]) {\n return Array.isArray(x0) ? x0.map(predictSingle) : predictSingle(x0);\n }\n function evaluateGrid(N: number) {\n return regressionGrid(ptsX[0], ptsX[n - 1], N, predictSingle);\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 = confidenceCriticalValue(alpha);\n if (comps.min === comps.max) {\n const v = predictSingle(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: v,\n lower: v - meanHalfWidth,\n upper: v + meanHalfWidth,\n predLower: v - predHalfWidth,\n predUpper: v + predHalfWidth\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 const meanHalfWidth = confidenceHalfWidth(z, errs.seMean);\n const predHalfWidth = confidenceHalfWidth(z, errs.sePred);\n out.push({\n x: px,\n mean: yh,\n lower: yh - meanHalfWidth,\n upper: yh + meanHalfWidth,\n predLower: yh - predHalfWidth,\n predUpper: yh + predHalfWidth\n });\n }\n return out;\n }\n\n return {\n predict,\n evaluate: predict,\n evaluateGrid,\n confidenceInterval,\n // 节点值按 x 排序,重复观测仍保持其统计权重。\n fitted: pts.map((p, i) => ({ x: p.x, y: fits[i] }))\n };\n}\nexport default regressionLowess;\n"]}
|
|
@@ -1,128 +1,60 @@
|
|
|
1
1
|
import { visitPoints, rSquared } from "./regression-linear";
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { regressionPoints, fitRegression, regressionPrediction, regressionCoefficients, regressionGrid } from "./regression-solver";
|
|
4
4
|
|
|
5
|
-
import { computeLinearCIComponents,
|
|
6
|
-
|
|
7
|
-
function solveLinearSystem(A, b) {
|
|
8
|
-
const n = b.length, M = new Array(n);
|
|
9
|
-
for (let i = 0; i < n; i++) M[i] = A[i].slice(), M[i].push(b[i]);
|
|
10
|
-
for (let k = 0; k < n; k++) {
|
|
11
|
-
let maxRow = k, maxVal = Math.abs(M[k][k]);
|
|
12
|
-
for (let i = k + 1; i < n; i++) {
|
|
13
|
-
const v = Math.abs(M[i][k]);
|
|
14
|
-
v > maxVal && (maxVal = v, maxRow = i);
|
|
15
|
-
}
|
|
16
|
-
if (maxRow !== k) {
|
|
17
|
-
const tmp = M[k];
|
|
18
|
-
M[k] = M[maxRow], M[maxRow] = tmp;
|
|
19
|
-
}
|
|
20
|
-
if (Math.abs(M[k][k]) < 1e-12) {
|
|
21
|
-
return new Array(n).fill(0);
|
|
22
|
-
}
|
|
23
|
-
for (let j = k + 1; j <= n; j++) M[k][j] = M[k][j] / M[k][k];
|
|
24
|
-
M[k][k] = 1;
|
|
25
|
-
for (let i = 0; i < n; i++) {
|
|
26
|
-
if (i === k) continue;
|
|
27
|
-
const factor = M[i][k];
|
|
28
|
-
if (0 !== factor) {
|
|
29
|
-
for (let j = k + 1; j <= n; j++) M[i][j] -= factor * M[k][j];
|
|
30
|
-
M[i][k] = 0;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
const x = new Array(n);
|
|
35
|
-
for (let i = 0; i < n; i++) x[i] = M[i][n];
|
|
36
|
-
return x;
|
|
37
|
-
}
|
|
5
|
+
import { computeLinearCIComponents, confidenceCriticalValue, confidenceHalfWidth, stdErrorsAt } from "./regression-utils";
|
|
38
6
|
|
|
39
7
|
export function regressionPolynomial(data, x = (d => d.x), y = (d => d.y), options = {}) {
|
|
40
8
|
var _a, _b;
|
|
41
|
-
|
|
42
|
-
degree < 0
|
|
43
|
-
const alpha = null !== (_b = options.alpha) && void 0 !== _b ? _b : .05,
|
|
44
|
-
visitPoints(data, x, y, ((dx, dy) => {
|
|
45
|
-
let xp = 1;
|
|
46
|
-
for (let k = 0; k < sums.length; k++) sums[k] += xp, xp *= dx;
|
|
47
|
-
}));
|
|
48
|
-
const A = new Array(m);
|
|
49
|
-
for (let i = 0; i < m; i++) {
|
|
50
|
-
A[i] = new Array(m).fill(0);
|
|
51
|
-
for (let j = 0; j < m; j++) A[i][j] = sums[i + j];
|
|
52
|
-
}
|
|
53
|
-
const B = new Array(m).fill(0);
|
|
54
|
-
visitPoints(data, x, y, ((dx, dy) => {
|
|
55
|
-
let xp = 1;
|
|
56
|
-
for (let k = 0; k < m; k++) B[k] += dy * xp, xp *= dx;
|
|
57
|
-
}));
|
|
58
|
-
const coef = solveLinearSystem(A, B), predict = xx => {
|
|
59
|
-
let xp = 1, v = 0;
|
|
60
|
-
for (let k = 0; k < coef.length; k++) v += coef[k] * xp, xp *= xx;
|
|
61
|
-
return v;
|
|
62
|
-
};
|
|
9
|
+
const degree = null !== (_a = options.degree) && void 0 !== _a ? _a : 0;
|
|
10
|
+
if (!Number.isInteger(degree) || degree < 0) throw new RangeError("Polynomial degree must be an nonnegative integer");
|
|
11
|
+
const alpha = null !== (_b = options.alpha) && void 0 !== _b ? _b : .05, points = regressionPoints(data, x, y), model = fitRegression(points, degree), coef = regressionCoefficients(model), predict = xx => regressionPrediction(model, xx);
|
|
63
12
|
return {
|
|
64
13
|
degree: degree,
|
|
14
|
+
rank: model.rank,
|
|
65
15
|
coef: coef,
|
|
66
16
|
predict: predict,
|
|
67
17
|
rSquared: rSquared(data, x, y, (() => {
|
|
18
|
+
// compute mean y
|
|
68
19
|
let sum = 0, cnt = 0;
|
|
69
20
|
return visitPoints(data, x, y, ((_dx, dy) => {
|
|
70
21
|
sum += dy, cnt++;
|
|
71
22
|
})), 0 === cnt ? 0 : sum / cnt;
|
|
72
23
|
})(), predict),
|
|
73
24
|
evaluateGrid(N) {
|
|
74
|
-
const out = [];
|
|
75
|
-
if (N <= 0) return out;
|
|
76
25
|
let min = 1 / 0, max = -1 / 0;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
})), min
|
|
80
|
-
if (min === max) {
|
|
81
|
-
const v = predict(min);
|
|
82
|
-
for (let i = 0; i < N; i++) out.push({
|
|
83
|
-
x: min,
|
|
84
|
-
y: v
|
|
85
|
-
});
|
|
86
|
-
return out;
|
|
87
|
-
}
|
|
88
|
-
const step = (max - min) / (N - 1);
|
|
89
|
-
for (let i = 0; i < N; i++) {
|
|
90
|
-
const px = i === N - 1 ? max : min + step * i;
|
|
91
|
-
out.push({
|
|
92
|
-
x: px,
|
|
93
|
-
y: predict(px)
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
return out;
|
|
26
|
+
return points.forEach((p => {
|
|
27
|
+
min = Math.min(min, p.x), max = Math.max(max, p.x);
|
|
28
|
+
})), regressionGrid(min, max, N, predict);
|
|
97
29
|
},
|
|
98
30
|
confidenceInterval(N = 50) {
|
|
99
31
|
const out = [];
|
|
100
32
|
if (N <= 0) return out;
|
|
101
33
|
const comps = computeLinearCIComponents(data, x, y, predict);
|
|
102
34
|
if (0 === comps.n) return out;
|
|
103
|
-
const z =
|
|
35
|
+
const z = confidenceCriticalValue(alpha);
|
|
104
36
|
if (comps.min === comps.max) {
|
|
105
|
-
const v = predict(comps.min), errs = stdErrorsAt(comps.min, comps);
|
|
37
|
+
const v = predict(comps.min), errs = stdErrorsAt(comps.min, comps), meanHalfWidth = confidenceHalfWidth(z, errs.seMean), predHalfWidth = confidenceHalfWidth(z, errs.sePred);
|
|
106
38
|
for (let i = 0; i < N; i++) out.push({
|
|
107
39
|
x: comps.min,
|
|
108
40
|
mean: v,
|
|
109
|
-
lower: v -
|
|
110
|
-
upper: v +
|
|
111
|
-
predLower: v -
|
|
112
|
-
predUpper: v +
|
|
41
|
+
lower: v - meanHalfWidth,
|
|
42
|
+
upper: v + meanHalfWidth,
|
|
43
|
+
predLower: v - predHalfWidth,
|
|
44
|
+
predUpper: v + predHalfWidth
|
|
113
45
|
});
|
|
114
46
|
return out;
|
|
115
47
|
}
|
|
116
48
|
const step = (comps.max - comps.min) / (N - 1);
|
|
117
49
|
for (let i = 0; i < N; i++) {
|
|
118
|
-
const px = i === N - 1 ? comps.max : comps.min + step * i, yh = predict(px), errs = stdErrorsAt(px, comps);
|
|
50
|
+
const px = i === N - 1 ? comps.max : comps.min + step * i, yh = predict(px), errs = stdErrorsAt(px, comps), meanHalfWidth = confidenceHalfWidth(z, errs.seMean), predHalfWidth = confidenceHalfWidth(z, errs.sePred);
|
|
119
51
|
out.push({
|
|
120
52
|
x: px,
|
|
121
53
|
mean: yh,
|
|
122
|
-
lower: yh -
|
|
123
|
-
upper: yh +
|
|
124
|
-
predLower: yh -
|
|
125
|
-
predUpper: yh +
|
|
54
|
+
lower: yh - meanHalfWidth,
|
|
55
|
+
upper: yh + meanHalfWidth,
|
|
56
|
+
predLower: yh - predHalfWidth,
|
|
57
|
+
predUpper: yh + predHalfWidth
|
|
126
58
|
});
|
|
127
59
|
}
|
|
128
60
|
return out;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/common/regression-polynomial.ts"],"names":[],"mappings":"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","file":"regression-polynomial.js","sourcesContent":["import { visitPoints, rSquared } from './regression-linear';\nimport isNil from './isNil';\nimport { computeLinearCIComponents, invNorm, stdErrorsAt } from './regression-utils';\n\nfunction solveLinearSystem(A: number[][], b: number[]): number[] {\n // Gaussian elimination with partial pivoting\n const n = b.length;\n // clone\n const M: number[][] = new Array(n);\n for (let i = 0; i < n; i++) {\n M[i] = A[i].slice();\n M[i].push(b[i]);\n }\n\n for (let k = 0; k < n; k++) {\n // find pivot\n let maxRow = k;\n let maxVal = Math.abs(M[k][k]);\n for (let i = k + 1; i < n; i++) {\n const v = Math.abs(M[i][k]);\n if (v > maxVal) {\n maxVal = v;\n maxRow = i;\n }\n }\n if (maxRow !== k) {\n const tmp = M[k];\n M[k] = M[maxRow];\n M[maxRow] = tmp;\n }\n\n // singular check\n if (Math.abs(M[k][k]) < 1e-12) {\n // return least squares fallback zeros\n const res: number[] = new Array(n).fill(0);\n return res;\n }\n\n // normalize row\n for (let j = k + 1; j <= n; j++) {\n M[k][j] = M[k][j] / M[k][k];\n }\n M[k][k] = 1;\n\n // eliminate\n for (let i = 0; i < n; i++) {\n if (i === k) {\n continue;\n }\n const factor = M[i][k];\n if (factor === 0) {\n continue;\n }\n for (let j = k + 1; j <= n; j++) {\n M[i][j] -= factor * M[k][j];\n }\n M[i][k] = 0;\n }\n }\n\n const x: number[] = new Array(n);\n for (let i = 0; i < n; i++) {\n x[i] = M[i][n];\n }\n return x;\n}\n\nexport function regressionPolynomial(\n data: any[],\n x: (d: any) => number = d => d.x,\n y: (d: any) => number = d => d.y,\n options: { degree?: number; alpha?: number } = {}\n) {\n let degree = options.degree ?? 0;\n if (degree < 0) {\n degree = 0;\n }\n const alpha = options.alpha ?? 0.05;\n const m = degree + 1;\n const sums: number[] = new Array(2 * degree + 1).fill(0);\n\n visitPoints(data, x, y, (dx, dy) => {\n let xp = 1;\n for (let k = 0; k < sums.length; k++) {\n sums[k] += xp;\n xp *= dx;\n }\n });\n\n // build normal matrix\n const A: number[][] = new Array(m);\n for (let i = 0; i < m; i++) {\n A[i] = new Array(m).fill(0);\n for (let j = 0; j < m; j++) {\n A[i][j] = sums[i + j];\n }\n }\n\n const B: number[] = new Array(m).fill(0);\n visitPoints(data, x, y, (dx, dy) => {\n let xp = 1;\n for (let k = 0; k < m; k++) {\n B[k] += dy * xp;\n xp *= dx;\n }\n });\n\n const coef = solveLinearSystem(A, B);\n\n const predict = (xx: number) => {\n let xp = 1;\n let v = 0;\n for (let k = 0; k < coef.length; k++) {\n v += coef[k] * xp;\n xp *= xx;\n }\n return v;\n };\n\n return {\n degree,\n coef,\n predict,\n rSquared: rSquared(\n data,\n x,\n y,\n (() => {\n // compute mean y\n let sum = 0;\n let cnt = 0;\n visitPoints(data, x, y, (_dx, dy) => {\n sum += dy;\n cnt++;\n });\n return cnt === 0 ? 0 : sum / cnt;\n })(),\n predict\n ),\n evaluateGrid(N: number) {\n const out: { x: number; y: number }[] = [];\n if (N <= 0) {\n return out;\n }\n // compute range\n let min = Infinity;\n let max = -Infinity;\n visitPoints(data, x, y, dx => {\n if (!isNil(dx)) {\n if (dx < min) {\n min = dx;\n }\n if (dx > max) {\n max = dx;\n }\n }\n });\n if (min === Infinity || max === -Infinity) {\n return out;\n }\n if (min === max) {\n const v = predict(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 for (let i = 0; i < N; i++) {\n const px = i === N - 1 ? max : min + step * i;\n out.push({ x: px, y: predict(px) });\n }\n return out;\n },\n 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\n const comps = computeLinearCIComponents(data, x, y, predict);\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 = predict(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 = (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 yh = predict(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}\n\nexport default regressionPolynomial;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/common/regression-polynomial.ts"],"names":[],"mappings":"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","file":"regression-polynomial.js","sourcesContent":["import { visitPoints, rSquared } from './regression-linear';\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\nexport function regressionPolynomial(\n data: any[],\n x: (d: any) => number = d => d.x,\n y: (d: any) => number = d => d.y,\n options: { degree?: number; alpha?: number } = {}\n) {\n const degree = options.degree ?? 0;\n if (!Number.isInteger(degree) || degree < 0) {\n throw new RangeError('Polynomial degree must be an nonnegative integer');\n }\n const alpha = options.alpha ?? 0.05;\n const points = regressionPoints(data, x, y);\n const model = fitRegression(points, degree);\n const coef = regressionCoefficients(model);\n const predict = (xx: number) => regressionPrediction(model, xx);\n\n return {\n degree,\n rank: model.rank,\n coef,\n predict,\n rSquared: rSquared(\n data,\n x,\n y,\n (() => {\n // compute mean y\n let sum = 0;\n let cnt = 0;\n visitPoints(data, x, y, (_dx, dy) => {\n sum += dy;\n cnt++;\n });\n return cnt === 0 ? 0 : sum / cnt;\n })(),\n predict\n ),\n evaluateGrid(N: number) {\n let min = Infinity;\n let max = -Infinity;\n points.forEach(p => {\n min = Math.min(min, p.x);\n max = Math.max(max, p.x);\n });\n return regressionGrid(min, max, N, predict);\n },\n 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\n const comps = computeLinearCIComponents(data, x, y, predict);\n if (comps.n === 0) {\n return out;\n }\n\n const z = confidenceCriticalValue(alpha);\n if (comps.min === comps.max) {\n const v = 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: v,\n lower: v - meanHalfWidth,\n upper: v + meanHalfWidth,\n predLower: v - predHalfWidth,\n predUpper: v + predHalfWidth\n });\n }\n return out;\n }\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 yh = 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: yh,\n lower: yh - meanHalfWidth,\n upper: yh + meanHalfWidth,\n predLower: yh - predHalfWidth,\n predUpper: yh + predHalfWidth\n });\n }\n return out;\n }\n };\n}\n\nexport default regressionPolynomial;\n"]}
|