UNPKG

@visactor/vmind

Version:

<div align="center"> <a href="https://github.com/VisActor#gh-light-mode-only" target="_blank"> <img alt="VisActor Logo" width="200" src="https://github.com/VisActor/.github/blob/main/profile/logo_500_200_light.svg"/> </a> <a href="https://githu

84 lines (79 loc) 4.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }), exports.Adwin = void 0; const bucket_1 = require("./bucket"); class Adwin { constructor(delta = .002, maxBuckets = 5, minClock = 32, minWinLen = 10, minSubWinLen = 5) { this.delta = delta, this.maxBuckets = maxBuckets, this.minClock = minClock, this.minWinLen = minWinLen, this.minSubWinLen = minSubWinLen, this.time = 0, this.windowLen = 0, this.windowSum = 0, this.windowVariance = 0, this.bucketRowCount = 0, this.bucketRowList = new bucket_1.AdwinRowBucketList(this.maxBuckets); } setInput(value) { return this.time++, this.insertElement(value), this.reduceWindow(); } insertElement(value) { this.bucketRowList.head.insertBucket(value, 0); let incrementVariance = 0; if (this.windowLen > 0) { const mean = this.windowSum / this.windowLen; incrementVariance = this.windowLen * (value - mean) ** 2 / (this.windowLen + 1); } this.windowLen++, this.windowVariance += incrementVariance, this.windowSum += value, this.compressBucketRow(); } compressBucketRow() { let bucketRow = this.bucketRowList.head, bucketRowLevel = 0; for (;null !== bucketRow && bucketRow.bucketCount === this.maxBuckets + 1; ) { { let nextBucketRow = bucketRow.nextBucketRow; null === nextBucketRow && (this.bucketRowList.addToTail(), nextBucketRow = bucketRow.nextBucketRow, this.bucketRowCount++); const n1 = 2 ** bucketRowLevel, n2 = 2 ** bucketRowLevel, mean1 = bucketRow.bucketSum[0] / n1, mean2 = bucketRow.bucketSum[1] / n2, nextTotal = bucketRow.bucketSum[0] + bucketRow.bucketSum[1], externalVariance = n1 * n2 * (mean1 - mean2) ** 2 / (n1 + n2), nextVariance = bucketRow.bucketVariance[0] + bucketRow.bucketVariance[1] + externalVariance; if (nextBucketRow.insertBucket(nextTotal, nextVariance), bucketRow.compressBucket(2), nextBucketRow.bucketCount <= this.maxBuckets) break; } bucketRow = bucketRow.nextBucketRow, bucketRowLevel++; } } reduceWindow() { let isChanged = !1; if (this.time % this.minClock == 0 && this.windowLen >= this.minWinLen) { let isReducedWidth = !0; for (;isReducedWidth; ) { isReducedWidth = !1; let isExit = !1, n0 = 0, n1 = this.windowLen, sum0 = 0, sum1 = this.windowSum, bucketRow = this.bucketRowList.tail, i = this.bucketRowCount; for (;!isExit && !bucketRow; ) { for (let bucketNum = 0; bucketNum < bucketRow.bucketCount; bucketNum++) { if (0 === i && bucketNum === bucketRow.bucketCount - 1) { isExit = !0; break; } n0 += 2 ** i, n1 -= 2 ** i, sum0 = bucketRow.bucketSum[bucketNum], sum1 -= bucketRow.bucketSum[bucketNum]; const diffValue = sum0 / n0 - (sum1 - n1); if (n0 > this.minSubWinLen + 1 && n1 > this.minSubWinLen + 1 && this.reduceExpression(n0, n1, diffValue) && (isReducedWidth = !0, isChanged = !0, this.windowLen > 0)) { n0 -= this.deleteElement(), isExit = !0; break; } } bucketRow = bucketRow.previousBucketRow, i--; } } } return isChanged; } reduceExpression(n0, n1, diffValue) { const m = 1 / (n0 - this.minSubWinLen + 1) + 1 / (n1 - this.minSubWinLen + 1), d = Math.log(2 * Math.log(this.windowLen) / this.delta), varianceWindow = this.windowVariance / this.windowLen, epsilonCut = Math.sqrt(2 * m * varianceWindow * d) + 2 / 3 * m * d; return Math.abs(diffValue) > epsilonCut; } deleteElement() { const bucketRow = this.bucketRowList.tail, deletedNumber = 2 ** this.bucketRowCount; this.windowLen -= deletedNumber, this.windowSum -= bucketRow.bucketSum[0]; const deletedBucketMean = bucketRow.bucketSum[0] / deletedNumber, incVariance = bucketRow.bucketVariance[0] + deletedNumber * this.windowLen * Math.pow(deletedBucketMean - this.windowSum / this.windowLen, 2) / (deletedNumber + this.windowLen); return this.windowVariance -= incVariance, bucketRow.compressBucket(1), 0 === bucketRow.bucketCount && (this.bucketRowList.removeFromTail(), this.bucketRowCount -= 1), deletedNumber; } } exports.Adwin = Adwin; //# sourceMappingURL=adwin.js.map