@@ -18,7 +18,7 @@ class DeviationProvider {
1818
1919 explicit DeviationProvider (const std::function<double (const K&)>& computeValueByKey);
2020
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 ;
2222
2323 double getDeviationValue (const K& key) const ;
2424
@@ -51,27 +51,38 @@ DeviationProvider<K, Hash>::DeviationProvider(const std::function<double(const K
5151 : m_computeValueByKey(computeValueByKey) {}
5252
5353template <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 {
5555 if (m_keyValueMap.find (key) == m_keyValueMap.end ()) {
5656 return false ;
5757 }
5858 if (m_keyValueMap.size () < 3 ) {
5959 return false ;
6060 }
6161
62+ double value = m_keyValueMap.at (key);
63+ if (std::isnan (value)) {
64+ return defaultVal;
65+ }
66+
6267 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));
6470}
6571
6672template <typename K, typename Hash>
6773double DeviationProvider<K, Hash>::getDeviationValue(const K& key) const {
6874 if (m_keyValueMap.find (key) == m_keyValueMap.end ()) {
69- return .0 ;
75+ return - 1 .0 ;
7076 }
7177 if (m_keyValueMap.size () < 2 ) {
7278 return .0 ;
7379 }
7480
81+ double value = m_keyValueMap.at (key);
82+ if (std::isnan (value)) {
83+ return -1.0 ;
84+ }
85+
7586 update ();
7687 return std::abs (m_keyValueMap.at (key) - m_meanValue);
7788}
@@ -97,7 +108,6 @@ void DeviationProvider<K, Hash>::remove(const K& key) {
97108 if (m_keyValueMap.find (key) == m_keyValueMap.end ()) {
98109 return ;
99110 }
100-
101111 m_keyValueMap.erase (key);
102112}
103113
@@ -110,20 +120,26 @@ void DeviationProvider<K, Hash>::update() const {
110120 return ;
111121 }
112122
123+ int count = 0 ;
113124 {
114125 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+ }
117131 }
118- m_meanValue = sum / m_keyValueMap. size () ;
132+ m_meanValue = sum / count ;
119133 }
120134
121135 {
122136 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+ }
125141 }
126- m_standardDeviation = std::sqrt (differencesSum / (m_keyValueMap. size () - 1 ));
142+ m_standardDeviation = std::sqrt (differencesSum / (count - 1 ));
127143 }
128144
129145 m_needUpdate = false ;
0 commit comments