Browse Source

Improve rate of change calculations.

Neal Wilson 10 years ago
parent
commit
2d25770e95
1 changed files with 19 additions and 38 deletions
  1. 19
    38
      src/rate.w

+ 19
- 38
src/rate.w View File

@@ -29,7 +29,6 @@ class RateOfChange : public QObject
29 29
 		int ct;
30 30
 		int st;
31 31
 		QList<Measurement> cache;
32
-		QMap<double,double> smoothCache;
33 32
 };
34 33
 
35 34
 @ The interesting part of this class is in the |newMeasurement()| method. This
@@ -88,51 +87,33 @@ if(cache.size() > 2)
88 87
 	}
89 88
 }
90 89
 
91
-@ The calculation method here is subject to change as this is still noisier
92
-than I would like. What we are doing here is calculating the rate of change
93
-between each pair of adjacent measurements in the cache and averaging them to
94
-produce something that is a little less noisy than just using the first and
95
-last measurements in the cache. Other techniques may be useful for reducing the
96
-noise further.
90
+@ Rather than work directly with changes from one measurement to the next and
91
+attempting to filter out the noise, we instead calculate the slope of a simple
92
+linear regression on the current window of data.
97 93
 
98 94
 The measurement will carry the fact that it is a relative measurement.
99 95
 
100 96
 @<Calculate rate of change@>=
101
-QList<double> rates;
102
-for(int i = 1; i < cache.size(); i++)
97
+int N = cache.size();
98
+double SXY = 0;
99
+double SX = 0;
100
+double SXX = 0;
101
+double SY = 0;
102
+double y;
103
+double x;
104
+for(int i = 0; i < N; i++)
103 105
 {
104
-	double mdiff = cache.at(i).temperature() - cache.at(i-1).temperature();
105
-	double tdiff = (double)(cache.at(i-1).time().msecsTo(cache.at(i).time())) / 1000.0;
106
-	rates.append(mdiff/tdiff);
106
+	y = cache.at(i).temperature();
107
+	SY += y;
108
+	x = cache.at(0).time().msecsTo(cache.at(i).time()) / 1000.0;
109
+	SX += x;
110
+	SXX += (x*x);
111
+	SXY += (x*y);
107 112
 }
108
-double acc = 0.0;
109
-for(int i = 0; i < rates.size(); i++)
110
-{
111
-	acc += rates.at(i);
112
-}
113
-double pavg = acc /= rates.size();
114
-double v2 = pavg * st;
115
-double refm = cache.back().temperature() - cache.front().temperature();
116
-double reft = (double)(cache.front().time().msecsTo(cache.back().time())) / 1000.0;
117
-double ref = refm/reft;
118
-Measurement value(v2, cache.back().time(), cache.back().scale());
113
+double M = ((N * SXY) - (SX * SY)) / ((N * SXX) - (SX * SX));
114
+Measurement value(M * st, cache.back().time(), cache.back().scale());
119 115
 value.insert("relative", true);
120 116
 emit newData(value);
121
-double calcdiff = ref - pavg;
122
-if(calcdiff < 0)
123
-{
124
-	calcdiff = -calcdiff;
125
-}
126
-if(pavg < 0)
127
-{
128
-	pavg = -pavg;
129
-}
130
-if(calcdiff > (pavg * 0.2))
131
-{
132
-	Measurement save = cache.back();
133
-	cache.clear();
134
-	cache.append(save);
135
-}
136 117
 
137 118
 @ The rest of the class implementation is trivial.
138 119
 

Loading…
Cancel
Save