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