stabilized-value.h
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2020 Intel Corporation. All Rights Reserved.
3 
4 #pragma once
5 
6 #include <string>
7 #include <atomic>
8 #include <mutex>
9 
10 namespace utilities {
11 namespace number {
12 
13 // Given a rapidly changing history of a value, we do not always want to show every minor
14 // change right away. Rather, a "stable" value can be deduced from the history and changed
15 // only when the history clearly reflects a new "stabilization percentage".
16 //
17 // The stabilized value is, in order of importance:
18 // - the highest-occurring value in history that's over the required percentage
19 // - the previous stabilized value, if it's still in history
20 // - the value which occurs the most in history
21 //
22 // If the history is empty, no stable value exists and an exception will be thrown.
23 //
24 // Inputs: Type of value <T>
25 // Required history size in the ctor
26 //
27 // The stabilized_value class is thread safe.
28 //
29 template < typename T >
31 {
32 public:
33  stabilized_value( size_t history_size )
34  : _history_size( history_size )
35  , _last_stable_value( 0 )
36  {
37  if( ! history_size )
38  throw std::runtime_error( "history size must be > 0" );
39  }
40 
41  stabilized_value() = delete;
42  stabilized_value( const stabilized_value & ) = delete;
43 
44 
45  void add( T val )
46  {
47  const std::lock_guard< std::mutex > lock( _mutex );
48  if( _values.empty() )
49  {
52  _values.push_back( val );
53  }
54  else
55  {
56  if( _values.size() >= _history_size )
57  _values.pop_front();
59  _values.push_back( val );
60  }
61  }
62 
63  T get( float stabilization_percent = 0.75f ) const
64  {
65  if( stabilization_percent <= 0.f || stabilization_percent > 1.f )
66  throw std::runtime_error( "illegal stabilization percentage "
67  + std::to_string( stabilization_percent ));
68 
69  std::lock_guard< std::mutex > lock( _mutex );
70 
71  if( _values.empty() )
72  throw std::runtime_error( "history is empty; no stable value" );
73 
74  if( _last_stable_percentage != stabilization_percent )
75  {
76  _last_stable_percentage = stabilization_percent;
77  std::unordered_map< T, int > values_count_map;
78  std::pair< T, int > most_stable_value = { 0.f, 0 };
79  for( T val : _values )
80  {
81  auto current_val = ++values_count_map[val];
82 
83  if( most_stable_value.second < current_val )
84  {
85  most_stable_value.first = val;
86  most_stable_value.second = current_val;
87  }
88  }
89 
90  auto new_value_percentage
91  = most_stable_value.second / static_cast< float >( _values.size() );
92 
93  // The stabilized value is, in order of importance:
94  // - the highest-occurring value in history that's over the required percentage
95  // - the previous stabilized value, if it's still in history
96  // - the value which occurs the most in history
97  if( new_value_percentage >= _last_stable_percentage
98  || values_count_map.find( _last_stable_value ) == values_count_map.end() )
99  {
100  _last_stable_value = most_stable_value.first;
101  }
102  }
103 
104  return _last_stable_value;
105  }
106 
107  void clear()
108  {
109  const std::lock_guard< std::mutex > lock( _mutex );
110  _values.clear();
111  }
112 
113  bool empty() const
114  {
115  const std::lock_guard< std::mutex > lock( _mutex );
116  return _values.empty();
117  }
118 
119 private:
120  std::deque< T > _values;
121  const size_t _history_size;
123  mutable float _last_stable_percentage;
124  mutable std::mutex _mutex;
125 };
126 
127 } // namespace number
128 } // namespace utilities
static const textual_icon lock
Definition: model-views.h:218
GLuint GLfloat * val
GLdouble f
std::string to_string(T value)


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:50:10