SumOfFourthDeviations combine()

in commons-statistics-descriptive/src/main/java/org/apache/commons/statistics/descriptive/SumOfFourthDeviations.java [369:403]


    SumOfFourthDeviations combine(SumOfFourthDeviations other) {
        if (n == 0) {
            sumFourthDev = other.sumFourthDev;
        } else if (other.n != 0) {
            // Avoid overflow to compute the difference.
            final double halfDiffOfMean = getFirstMomentHalfDifference(other);
            sumFourthDev += other.sumFourthDev;
            // Add additional terms that do not cancel to zero
            if (halfDiffOfMean != 0) {
                final double n1 = n;
                final double n2 = other.n;
                if (n1 == n2) {
                    // Optimisation where sizes are equal in double-precision.
                    // This is of use in JDK streams as spliterators use a divide by two
                    // strategy for parallel streams.
                    // Note: (n1 * n2) * ((n1+n2)^2 - 3 * (n1 * n2)) == n^4
                    sumFourthDev +=
                        (sumCubedDev - other.sumCubedDev) * halfDiffOfMean * 4 +
                        (sumSquaredDev + other.sumSquaredDev) * (halfDiffOfMean * halfDiffOfMean) * 6 +
                        pow4(halfDiffOfMean) * n1 * 2;
                } else {
                    final double n1n2 = n1 + n2;
                    final double dm = 2 * (halfDiffOfMean / n1n2);
                    // Use the rearrangement for parity with the accept method
                    // n1*n1 - n1*n2 + n2*n2 == (n1+n2)^2 - 3*n1*n2
                    sumFourthDev +=
                        (sumCubedDev * n2 - other.sumCubedDev * n1) * dm * 4 +
                        (n2 * n2 * sumSquaredDev + n1 * n1 * other.sumSquaredDev) * (dm * dm) * 6 +
                        (n1 * n2) * (n1n2 * n1n2 - 3 * (n1 * n2)) * pow4(dm) * n1n2;
                }
            }
        }
        super.combine(other);
        return this;
    }