@@ -18,7 +18,7 @@ class DeviationProvider {
18
18
19
19
explicit DeviationProvider (const std::function<double (const K&)>& computeValueByKey);
20
20
21
- bool isDeviant (const K& key, double coefficient = 1.0 , double threshold = 0.0 ) const ;
21
+ bool isDeviant (const K& key, double coefficient = 1.0 , double threshold = 0.0 , bool defaultVal = false ) const ;
22
22
23
23
double getDeviationValue (const K& key) const ;
24
24
@@ -51,27 +51,38 @@ DeviationProvider<K, Hash>::DeviationProvider(const std::function<double(const K
51
51
: m_computeValueByKey(computeValueByKey) {}
52
52
53
53
template <typename K, typename Hash>
54
- bool DeviationProvider<K, Hash>::isDeviant(const K& key, const double coefficient, const double threshold) const {
54
+ bool DeviationProvider<K, Hash>::isDeviant(const K& key, double coefficient, double threshold, bool defaultVal ) const {
55
55
if (m_keyValueMap.find (key) == m_keyValueMap.end ()) {
56
56
return false ;
57
57
}
58
58
if (m_keyValueMap.size () < 3 ) {
59
59
return false ;
60
60
}
61
61
62
+ double value = m_keyValueMap.at (key);
63
+ if (std::isnan (value)) {
64
+ return defaultVal;
65
+ }
66
+
62
67
update ();
63
- return (std::abs (m_keyValueMap.at (key) - m_meanValue) > std::max ((coefficient * m_standardDeviation), threshold));
68
+ return (std::abs (value - m_meanValue)
69
+ > std::max ((coefficient * m_standardDeviation), (threshold / 100 ) * m_meanValue));
64
70
}
65
71
66
72
template <typename K, typename Hash>
67
73
double DeviationProvider<K, Hash>::getDeviationValue(const K& key) const {
68
74
if (m_keyValueMap.find (key) == m_keyValueMap.end ()) {
69
- return .0 ;
75
+ return - 1 .0 ;
70
76
}
71
77
if (m_keyValueMap.size () < 2 ) {
72
78
return .0 ;
73
79
}
74
80
81
+ double value = m_keyValueMap.at (key);
82
+ if (std::isnan (value)) {
83
+ return -1.0 ;
84
+ }
85
+
75
86
update ();
76
87
return std::abs (m_keyValueMap.at (key) - m_meanValue);
77
88
}
@@ -97,7 +108,6 @@ void DeviationProvider<K, Hash>::remove(const K& key) {
97
108
if (m_keyValueMap.find (key) == m_keyValueMap.end ()) {
98
109
return ;
99
110
}
100
-
101
111
m_keyValueMap.erase (key);
102
112
}
103
113
@@ -110,20 +120,26 @@ void DeviationProvider<K, Hash>::update() const {
110
120
return ;
111
121
}
112
122
123
+ int count = 0 ;
113
124
{
114
125
double sum = .0 ;
115
- for (const std::pair<K, double >& keyAndValue : m_keyValueMap) {
116
- sum += keyAndValue.second ;
126
+ for (const auto & [key, value] : m_keyValueMap) {
127
+ if (!std::isnan (value)) {
128
+ sum += value;
129
+ count++;
130
+ }
117
131
}
118
- m_meanValue = sum / m_keyValueMap. size () ;
132
+ m_meanValue = sum / count ;
119
133
}
120
134
121
135
{
122
136
double differencesSum = .0 ;
123
- for (const std::pair<K, double >& keyAndValue : m_keyValueMap) {
124
- differencesSum += std::pow (keyAndValue.second - m_meanValue, 2 );
137
+ for (const auto & [key, value] : m_keyValueMap) {
138
+ if (!std::isnan (value)) {
139
+ differencesSum += std::pow (value - m_meanValue, 2 );
140
+ }
125
141
}
126
- m_standardDeviation = std::sqrt (differencesSum / (m_keyValueMap. size () - 1 ));
142
+ m_standardDeviation = std::sqrt (differencesSum / (count - 1 ));
127
143
}
128
144
129
145
m_needUpdate = false ;
0 commit comments