• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.math;
18 
19 import static com.google.common.math.StatsTesting.ALLOWED_ERROR;
20 import static com.google.common.math.StatsTesting.ALL_MANY_VALUES;
21 import static com.google.common.math.StatsTesting.EMPTY_STATS_ITERABLE;
22 import static com.google.common.math.StatsTesting.MANY_VALUES;
23 import static com.google.common.math.StatsTesting.MANY_VALUES_COUNT;
24 import static com.google.common.math.StatsTesting.MANY_VALUES_STATS_ITERABLE;
25 import static com.google.common.math.StatsTesting.MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS;
26 import static com.google.common.math.StatsTesting.ONE_VALUE;
27 import static com.google.common.math.StatsTesting.ONE_VALUE_STATS;
28 import static com.google.common.math.StatsTesting.OTHER_MANY_VALUES;
29 import static com.google.common.math.StatsTesting.OTHER_MANY_VALUES_COUNT;
30 import static com.google.common.math.StatsTesting.OTHER_MANY_VALUES_STATS;
31 import static com.google.common.math.StatsTesting.OTHER_ONE_VALUE;
32 import static com.google.common.math.StatsTesting.OTHER_ONE_VALUE_STATS;
33 import static com.google.common.math.StatsTesting.OTHER_TWO_VALUES;
34 import static com.google.common.math.StatsTesting.OTHER_TWO_VALUES_STATS;
35 import static com.google.common.math.StatsTesting.TWO_VALUES;
36 import static com.google.common.math.StatsTesting.TWO_VALUES_STATS;
37 import static com.google.common.math.StatsTesting.TWO_VALUES_SUM_OF_PRODUCTS_OF_DELTAS;
38 import static com.google.common.math.StatsTesting.assertDiagonalLinearTransformation;
39 import static com.google.common.math.StatsTesting.assertHorizontalLinearTransformation;
40 import static com.google.common.math.StatsTesting.assertLinearTransformationNaN;
41 import static com.google.common.math.StatsTesting.assertStatsApproxEqual;
42 import static com.google.common.math.StatsTesting.assertVerticalLinearTransformation;
43 import static com.google.common.math.StatsTesting.createFilledPairedStatsAccumulator;
44 import static com.google.common.math.StatsTesting.createPartitionedFilledPairedStatsAccumulator;
45 import static com.google.common.truth.Truth.assertThat;
46 import static com.google.common.truth.Truth.assertWithMessage;
47 import static org.junit.Assert.assertThrows;
48 
49 import com.google.common.math.StatsTesting.ManyValues;
50 import java.util.Collections;
51 import junit.framework.TestCase;
52 
53 /**
54  * Tests for {@link PairedStatsAccumulator}. This tests the stats methods for instances built with
55  * {@link PairedStatsAccumulator#add}, and various error cases of that method. For tests of the
56  * {@link PairedStatsAccumulator#snapshot} method which returns {@link PairedStats} instances, see
57  * {@link PairedStatsTest}.
58  *
59  * @author Pete Gillin
60  */
61 public class PairedStatsAccumulatorTest extends TestCase {
62 
63   private PairedStatsAccumulator emptyAccumulator;
64   private PairedStatsAccumulator emptyAccumulatorByAddAllEmptyPairedStats;
65   private PairedStatsAccumulator oneValueAccumulator;
66   private PairedStatsAccumulator oneValueAccumulatorByAddAllEmptyPairedStats;
67   private PairedStatsAccumulator twoValuesAccumulator;
68   private PairedStatsAccumulator twoValuesAccumulatorByAddAllPartitionedPairedStats;
69   private PairedStatsAccumulator manyValuesAccumulator;
70   private PairedStatsAccumulator manyValuesAccumulatorByAddAllPartitionedPairedStats;
71   private PairedStatsAccumulator horizontalValuesAccumulator;
72   private PairedStatsAccumulator horizontalValuesAccumulatorByAddAllPartitionedPairedStats;
73   private PairedStatsAccumulator verticalValuesAccumulator;
74   private PairedStatsAccumulator verticalValuesAccumulatorByAddAllPartitionedPairedStats;
75   private PairedStatsAccumulator constantValuesAccumulator;
76   private PairedStatsAccumulator constantValuesAccumulatorByAddAllPartitionedPairedStats;
77 
78   @Override
setUp()79   protected void setUp() throws Exception {
80     super.setUp();
81 
82     emptyAccumulator = new PairedStatsAccumulator();
83 
84     emptyAccumulatorByAddAllEmptyPairedStats = new PairedStatsAccumulator();
85     emptyAccumulatorByAddAllEmptyPairedStats.addAll(emptyAccumulator.snapshot());
86 
87     oneValueAccumulator = new PairedStatsAccumulator();
88     oneValueAccumulator.add(ONE_VALUE, OTHER_ONE_VALUE);
89 
90     oneValueAccumulatorByAddAllEmptyPairedStats = new PairedStatsAccumulator();
91     oneValueAccumulatorByAddAllEmptyPairedStats.add(ONE_VALUE, OTHER_ONE_VALUE);
92     oneValueAccumulatorByAddAllEmptyPairedStats.addAll(emptyAccumulator.snapshot());
93 
94     twoValuesAccumulator = createFilledPairedStatsAccumulator(TWO_VALUES, OTHER_TWO_VALUES);
95     twoValuesAccumulatorByAddAllPartitionedPairedStats =
96         createPartitionedFilledPairedStatsAccumulator(TWO_VALUES, OTHER_TWO_VALUES, 1);
97 
98     manyValuesAccumulator = createFilledPairedStatsAccumulator(MANY_VALUES, OTHER_MANY_VALUES);
99     manyValuesAccumulatorByAddAllPartitionedPairedStats =
100         createPartitionedFilledPairedStatsAccumulator(MANY_VALUES, OTHER_MANY_VALUES, 2);
101 
102     horizontalValuesAccumulator =
103         createFilledPairedStatsAccumulator(
104             MANY_VALUES, Collections.nCopies(MANY_VALUES_COUNT, OTHER_ONE_VALUE));
105     horizontalValuesAccumulatorByAddAllPartitionedPairedStats =
106         createPartitionedFilledPairedStatsAccumulator(
107             MANY_VALUES, Collections.nCopies(MANY_VALUES_COUNT, OTHER_ONE_VALUE), 2);
108 
109     verticalValuesAccumulator =
110         createFilledPairedStatsAccumulator(
111             Collections.nCopies(OTHER_MANY_VALUES_COUNT, ONE_VALUE), OTHER_MANY_VALUES);
112     verticalValuesAccumulatorByAddAllPartitionedPairedStats =
113         createPartitionedFilledPairedStatsAccumulator(
114             Collections.nCopies(OTHER_MANY_VALUES_COUNT, ONE_VALUE), OTHER_MANY_VALUES, 2);
115 
116     constantValuesAccumulator =
117         createFilledPairedStatsAccumulator(
118             Collections.nCopies(MANY_VALUES_COUNT, ONE_VALUE),
119             Collections.nCopies(MANY_VALUES_COUNT, OTHER_ONE_VALUE));
120     constantValuesAccumulatorByAddAllPartitionedPairedStats =
121         createPartitionedFilledPairedStatsAccumulator(
122             Collections.nCopies(MANY_VALUES_COUNT, ONE_VALUE),
123             Collections.nCopies(MANY_VALUES_COUNT, OTHER_ONE_VALUE),
124             2);
125   }
126 
testCount()127   public void testCount() {
128     assertThat(emptyAccumulator.count()).isEqualTo(0);
129     assertThat(emptyAccumulatorByAddAllEmptyPairedStats.count()).isEqualTo(0);
130     assertThat(oneValueAccumulator.count()).isEqualTo(1);
131     assertThat(oneValueAccumulatorByAddAllEmptyPairedStats.count()).isEqualTo(1);
132     assertThat(twoValuesAccumulator.count()).isEqualTo(2);
133     assertThat(twoValuesAccumulatorByAddAllPartitionedPairedStats.count()).isEqualTo(2);
134     assertThat(manyValuesAccumulator.count()).isEqualTo(MANY_VALUES_COUNT);
135     assertThat(manyValuesAccumulatorByAddAllPartitionedPairedStats.count())
136         .isEqualTo(MANY_VALUES_COUNT);
137   }
138 
testCountOverflow_doesNotThrow()139   public void testCountOverflow_doesNotThrow() {
140     PairedStatsAccumulator accumulator = new PairedStatsAccumulator();
141     accumulator.add(ONE_VALUE, OTHER_ONE_VALUE);
142     for (int power = 1; power < Long.SIZE - 1; power++) {
143       accumulator.addAll(accumulator.snapshot());
144     }
145     // Should overflow without throwing.
146     accumulator.addAll(accumulator.snapshot());
147     assertThat(accumulator.count()).isLessThan(0L);
148   }
149 
testXStats()150   public void testXStats() {
151     assertStatsApproxEqual(EMPTY_STATS_ITERABLE, emptyAccumulator.xStats());
152     assertStatsApproxEqual(EMPTY_STATS_ITERABLE, emptyAccumulatorByAddAllEmptyPairedStats.xStats());
153     assertStatsApproxEqual(ONE_VALUE_STATS, oneValueAccumulator.xStats());
154     assertStatsApproxEqual(ONE_VALUE_STATS, oneValueAccumulatorByAddAllEmptyPairedStats.xStats());
155     assertStatsApproxEqual(TWO_VALUES_STATS, twoValuesAccumulator.xStats());
156     assertStatsApproxEqual(
157         TWO_VALUES_STATS, twoValuesAccumulatorByAddAllPartitionedPairedStats.xStats());
158     assertStatsApproxEqual(MANY_VALUES_STATS_ITERABLE, manyValuesAccumulator.xStats());
159     assertStatsApproxEqual(
160         MANY_VALUES_STATS_ITERABLE, manyValuesAccumulatorByAddAllPartitionedPairedStats.xStats());
161   }
162 
testYStats()163   public void testYStats() {
164     assertStatsApproxEqual(EMPTY_STATS_ITERABLE, emptyAccumulator.yStats());
165     assertStatsApproxEqual(EMPTY_STATS_ITERABLE, emptyAccumulatorByAddAllEmptyPairedStats.yStats());
166     assertStatsApproxEqual(OTHER_ONE_VALUE_STATS, oneValueAccumulator.yStats());
167     assertStatsApproxEqual(
168         OTHER_ONE_VALUE_STATS, oneValueAccumulatorByAddAllEmptyPairedStats.yStats());
169     assertStatsApproxEqual(OTHER_TWO_VALUES_STATS, twoValuesAccumulator.yStats());
170     assertStatsApproxEqual(
171         OTHER_TWO_VALUES_STATS, twoValuesAccumulatorByAddAllPartitionedPairedStats.yStats());
172     assertStatsApproxEqual(OTHER_MANY_VALUES_STATS, manyValuesAccumulator.yStats());
173     assertStatsApproxEqual(
174         OTHER_MANY_VALUES_STATS, manyValuesAccumulatorByAddAllPartitionedPairedStats.yStats());
175   }
176 
testPopulationCovariance()177   public void testPopulationCovariance() {
178     assertThrows(IllegalStateException.class, () -> emptyAccumulator.populationCovariance());
179     assertThrows(
180         IllegalStateException.class,
181         () -> emptyAccumulatorByAddAllEmptyPairedStats.populationCovariance());
182     assertThat(oneValueAccumulator.populationCovariance()).isEqualTo(0.0);
183     assertThat(oneValueAccumulatorByAddAllEmptyPairedStats.populationCovariance()).isEqualTo(0.0);
184     assertThat(twoValuesAccumulator.populationCovariance())
185         .isWithin(ALLOWED_ERROR)
186         .of(TWO_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / 2);
187     assertThat(twoValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
188         .isWithin(ALLOWED_ERROR)
189         .of(TWO_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / 2);
190     assertThat(manyValuesAccumulator.populationCovariance())
191         .isWithin(ALLOWED_ERROR)
192         .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
193     assertThat(manyValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
194         .isWithin(ALLOWED_ERROR)
195         .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
196     // For datasets of many double values, we test many combinations of finite and non-finite
197     // x-values:
198     for (ManyValues values : ALL_MANY_VALUES) {
199       PairedStatsAccumulator accumulator =
200           createFilledPairedStatsAccumulator(values.asIterable(), OTHER_MANY_VALUES);
201       PairedStatsAccumulator accumulatorByAddAllPartitionedPairedStats =
202           createPartitionedFilledPairedStatsAccumulator(values.asIterable(), OTHER_MANY_VALUES, 2);
203       double populationCovariance = accumulator.populationCovariance();
204       double populationCovarianceByAddAllPartitionedPairedStats =
205           accumulatorByAddAllPartitionedPairedStats.populationCovariance();
206       if (values.hasAnyNonFinite()) {
207         assertWithMessage("population covariance of " + values).that(populationCovariance).isNaN();
208         assertWithMessage("population covariance by addAll(PairedStats) of " + values)
209             .that(populationCovarianceByAddAllPartitionedPairedStats)
210             .isNaN();
211       } else {
212         assertWithMessage("population covariance of " + values)
213             .that(populationCovariance)
214             .isWithin(ALLOWED_ERROR)
215             .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
216         assertWithMessage("population covariance by addAll(PairedStats) of " + values)
217             .that(populationCovarianceByAddAllPartitionedPairedStats)
218             .isWithin(ALLOWED_ERROR)
219             .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
220       }
221     }
222     assertThat(horizontalValuesAccumulator.populationCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
223     assertThat(horizontalValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
224         .isWithin(ALLOWED_ERROR)
225         .of(0.0);
226     assertThat(verticalValuesAccumulator.populationCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
227     assertThat(verticalValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
228         .isWithin(ALLOWED_ERROR)
229         .of(0.0);
230     assertThat(constantValuesAccumulator.populationCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
231     assertThat(constantValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
232         .isWithin(ALLOWED_ERROR)
233         .of(0.0);
234   }
235 
testSampleCovariance()236   public void testSampleCovariance() {
237     assertThrows(IllegalStateException.class, () -> emptyAccumulator.sampleCovariance());
238     assertThrows(
239         IllegalStateException.class,
240         () -> emptyAccumulatorByAddAllEmptyPairedStats.sampleCovariance());
241     assertThrows(IllegalStateException.class, () -> oneValueAccumulator.sampleCovariance());
242     assertThrows(
243         IllegalStateException.class,
244         () -> oneValueAccumulatorByAddAllEmptyPairedStats.sampleCovariance());
245     assertThat(twoValuesAccumulator.sampleCovariance())
246         .isWithin(ALLOWED_ERROR)
247         .of(TWO_VALUES_SUM_OF_PRODUCTS_OF_DELTAS);
248     assertThat(twoValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
249         .isWithin(ALLOWED_ERROR)
250         .of(TWO_VALUES_SUM_OF_PRODUCTS_OF_DELTAS);
251     assertThat(manyValuesAccumulator.sampleCovariance())
252         .isWithin(ALLOWED_ERROR)
253         .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / (MANY_VALUES_COUNT - 1));
254     assertThat(manyValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
255         .isWithin(ALLOWED_ERROR)
256         .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / (MANY_VALUES_COUNT - 1));
257     assertThat(horizontalValuesAccumulator.sampleCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
258     assertThat(horizontalValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
259         .isWithin(ALLOWED_ERROR)
260         .of(0.0);
261     assertThat(verticalValuesAccumulator.sampleCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
262     assertThat(verticalValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
263         .isWithin(ALLOWED_ERROR)
264         .of(0.0);
265     assertThat(constantValuesAccumulator.sampleCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
266     assertThat(constantValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
267         .isWithin(ALLOWED_ERROR)
268         .of(0.0);
269   }
270 
testPearsonsCorrelationCoefficient()271   public void testPearsonsCorrelationCoefficient() {
272     assertThrows(
273         IllegalStateException.class, () -> emptyAccumulator.pearsonsCorrelationCoefficient());
274     assertThrows(
275         IllegalStateException.class,
276         () -> emptyAccumulatorByAddAllEmptyPairedStats.pearsonsCorrelationCoefficient());
277     assertThrows(
278         IllegalStateException.class, () -> oneValueAccumulator.pearsonsCorrelationCoefficient());
279     assertThrows(
280         IllegalStateException.class,
281         () -> oneValueAccumulatorByAddAllEmptyPairedStats.pearsonsCorrelationCoefficient());
282     assertThat(twoValuesAccumulator.pearsonsCorrelationCoefficient())
283         .isWithin(ALLOWED_ERROR)
284         .of(
285             twoValuesAccumulator.populationCovariance()
286                 / (twoValuesAccumulator.xStats().populationStandardDeviation()
287                     * twoValuesAccumulator.yStats().populationStandardDeviation()));
288     assertThat(manyValuesAccumulator.pearsonsCorrelationCoefficient())
289         .isWithin(ALLOWED_ERROR)
290         .of(
291             manyValuesAccumulator.populationCovariance()
292                 / (manyValuesAccumulator.xStats().populationStandardDeviation()
293                     * manyValuesAccumulator.yStats().populationStandardDeviation()));
294     assertThat(manyValuesAccumulatorByAddAllPartitionedPairedStats.pearsonsCorrelationCoefficient())
295         .isWithin(ALLOWED_ERROR)
296         .of(
297             manyValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance()
298                 / (manyValuesAccumulatorByAddAllPartitionedPairedStats
299                         .xStats()
300                         .populationStandardDeviation()
301                     * manyValuesAccumulatorByAddAllPartitionedPairedStats
302                         .yStats()
303                         .populationStandardDeviation()));
304     // For datasets of many double values, we test many combinations of finite and non-finite
305     // y-values:
306     for (ManyValues values : ALL_MANY_VALUES) {
307       PairedStatsAccumulator accumulator =
308           createFilledPairedStatsAccumulator(MANY_VALUES, values.asIterable());
309       PairedStatsAccumulator accumulatorByAddAllPartitionedPairedStats =
310           createPartitionedFilledPairedStatsAccumulator(MANY_VALUES, values.asIterable(), 2);
311       double pearsonsCorrelationCoefficient = accumulator.pearsonsCorrelationCoefficient();
312       double pearsonsCorrelationCoefficientByAddAllPartitionedPairedStats =
313           accumulatorByAddAllPartitionedPairedStats.pearsonsCorrelationCoefficient();
314       if (values.hasAnyNonFinite()) {
315         assertWithMessage("Pearson's correlation coefficient of " + values)
316             .that(pearsonsCorrelationCoefficient)
317             .isNaN();
318         assertWithMessage("Pearson's correlation coefficient by addAll(PairedStats) of " + values)
319             .that(pearsonsCorrelationCoefficient)
320             .isNaN();
321       } else {
322         assertWithMessage("Pearson's correlation coefficient of " + values)
323             .that(pearsonsCorrelationCoefficient)
324             .isWithin(ALLOWED_ERROR)
325             .of(
326                 accumulator.populationCovariance()
327                     / (accumulator.xStats().populationStandardDeviation()
328                         * accumulator.yStats().populationStandardDeviation()));
329         assertWithMessage("Pearson's correlation coefficient by addAll(PairedStats) of " + values)
330             .that(pearsonsCorrelationCoefficientByAddAllPartitionedPairedStats)
331             .isWithin(ALLOWED_ERROR)
332             .of(
333                 accumulatorByAddAllPartitionedPairedStats.populationCovariance()
334                     / (accumulatorByAddAllPartitionedPairedStats
335                             .xStats()
336                             .populationStandardDeviation()
337                         * accumulatorByAddAllPartitionedPairedStats
338                             .yStats()
339                             .populationStandardDeviation()));
340       }
341     }
342     assertThrows(
343         IllegalStateException.class,
344         () -> horizontalValuesAccumulator.pearsonsCorrelationCoefficient());
345     assertThrows(
346         IllegalStateException.class,
347         () ->
348             horizontalValuesAccumulatorByAddAllPartitionedPairedStats
349                 .pearsonsCorrelationCoefficient());
350     assertThrows(
351         IllegalStateException.class,
352         () -> verticalValuesAccumulator.pearsonsCorrelationCoefficient());
353     assertThrows(
354         IllegalStateException.class,
355         () ->
356             verticalValuesAccumulatorByAddAllPartitionedPairedStats
357                 .pearsonsCorrelationCoefficient());
358     assertThrows(
359         IllegalStateException.class,
360         () -> constantValuesAccumulator.pearsonsCorrelationCoefficient());
361     assertThrows(
362         IllegalStateException.class,
363         () ->
364             constantValuesAccumulatorByAddAllPartitionedPairedStats
365                 .pearsonsCorrelationCoefficient());
366   }
367 
testLeastSquaresFit()368   public void testLeastSquaresFit() {
369     assertThrows(IllegalStateException.class, () -> emptyAccumulator.leastSquaresFit());
370     assertThrows(
371         IllegalStateException.class,
372         () -> emptyAccumulatorByAddAllEmptyPairedStats.leastSquaresFit());
373     assertThrows(IllegalStateException.class, () -> oneValueAccumulator.leastSquaresFit());
374     assertThrows(
375         IllegalStateException.class,
376         () -> oneValueAccumulatorByAddAllEmptyPairedStats.leastSquaresFit());
377     assertDiagonalLinearTransformation(
378         twoValuesAccumulator.leastSquaresFit(),
379         twoValuesAccumulator.xStats().mean(),
380         twoValuesAccumulator.yStats().mean(),
381         twoValuesAccumulator.xStats().populationVariance(),
382         twoValuesAccumulator.populationCovariance());
383     assertDiagonalLinearTransformation(
384         twoValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit(),
385         twoValuesAccumulatorByAddAllPartitionedPairedStats.xStats().mean(),
386         twoValuesAccumulatorByAddAllPartitionedPairedStats.yStats().mean(),
387         twoValuesAccumulatorByAddAllPartitionedPairedStats.xStats().populationVariance(),
388         twoValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance());
389     assertDiagonalLinearTransformation(
390         manyValuesAccumulator.leastSquaresFit(),
391         manyValuesAccumulator.xStats().mean(),
392         manyValuesAccumulator.yStats().mean(),
393         manyValuesAccumulator.xStats().populationVariance(),
394         manyValuesAccumulator.populationCovariance());
395     assertDiagonalLinearTransformation(
396         manyValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit(),
397         manyValuesAccumulatorByAddAllPartitionedPairedStats.xStats().mean(),
398         manyValuesAccumulatorByAddAllPartitionedPairedStats.yStats().mean(),
399         manyValuesAccumulatorByAddAllPartitionedPairedStats.xStats().populationVariance(),
400         manyValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance());
401     // For datasets of many double values, we test many combinations of finite and non-finite
402     // x-values:
403     for (ManyValues values : ALL_MANY_VALUES) {
404       PairedStatsAccumulator accumulator =
405           createFilledPairedStatsAccumulator(values.asIterable(), OTHER_MANY_VALUES);
406       PairedStatsAccumulator accumulatorByAddAllPartitionedPairedStats =
407           createPartitionedFilledPairedStatsAccumulator(values.asIterable(), OTHER_MANY_VALUES, 2);
408       LinearTransformation fit = accumulator.leastSquaresFit();
409       LinearTransformation fitByAddAllPartitionedPairedStats =
410           accumulatorByAddAllPartitionedPairedStats.leastSquaresFit();
411       if (values.hasAnyNonFinite()) {
412         assertLinearTransformationNaN(fit);
413         assertLinearTransformationNaN(fitByAddAllPartitionedPairedStats);
414       } else {
415         assertDiagonalLinearTransformation(
416             fit,
417             accumulator.xStats().mean(),
418             accumulator.yStats().mean(),
419             accumulator.xStats().populationVariance(),
420             accumulator.populationCovariance());
421         assertDiagonalLinearTransformation(
422             fitByAddAllPartitionedPairedStats,
423             accumulatorByAddAllPartitionedPairedStats.xStats().mean(),
424             accumulatorByAddAllPartitionedPairedStats.yStats().mean(),
425             accumulatorByAddAllPartitionedPairedStats.xStats().populationVariance(),
426             accumulatorByAddAllPartitionedPairedStats.populationCovariance());
427       }
428     }
429     assertHorizontalLinearTransformation(
430         horizontalValuesAccumulator.leastSquaresFit(), horizontalValuesAccumulator.yStats().mean());
431     assertHorizontalLinearTransformation(
432         horizontalValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit(),
433         horizontalValuesAccumulatorByAddAllPartitionedPairedStats.yStats().mean());
434     assertVerticalLinearTransformation(
435         verticalValuesAccumulator.leastSquaresFit(), verticalValuesAccumulator.xStats().mean());
436     assertVerticalLinearTransformation(
437         verticalValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit(),
438         verticalValuesAccumulatorByAddAllPartitionedPairedStats.xStats().mean());
439     assertThrows(IllegalStateException.class, () -> constantValuesAccumulator.leastSquaresFit());
440     assertThrows(
441         IllegalStateException.class,
442         () -> constantValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit());
443   }
444 }
445