@Override
    public double[] smooth(double[] input) {

        if (input.length < weights.length) {
            return input;
        }

        double[] smoothed = new double[input.length];
        int halfWindowFloored = weights.length / 2; // we want to exclude the center point

        fillSmoothedLeftSide(smoothed, input, halfWindowFloored);
        fillSmoothedRightSide(smoothed, input, halfWindowFloored);

        for (int i = halfWindowFloored; i < input.length - halfWindowFloored; i++) {
            for (int windowIndex = 0; windowIndex < smoothCoeff.length; windowIndex++) {
                smoothed[i] += smoothCoeff[windowIndex] * input[i + windowIndex + offsetFromWindowCenter];
            }
        }
        return smoothed;
    }
@Test
    public void Smooth_FromFakeTrackWithOutlier_RemoveBumps() {
        SavitzkyGolayFilter test = new SavitzkyGolayFilter(1.0);

        double[] input = new double[]{
            10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 13.0, // <-- outlier
            10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0
        };
        double[] actual = test.smooth(input);

        assertThat(actual.length, equalTo(input.length));

        for (int i = 0; i < input.length; i++) {
            assertThat(actual[i], closeTo(10.0, 1.0));
        }
    }