• 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 
48 import com.google.common.math.StatsTesting.ManyValues;
49 import java.util.Collections;
50 import junit.framework.TestCase;
51 
52 /**
53  * Tests for {@link PairedStatsAccumulator}. This tests the stats methods for instances built with
54  * {@link PairedStatsAccumulator#add}, and various error cases of that method. For tests of the
55  * {@link PairedStatsAccumulator#snapshot} method which returns {@link PairedStats} instances, see
56  * {@link PairedStatsTest}.
57  *
58  * @author Pete Gillin
59  */
60 public class PairedStatsAccumulatorTest extends TestCase {
61 
62   private PairedStatsAccumulator emptyAccumulator;
63   private PairedStatsAccumulator emptyAccumulatorByAddAllEmptyPairedStats;
64   private PairedStatsAccumulator oneValueAccumulator;
65   private PairedStatsAccumulator oneValueAccumulatorByAddAllEmptyPairedStats;
66   private PairedStatsAccumulator twoValuesAccumulator;
67   private PairedStatsAccumulator twoValuesAccumulatorByAddAllPartitionedPairedStats;
68   private PairedStatsAccumulator manyValuesAccumulator;
69   private PairedStatsAccumulator manyValuesAccumulatorByAddAllPartitionedPairedStats;
70   private PairedStatsAccumulator horizontalValuesAccumulator;
71   private PairedStatsAccumulator horizontalValuesAccumulatorByAddAllPartitionedPairedStats;
72   private PairedStatsAccumulator verticalValuesAccumulator;
73   private PairedStatsAccumulator verticalValuesAccumulatorByAddAllPartitionedPairedStats;
74   private PairedStatsAccumulator constantValuesAccumulator;
75   private PairedStatsAccumulator constantValuesAccumulatorByAddAllPartitionedPairedStats;
76 
77   @Override
setUp()78   protected void setUp() throws Exception {
79     super.setUp();
80 
81     emptyAccumulator = new PairedStatsAccumulator();
82 
83     emptyAccumulatorByAddAllEmptyPairedStats = new PairedStatsAccumulator();
84     emptyAccumulatorByAddAllEmptyPairedStats.addAll(emptyAccumulator.snapshot());
85 
86     oneValueAccumulator = new PairedStatsAccumulator();
87     oneValueAccumulator.add(ONE_VALUE, OTHER_ONE_VALUE);
88 
89     oneValueAccumulatorByAddAllEmptyPairedStats = new PairedStatsAccumulator();
90     oneValueAccumulatorByAddAllEmptyPairedStats.add(ONE_VALUE, OTHER_ONE_VALUE);
91     oneValueAccumulatorByAddAllEmptyPairedStats.addAll(emptyAccumulator.snapshot());
92 
93     twoValuesAccumulator = createFilledPairedStatsAccumulator(TWO_VALUES, OTHER_TWO_VALUES);
94     twoValuesAccumulatorByAddAllPartitionedPairedStats =
95         createPartitionedFilledPairedStatsAccumulator(TWO_VALUES, OTHER_TWO_VALUES, 1);
96 
97     manyValuesAccumulator = createFilledPairedStatsAccumulator(MANY_VALUES, OTHER_MANY_VALUES);
98     manyValuesAccumulatorByAddAllPartitionedPairedStats =
99         createPartitionedFilledPairedStatsAccumulator(MANY_VALUES, OTHER_MANY_VALUES, 2);
100 
101     horizontalValuesAccumulator =
102         createFilledPairedStatsAccumulator(
103             MANY_VALUES, Collections.nCopies(MANY_VALUES_COUNT, OTHER_ONE_VALUE));
104     horizontalValuesAccumulatorByAddAllPartitionedPairedStats =
105         createPartitionedFilledPairedStatsAccumulator(
106             MANY_VALUES, Collections.nCopies(MANY_VALUES_COUNT, OTHER_ONE_VALUE), 2);
107 
108     verticalValuesAccumulator =
109         createFilledPairedStatsAccumulator(
110             Collections.nCopies(OTHER_MANY_VALUES_COUNT, ONE_VALUE), OTHER_MANY_VALUES);
111     verticalValuesAccumulatorByAddAllPartitionedPairedStats =
112         createPartitionedFilledPairedStatsAccumulator(
113             Collections.nCopies(OTHER_MANY_VALUES_COUNT, ONE_VALUE), OTHER_MANY_VALUES, 2);
114 
115     constantValuesAccumulator =
116         createFilledPairedStatsAccumulator(
117             Collections.nCopies(MANY_VALUES_COUNT, ONE_VALUE),
118             Collections.nCopies(MANY_VALUES_COUNT, OTHER_ONE_VALUE));
119     constantValuesAccumulatorByAddAllPartitionedPairedStats =
120         createPartitionedFilledPairedStatsAccumulator(
121             Collections.nCopies(MANY_VALUES_COUNT, ONE_VALUE),
122             Collections.nCopies(MANY_VALUES_COUNT, OTHER_ONE_VALUE),
123             2);
124   }
125 
testCount()126   public void testCount() {
127     assertThat(emptyAccumulator.count()).isEqualTo(0);
128     assertThat(emptyAccumulatorByAddAllEmptyPairedStats.count()).isEqualTo(0);
129     assertThat(oneValueAccumulator.count()).isEqualTo(1);
130     assertThat(oneValueAccumulatorByAddAllEmptyPairedStats.count()).isEqualTo(1);
131     assertThat(twoValuesAccumulator.count()).isEqualTo(2);
132     assertThat(twoValuesAccumulatorByAddAllPartitionedPairedStats.count()).isEqualTo(2);
133     assertThat(manyValuesAccumulator.count()).isEqualTo(MANY_VALUES_COUNT);
134     assertThat(manyValuesAccumulatorByAddAllPartitionedPairedStats.count())
135         .isEqualTo(MANY_VALUES_COUNT);
136   }
137 
testCountOverflow_doesNotThrow()138   public void testCountOverflow_doesNotThrow() {
139     PairedStatsAccumulator accumulator = new PairedStatsAccumulator();
140     accumulator.add(ONE_VALUE, OTHER_ONE_VALUE);
141     for (int power = 1; power < Long.SIZE - 1; power++) {
142       accumulator.addAll(accumulator.snapshot());
143     }
144     // Should overflow without throwing.
145     accumulator.addAll(accumulator.snapshot());
146     assertThat(accumulator.count()).isLessThan(0L);
147   }
148 
testXStats()149   public void testXStats() {
150     assertStatsApproxEqual(EMPTY_STATS_ITERABLE, emptyAccumulator.xStats());
151     assertStatsApproxEqual(EMPTY_STATS_ITERABLE, emptyAccumulatorByAddAllEmptyPairedStats.xStats());
152     assertStatsApproxEqual(ONE_VALUE_STATS, oneValueAccumulator.xStats());
153     assertStatsApproxEqual(ONE_VALUE_STATS, oneValueAccumulatorByAddAllEmptyPairedStats.xStats());
154     assertStatsApproxEqual(TWO_VALUES_STATS, twoValuesAccumulator.xStats());
155     assertStatsApproxEqual(
156         TWO_VALUES_STATS, twoValuesAccumulatorByAddAllPartitionedPairedStats.xStats());
157     assertStatsApproxEqual(MANY_VALUES_STATS_ITERABLE, manyValuesAccumulator.xStats());
158     assertStatsApproxEqual(
159         MANY_VALUES_STATS_ITERABLE, manyValuesAccumulatorByAddAllPartitionedPairedStats.xStats());
160   }
161 
testYStats()162   public void testYStats() {
163     assertStatsApproxEqual(EMPTY_STATS_ITERABLE, emptyAccumulator.yStats());
164     assertStatsApproxEqual(EMPTY_STATS_ITERABLE, emptyAccumulatorByAddAllEmptyPairedStats.yStats());
165     assertStatsApproxEqual(OTHER_ONE_VALUE_STATS, oneValueAccumulator.yStats());
166     assertStatsApproxEqual(
167         OTHER_ONE_VALUE_STATS, oneValueAccumulatorByAddAllEmptyPairedStats.yStats());
168     assertStatsApproxEqual(OTHER_TWO_VALUES_STATS, twoValuesAccumulator.yStats());
169     assertStatsApproxEqual(
170         OTHER_TWO_VALUES_STATS, twoValuesAccumulatorByAddAllPartitionedPairedStats.yStats());
171     assertStatsApproxEqual(OTHER_MANY_VALUES_STATS, manyValuesAccumulator.yStats());
172     assertStatsApproxEqual(
173         OTHER_MANY_VALUES_STATS, manyValuesAccumulatorByAddAllPartitionedPairedStats.yStats());
174   }
175 
testPopulationCovariance()176   public void testPopulationCovariance() {
177     try {
178       emptyAccumulator.populationCovariance();
179       fail("Expected IllegalStateException");
180     } catch (IllegalStateException expected) {
181     }
182     try {
183       emptyAccumulatorByAddAllEmptyPairedStats.populationCovariance();
184       fail("Expected IllegalStateException");
185     } catch (IllegalStateException expected) {
186     }
187     assertThat(oneValueAccumulator.populationCovariance()).isWithin(0.0).of(0.0);
188     assertThat(oneValueAccumulatorByAddAllEmptyPairedStats.populationCovariance())
189         .isWithin(0.0)
190         .of(0.0);
191     assertThat(twoValuesAccumulator.populationCovariance())
192         .isWithin(ALLOWED_ERROR)
193         .of(TWO_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / 2);
194     assertThat(twoValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
195         .isWithin(ALLOWED_ERROR)
196         .of(TWO_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / 2);
197     assertThat(manyValuesAccumulator.populationCovariance())
198         .isWithin(ALLOWED_ERROR)
199         .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
200     assertThat(manyValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
201         .isWithin(ALLOWED_ERROR)
202         .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
203     // For datasets of many double values, we test many combinations of finite and non-finite
204     // x-values:
205     for (ManyValues values : ALL_MANY_VALUES) {
206       PairedStatsAccumulator accumulator =
207           createFilledPairedStatsAccumulator(values.asIterable(), OTHER_MANY_VALUES);
208       PairedStatsAccumulator accumulatorByAddAllPartitionedPairedStats =
209           createPartitionedFilledPairedStatsAccumulator(values.asIterable(), OTHER_MANY_VALUES, 2);
210       double populationCovariance = accumulator.populationCovariance();
211       double populationCovarianceByAddAllPartitionedPairedStats =
212           accumulatorByAddAllPartitionedPairedStats.populationCovariance();
213       if (values.hasAnyNonFinite()) {
214         assertWithMessage("population covariance of " + values).that(populationCovariance).isNaN();
215         assertWithMessage("population covariance by addAll(PairedStats) of " + values)
216             .that(populationCovarianceByAddAllPartitionedPairedStats)
217             .isNaN();
218       } else {
219         assertWithMessage("population covariance of " + values)
220             .that(populationCovariance)
221             .isWithin(ALLOWED_ERROR)
222             .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
223         assertWithMessage("population covariance by addAll(PairedStats) of " + values)
224             .that(populationCovarianceByAddAllPartitionedPairedStats)
225             .isWithin(ALLOWED_ERROR)
226             .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / MANY_VALUES_COUNT);
227       }
228     }
229     assertThat(horizontalValuesAccumulator.populationCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
230     assertThat(horizontalValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
231         .isWithin(ALLOWED_ERROR)
232         .of(0.0);
233     assertThat(verticalValuesAccumulator.populationCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
234     assertThat(verticalValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
235         .isWithin(ALLOWED_ERROR)
236         .of(0.0);
237     assertThat(constantValuesAccumulator.populationCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
238     assertThat(constantValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance())
239         .isWithin(ALLOWED_ERROR)
240         .of(0.0);
241   }
242 
testSampleCovariance()243   public void testSampleCovariance() {
244     try {
245       emptyAccumulator.sampleCovariance();
246       fail("Expected IllegalStateException");
247     } catch (IllegalStateException expected) {
248     }
249     try {
250       emptyAccumulatorByAddAllEmptyPairedStats.sampleCovariance();
251       fail("Expected IllegalStateException");
252     } catch (IllegalStateException expected) {
253     }
254     try {
255       oneValueAccumulator.sampleCovariance();
256       fail("Expected IllegalStateException");
257     } catch (IllegalStateException expected) {
258     }
259     try {
260       oneValueAccumulatorByAddAllEmptyPairedStats.sampleCovariance();
261       fail("Expected IllegalStateException");
262     } catch (IllegalStateException expected) {
263     }
264     assertThat(twoValuesAccumulator.sampleCovariance())
265         .isWithin(ALLOWED_ERROR)
266         .of(TWO_VALUES_SUM_OF_PRODUCTS_OF_DELTAS);
267     assertThat(twoValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
268         .isWithin(ALLOWED_ERROR)
269         .of(TWO_VALUES_SUM_OF_PRODUCTS_OF_DELTAS);
270     assertThat(manyValuesAccumulator.sampleCovariance())
271         .isWithin(ALLOWED_ERROR)
272         .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / (MANY_VALUES_COUNT - 1));
273     assertThat(manyValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
274         .isWithin(ALLOWED_ERROR)
275         .of(MANY_VALUES_SUM_OF_PRODUCTS_OF_DELTAS / (MANY_VALUES_COUNT - 1));
276     assertThat(horizontalValuesAccumulator.sampleCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
277     assertThat(horizontalValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
278         .isWithin(ALLOWED_ERROR)
279         .of(0.0);
280     assertThat(verticalValuesAccumulator.sampleCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
281     assertThat(verticalValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
282         .isWithin(ALLOWED_ERROR)
283         .of(0.0);
284     assertThat(constantValuesAccumulator.sampleCovariance()).isWithin(ALLOWED_ERROR).of(0.0);
285     assertThat(constantValuesAccumulatorByAddAllPartitionedPairedStats.sampleCovariance())
286         .isWithin(ALLOWED_ERROR)
287         .of(0.0);
288   }
289 
testPearsonsCorrelationCoefficient()290   public void testPearsonsCorrelationCoefficient() {
291     try {
292       emptyAccumulator.pearsonsCorrelationCoefficient();
293       fail("Expected IllegalStateException");
294     } catch (IllegalStateException expected) {
295     }
296     try {
297       emptyAccumulatorByAddAllEmptyPairedStats.pearsonsCorrelationCoefficient();
298       fail("Expected IllegalStateException");
299     } catch (IllegalStateException expected) {
300     }
301     try {
302       oneValueAccumulator.pearsonsCorrelationCoefficient();
303       fail("Expected IllegalStateException");
304     } catch (IllegalStateException expected) {
305     }
306     try {
307       oneValueAccumulatorByAddAllEmptyPairedStats.pearsonsCorrelationCoefficient();
308       fail("Expected IllegalStateException");
309     } catch (IllegalStateException expected) {
310     }
311     assertThat(twoValuesAccumulator.pearsonsCorrelationCoefficient())
312         .isWithin(ALLOWED_ERROR)
313         .of(
314             twoValuesAccumulator.populationCovariance()
315                 / (twoValuesAccumulator.xStats().populationStandardDeviation()
316                     * twoValuesAccumulator.yStats().populationStandardDeviation()));
317     assertThat(manyValuesAccumulator.pearsonsCorrelationCoefficient())
318         .isWithin(ALLOWED_ERROR)
319         .of(
320             manyValuesAccumulator.populationCovariance()
321                 / (manyValuesAccumulator.xStats().populationStandardDeviation()
322                     * manyValuesAccumulator.yStats().populationStandardDeviation()));
323     assertThat(manyValuesAccumulatorByAddAllPartitionedPairedStats.pearsonsCorrelationCoefficient())
324         .isWithin(ALLOWED_ERROR)
325         .of(
326             manyValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance()
327                 / (manyValuesAccumulatorByAddAllPartitionedPairedStats
328                         .xStats()
329                         .populationStandardDeviation()
330                     * manyValuesAccumulatorByAddAllPartitionedPairedStats
331                         .yStats()
332                         .populationStandardDeviation()));
333     // For datasets of many double values, we test many combinations of finite and non-finite
334     // y-values:
335     for (ManyValues values : ALL_MANY_VALUES) {
336       PairedStatsAccumulator accumulator =
337           createFilledPairedStatsAccumulator(MANY_VALUES, values.asIterable());
338       PairedStatsAccumulator accumulatorByAddAllPartitionedPairedStats =
339           createPartitionedFilledPairedStatsAccumulator(MANY_VALUES, values.asIterable(), 2);
340       double pearsonsCorrelationCoefficient = accumulator.pearsonsCorrelationCoefficient();
341       double pearsonsCorrelationCoefficientByAddAllPartitionedPairedStats =
342           accumulatorByAddAllPartitionedPairedStats.pearsonsCorrelationCoefficient();
343       if (values.hasAnyNonFinite()) {
344         assertWithMessage("Pearson's correlation coefficient of " + values)
345             .that(pearsonsCorrelationCoefficient)
346             .isNaN();
347         assertWithMessage("Pearson's correlation coefficient by addAll(PairedStats) of " + values)
348             .that(pearsonsCorrelationCoefficient)
349             .isNaN();
350       } else {
351         assertWithMessage("Pearson's correlation coefficient of " + values)
352             .that(pearsonsCorrelationCoefficient)
353             .isWithin(ALLOWED_ERROR)
354             .of(
355                 accumulator.populationCovariance()
356                     / (accumulator.xStats().populationStandardDeviation()
357                         * accumulator.yStats().populationStandardDeviation()));
358         assertWithMessage("Pearson's correlation coefficient by addAll(PairedStats) of " + values)
359             .that(pearsonsCorrelationCoefficientByAddAllPartitionedPairedStats)
360             .isWithin(ALLOWED_ERROR)
361             .of(
362                 accumulatorByAddAllPartitionedPairedStats.populationCovariance()
363                     / (accumulatorByAddAllPartitionedPairedStats
364                             .xStats()
365                             .populationStandardDeviation()
366                         * accumulatorByAddAllPartitionedPairedStats
367                             .yStats()
368                             .populationStandardDeviation()));
369       }
370     }
371     try {
372       horizontalValuesAccumulator.pearsonsCorrelationCoefficient();
373       fail("Expected IllegalStateException");
374     } catch (IllegalStateException expected) {
375     }
376     try {
377       horizontalValuesAccumulatorByAddAllPartitionedPairedStats.pearsonsCorrelationCoefficient();
378       fail("Expected IllegalStateException");
379     } catch (IllegalStateException expected) {
380     }
381     try {
382       verticalValuesAccumulator.pearsonsCorrelationCoefficient();
383       fail("Expected IllegalStateException");
384     } catch (IllegalStateException expected) {
385     }
386     try {
387       verticalValuesAccumulatorByAddAllPartitionedPairedStats.pearsonsCorrelationCoefficient();
388       fail("Expected IllegalStateException");
389     } catch (IllegalStateException expected) {
390     }
391     try {
392       constantValuesAccumulator.pearsonsCorrelationCoefficient();
393       fail("Expected IllegalStateException");
394     } catch (IllegalStateException expected) {
395     }
396     try {
397       constantValuesAccumulatorByAddAllPartitionedPairedStats.pearsonsCorrelationCoefficient();
398       fail("Expected IllegalStateException");
399     } catch (IllegalStateException expected) {
400     }
401   }
402 
testLeastSquaresFit()403   public void testLeastSquaresFit() {
404     try {
405       emptyAccumulator.leastSquaresFit();
406       fail("Expected IllegalStateException");
407     } catch (IllegalStateException expected) {
408     }
409     try {
410       emptyAccumulatorByAddAllEmptyPairedStats.leastSquaresFit();
411       fail("Expected IllegalStateException");
412     } catch (IllegalStateException expected) {
413     }
414     try {
415       oneValueAccumulator.leastSquaresFit();
416       fail("Expected IllegalStateException");
417     } catch (IllegalStateException expected) {
418     }
419     try {
420       oneValueAccumulatorByAddAllEmptyPairedStats.leastSquaresFit();
421       fail("Expected IllegalStateException");
422     } catch (IllegalStateException expected) {
423     }
424     assertDiagonalLinearTransformation(
425         twoValuesAccumulator.leastSquaresFit(),
426         twoValuesAccumulator.xStats().mean(),
427         twoValuesAccumulator.yStats().mean(),
428         twoValuesAccumulator.xStats().populationVariance(),
429         twoValuesAccumulator.populationCovariance());
430     assertDiagonalLinearTransformation(
431         twoValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit(),
432         twoValuesAccumulatorByAddAllPartitionedPairedStats.xStats().mean(),
433         twoValuesAccumulatorByAddAllPartitionedPairedStats.yStats().mean(),
434         twoValuesAccumulatorByAddAllPartitionedPairedStats.xStats().populationVariance(),
435         twoValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance());
436     assertDiagonalLinearTransformation(
437         manyValuesAccumulator.leastSquaresFit(),
438         manyValuesAccumulator.xStats().mean(),
439         manyValuesAccumulator.yStats().mean(),
440         manyValuesAccumulator.xStats().populationVariance(),
441         manyValuesAccumulator.populationCovariance());
442     assertDiagonalLinearTransformation(
443         manyValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit(),
444         manyValuesAccumulatorByAddAllPartitionedPairedStats.xStats().mean(),
445         manyValuesAccumulatorByAddAllPartitionedPairedStats.yStats().mean(),
446         manyValuesAccumulatorByAddAllPartitionedPairedStats.xStats().populationVariance(),
447         manyValuesAccumulatorByAddAllPartitionedPairedStats.populationCovariance());
448     // For datasets of many double values, we test many combinations of finite and non-finite
449     // x-values:
450     for (ManyValues values : ALL_MANY_VALUES) {
451       PairedStatsAccumulator accumulator =
452           createFilledPairedStatsAccumulator(values.asIterable(), OTHER_MANY_VALUES);
453       PairedStatsAccumulator accumulatorByAddAllPartitionedPairedStats =
454           createPartitionedFilledPairedStatsAccumulator(values.asIterable(), OTHER_MANY_VALUES, 2);
455       LinearTransformation fit = accumulator.leastSquaresFit();
456       LinearTransformation fitByAddAllPartitionedPairedStats =
457           accumulatorByAddAllPartitionedPairedStats.leastSquaresFit();
458       if (values.hasAnyNonFinite()) {
459         assertLinearTransformationNaN(fit);
460         assertLinearTransformationNaN(fitByAddAllPartitionedPairedStats);
461       } else {
462         assertDiagonalLinearTransformation(
463             fit,
464             accumulator.xStats().mean(),
465             accumulator.yStats().mean(),
466             accumulator.xStats().populationVariance(),
467             accumulator.populationCovariance());
468         assertDiagonalLinearTransformation(
469             fitByAddAllPartitionedPairedStats,
470             accumulatorByAddAllPartitionedPairedStats.xStats().mean(),
471             accumulatorByAddAllPartitionedPairedStats.yStats().mean(),
472             accumulatorByAddAllPartitionedPairedStats.xStats().populationVariance(),
473             accumulatorByAddAllPartitionedPairedStats.populationCovariance());
474       }
475     }
476     assertHorizontalLinearTransformation(
477         horizontalValuesAccumulator.leastSquaresFit(), horizontalValuesAccumulator.yStats().mean());
478     assertHorizontalLinearTransformation(
479         horizontalValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit(),
480         horizontalValuesAccumulatorByAddAllPartitionedPairedStats.yStats().mean());
481     assertVerticalLinearTransformation(
482         verticalValuesAccumulator.leastSquaresFit(), verticalValuesAccumulator.xStats().mean());
483     assertVerticalLinearTransformation(
484         verticalValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit(),
485         verticalValuesAccumulatorByAddAllPartitionedPairedStats.xStats().mean());
486     try {
487       constantValuesAccumulator.leastSquaresFit();
488       fail("Expected IllegalStateException");
489     } catch (IllegalStateException expected) {
490     }
491     try {
492       constantValuesAccumulatorByAddAllPartitionedPairedStats.leastSquaresFit();
493       fail("Expected IllegalStateException");
494     } catch (IllegalStateException expected) {
495     }
496   }
497 }
498