AGX Dynamics 2.41.1.2
Loading...
Searching...
No Matches
Statistic.h
Go to the documentation of this file.
1/*
2Copyright 2007-2025. Algoryx Simulation AB.
3
4All AGX source code, intellectual property, documentation, sample code,
5tutorials, scene files and technical white papers, are copyrighted, proprietary
6and confidential material of Algoryx Simulation AB. You may not download, read,
7store, distribute, publish, copy or otherwise disseminate, use or expose this
8material unless having a written signed agreement with Algoryx Simulation AB, or
9having been advised so by Algoryx Simulation AB for a time limited evaluation,
10or having purchased a valid commercial license from Algoryx Simulation AB.
11
12Algoryx Simulation AB disclaims all responsibilities for loss or damage caused
13from using this software, unless otherwise stated in written agreements with
14Algoryx Simulation AB.
15*/
16
17#pragma once
18
19
20#include <agx/Real.h>
21#include <agx/Integer.h>
22#include <agx/Math.h>
23#include <agx/Referenced.h>
25
27
28#include <memory>
29
30
31namespace agxUtil
32{
37 {
38 public:
44 virtual agx::Real update( agx::Real observation ) = 0;
45
49 virtual agx::Real get() const = 0;
50
51 virtual ~Statistic() {}
52 };
53
54
55
63 {
64 public:
66 : m_statistic(statistic)
67 {
68 }
69
70#ifndef SWIG
71 std::unique_ptr<Statistic> takeStatistic()
72 {
73 return std::move(m_statistic);
74 }
75#endif
76
77 protected:
78 virtual ~StatisticHandle() {}
79
80 private:
81 std::unique_ptr<Statistic> m_statistic;
82 };
83
85
86
94 {
95 public:
100 ExponentialMovingAverageStatistic( agx::Real smoothFactor, agx::Real initialObservation = 0 )
101 : m_smoothFactor( smoothFactor ), m_s( initialObservation ) {}
102
103 virtual inline agx::Real update( agx::Real observation )
104 {
105 m_s += m_smoothFactor * ( observation - m_s );
106 return m_s;
107 }
108
114 void set( agx::Real val ) { m_s = val; }
115
116 virtual inline agx::Real get() const { return m_s; }
117
121 inline agx::Real getSmoothFactor() const { return m_smoothFactor; }
122
126 inline void setSmoothFactor( agx::Real smoothFactor ) { m_smoothFactor = smoothFactor; }
127
129
131 agx::Real maxSmoothingFactor, agx::Real initialObservation = 0)
132 {
133 return new StatisticHandle(
134 new ExponentialMovingAverageStatistic(maxSmoothingFactor, initialObservation));
135 }
136
137 protected:
140 };
141
148 {
149 public:
154 VariableSmoothFactorEMAStatistic( agx::Real maxSmoothingFactor, agx::Real initialObservation = 0 )
155 : ExponentialMovingAverageStatistic( maxSmoothingFactor, initialObservation ) {}
156
157 virtual inline agx::Real update( agx::Real observation )
158 {
159 agx::Real absDeltaObservation = std::abs( m_s - observation );
160 agx::Real absStatistic = std::abs( m_s );
161 agx::Real alpha = ( absDeltaObservation > 0 && absStatistic > 0 ? absStatistic / absDeltaObservation : m_smoothFactor );
162 alpha = agx::clamp( alpha, agx::Real( 0 ), m_smoothFactor );
163 m_s += alpha * ( observation - m_s );
164 return m_s;
165 }
166
168
170 agx::Real maxSmoothingFactor, agx::Real initialObservation = 0)
171 {
172 return new StatisticHandle(new VariableSmoothFactorEMAStatistic(maxSmoothingFactor, initialObservation));
173 }
174 };
175
181 {
182 public:
186 MedianStatistic(size_t maxHistorySize)
187 : m_maxHistorySize(maxHistorySize)
188 {
189 m_historyByAge.reserve(m_maxHistorySize);
190 m_historyByValue.reserve(m_maxHistorySize);
191 }
192
196 virtual agx::Real get() const override
197 {
198 size_t n = this->getCurrentHistorySize();
199
200 if (n == 0) {
202 return agx::Real(0.0);
203 }
204
205 size_t middle = n / 2;
206 if (n % 2 == 0) {
207 // Two in the middle, return their average.
208 return (m_historyByValue[middle - 1] + m_historyByValue[middle]) / agx::Real(2.0);
209 }
210 else {
211 return m_historyByValue[middle];
212 }
213 }
214
219 virtual agx::Real update(agx::Real observation) override
220 {
221 // Remove old values.
222 while (this->getCurrentHistorySize() >= this->getMaxHistorySize()) {
223 agx::Real v = m_historyByAge.back();
224 m_historyByAge.pop_back();
225 m_historyByValue.findAndErase(v, false);
226 }
227
228 // Insert new value.
229 using namespace std;
230 auto insertAt = lower_bound(begin(m_historyByValue), end(m_historyByValue), observation);
231 m_historyByValue.insert(insertAt, observation);
232 m_historyByAge.insert(size_t(0), observation);
233
234 return this->get();
235 }
236
237
238 void clear()
239 {
240 m_historyByAge.clear();
241 m_historyByValue.clear();
242 }
243
244
245 size_t getMaxHistorySize() const
246 {
247 return m_maxHistorySize;
248 }
249
250
251
253 {
254 agxAssert(m_historyByAge.size() == m_historyByValue.size());
255 size_t n = m_historyByAge.size();
256 return n;
257 }
258
259
261 {
262 return m_historyByAge;
263 }
264
265
267 {
268 return m_historyByValue;
269 }
270
271 static StatisticHandleRef make_statistic(size_t maxHistorySize)
272 {
273 return new StatisticHandle(new MedianStatistic(maxHistorySize));
274 }
275
276 private:
277 size_t m_maxHistorySize;
278 agx::RealVector m_historyByAge;
279 agx::RealVector m_historyByValue;
280 };
281
282
287 {
288 public:
292 MovingAverageStatistic( size_t maxHistorySize )
293 : m_maxHistorySize( maxHistorySize ) {}
294
295 virtual inline agx::Real update( agx::Real observation )
296 {
297 m_values.push_back( observation );
298 if ( m_values.size() > m_maxHistorySize ) {
299 m_values.erase( m_values.begin() );
300 }
301
302 return this->get();
303 }
304
305 virtual inline agx::Real get() const {
306 if ( m_values.empty() ) return 0;
307 agx::Real sum = 0.0;
308 for ( agx::Real value : m_values ) {
309 sum += value;
310 }
311 return sum / static_cast< agx::Real >( m_values.size() );
312 }
313
315
317 size_t maxHistorySize )
318 {
319 return new StatisticHandle(
320 new MovingAverageStatistic( maxHistorySize ) );
321 }
322
323 protected:
326 };
327
328
329}
#define AGX_DECLARE_POINTER_TYPES(type)
Definition: Referenced.h:254
#define AGXPHYSICS_EXPORT
Exponential moving average statistic.
Definition: Statistic.h:94
ExponentialMovingAverageStatistic(agx::Real smoothFactor, agx::Real initialObservation=0)
Definition: Statistic.h:100
virtual agx::Real update(agx::Real observation)
Updates the statistic given the current observation and returns the current value of this statistic.
Definition: Statistic.h:103
void setSmoothFactor(agx::Real smoothFactor)
Definition: Statistic.h:126
static StatisticHandleRef make_statistic(agx::Real maxSmoothingFactor, agx::Real initialObservation=0)
Definition: Statistic.h:130
void set(agx::Real val)
Set the raw value of the statistic scalar.
Definition: Statistic.h:114
Median statistic that keeps a history of a number of observations and reports the median,...
Definition: Statistic.h:181
MedianStatistic(size_t maxHistorySize)
Definition: Statistic.h:186
virtual agx::Real get() const override
Definition: Statistic.h:196
size_t getCurrentHistorySize() const
Definition: Statistic.h:252
virtual agx::Real update(agx::Real observation) override
Ad a new observation to the history, removing the oldest if the maximum history size has been reached...
Definition: Statistic.h:219
const agx::RealVector & getHistoryByAge() const
Definition: Statistic.h:260
const agx::RealVector & getHistoryByValue() const
Definition: Statistic.h:266
static StatisticHandleRef make_statistic(size_t maxHistorySize)
Definition: Statistic.h:271
size_t getMaxHistorySize() const
Definition: Statistic.h:245
Simple moving average statistic.
Definition: Statistic.h:287
virtual agx::Real update(agx::Real observation)
Updates the statistic given the current observation and returns the current value of this statistic.
Definition: Statistic.h:295
virtual agx::Real get() const
Definition: Statistic.h:305
MovingAverageStatistic(size_t maxHistorySize)
Definition: Statistic.h:292
static StatisticHandleRef make_statistic(size_t maxHistorySize)
Definition: Statistic.h:316
Extra level of indirection provided for use by garbage collected languages.
Definition: Statistic.h:63
virtual ~StatisticHandle()
Definition: Statistic.h:78
StatisticHandle(Statistic *statistic)
Definition: Statistic.h:65
std::unique_ptr< Statistic > takeStatistic()
Definition: Statistic.h:71
Pure virtual statistic class containing the fundamentals for implementing a statistics method.
Definition: Statistic.h:37
virtual ~Statistic()
Definition: Statistic.h:51
virtual agx::Real get() const =0
virtual agx::Real update(agx::Real observation)=0
Updates the statistic given the current observation and returns the current value of this statistic.
Variable Smooth Factor Exponential Moving Average statistic.
Definition: Statistic.h:148
virtual agx::Real update(agx::Real observation)
Updates the statistic given the current observation and returns the current value of this statistic.
Definition: Statistic.h:157
static StatisticHandleRef make_statistic(agx::Real maxSmoothingFactor, agx::Real initialObservation=0)
Definition: Statistic.h:169
VariableSmoothFactorEMAStatistic(agx::Real maxSmoothingFactor, agx::Real initialObservation=0)
Definition: Statistic.h:154
Base class providing referencing counted objects.
Definition: Referenced.h:120
Smart pointer for handling referenced counted objects.
Definition: ref_ptr.h:30
#define agxAssert(expr)
Definition: debug.h:143
The agxUtil namespace contain classes and methods for utility functionality.
T1 clamp(T1 v, T2 minimum, T3 maximum)
Definition: Math.h:318
double Real
Definition: Real.h:42
STL namespace.