• 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()).isWithin(0.0).of(0.0);
183     assertThat(oneValueAccumulatorByAddAllEmptyPairedStats.populationCovariance())
184         .isWithin(0.0)
185         .of(0.0);
186     assertThat(twoValuesAccumulator.populationCovariance())
187         .isWithin(ALLOWED_ERROR)
188         .of(TWO_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / 2);
189     assertThat(twoValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
190         .isWithin(ALLOWED_ERROR)
191         .of(TWO_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / 2);
192     assertThat(manyValuesAccumulator.populationCovariance())
193         .isWithin(ALLOWED_ERROR)
194         .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
195     assertThat(manyValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
196         .isWithin(ALLOWED_ERROR)
197         .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
198     // For datasets of many double values, we test many combinations of finite and non-finite
199     // x-values:
200     for (ManyValues values : ALL_MANY_VALUES) {
201       PairedStatsAccumulator accumulator =
202           createFilledPairedStatsAccumulator(values.asIterable(), OTHER_MANY_VALUES);
203       PairedStatsAccumulator accumulatorByAddAllPartitionedPairedStats =
204           createPartitionedFilledPairedStatsAccumulator(values.asIterable(), OTHER_MANY_VALUES, 2);
205       double populationCovariance = accumulator.populationCovariance();
206       double populationCovarianceByAddAllPartitionedPairedStats =
207           accumulatorByAddAllPartitionedPairedStats.populationCovariance();
208       if (values.hasAnyNonFinite()) {
209         assertWithMessage("population covariance of " + values).that(populationCovariance).isNaN();
210         assertWithMessage("population covariance by addAll(PairedStats) of " + values)
211             .that(populationCovarianceByAddAllPartitionedPairedStats)
212             .isNaN();
213       } else {
214         assertWithMessage("population covariance of " + values)
215             .that(populationCovariance)
216             .isWithin(ALLOWED_ERROR)
217             .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
218         assertWithMessage("population covariance by addAll(PairedStats) of " + values)
219             .that(populationCovarianceByAddAllPartitionedPairedStats)
220             .isWithin(ALLOWED_ERROR)
221             .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
222       }
223     }
224     assertThat(horizontalValuesAccumulator.populationCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
225     assertThat(horizontalValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
226         .isWithin(ALLOWED_ERROR)
227         .of(0.0);
228     assertThat(verticalValuesAccumulator.populationCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
229     assertThat(verticalValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
230         .isWithin(ALLOWED_ERROR)
231         .of(0.0);
232     assertThat(constantValuesAccumulator.populationCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
233     assertThat(constantValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
234         .isWithin(ALLOWED_ERROR)
235         .of(0.0);
236   }
237 
testSampleCovariance()238   public void testSampleCovariance() {
239     assertThrows(IllegalStateException.class, () -> emptyAccumulator.sampleCovariance());
240     assertThrows(
241         IllegalStateException.class,
242         () -> emptyAccumulatorByAddAllEmptyPairedStats.sampleCovariance());
243     assertThrows(IllegalStateException.class, () -> oneValueAccumulator.sampleCovariance());
244     assertThrows(
245         IllegalStateException.class,
246         () -> oneValueAccumulatorByAddAllEmptyPairedStats.sampleCovariance());
247     assertThat(twoValuesAccumulator.sampleCovariance())
248         .isWithin(ALLOWED_ERROR)
249         .of(TWO_VALUES_SUM_OF_PRODUCTS_OF_DELTAS);
250     assertThat(twoValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
251         .isWithin(ALLOWED_ERROR)
252         .of(TWO_VALUES_SUM_OF_PRODUCTS_OF_DELTAS);
253     assertThat(manyValuesAccumulator.sampleCovariance())
254         .isWithin(ALLOWED_ERROR)
255         .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / (MANY_VALUES_COUNT - 1));
256     assertThat(manyValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
257         .isWithin(ALLOWED_ERROR)
258         .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / (MANY_VALUES_COUNT - 1));
259     assertThat(horizontalValuesAccumulator.sampleCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
260     assertThat(horizontalValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
261         .isWithin(ALLOWED_ERROR)
262         .of(0.0);
263     assertThat(verticalValuesAccumulator.sampleCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
264     assertThat(verticalValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
265         .isWithin(ALLOWED_ERROR)
266         .of(0.0);
267     assertThat(constantValuesAccumulator.sampleCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
268     assertThat(constantValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
269         .isWithin(ALLOWED_ERROR)
270         .of(0.0);
271   }
272 
testPearsonsCorrelationCoefficient()273   public void testPearsonsCorrelationCoefficient() {
274     assertThrows(
275         IllegalStateException.class, () -> emptyAccumulator.pearsonsCorrelationCoefficient());
276     assertThrows(
277         IllegalStateException.class,
278         () -> emptyAccumulatorByAddAllEmptyPairedStats.pearsonsCorrelationCoefficient());
279     assertThrows(
280         IllegalStateException.class, () -> oneValueAccumulator.pearsonsCorrelationCoefficient());
281     assertThrows(
282         IllegalStateException.class,
283         () -> oneValueAccumulatorByAddAllEmptyPairedStats.pearsonsCorrelationCoefficient());
284     assertThat(twoValuesAccumulator.pearsonsCorrelationCoefficient())
285         .isWithin(ALLOWED_ERROR)
286         .of(
287             twoValuesAccumulator.populationCovariance()
288                 / (twoValuesAccumulator.xStats().populationStandardDeviation()
289                     * twoValuesAccumulator.yStats().populationStandardDeviation()));
290     assertThat(manyValuesAccumulator.pearsonsCorrelationCoefficient())
291         .isWithin(ALLOWED_ERROR)
292         .of(
293             manyValuesAccumulator.populationCovariance()
294                 / (manyValuesAccumulator.xStats().populationStandardDeviation()
295                     * manyValuesAccumulator.yStats().populationStandardDeviation()));
296     assertThat(manyValuesAccumulatorByAddAllPartitionedPairedStats.pearsonsCorrelationCoefficient())
297         .isWithin(ALLOWED_ERROR)
298         .of(
299             manyValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance()
300                 / (manyValuesAccumulatorByAddAllPartitionedPairedStats
301                         .xStats()
302                         .populationStandardDeviation()
303                     * manyValuesAccumulatorByAddAllPartitionedPairedStats
304                         .yStats()
305                         .populationStandardDeviation()));
306     // For datasets of many double values, we test many combinations of finite and non-finite
307     // y-values:
308     for (ManyValues values : ALL_MANY_VALUES) {
309       PairedStatsAccumulator accumulator =
310           createFilledPairedStatsAccumulator(MANY_VALUES, values.asIterable());
311       PairedStatsAccumulator accumulatorByAddAllPartitionedPairedStats =
312           createPartitionedFilledPairedStatsAccumulator(MANY_VALUES, values.asIterable(), 2);
313       double pearsonsCorrelationCoefficient = accumulator.pearsonsCorrelationCoefficient();
314       double pearsonsCorrelationCoefficientByAddAllPartitionedPairedStats =
315           accumulatorByAddAllPartitionedPairedStats.pearsonsCorrelationCoefficient();
316       if (values.hasAnyNonFinite()) {
317         assertWithMessage("Pearson's correlation coefficient of " + values)
318             .that(pearsonsCorrelationCoefficient)
319             .isNaN();
320         assertWithMessage("Pearson's correlation coefficient by addAll(PairedStats) of " + values)
321             .that(pearsonsCorrelationCoefficient)
322             .isNaN();
323       } else {
324         assertWithMessage("Pearson's correlation coefficient of " + values)
325             .that(pearsonsCorrelationCoefficient)
326             .isWithin(ALLOWED_ERROR)
327             .of(
328                 accumulator.populationCovariance()
329                     / (accumulator.xStats().populationStandardDeviation()
330                         * accumulator.yStats().populationStandardDeviation()));
331         assertWithMessage("Pearson's correlation coefficient by addAll(PairedStats) of " + values)
332             .that(pearsonsCorrelationCoefficientByAddAllPartitionedPairedStats)
333             .isWithin(ALLOWED_ERROR)
334             .of(
335                 accumulatorByAddAllPartitionedPairedStats.populationCovariance()
336                     / (accumulatorByAddAllPartitionedPairedStats
337                             .xStats()
338                             .populationStandardDeviation()
339                         * accumulatorByAddAllPartitionedPairedStats
340                             .yStats()
341                             .populationStandardDeviation()));
342       }
343     }
344     assertThrows(
345         IllegalStateException.class,
346         () -> horizontalValuesAccumulator.pearsonsCorrelationCoefficient());
347     assertThrows(
348         IllegalStateException.class,
349         () ->
350             horizontalValuesAccumulatorByAddAllPartitionedPairedStats
351                 .pearsonsCorrelationCoefficient());
352     assertThrows(
353         IllegalStateException.class,
354         () -> verticalValuesAccumulator.pearsonsCorrelationCoefficient());
355     assertThrows(
356         IllegalStateException.class,
357         () ->
358             verticalValuesAccumulatorByAddAllPartitionedPairedStats
359                 .pearsonsCorrelationCoefficient());
360     assertThrows(
361         IllegalStateException.class,
362         () -> constantValuesAccumulator.pearsonsCorrelationCoefficient());
363     assertThrows(
364         IllegalStateException.class,
365         () ->
366             constantValuesAccumulatorByAddAllPartitionedPairedStats
367                 .pearsonsCorrelationCoefficient());
368   }
369 
testLeastSquaresFit()370   public void testLeastSquaresFit() {
371     assertThrows(IllegalStateException.class, () -> emptyAccumulator.leastSquaresFit());
372     assertThrows(
373         IllegalStateException.class,
374         () -> emptyAccumulatorByAddAllEmptyPairedStats.leastSquaresFit());
375     assertThrows(IllegalStateException.class, () -> oneValueAccumulator.leastSquaresFit());
376     assertThrows(
377         IllegalStateException.class,
378         () -> oneValueAccumulatorByAddAllEmptyPairedStats.leastSquaresFit());
379     assertDiagonalLinearTransformation(
380         twoValuesAccumulator.leastSquaresFit(),
381         twoValuesAccumulator.xStats().mean(),
382         twoValuesAccumulator.yStats().mean(),
383         twoValuesAccumulator.xStats().populationVariance(),
384         twoValuesAccumulator.populationCovariance());
385     assertDiagonalLinearTransformation(
386         twoValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit(),
387         twoValuesAccumulatorByAddAllPartitionedPairedStats.xStats().mean(),
388         twoValuesAccumulatorByAddAllPartitionedPairedStats.yStats().mean(),
389         twoValuesAccumulatorByAddAllPartitionedPairedStats.xStats().populationVariance(),
390         twoValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance());
391     assertDiagonalLinearTransformation(
392         manyValuesAccumulator.leastSquaresFit(),
393         manyValuesAccumulator.xStats().mean(),
394         manyValuesAccumulator.yStats().mean(),
395         manyValuesAccumulator.xStats().populationVariance(),
396         manyValuesAccumulator.populationCovariance());
397     assertDiagonalLinearTransformation(
398         manyValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit(),
399         manyValuesAccumulatorByAddAllPartitionedPairedStats.xStats().mean(),
400         manyValuesAccumulatorByAddAllPartitionedPairedStats.yStats().mean(),
401         manyValuesAccumulatorByAddAllPartitionedPairedStats.xStats().populationVariance(),
402         manyValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance());
403     // For datasets of many double values, we test many combinations of finite and non-finite
404     // x-values:
405     for (ManyValues values : ALL_MANY_VALUES) {
406       PairedStatsAccumulator accumulator =
407           createFilledPairedStatsAccumulator(values.asIterable(), OTHER_MANY_VALUES);
408       PairedStatsAccumulator accumulatorByAddAllPartitionedPairedStats =
409           createPartitionedFilledPairedStatsAccumulator(values.asIterable(), OTHER_MANY_VALUES, 2);
410       LinearTransformation fit = accumulator.leastSquaresFit();
411       LinearTransformation fitByAddAllPartitionedPairedStats =
412           accumulatorByAddAllPartitionedPairedStats.leastSquaresFit();
413       if (values.hasAnyNonFinite()) {
414         assertLinearTransformationNaN(fit);
415         assertLinearTransformationNaN(fitByAddAllPartitionedPairedStats);
416       } else {
417         assertDiagonalLinearTransformation(
418             fit,
419             accumulator.xStats().mean(),
420             accumulator.yStats().mean(),
421             accumulator.xStats().populationVariance(),
422             accumulator.populationCovariance());
423         assertDiagonalLinearTransformation(
424             fitByAddAllPartitionedPairedStats,
425             accumulatorByAddAllPartitionedPairedStats.xStats().mean(),
426             accumulatorByAddAllPartitionedPairedStats.yStats().mean(),
427             accumulatorByAddAllPartitionedPairedStats.xStats().populationVariance(),
428             accumulatorByAddAllPartitionedPairedStats.populationCovariance());
429       }
430     }
431     assertHorizontalLinearTransformation(
432         horizontalValuesAccumulator.leastSquaresFit(), horizontalValuesAccumulator.yStats().mean());
433     assertHorizontalLinearTransformation(
434         horizontalValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit(),
435         horizontalValuesAccumulatorByAddAllPartitionedPairedStats.yStats().mean());
436     assertVerticalLinearTransformation(
437         verticalValuesAccumulator.leastSquaresFit(), verticalValuesAccumulator.xStats().mean());
438     assertVerticalLinearTransformation(
439         verticalValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit(),
440         verticalValuesAccumulatorByAddAllPartitionedPairedStats.xStats().mean());
441     assertThrows(IllegalStateException.class, () -> constantValuesAccumulator.leastSquaresFit());
442     assertThrows(
443         IllegalStateException.class,
444         () -> constantValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit());
445   }
446 }
447