@visactor/vutils 1.0.23 → 1.0.25
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/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/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 +2 -1
- 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/getType.js +1 -2
- 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 +4 -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 +26 -0
- package/cjs/common/isFunction.js.map +1 -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 +23 -2
- 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 +2 -1
- package/cjs/common/isPlainObject.js.map +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/isUndefined.js +1 -1
- package/cjs/common/isValid.js +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-linear.d.ts +4 -0
- package/cjs/common/regression-linear.js +19 -12
- 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 +9 -0
- package/cjs/common/regression-lowess.js +64 -26
- package/cjs/common/regression-lowess.js.map +1 -1
- package/cjs/common/regression-polynomial.js +26 -15
- package/cjs/common/regression-polynomial.js.map +1 -1
- 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 +1627 -116
- 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/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 +6 -2
- 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/getType.js +1 -2
- 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 +4 -0
- package/es/common/index.js +24 -1
- 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 +26 -0
- package/es/common/isFunction.js.map +1 -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 +23 -2
- 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 +28 -1
- package/es/common/isPlainObject.js.map +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/isUndefined.js +1 -1
- package/es/common/isValid.js +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-linear.d.ts +4 -0
- package/es/common/regression-linear.js +18 -14
- 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 +9 -0
- package/es/common/regression-lowess.js +63 -27
- package/es/common/regression-lowess.js.map +1 -1
- package/es/common/regression-polynomial.js +25 -16
- package/es/common/regression-polynomial.js.map +1 -1
- 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 +8 -3
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import isNil from "./isNil";
|
|
2
2
|
|
|
3
|
-
import { computeLinearCIComponents,
|
|
3
|
+
import { computeLinearCIComponents, confidenceCriticalValue, confidenceHalfWidth, stdErrorsAt } from "./regression-utils";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Linear regression utilities (single clean implementation).
|
|
7
|
+
* Exports: ordinaryLeastSquares, visitPoints, rSquared, regressionLinear
|
|
8
|
+
*/ export function ordinaryLeastSquares(uX, uY, uXY, uX2) {
|
|
6
9
|
const denom = uX2 - uX * uX;
|
|
7
10
|
if (Math.abs(denom) < Number.EPSILON) return {
|
|
8
11
|
a: uY,
|
|
@@ -41,7 +44,8 @@ export function rSquared(data, x, y, uY, predict) {
|
|
|
41
44
|
export function regressionLinear(data, x = (d => d.x), y = (d => d.y), options) {
|
|
42
45
|
var _a;
|
|
43
46
|
const alpha = null !== (_a = null == options ? void 0 : options.alpha) && void 0 !== _a ? _a : .05;
|
|
44
|
-
|
|
47
|
+
// accumulate online means (sufficient statistics)
|
|
48
|
+
let n = 0, meanX = 0, meanY = 0, meanXY = 0, meanX2 = 0;
|
|
45
49
|
visitPoints(data, x, y, ((xi, yi) => {
|
|
46
50
|
n++, meanX += (xi - meanX) / n, meanY += (yi - meanY) / n, meanXY += (xi * yi - meanXY) / n,
|
|
47
51
|
meanX2 += (xi * xi - meanX2) / n;
|
|
@@ -77,29 +81,29 @@ export function regressionLinear(data, x = (d => d.x), y = (d => d.y), options)
|
|
|
77
81
|
confidenceInterval: function(N = 50) {
|
|
78
82
|
const out = [];
|
|
79
83
|
if (0 === comps.n || N <= 0) return out;
|
|
80
|
-
const z =
|
|
84
|
+
const z = confidenceCriticalValue(alpha);
|
|
81
85
|
if (comps.min === comps.max) {
|
|
82
|
-
const m = predict(comps.min), errs = stdErrorsAt(comps.min, comps);
|
|
86
|
+
const m = predict(comps.min), errs = stdErrorsAt(comps.min, comps), meanHalfWidth = confidenceHalfWidth(z, errs.seMean), predHalfWidth = confidenceHalfWidth(z, errs.sePred);
|
|
83
87
|
for (let i = 0; i < N; i++) out.push({
|
|
84
88
|
x: comps.min,
|
|
85
89
|
mean: m,
|
|
86
|
-
lower: m -
|
|
87
|
-
upper: m +
|
|
88
|
-
predLower: m -
|
|
89
|
-
predUpper: m +
|
|
90
|
+
lower: m - meanHalfWidth,
|
|
91
|
+
upper: m + meanHalfWidth,
|
|
92
|
+
predLower: m - predHalfWidth,
|
|
93
|
+
predUpper: m + predHalfWidth
|
|
90
94
|
});
|
|
91
95
|
return out;
|
|
92
96
|
}
|
|
93
97
|
const step = (comps.max - comps.min) / (N - 1);
|
|
94
98
|
for (let i = 0; i < N; i++) {
|
|
95
|
-
const px = i === N - 1 ? comps.max : comps.min + step * i, m = predict(px), errs = stdErrorsAt(px, comps);
|
|
99
|
+
const px = i === N - 1 ? comps.max : comps.min + step * i, m = predict(px), errs = stdErrorsAt(px, comps), meanHalfWidth = confidenceHalfWidth(z, errs.seMean), predHalfWidth = confidenceHalfWidth(z, errs.sePred);
|
|
96
100
|
out.push({
|
|
97
101
|
x: px,
|
|
98
102
|
mean: m,
|
|
99
|
-
lower: m -
|
|
100
|
-
upper: m +
|
|
101
|
-
predLower: m -
|
|
102
|
-
predUpper: m +
|
|
103
|
+
lower: m - meanHalfWidth,
|
|
104
|
+
upper: m + meanHalfWidth,
|
|
105
|
+
predLower: m - predHalfWidth,
|
|
106
|
+
predUpper: m + predHalfWidth
|
|
103
107
|
});
|
|
104
108
|
}
|
|
105
109
|
return 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 { computeLinearCIComponents, invNorm, stdErrorsAt } 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 = invNorm(1 - alpha / 2);\n if (comps.min === comps.max) {\n const m = 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: m,\n lower: m - z * errs.seMean,\n upper: m + z * errs.seMean,\n predLower: m - z * errs.sePred,\n predUpper: m + z * errs.sePred\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 out.push({\n x: px,\n mean: m,\n lower: m - z * errs.seMean,\n upper: m + z * errs.seMean,\n predLower: m - z * errs.sePred,\n predUpper: m + z * errs.sePred\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":"AAAA,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,WAAW,EACZ,MAAM,oBAAoB,CAAC;AAE5B;;;GAGG;AAEH,MAAM,UAAU,oBAAoB,CAAC,EAAU,EAAE,EAAU,EAAE,GAAW,EAAE,GAAW;IACnF,MAAM,KAAK,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC;IAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE;QACpC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;KACxB;IACD,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC;IAClC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;IACtB,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,IAAW,EACX,CAAqB,EACrB,CAAqB,EACrB,QAAuD;IAEvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACpC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACd,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACd,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE;YACpE,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;SACrB;KACF;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,IAAW,EACX,CAAqB,EACrB,CAAqB,EACrB,EAAU,EACV,OAA8B;IAE9B,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACpC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACd,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE;YAClC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACjB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YACb,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;YAClB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;SACd;KACF;IACD,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IAAW,EACX,IAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAChC,IAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAChC,OAEC;;IAED,MAAM,KAAK,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,KAAK,mCAAI,IAAI,CAAC;IACrC,kDAAkD;IAClD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;QACjC,CAAC,EAAE,CAAC;QACJ,KAAK,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1B,KAAK,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1B,MAAM,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,oBAAoB,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpE,MAAM,OAAO,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IAE3C,MAAM,KAAK,GAAG,yBAAyB,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IAE7D,SAAS,YAAY,CAAC,CAAS;QAC7B,MAAM,GAAG,GAA+B,EAAE,CAAC;QAC3C,IAAI,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC3B,OAAO,GAAG,CAAC;SACZ;QACD,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,EAAE;YAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;gBAC1B,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;aACnD;YACD,OAAO,GAAG,CAAC;SACZ;QACD,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1B,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC;YAC1D,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;SACrC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,SAAS,kBAAkB,CAAC,IAAY,EAAE;QACxC,MAAM,GAAG,GAAsG,EAAE,CAAC;QAClH,IAAI,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC3B,OAAO,GAAG,CAAC;SACZ;QACD,MAAM,CAAC,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,EAAE;YAC3B,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7B,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC3C,MAAM,aAAa,GAAG,mBAAmB,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC1D,MAAM,aAAa,GAAG,mBAAmB,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;gBAC1B,GAAG,CAAC,IAAI,CAAC;oBACP,CAAC,EAAE,KAAK,CAAC,GAAG;oBACZ,IAAI,EAAE,CAAC;oBACP,KAAK,EAAE,CAAC,GAAG,aAAa;oBACxB,KAAK,EAAE,CAAC,GAAG,aAAa;oBACxB,SAAS,EAAE,CAAC,GAAG,aAAa;oBAC5B,SAAS,EAAE,CAAC,GAAG,aAAa;iBAC7B,CAAC,CAAC;aACJ;YACD,OAAO,GAAG,CAAC;SACZ;QACD,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1B,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC;YAC1D,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;YACtB,MAAM,IAAI,GAAG,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YACpC,MAAM,aAAa,GAAG,mBAAmB,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC1D,MAAM,aAAa,GAAG,mBAAmB,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAC1D,GAAG,CAAC,IAAI,CAAC;gBACP,CAAC,EAAE,EAAE;gBACL,IAAI,EAAE,CAAC;gBACP,KAAK,EAAE,CAAC,GAAG,aAAa;gBACxB,KAAK,EAAE,CAAC,GAAG,aAAa;gBACxB,SAAS,EAAE,CAAC,GAAG,aAAa;gBAC5B,SAAS,EAAE,CAAC,GAAG,aAAa;aAC7B,CAAC,CAAC;SACJ;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,OAAO;QACL,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE;QACd,OAAO;QACP,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC;QAC9C,YAAY;QACZ,kBAAkB;KACnB,CAAC;AACJ,CAAC;AAED,eAAe;IACb,oBAAoB;IACpB,WAAW;IACX,QAAQ;IACR,gBAAgB;CACjB,CAAC","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,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple logistic regression (binary) using Newton-Raphson (IRLS).
|
|
3
|
+
* Returns { coef, predict, evaluateGrid }
|
|
4
|
+
* - coef: [intercept, beta]
|
|
5
|
+
* - predict(x): probability p(y=1|x)
|
|
6
|
+
*/
|
|
1
7
|
export declare function regressionLogistic(data: any[], x?: (d: any) => number, y?: (d: any) => number, options?: {
|
|
2
8
|
maxIteration?: number;
|
|
3
9
|
tol?: number;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { visitPoints } from "./regression-linear";
|
|
2
2
|
|
|
3
|
-
import { computeLinearCIComponents,
|
|
3
|
+
import { computeLinearCIComponents, confidenceCriticalValue, confidenceHalfWidth, stdErrorsAt } from "./regression-utils";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Simple logistic regression (binary) using Newton-Raphson (IRLS).
|
|
7
|
+
* Returns { coef, predict, evaluateGrid }
|
|
8
|
+
* - coef: [intercept, beta]
|
|
9
|
+
* - predict(x): probability p(y=1|x)
|
|
10
|
+
*/ export function regressionLogistic(data, x = (d => d.x), y = (d => d.y), options) {
|
|
6
11
|
var _a, _b, _c;
|
|
7
12
|
const maxIter = null !== (_a = null == options ? void 0 : options.maxIteration) && void 0 !== _a ? _a : 25, tol = null !== (_b = null == options ? void 0 : options.tol) && void 0 !== _b ? _b : 1e-6, alpha = null !== (_c = null == options ? void 0 : options.alpha) && void 0 !== _c ? _c : .05, xs = [], ys = [];
|
|
8
13
|
visitPoints(data, x, y, ((dx, dy) => {
|
|
@@ -15,7 +20,8 @@ export function regressionLogistic(data, x = (d => d.x), y = (d => d.y), options
|
|
|
15
20
|
evaluateGrid: N => [],
|
|
16
21
|
confidenceInterval: (N = 50) => []
|
|
17
22
|
};
|
|
18
|
-
|
|
23
|
+
// initial coef via linear regression rough guess
|
|
24
|
+
let intercept = 0, beta = 0;
|
|
19
25
|
for (let iter = 0; iter < maxIter; iter++) {
|
|
20
26
|
const p = new Array(n);
|
|
21
27
|
let converged = !0;
|
|
@@ -23,12 +29,14 @@ export function regressionLogistic(data, x = (d => d.x), y = (d => d.y), options
|
|
|
23
29
|
const z = intercept + beta * xs[i], pi = 1 / (1 + Math.exp(-z));
|
|
24
30
|
p[i] = pi;
|
|
25
31
|
}
|
|
26
|
-
|
|
32
|
+
// compute gradient and hessian
|
|
33
|
+
let g0 = 0, g1 = 0, h00 = 0, h01 = 0, h11 = 0;
|
|
27
34
|
for (let i = 0; i < n; i++) {
|
|
28
35
|
const wi = p[i] * (1 - p[i]), diff = ys[i] - p[i];
|
|
29
36
|
g0 += diff, g1 += diff * xs[i], h00 += wi, h01 += wi * xs[i], h11 += wi * xs[i] * xs[i];
|
|
30
37
|
}
|
|
31
|
-
|
|
38
|
+
// solve 2x2 system H * delta = g
|
|
39
|
+
const det = h00 * h11 - h01 * h01;
|
|
32
40
|
if (Math.abs(det) < 1e-12) break;
|
|
33
41
|
const delta0 = (h11 * g0 - h01 * g1) / det, delta1 = (-h01 * g0 + h00 * g1) / det;
|
|
34
42
|
if (intercept += delta0, beta += delta1, (Math.abs(delta0) > tol || Math.abs(delta1) > tol) && (converged = !1),
|
|
@@ -71,29 +79,29 @@ export function regressionLogistic(data, x = (d => d.x), y = (d => d.y), options
|
|
|
71
79
|
if (N <= 0) return out;
|
|
72
80
|
const comps = computeLinearCIComponents(data, x, y, predict);
|
|
73
81
|
if (0 === comps.n) return out;
|
|
74
|
-
const z =
|
|
82
|
+
const z = confidenceCriticalValue(alpha);
|
|
75
83
|
if (comps.min === comps.max) {
|
|
76
|
-
const v = predict(comps.min), errs = stdErrorsAt(comps.min, comps);
|
|
84
|
+
const v = predict(comps.min), errs = stdErrorsAt(comps.min, comps), meanHalfWidth = confidenceHalfWidth(z, errs.seMean), predHalfWidth = confidenceHalfWidth(z, errs.sePred);
|
|
77
85
|
for (let i = 0; i < N; i++) out.push({
|
|
78
86
|
x: comps.min,
|
|
79
87
|
mean: v,
|
|
80
|
-
lower: v -
|
|
81
|
-
upper: v +
|
|
82
|
-
predLower: v -
|
|
83
|
-
predUpper: v +
|
|
88
|
+
lower: v - meanHalfWidth,
|
|
89
|
+
upper: v + meanHalfWidth,
|
|
90
|
+
predLower: v - predHalfWidth,
|
|
91
|
+
predUpper: v + predHalfWidth
|
|
84
92
|
});
|
|
85
93
|
return out;
|
|
86
94
|
}
|
|
87
95
|
const step = (comps.max - comps.min) / (N - 1);
|
|
88
96
|
for (let i = 0; i < N; i++) {
|
|
89
|
-
const px = i === N - 1 ? comps.max : comps.min + step * i, yh = predict(px), errs = stdErrorsAt(px, comps);
|
|
97
|
+
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);
|
|
90
98
|
out.push({
|
|
91
99
|
x: px,
|
|
92
100
|
mean: yh,
|
|
93
|
-
lower: yh -
|
|
94
|
-
upper: yh +
|
|
95
|
-
predLower: yh -
|
|
96
|
-
predUpper: yh +
|
|
101
|
+
lower: yh - meanHalfWidth,
|
|
102
|
+
upper: yh + meanHalfWidth,
|
|
103
|
+
predLower: yh - predHalfWidth,
|
|
104
|
+
predUpper: yh + predHalfWidth
|
|
97
105
|
});
|
|
98
106
|
}
|
|
99
107
|
return out;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/common/regression-logistic.ts"],"names":[],"mappings":"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","file":"regression-logistic.js","sourcesContent":["import { visitPoints } from './regression-linear';\nimport { computeLinearCIComponents, invNorm, stdErrorsAt } from './regression-utils';\n\n/**\n * Simple logistic regression (binary) using Newton-Raphson (IRLS).\n * Returns { coef, predict, evaluateGrid }\n * - coef: [intercept, beta]\n * - predict(x): probability p(y=1|x)\n */\nexport function regressionLogistic(\n data: any[],\n x: (d: any) => number = d => d.x,\n y: (d: any) => number = d => d.y,\n options?: { maxIteration?: number; tol?: number; alpha?: number }\n) {\n const maxIter = options?.maxIteration ?? 25;\n const tol = options?.tol ?? 1e-6;\n const alpha = options?.alpha ?? 0.05;\n // build arrays\n const xs: number[] = [];\n const ys: number[] = [];\n visitPoints(data, x, y, (dx, dy) => {\n xs.push(dx);\n ys.push(dy ? 1 : 0);\n });\n\n const n = xs.length;\n if (n === 0) {\n return {\n coef: [0, 0],\n predict: (_x: number) => 0,\n evaluateGrid: (N: number) => [] as { x: number; y: number }[],\n confidenceInterval: (N: number = 50) =>\n [] as { x: number; mean: number; lower: number; upper: number; predLower: number; predUpper: number }[]\n };\n }\n\n // initial coef via linear regression rough guess\n let intercept = 0;\n let beta = 0;\n\n for (let iter = 0; iter < maxIter; iter++) {\n const p: number[] = new Array(n);\n let converged = true;\n for (let i = 0; i < n; i++) {\n const z = intercept + beta * xs[i];\n const pi = 1 / (1 + Math.exp(-z));\n p[i] = pi;\n }\n\n // compute gradient and hessian\n let g0 = 0;\n let g1 = 0;\n let h00 = 0;\n let h01 = 0;\n let h11 = 0;\n for (let i = 0; i < n; i++) {\n const wi = p[i] * (1 - p[i]);\n const diff = ys[i] - p[i];\n g0 += diff;\n g1 += diff * xs[i];\n h00 += wi;\n h01 += wi * xs[i];\n h11 += wi * xs[i] * xs[i];\n }\n\n // solve 2x2 system H * delta = g\n const det = h00 * h11 - h01 * h01;\n if (Math.abs(det) < 1e-12) {\n break;\n }\n const delta0 = (h11 * g0 - h01 * g1) / det;\n const delta1 = (-h01 * g0 + h00 * g1) / det;\n\n intercept += delta0;\n beta += delta1;\n\n if (Math.abs(delta0) > tol || Math.abs(delta1) > tol) {\n converged = false;\n }\n if (converged) {\n break;\n }\n }\n\n const predict = (xx: number) => {\n const z = intercept + beta * xx;\n return 1 / (1 + Math.exp(-z));\n };\n\n function evaluateGrid(N: number) {\n const out: { x: number; y: number }[] = [];\n if (N <= 0) {\n return out;\n }\n let min = Infinity;\n let max = -Infinity;\n visitPoints(data, x, y, dx => {\n if (dx < min) {\n min = dx;\n }\n if (dx > max) {\n max = dx;\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\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\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 return {\n coef: [intercept, beta],\n predict,\n evaluateGrid,\n confidenceInterval\n };\n}\n\nexport default regressionLogistic;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/common/regression-logistic.ts"],"names":[],"mappings":"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","file":"regression-logistic.js","sourcesContent":["import { visitPoints } from './regression-linear';\nimport {\n computeLinearCIComponents,\n confidenceCriticalValue,\n confidenceHalfWidth,\n stdErrorsAt\n} from './regression-utils';\n\n/**\n * Simple logistic regression (binary) using Newton-Raphson (IRLS).\n * Returns { coef, predict, evaluateGrid }\n * - coef: [intercept, beta]\n * - predict(x): probability p(y=1|x)\n */\nexport function regressionLogistic(\n data: any[],\n x: (d: any) => number = d => d.x,\n y: (d: any) => number = d => d.y,\n options?: { maxIteration?: number; tol?: number; alpha?: number }\n) {\n const maxIter = options?.maxIteration ?? 25;\n const tol = options?.tol ?? 1e-6;\n const alpha = options?.alpha ?? 0.05;\n // build arrays\n const xs: number[] = [];\n const ys: number[] = [];\n visitPoints(data, x, y, (dx, dy) => {\n xs.push(dx);\n ys.push(dy ? 1 : 0);\n });\n\n const n = xs.length;\n if (n === 0) {\n return {\n coef: [0, 0],\n predict: (_x: number) => 0,\n evaluateGrid: (N: number) => [] as { x: number; y: number }[],\n confidenceInterval: (N: number = 50) =>\n [] as { x: number; mean: number; lower: number; upper: number; predLower: number; predUpper: number }[]\n };\n }\n\n // initial coef via linear regression rough guess\n let intercept = 0;\n let beta = 0;\n\n for (let iter = 0; iter < maxIter; iter++) {\n const p: number[] = new Array(n);\n let converged = true;\n for (let i = 0; i < n; i++) {\n const z = intercept + beta * xs[i];\n const pi = 1 / (1 + Math.exp(-z));\n p[i] = pi;\n }\n\n // compute gradient and hessian\n let g0 = 0;\n let g1 = 0;\n let h00 = 0;\n let h01 = 0;\n let h11 = 0;\n for (let i = 0; i < n; i++) {\n const wi = p[i] * (1 - p[i]);\n const diff = ys[i] - p[i];\n g0 += diff;\n g1 += diff * xs[i];\n h00 += wi;\n h01 += wi * xs[i];\n h11 += wi * xs[i] * xs[i];\n }\n\n // solve 2x2 system H * delta = g\n const det = h00 * h11 - h01 * h01;\n if (Math.abs(det) < 1e-12) {\n break;\n }\n const delta0 = (h11 * g0 - h01 * g1) / det;\n const delta1 = (-h01 * g0 + h00 * g1) / det;\n\n intercept += delta0;\n beta += delta1;\n\n if (Math.abs(delta0) > tol || Math.abs(delta1) > tol) {\n converged = false;\n }\n if (converged) {\n break;\n }\n }\n\n const predict = (xx: number) => {\n const z = intercept + beta * xx;\n return 1 / (1 + Math.exp(-z));\n };\n\n function evaluateGrid(N: number) {\n const out: { x: number; y: number }[] = [];\n if (N <= 0) {\n return out;\n }\n let min = Infinity;\n let max = -Infinity;\n visitPoints(data, x, y, dx => {\n if (dx < min) {\n min = dx;\n }\n if (dx > max) {\n max = dx;\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\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\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 return {\n coef: [intercept, beta],\n predict,\n evaluateGrid,\n confidenceInterval\n };\n}\n\nexport default regressionLogistic;\n"]}
|
|
@@ -1,3 +1,12 @@
|
|
|
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)
|
|
9
|
+
*/
|
|
1
10
|
export declare function regressionLowess(data: any[], x?: (d: any) => number, y?: (d: any) => number, options?: {
|
|
2
11
|
span?: number;
|
|
3
12
|
degree?: 1 | 0;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { visitPoints } from "./regression-linear";
|
|
2
2
|
|
|
3
|
-
import { computeLinearCIComponents,
|
|
3
|
+
import { computeLinearCIComponents, confidenceCriticalValue, confidenceHalfWidth, stdErrorsAt } from "./regression-utils";
|
|
4
4
|
|
|
5
5
|
function tricube(u) {
|
|
6
6
|
const uu = Math.abs(u);
|
|
@@ -9,43 +9,65 @@ function tricube(u) {
|
|
|
9
9
|
return t * t * t;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Stratified sampling to reduce data size while preserving distribution
|
|
14
|
+
*/ function stratifiedSample(sortedData, maxSamples) {
|
|
13
15
|
const n = sortedData.length;
|
|
14
16
|
if (n <= maxSamples) return sortedData;
|
|
15
17
|
const sampled = [], step = n / maxSamples;
|
|
16
|
-
|
|
18
|
+
// More aggressive sampling - use exact step size
|
|
19
|
+
for (let i = 0; i < maxSamples; i++) {
|
|
17
20
|
const idx = Math.min(Math.floor(i * step), n - 1);
|
|
18
21
|
sampled.push(sortedData[idx]);
|
|
19
22
|
}
|
|
20
23
|
return sampled;
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Simple lowess implementation (univariate x)
|
|
28
|
+
* options:
|
|
29
|
+
* - span: fraction of points used in local regression (0,1]
|
|
30
|
+
* - degree: 0 (constant) or 1 (linear)
|
|
31
|
+
* - iterations: number of robustifying iterations
|
|
32
|
+
* - alpha: confidence level for CI
|
|
33
|
+
* - maxSamples: maximum number of points to use (default: 1000 for fast processing)
|
|
34
|
+
*/ export function regressionLowess(data, x = (d => d.x), y = (d => d.y), options = {}) {
|
|
24
35
|
var _a;
|
|
25
36
|
const span = options.span || .3, degree = 0 === options.degree ? 0 : 1, alpha = null !== (_a = options.alpha) && void 0 !== _a ? _a : .05, iterations = null == options.iterations ? 2 : options.iterations, maxSamples = options.maxSamples || 1e3, rawPoints = [];
|
|
26
|
-
visitPoints(data, x, y, ((dx, dy) => {
|
|
37
|
+
visitPoints(data, x, y, ((dx, dy, index) => {
|
|
27
38
|
rawPoints.push({
|
|
28
39
|
x: dx,
|
|
29
|
-
y: dy
|
|
40
|
+
y: dy,
|
|
41
|
+
index: index
|
|
30
42
|
});
|
|
31
43
|
})), rawPoints.sort(((a, b) => a.x - b.x));
|
|
44
|
+
// Apply sampling if needed
|
|
32
45
|
const sampledPoints = stratifiedSample(rawPoints, maxSamples), n = sampledPoints.length, ptsX = new Array(n), ptsY = new Array(n);
|
|
33
46
|
for (let i = 0; i < n; i++) ptsX[i] = sampledPoints[i].x, ptsY[i] = sampledPoints[i].y;
|
|
34
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Optimized predictSingle using binary search on pre-sorted data
|
|
49
|
+
*/ function predictSingle(x0, robustWeights) {
|
|
35
50
|
if (0 === n) return 0;
|
|
36
|
-
|
|
51
|
+
// Binary search to find insertion point
|
|
52
|
+
let left = 0, right = n;
|
|
37
53
|
for (;left < right; ) {
|
|
38
54
|
const mid = left + right >> 1;
|
|
39
55
|
ptsX[mid] < x0 ? left = mid + 1 : right = mid;
|
|
40
56
|
}
|
|
41
|
-
const m = Math.
|
|
57
|
+
const m = Math.min(n, Math.max(2, Math.floor(span * n)));
|
|
58
|
+
// Expand by distance: equal numbers on either side need not be the nearest points.
|
|
59
|
+
let lo = left - 1, hi = left;
|
|
60
|
+
for (let count = 0; count < m; count++) lo >= 0 && (hi >= n || x0 - ptsX[lo] <= ptsX[hi] - x0) ? lo-- : hi++;
|
|
61
|
+
const actualStart = lo + 1, end = hi;
|
|
62
|
+
// Find max distance and compute weights in single pass
|
|
42
63
|
let maxDist = 0;
|
|
43
64
|
const windowSize = end - actualStart, distances = new Array(windowSize);
|
|
44
65
|
for (let i = actualStart; i < end; i++) {
|
|
45
66
|
const dist = Math.abs(ptsX[i] - x0);
|
|
46
67
|
distances[i - actualStart] = dist, dist > maxDist && (maxDist = dist);
|
|
47
68
|
}
|
|
48
|
-
|
|
69
|
+
// Compute weights using pre-calculated distances
|
|
70
|
+
let sumw = 0;
|
|
49
71
|
const w = new Array(windowSize);
|
|
50
72
|
for (let i = 0; i < windowSize; i++) {
|
|
51
73
|
let wi = tricube(0 === maxDist ? 0 : distances[i] / maxDist);
|
|
@@ -53,14 +75,22 @@ export function regressionLowess(data, x = (d => d.x), y = (d => d.y), options =
|
|
|
53
75
|
w[i] = wi, sumw += wi;
|
|
54
76
|
}
|
|
55
77
|
if (0 === sumw) {
|
|
56
|
-
|
|
78
|
+
// Fall back to the nearest y, preserving input order for equal distances.
|
|
79
|
+
let nearestIdx = 0, nearestDistance = Math.abs(ptsX[0] - x0);
|
|
80
|
+
for (let i = 1; i < n; i++) {
|
|
81
|
+
const distance = Math.abs(ptsX[i] - x0);
|
|
82
|
+
(distance < nearestDistance || distance === nearestDistance && sampledPoints[i].index < sampledPoints[nearestIdx].index) && (nearestIdx = i,
|
|
83
|
+
nearestDistance = distance);
|
|
84
|
+
}
|
|
85
|
+
return ptsY[nearestIdx];
|
|
57
86
|
}
|
|
58
87
|
if (0 === degree) {
|
|
59
88
|
let s = 0;
|
|
60
89
|
for (let i = 0; i < w.length; i++) s += w[i] * ptsY[actualStart + i];
|
|
61
90
|
return s / sumw;
|
|
62
91
|
}
|
|
63
|
-
|
|
92
|
+
// weighted linear regression on local points
|
|
93
|
+
let sw = 0, sx = 0, sy = 0, sxx = 0, sxy = 0;
|
|
64
94
|
for (let i = actualStart; i < end; i++) {
|
|
65
95
|
const idx = i - actualStart, xi = ptsX[i], yi = ptsY[i], wi = w[idx];
|
|
66
96
|
sw += wi, sx += wi * xi, sy += wi * yi, sxx += wi * xi * xi, sxy += wi * xi * yi;
|
|
@@ -92,12 +122,17 @@ export function regressionLowess(data, x = (d => d.x), y = (d => d.y), options =
|
|
|
92
122
|
return out;
|
|
93
123
|
}
|
|
94
124
|
const step = (max - min) / (N - 1);
|
|
95
|
-
|
|
96
|
-
|
|
125
|
+
// optionally add robust iterations
|
|
126
|
+
let robustWeights;
|
|
127
|
+
// Disable robustness iterations for large datasets to improve performance
|
|
128
|
+
// Users can override by setting iterations explicitly
|
|
129
|
+
const effectiveIterations = null != options.iterations ? iterations : n > 500 ? 0 : iterations;
|
|
97
130
|
if (effectiveIterations > 0) for (let iter = 0; iter < effectiveIterations; iter++) {
|
|
131
|
+
// compute fits - pre-allocate arrays
|
|
98
132
|
const fits = new Array(n), res = new Array(n);
|
|
99
133
|
for (let i = 0; i < n; i++) fits[i] = predictSingle(ptsX[i], robustWeights), res[i] = Math.abs(ptsY[i] - fits[i]);
|
|
100
|
-
|
|
134
|
+
// median absolute deviation
|
|
135
|
+
const med = res.slice().sort(((a, b) => a - b))[Math.floor(n / 2)] || 0;
|
|
101
136
|
robustWeights = new Array(n);
|
|
102
137
|
for (let i = 0; i < n; i++) {
|
|
103
138
|
const u = 0 === med ? 0 : res[i] / (6 * med), w = Math.abs(u) >= 1 ? 0 : (1 - u * u) * (1 - u * u);
|
|
@@ -117,33 +152,34 @@ export function regressionLowess(data, x = (d => d.x), y = (d => d.y), options =
|
|
|
117
152
|
const out = [];
|
|
118
153
|
if (N <= 0) return out;
|
|
119
154
|
if (0 === n) return out;
|
|
120
|
-
|
|
155
|
+
// use data x-range (already sorted)
|
|
156
|
+
const min = ptsX[0], max = ptsX[n - 1];
|
|
121
157
|
if (void 0 === min || void 0 === max || min === 1 / 0 || max === -1 / 0) return out;
|
|
122
158
|
const comps = computeLinearCIComponents(data, x, y, (xx => predictSingle(xx)));
|
|
123
159
|
if (0 === comps.n) return out;
|
|
124
|
-
const z =
|
|
160
|
+
const z = confidenceCriticalValue(alpha);
|
|
125
161
|
if (comps.min === comps.max) {
|
|
126
|
-
const v = predictSingle(comps.min), errs = stdErrorsAt(comps.min, comps);
|
|
162
|
+
const v = predictSingle(comps.min), errs = stdErrorsAt(comps.min, comps), meanHalfWidth = confidenceHalfWidth(z, errs.seMean), predHalfWidth = confidenceHalfWidth(z, errs.sePred);
|
|
127
163
|
for (let i = 0; i < N; i++) out.push({
|
|
128
164
|
x: comps.min,
|
|
129
165
|
mean: v,
|
|
130
|
-
lower: v -
|
|
131
|
-
upper: v +
|
|
132
|
-
predLower: v -
|
|
133
|
-
predUpper: v +
|
|
166
|
+
lower: v - meanHalfWidth,
|
|
167
|
+
upper: v + meanHalfWidth,
|
|
168
|
+
predLower: v - predHalfWidth,
|
|
169
|
+
predUpper: v + predHalfWidth
|
|
134
170
|
});
|
|
135
171
|
return out;
|
|
136
172
|
}
|
|
137
173
|
const step = (max - min) / (N - 1);
|
|
138
174
|
for (let i = 0; i < N; i++) {
|
|
139
|
-
const px = i === N - 1 ? max : min + step * i, yh = predictSingle(px), errs = stdErrorsAt(px, comps);
|
|
175
|
+
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);
|
|
140
176
|
out.push({
|
|
141
177
|
x: px,
|
|
142
178
|
mean: yh,
|
|
143
|
-
lower: yh -
|
|
144
|
-
upper: yh +
|
|
145
|
-
predLower: yh -
|
|
146
|
-
predUpper: yh +
|
|
179
|
+
lower: yh - meanHalfWidth,
|
|
180
|
+
upper: yh + meanHalfWidth,
|
|
181
|
+
predLower: yh - predHalfWidth,
|
|
182
|
+
predUpper: yh + predHalfWidth
|
|
147
183
|
});
|
|
148
184
|
}
|
|
149
185
|
return out;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/common/regression-lowess.ts"],"names":[],"mappings":"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","file":"regression-lowess.js","sourcesContent":["import { visitPoints } from './regression-linear';\nimport { computeLinearCIComponents, invNorm, stdErrorsAt } from './regression-utils';\n\nfunction tricube(u: number) {\n const uu = Math.abs(u);\n if (uu >= 1) {\n return 0;\n }\n const t = 1 - uu * uu * uu;\n return t * t * t;\n}\n\n/**\n * Stratified sampling to reduce data size while preserving distribution\n */\nfunction stratifiedSample(sortedData: { x: number; y: number }[], maxSamples: number) {\n const n = sortedData.length;\n if (n <= maxSamples) {\n return sortedData;\n }\n\n const sampled: { x: number; y: number }[] = [];\n\n // More aggressive sampling - use exact step size\n const step = n / maxSamples;\n\n for (let i = 0; i < maxSamples; i++) {\n const idx = Math.min(Math.floor(i * step), n - 1);\n sampled.push(sortedData[idx]);\n }\n\n return sampled;\n}\n\n/**\n * Simple lowess implementation (univariate x)\n * options:\n * - span: fraction of points used in local regression (0,1]\n * - degree: 0 (constant) or 1 (linear)\n * - iterations: number of robustifying iterations\n * - alpha: confidence level for CI\n * - maxSamples: maximum number of points to use (default: 1000 for fast processing)\n */\nexport function regressionLowess(\n data: any[],\n x: (d: any) => number = d => d.x,\n y: (d: any) => number = d => d.y,\n options: { span?: number; degree?: 1 | 0; iterations?: number; alpha?: number; maxSamples?: number } = {}\n) {\n const span = options.span || 0.3;\n const degree = options.degree === 0 ? 0 : 1;\n const alpha = options.alpha ?? 0.05;\n const iterations = options.iterations == null ? 2 : options.iterations;\n const maxSamples = options.maxSamples || 1000;\n\n // Collect and sort data by x\n const rawPoints: { x: number; y: number }[] = [];\n visitPoints(data, x, y, (dx, dy) => {\n rawPoints.push({ x: dx, y: dy });\n });\n\n rawPoints.sort((a, b) => a.x - b.x);\n\n // Apply sampling if needed\n const sampledPoints = stratifiedSample(rawPoints, maxSamples);\n\n const n = sampledPoints.length;\n const ptsX: number[] = new Array(n);\n const ptsY: number[] = new Array(n);\n\n for (let i = 0; i < n; i++) {\n ptsX[i] = sampledPoints[i].x;\n ptsY[i] = sampledPoints[i].y;\n }\n\n /**\n * Optimized predictSingle using binary search on pre-sorted data\n */\n function predictSingle(x0: number, robustWeights?: number[]) {\n if (n === 0) {\n return 0;\n }\n\n // Binary search to find insertion point\n let left = 0;\n let right = n;\n while (left < right) {\n const mid = (left + right) >> 1;\n if (ptsX[mid] < x0) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n\n const m = Math.max(2, Math.min(n, Math.floor(span * n)));\n\n // Calculate range around insertion point\n const start = Math.max(0, left - Math.floor(m / 2));\n const end = Math.min(n, start + m);\n const actualStart = Math.max(0, end - m);\n\n // Find max distance and compute weights in single pass\n let maxDist = 0;\n const windowSize = end - actualStart;\n const distances: number[] = new Array(windowSize);\n\n for (let i = actualStart; i < end; i++) {\n const dist = Math.abs(ptsX[i] - x0);\n distances[i - actualStart] = dist;\n if (dist > maxDist) {\n maxDist = dist;\n }\n }\n\n // Compute weights using pre-calculated distances\n let sumw = 0;\n const w: number[] = new Array(windowSize);\n for (let i = 0; i < windowSize; i++) {\n const u = maxDist === 0 ? 0 : distances[i] / maxDist;\n let wi = tricube(u);\n if (robustWeights && robustWeights[actualStart + i] != null) {\n wi *= robustWeights[actualStart + i];\n }\n w[i] = wi;\n sumw += wi;\n }\n\n if (sumw === 0) {\n // fallback to nearest y\n const nearestIdx = left < n ? left : n - 1;\n return ptsY[nearestIdx];\n }\n\n if (degree === 0) {\n let s = 0;\n for (let i = 0; i < w.length; i++) {\n s += w[i] * ptsY[actualStart + i];\n }\n return s / sumw;\n }\n\n // weighted linear regression on local points\n let sw = 0;\n let sx = 0;\n let sy = 0;\n let sxx = 0;\n let sxy = 0;\n for (let i = actualStart; i < end; i++) {\n const idx = i - actualStart;\n const xi = ptsX[i];\n const yi = ptsY[i];\n const wi = w[idx];\n sw += wi;\n sx += wi * xi;\n sy += wi * yi;\n sxx += wi * xi * xi;\n sxy += wi * xi * yi;\n }\n\n const meanX = sx / sw;\n const meanY = sy / sw;\n const denom = sxx - sx * meanX;\n const slope = Math.abs(denom) < 1e-12 ? 0 : (sxy - sx * meanY) / denom;\n const intercept = meanY - slope * meanX;\n return intercept + slope * x0;\n }\n\n function predict(x0: number | number[]) {\n if (Array.isArray(x0)) {\n const len = x0.length;\n const out: number[] = new Array(len);\n for (let i = 0; i < len; i++) {\n out[i] = predictSingle(x0[i]);\n }\n return out;\n }\n return predictSingle(x0 as number);\n }\n\n function evaluateGrid(N: number) {\n if (N <= 0) {\n return [];\n }\n if (n === 0) {\n return [];\n }\n\n const out: { x: number; y: number }[] = new Array(N);\n const min = ptsX[0];\n const max = ptsX[n - 1];\n\n if (min === max) {\n const v = predictSingle(min);\n for (let i = 0; i < N; i++) {\n out[i] = { x: min, y: v };\n }\n return out;\n }\n const step = (max - min) / (N - 1);\n\n // optionally add robust iterations\n let robustWeights: number[] | undefined;\n\n // Disable robustness iterations for large datasets to improve performance\n // Users can override by setting iterations explicitly\n const effectiveIterations = options.iterations != null ? iterations : n > 500 ? 0 : iterations;\n\n if (effectiveIterations > 0) {\n for (let iter = 0; iter < effectiveIterations; iter++) {\n // compute fits - pre-allocate arrays\n const fits: number[] = new Array(n);\n const res: number[] = new Array(n);\n\n for (let i = 0; i < n; i++) {\n fits[i] = predictSingle(ptsX[i], robustWeights);\n res[i] = Math.abs(ptsY[i] - fits[i]);\n }\n\n // median absolute deviation\n const sortedRes = res.slice().sort((a, b) => a - b);\n const med = sortedRes[Math.floor(n / 2)] || 0;\n robustWeights = new Array(n);\n for (let i = 0; i < n; i++) {\n const u = med === 0 ? 0 : res[i] / (6 * med);\n const w = Math.abs(u) >= 1 ? 0 : (1 - u * u) * (1 - u * u);\n robustWeights[i] = w;\n }\n }\n }\n\n for (let i = 0; i < N; i++) {\n const px = i === N - 1 ? max : min + step * i;\n out[i] = { x: px, y: predictSingle(px, robustWeights) };\n }\n return out;\n }\n\n function confidenceInterval(N: number = 50) {\n const out: { x: number; mean: number; lower: number; upper: number; predLower: number; predUpper: number }[] = [];\n\n if (N <= 0) {\n return out;\n }\n if (n === 0) {\n return out;\n }\n\n // use data x-range (already sorted)\n const min = ptsX[0];\n const max = ptsX[n - 1];\n\n if (min === undefined || max === undefined || min === Infinity || max === -Infinity) {\n return out;\n }\n\n const comps = computeLinearCIComponents(data, x, y, (xx: number) => predictSingle(xx));\n if (comps.n === 0) {\n return out;\n }\n\n const z = Math.abs(invNorm(1 - alpha / 2));\n if (comps.min === comps.max) {\n const v = predictSingle(comps.min);\n const errs = stdErrorsAt(comps.min, comps);\n for (let i = 0; i < N; i++) {\n out.push({\n x: comps.min,\n mean: v,\n lower: v - z * errs.seMean,\n upper: v + z * errs.seMean,\n predLower: v - z * errs.sePred,\n predUpper: v + z * errs.sePred\n });\n }\n return out;\n }\n\n const step = (max - min) / (N - 1);\n for (let i = 0; i < N; i++) {\n const px = i === N - 1 ? max : min + step * i;\n const yh = predictSingle(px);\n const errs = stdErrorsAt(px, comps);\n out.push({\n x: px,\n mean: yh,\n lower: yh - z * errs.seMean,\n upper: yh + z * errs.seMean,\n predLower: yh - z * errs.sePred,\n predUpper: yh + z * errs.sePred\n });\n }\n return out;\n }\n\n return {\n predict,\n evaluate: predict as any,\n evaluateGrid,\n confidenceInterval\n };\n}\n\nexport default regressionLowess;\n"]}
|
|
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 {\n computeLinearCIComponents,\n confidenceCriticalValue,\n confidenceHalfWidth,\n stdErrorsAt\n} 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 = 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 as any,\n evaluateGrid,\n confidenceInterval\n };\n}\n\nexport default regressionLowess;\n"]}
|