running_stat_meat.hpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
  2. // Copyright 2008-2016 National ICT Australia (NICTA)
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // ------------------------------------------------------------------------
  15. //! \addtogroup running_stat
  16. //! @{
  17. template<typename eT>
  18. inline
  19. arma_counter<eT>::~arma_counter()
  20. {
  21. arma_extra_debug_sigprint_this(this);
  22. }
  23. template<typename eT>
  24. inline
  25. arma_counter<eT>::arma_counter()
  26. : d_count( eT(0))
  27. , i_count(uword(0))
  28. {
  29. arma_extra_debug_sigprint_this(this);
  30. }
  31. template<typename eT>
  32. inline
  33. const arma_counter<eT>&
  34. arma_counter<eT>::operator++()
  35. {
  36. if(i_count < ARMA_MAX_UWORD)
  37. {
  38. i_count++;
  39. }
  40. else
  41. {
  42. d_count += eT(ARMA_MAX_UWORD);
  43. i_count = 1;
  44. }
  45. return *this;
  46. }
  47. template<typename eT>
  48. inline
  49. void
  50. arma_counter<eT>::operator++(int)
  51. {
  52. operator++();
  53. }
  54. template<typename eT>
  55. inline
  56. void
  57. arma_counter<eT>::reset()
  58. {
  59. d_count = eT(0);
  60. i_count = uword(0);
  61. }
  62. template<typename eT>
  63. inline
  64. eT
  65. arma_counter<eT>::value() const
  66. {
  67. return d_count + eT(i_count);
  68. }
  69. template<typename eT>
  70. inline
  71. eT
  72. arma_counter<eT>::value_plus_1() const
  73. {
  74. if(i_count < ARMA_MAX_UWORD)
  75. {
  76. return d_count + eT(i_count + 1);
  77. }
  78. else
  79. {
  80. return d_count + eT(ARMA_MAX_UWORD) + eT(1);
  81. }
  82. }
  83. template<typename eT>
  84. inline
  85. eT
  86. arma_counter<eT>::value_minus_1() const
  87. {
  88. if(i_count > 0)
  89. {
  90. return d_count + eT(i_count - 1);
  91. }
  92. else
  93. {
  94. return d_count - eT(1);
  95. }
  96. }
  97. //
  98. template<typename eT>
  99. inline
  100. running_stat<eT>::~running_stat()
  101. {
  102. arma_extra_debug_sigprint_this(this);
  103. }
  104. template<typename eT>
  105. inline
  106. running_stat<eT>::running_stat()
  107. : r_mean ( eT(0))
  108. , r_var (typename running_stat<eT>::T(0))
  109. , min_val ( eT(0))
  110. , max_val ( eT(0))
  111. , min_val_norm(typename running_stat<eT>::T(0))
  112. , max_val_norm(typename running_stat<eT>::T(0))
  113. {
  114. arma_extra_debug_sigprint_this(this);
  115. }
  116. //! update statistics to reflect new sample
  117. template<typename eT>
  118. inline
  119. void
  120. running_stat<eT>::operator() (const typename running_stat<eT>::T sample)
  121. {
  122. arma_extra_debug_sigprint();
  123. if( arma_isfinite(sample) == false )
  124. {
  125. arma_debug_warn("running_stat: sample ignored as it is non-finite" );
  126. return;
  127. }
  128. running_stat_aux::update_stats(*this, sample);
  129. }
  130. //! update statistics to reflect new sample (version for complex numbers)
  131. template<typename eT>
  132. inline
  133. void
  134. running_stat<eT>::operator() (const std::complex< typename running_stat<eT>::T >& sample)
  135. {
  136. arma_extra_debug_sigprint();
  137. if( arma_isfinite(sample) == false )
  138. {
  139. arma_debug_warn("running_stat: sample ignored as it is non-finite" );
  140. return;
  141. }
  142. running_stat_aux::update_stats(*this, sample);
  143. }
  144. //! set all statistics to zero
  145. template<typename eT>
  146. inline
  147. void
  148. running_stat<eT>::reset()
  149. {
  150. arma_extra_debug_sigprint();
  151. // typedef typename running_stat<eT>::T T;
  152. counter.reset();
  153. r_mean = eT(0);
  154. r_var = T(0);
  155. min_val = eT(0);
  156. max_val = eT(0);
  157. min_val_norm = T(0);
  158. max_val_norm = T(0);
  159. }
  160. //! mean or average value
  161. template<typename eT>
  162. inline
  163. eT
  164. running_stat<eT>::mean() const
  165. {
  166. arma_extra_debug_sigprint();
  167. return r_mean;
  168. }
  169. //! variance
  170. template<typename eT>
  171. inline
  172. typename running_stat<eT>::T
  173. running_stat<eT>::var(const uword norm_type) const
  174. {
  175. arma_extra_debug_sigprint();
  176. const T N = counter.value();
  177. if(N > T(1))
  178. {
  179. if(norm_type == 0)
  180. {
  181. return r_var;
  182. }
  183. else
  184. {
  185. const T N_minus_1 = counter.value_minus_1();
  186. return (N_minus_1/N) * r_var;
  187. }
  188. }
  189. else
  190. {
  191. return T(0);
  192. }
  193. }
  194. //! standard deviation
  195. template<typename eT>
  196. inline
  197. typename running_stat<eT>::T
  198. running_stat<eT>::stddev(const uword norm_type) const
  199. {
  200. arma_extra_debug_sigprint();
  201. return std::sqrt( (*this).var(norm_type) );
  202. }
  203. //! minimum value
  204. template<typename eT>
  205. inline
  206. eT
  207. running_stat<eT>::min() const
  208. {
  209. arma_extra_debug_sigprint();
  210. return min_val;
  211. }
  212. //! maximum value
  213. template<typename eT>
  214. inline
  215. eT
  216. running_stat<eT>::max() const
  217. {
  218. arma_extra_debug_sigprint();
  219. return max_val;
  220. }
  221. template<typename eT>
  222. inline
  223. eT
  224. running_stat<eT>::range() const
  225. {
  226. arma_extra_debug_sigprint();
  227. return (max_val - min_val);
  228. }
  229. //! number of samples so far
  230. template<typename eT>
  231. inline
  232. typename get_pod_type<eT>::result
  233. running_stat<eT>::count() const
  234. {
  235. arma_extra_debug_sigprint();
  236. return counter.value();
  237. }
  238. //! update statistics to reflect new sample (version for non-complex numbers, non-complex sample)
  239. template<typename eT>
  240. inline
  241. void
  242. running_stat_aux::update_stats(running_stat<eT>& x, const eT sample, const typename arma_not_cx<eT>::result* junk)
  243. {
  244. arma_extra_debug_sigprint();
  245. arma_ignore(junk);
  246. typedef typename running_stat<eT>::T T;
  247. const T N = x.counter.value();
  248. if(N > T(0))
  249. {
  250. if(sample < x.min_val)
  251. {
  252. x.min_val = sample;
  253. }
  254. if(sample > x.max_val)
  255. {
  256. x.max_val = sample;
  257. }
  258. const T N_plus_1 = x.counter.value_plus_1();
  259. const T N_minus_1 = x.counter.value_minus_1();
  260. // note: variance has to be updated before the mean
  261. const eT tmp = sample - x.r_mean;
  262. x.r_var = N_minus_1/N * x.r_var + (tmp*tmp)/N_plus_1;
  263. x.r_mean = x.r_mean + (sample - x.r_mean)/N_plus_1;
  264. //x.r_mean = (N/N_plus_1)*x.r_mean + sample/N_plus_1;
  265. //x.r_mean = (x.r_mean + sample/N) * N/N_plus_1;
  266. }
  267. else
  268. {
  269. x.r_mean = sample;
  270. x.min_val = sample;
  271. x.max_val = sample;
  272. // r_var is initialised to zero
  273. // in the constructor and reset()
  274. }
  275. x.counter++;
  276. }
  277. //! update statistics to reflect new sample (version for non-complex numbers, complex sample)
  278. template<typename eT>
  279. inline
  280. void
  281. running_stat_aux::update_stats(running_stat<eT>& x, const std::complex<eT>& sample, const typename arma_not_cx<eT>::result* junk)
  282. {
  283. arma_extra_debug_sigprint();
  284. arma_ignore(junk);
  285. running_stat_aux::update_stats(x, std::real(sample));
  286. }
  287. //! update statistics to reflect new sample (version for complex numbers, non-complex sample)
  288. template<typename eT>
  289. inline
  290. void
  291. running_stat_aux::update_stats(running_stat<eT>& x, const typename eT::value_type sample, const typename arma_cx_only<eT>::result* junk)
  292. {
  293. arma_extra_debug_sigprint();
  294. arma_ignore(junk);
  295. typedef typename eT::value_type T;
  296. running_stat_aux::update_stats(x, std::complex<T>(sample));
  297. }
  298. //! alter statistics to reflect new sample (version for complex numbers, complex sample)
  299. template<typename eT>
  300. inline
  301. void
  302. running_stat_aux::update_stats(running_stat<eT>& x, const eT& sample, const typename arma_cx_only<eT>::result* junk)
  303. {
  304. arma_extra_debug_sigprint();
  305. arma_ignore(junk);
  306. typedef typename eT::value_type T;
  307. const T sample_norm = std::norm(sample);
  308. const T N = x.counter.value();
  309. if(N > T(0))
  310. {
  311. if(sample_norm < x.min_val_norm)
  312. {
  313. x.min_val_norm = sample_norm;
  314. x.min_val = sample;
  315. }
  316. if(sample_norm > x.max_val_norm)
  317. {
  318. x.max_val_norm = sample_norm;
  319. x.max_val = sample;
  320. }
  321. const T N_plus_1 = x.counter.value_plus_1();
  322. const T N_minus_1 = x.counter.value_minus_1();
  323. x.r_var = N_minus_1/N * x.r_var + std::norm(sample - x.r_mean)/N_plus_1;
  324. x.r_mean = x.r_mean + (sample - x.r_mean)/N_plus_1;
  325. //x.r_mean = (N/N_plus_1)*x.r_mean + sample/N_plus_1;
  326. //x.r_mean = (x.r_mean + sample/N) * N/N_plus_1;
  327. }
  328. else
  329. {
  330. x.r_mean = sample;
  331. x.min_val = sample;
  332. x.max_val = sample;
  333. x.min_val_norm = sample_norm;
  334. x.max_val_norm = sample_norm;
  335. // r_var is initialised to zero
  336. // in the constructor and reset()
  337. }
  338. x.counter++;
  339. }
  340. //! @}