1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chromecast/base/statistics/weighted_moving_linear_regression.h"
6 #include "testing/gtest/include/gtest/gtest.h"
7 
8 namespace chromecast {
9 
TEST(WeightedMovingLinearRegressionTest,NotEnoughSamples)10 TEST(WeightedMovingLinearRegressionTest, NotEnoughSamples) {
11   for (int num_samples = 0; num_samples <= 2; ++num_samples) {
12     WeightedMovingLinearRegression linear(1e6);
13     for (int s = 0; s < num_samples; ++s)
14       linear.AddSample(s, s, 1.0);
15 
16     int64_t y = 12345;
17     double error = 12345.0;
18     EXPECT_FALSE(linear.EstimateY(0, &y, &error));
19     EXPECT_EQ(12345, y);
20     EXPECT_EQ(12345.0, error);
21 
22     double slope = 12345.0;
23     EXPECT_FALSE(linear.EstimateSlope(&slope, &error));
24     EXPECT_EQ(12345.0, slope);
25     EXPECT_EQ(12345.0, error);
26   }
27 }
28 
TEST(WeightedMovingLinearRegressionTest,NoXVariance)29 TEST(WeightedMovingLinearRegressionTest, NoXVariance) {
30   WeightedMovingLinearRegression linear(1e6);
31   for (int s = 0; s < 10; ++s)
32     linear.AddSample(0, s, 1.0);
33 
34   int64_t y = 12345;
35   double error = 12345.0;
36   EXPECT_FALSE(linear.EstimateY(0, &y, &error));
37   EXPECT_EQ(12345, y);
38   EXPECT_EQ(12345.0, error);
39 
40   double slope = 12345.0;
41   EXPECT_FALSE(linear.EstimateSlope(&slope, &error));
42   EXPECT_EQ(12345.0, slope);
43   EXPECT_EQ(12345.0, error);
44 }
45 
TEST(WeightedMovingLinearRegressionTest,ZeroWeight)46 TEST(WeightedMovingLinearRegressionTest, ZeroWeight) {
47   WeightedMovingLinearRegression linear(1e6);
48   for (int s = 0; s < 10; ++s)
49     linear.AddSample(s, s, 0.0);
50 
51   int64_t y = 12345;
52   double error = 12345.0;
53   EXPECT_FALSE(linear.EstimateY(0, &y, &error));
54   EXPECT_EQ(12345, y);
55   EXPECT_EQ(12345.0, error);
56 
57   double slope = 12345.0;
58   EXPECT_FALSE(linear.EstimateSlope(&slope, &error));
59   EXPECT_EQ(12345.0, slope);
60   EXPECT_EQ(12345.0, error);
61 }
62 
TEST(WeightedMovingLinearRegressionTest,SimpleLine)63 TEST(WeightedMovingLinearRegressionTest, SimpleLine) {
64   WeightedMovingLinearRegression linear(1e6);
65   for (int s = 0; s < 3; ++s)
66     linear.AddSample(s, s, 1.0);
67 
68   int64_t y;
69   double error;
70   EXPECT_TRUE(linear.EstimateY(20, &y, &error));
71   EXPECT_EQ(20, y);
72   EXPECT_DOUBLE_EQ(0.0, error);
73 
74   double slope;
75   EXPECT_TRUE(linear.EstimateSlope(&slope, &error));
76   EXPECT_DOUBLE_EQ(1.0, slope);
77   EXPECT_DOUBLE_EQ(0.0, error);
78 }
79 
TEST(WeightedMovingLinearRegressionTest,SimpleLineHighX)80 TEST(WeightedMovingLinearRegressionTest, SimpleLineHighX) {
81   WeightedMovingLinearRegression linear(1e6);
82   for (int s = 0; s < 10; ++s)
83     linear.AddSample(1000000000 + s, s, 1.0);
84 
85   int64_t y;
86   double error;
87   EXPECT_TRUE(linear.EstimateY(0, &y, &error));
88   EXPECT_EQ(-1000000000, y);
89   EXPECT_DOUBLE_EQ(0.0, error);
90 
91   EXPECT_TRUE(linear.EstimateY(1000000020, &y, &error));
92   EXPECT_EQ(20, y);
93   EXPECT_DOUBLE_EQ(0.0, error);
94 
95   double slope;
96   EXPECT_TRUE(linear.EstimateSlope(&slope, &error));
97   EXPECT_DOUBLE_EQ(1.0, slope);
98   EXPECT_DOUBLE_EQ(0.0, error);
99 }
100 
TEST(WeightedMovingLinearRegressionTest,Weighted)101 TEST(WeightedMovingLinearRegressionTest, Weighted) {
102   WeightedMovingLinearRegression linear(1e6);
103   // Add some weight 1.0 points on the line y = x/2, and some weight 2.0 points
104   // on the line y = x/2 + 4.5.
105   for (int s = 0; s < 1000; ++s) {
106     linear.AddSample(2 * s, s, 1.0);
107     linear.AddSample(2 * s + 1, s + 5, 2.0);
108   }
109 
110   // The resulting estimate should be y = x/2 + 3.
111   int64_t y;
112   double error;
113   EXPECT_TRUE(linear.EstimateY(20, &y, &error));
114   EXPECT_EQ(13, y);
115 
116   EXPECT_TRUE(linear.EstimateY(-20, &y, &error));
117   EXPECT_EQ(-7, y);
118   EXPECT_NEAR(0.0, error, 0.1);
119 
120   double slope;
121   EXPECT_TRUE(linear.EstimateSlope(&slope, &error));
122   EXPECT_NEAR(0.5, slope, 0.001);
123   EXPECT_NEAR(0.0, error, 0.001);
124 }
125 
TEST(WeightedMovingLinearRegressionTest,DropOldSamples)126 TEST(WeightedMovingLinearRegressionTest, DropOldSamples) {
127   WeightedMovingLinearRegression linear(1999);
128   // First add some points that will fall outside of the window.
129   for (int s = -1000; s < 0; ++s)
130     linear.AddSample(s, 0, 1.0);
131 
132   // Add some weight 1.0 points on the line y = x/2, and some weight 2.0 points
133   // on the line y = x/2 + 4.5.
134   for (int s = 0; s < 1000; ++s) {
135     linear.AddSample(2 * s, s, 1.0);
136     linear.AddSample(2 * s + 1, s + 5, 2.0);
137   }
138 
139   // The resulting estimate should be y = x/2 + 3.
140   int64_t y;
141   double error;
142   EXPECT_TRUE(linear.EstimateY(20, &y, &error));
143   EXPECT_EQ(13, y);
144 
145   EXPECT_TRUE(linear.EstimateY(-20, &y, &error));
146   EXPECT_EQ(-7, y);
147   EXPECT_NEAR(0.0, error, 0.1);
148 
149   double slope;
150   EXPECT_TRUE(linear.EstimateSlope(&slope, &error));
151   EXPECT_NEAR(0.5, slope, 0.001);
152   EXPECT_NEAR(0.0, error, 0.001);
153 }
154 
155 }  // namespace chromecast
156