| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.beam.sdk.extensions.sql.impl.transform.agg; |
| |
| import static java.math.BigDecimal.ONE; |
| import static java.math.BigDecimal.ZERO; |
| import static org.apache.beam.sdk.extensions.sql.impl.transform.agg.VarianceAccumulator.newVarianceAccumulator; |
| import static org.apache.beam.sdk.extensions.sql.impl.transform.agg.VarianceAccumulator.ofSingleElement; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotEquals; |
| |
| import java.math.BigDecimal; |
| import org.junit.Test; |
| |
| /** Unit tests for {@link VarianceAccumulator}. */ |
| public class VarianceAccumulatorTest { |
| private static final double DELTA = 1e-7; |
| private static final BigDecimal FIFTEEN = new BigDecimal(15); |
| private static final BigDecimal SIXTEEN = new BigDecimal(16); |
| private static final BigDecimal THREE = new BigDecimal(3); |
| private static final BigDecimal FOUR = new BigDecimal(4); |
| private static final BigDecimal FIVE = new BigDecimal(5); |
| |
| @Test |
| public void testInitialized() { |
| VarianceAccumulator accumulator = newVarianceAccumulator(FIFTEEN, THREE, FOUR); |
| |
| assertNotEquals(VarianceAccumulator.EMPTY, accumulator); |
| assertEquals(FIFTEEN, accumulator.variance()); |
| assertEquals(THREE, accumulator.count()); |
| assertEquals(FOUR, accumulator.sum()); |
| } |
| |
| @Test |
| public void testEmpty() { |
| VarianceAccumulator zeroAccumulator = newVarianceAccumulator(ZERO, ZERO, ZERO); |
| |
| assertEquals(zeroAccumulator, VarianceAccumulator.EMPTY); |
| assertEquals(zeroAccumulator, VarianceAccumulator.ofZeroElements()); |
| } |
| |
| @Test |
| public void testAccumulatorOfSingleElement() { |
| VarianceAccumulator accumulatorOfSingleElement = ofSingleElement(THREE); |
| |
| assertEquals(newVarianceAccumulator(ZERO, ONE, THREE), accumulatorOfSingleElement); |
| } |
| |
| @Test |
| public void testCombinesEmptyWithEmpty() { |
| VarianceAccumulator result = VarianceAccumulator.EMPTY.combineWith(VarianceAccumulator.EMPTY); |
| |
| assertEquals(VarianceAccumulator.EMPTY, result); |
| } |
| |
| @Test |
| public void testCombinesEmptyWithNonEmpty() { |
| VarianceAccumulator result = VarianceAccumulator.EMPTY.combineWith(ofSingleElement(THREE)); |
| |
| assertEquals(newVarianceAccumulator(ZERO, ONE, THREE), result); |
| } |
| |
| @Test |
| public void testCombinesNonEmptyWithEmpty() { |
| VarianceAccumulator result = ofSingleElement(THREE).combineWith(VarianceAccumulator.EMPTY); |
| |
| assertEquals(newVarianceAccumulator(ZERO, ONE, THREE), result); |
| } |
| |
| @Test |
| public void testCombinesNonTrivial() { |
| VarianceAccumulator accumulator1 = newVarianceAccumulator(FIFTEEN, THREE, FOUR); |
| VarianceAccumulator accumulator2 = newVarianceAccumulator(SIXTEEN, FOUR, FIVE); |
| |
| // values: |
| // var(x)=15, m=3, sum(x)=4; |
| // var(y)=16, n=4, sum(y)=5; |
| // |
| // formula: |
| // var(combine(x,y)) = var(x) + var(y) + increment(); |
| // increment() = m/(n(m+n)) * (sum(x) * n/m - sum(y))^2; |
| // |
| // result: |
| // increment() = 3/(4(3+4)) * (4 * 4/3 - 5)^2 = 0.107142857 * 0.111111111 = 0.011904762 |
| // var(combine(x,y)) = 15 + 16 + increment() = 31.011904762 |
| VarianceAccumulator expectedCombined = |
| newVarianceAccumulator( |
| FIFTEEN.add(SIXTEEN).add(new BigDecimal(0.011904762)), THREE.add(FOUR), FOUR.add(FIVE)); |
| |
| VarianceAccumulator combined1 = accumulator1.combineWith(accumulator2); |
| VarianceAccumulator combined2 = accumulator2.combineWith(accumulator1); |
| |
| assertEquals( |
| expectedCombined.variance().doubleValue(), combined1.variance().doubleValue(), DELTA); |
| |
| assertEquals( |
| expectedCombined.variance().doubleValue(), combined2.variance().doubleValue(), DELTA); |
| |
| assertEquals(expectedCombined.count(), combined1.count()); |
| assertEquals(expectedCombined.sum(), combined1.sum()); |
| |
| assertEquals(expectedCombined.count(), combined2.count()); |
| assertEquals(expectedCombined.sum(), combined2.sum()); |
| } |
| } |