public convert()

in src/converter/data/dataSmooth.ts [55:126]


    public convert(points: IDataRepresentationPoint[]): IDataRepresentationPoint[] {
        const length = points.length;
        const bandwidthInPoints = Math.floor(this.bandwidth * length);
        const resultPoints: IDataRepresentationPoint[] = [];
        const residuals: number[] = [];
        const robustnessWeights: number[] = [];

        for (let i: number = 0; i < length; i++) {
            residuals[i] = 0;
            robustnessWeights[i] = 1;
        }

        let alphaBeta: IAlphaBeta;

        for (let iter: number = 0; iter < this.robustnessIters; iter++) {
            const bandwidthInterval: number[] = [0, bandwidthInPoints - 1];

            for (let i: number = 0; i < length; i++) {
                const x: number = points[i].x.getTime();

                if (i > 0) {
                    this.science_stats_loessUpdateBandwidthInterval(points, i, bandwidthInterval);
                }

                const ileft: number = bandwidthInterval[0];
                const iright: number = bandwidthInterval[1];

                if (!isNaN(ileft)
                    && !isNaN(iright)
                    && ileft !== iright
                    && ileft >= 0
                    && iright >= 0
                ) {
                    alphaBeta = this.calcAlphaBeta(robustnessWeights, i, x, ileft, iright, points);

                    if (!isNaN(alphaBeta.beta) && !isNaN(alphaBeta.alpha)) {
                        resultPoints[i] = {
                            ...points[i],
                            y: alphaBeta.beta * x + alphaBeta.alpha,
                        };
                    } else {
                        resultPoints[i] = { ...points[i] };
                    }

                    residuals[i] = Math.abs(points[i].y - resultPoints[i].y);
                } else {
                    resultPoints[i] = { ...points[i] };
                }
            }

            if (iter === this.robustnessIters) {
                break;
            }

            const sortedResiduals: number[] = residuals
                .slice()
                .sort();

            const medianResidual: number = sortedResiduals[Math.floor(length / 2)];

            if (Math.abs(medianResidual) < this.accuracy) {
                break;
            }

            for (let i: number = 0; i < length; i++) {
                const arg: number = residuals[i] / (6 * medianResidual);
                robustnessWeights[i] = (arg >= 1) ? 0 : ((alphaBeta.w = 1 - arg * arg) * alphaBeta.w);
            }
        }

        return resultPoints;
    }