max@0: // Copyright (C) 2009-2011 NICTA (www.nicta.com.au) max@0: // Copyright (C) 2009-2011 Conrad Sanderson max@0: // max@0: // This file is part of the Armadillo C++ library. max@0: // It is provided without any warranty of fitness max@0: // for any purpose. You can redistribute this file max@0: // and/or modify it under the terms of the GNU max@0: // Lesser General Public License (LGPL) as published max@0: // by the Free Software Foundation, either version 3 max@0: // of the License or (at your option) any later version. max@0: // (see http://www.opensource.org/licenses for more info) max@0: max@0: max@0: //! \addtogroup running_stat max@0: //! @{ max@0: max@0: max@0: max@0: template max@0: inline max@0: arma_counter::~arma_counter() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: arma_counter::arma_counter() max@0: : d_count( eT(0)) max@0: , i_count(uword(0)) max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: const arma_counter& max@0: arma_counter::operator++() max@0: { max@0: if(i_count < ARMA_MAX_UWORD) max@0: { max@0: i_count++; max@0: } max@0: else max@0: { max@0: d_count += eT(ARMA_MAX_UWORD); max@0: i_count = 0; max@0: } max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: void max@0: arma_counter::operator++(int) max@0: { max@0: operator++(); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: void max@0: arma_counter::reset() max@0: { max@0: d_count = eT(0); max@0: i_count = uword(0); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: eT max@0: arma_counter::value() const max@0: { max@0: return d_count + eT(i_count); max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: eT max@0: arma_counter::value_plus_1() const max@0: { max@0: if(i_count < ARMA_MAX_UWORD) max@0: { max@0: return d_count + eT(i_count + 1); max@0: } max@0: else max@0: { max@0: return d_count + eT(ARMA_MAX_UWORD) + eT(1); max@0: } max@0: } max@0: max@0: max@0: max@0: template max@0: inline max@0: eT max@0: arma_counter::value_minus_1() const max@0: { max@0: if(i_count > 0) max@0: { max@0: return d_count + eT(i_count - 1); max@0: } max@0: else max@0: { max@0: return d_count - eT(1); max@0: } max@0: } max@0: max@0: max@0: max@0: // max@0: max@0: max@0: max@0: template max@0: running_stat::~running_stat() max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: } max@0: max@0: max@0: max@0: template max@0: running_stat::running_stat() max@0: : r_mean ( eT(0)) max@0: , r_var (typename running_stat::T(0)) max@0: , min_val ( eT(0)) max@0: , max_val ( eT(0)) max@0: , min_val_norm(typename running_stat::T(0)) max@0: , max_val_norm(typename running_stat::T(0)) max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: } max@0: max@0: max@0: max@0: //! update statistics to reflect new sample max@0: template max@0: inline max@0: void max@0: running_stat::operator() (const typename running_stat::T sample) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: if( arma_isfinite(sample) == false ) max@0: { max@0: arma_warn(true, "running_stat: sample ignored as it is non-finite" ); max@0: return; max@0: } max@0: max@0: running_stat_aux::update_stats(*this, sample); max@0: } max@0: max@0: max@0: max@0: //! update statistics to reflect new sample (version for complex numbers) max@0: template max@0: inline max@0: void max@0: running_stat::operator() (const std::complex< typename running_stat::T >& sample) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: arma_type_check(( is_same_type::T > >::value == false )); max@0: max@0: if( arma_isfinite(sample) == false ) max@0: { max@0: arma_warn(true, "running_stat: sample ignored as it is non-finite" ); max@0: return; max@0: } max@0: max@0: running_stat_aux::update_stats(*this, sample); max@0: } max@0: max@0: max@0: max@0: //! set all statistics to zero max@0: template max@0: inline max@0: void max@0: running_stat::reset() max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename running_stat::T T; max@0: max@0: counter.reset(); max@0: max@0: r_mean = eT(0); max@0: r_var = T(0); max@0: max@0: min_val = eT(0); max@0: max_val = eT(0); max@0: max@0: min_val_norm = T(0); max@0: max_val_norm = T(0); max@0: } max@0: max@0: max@0: max@0: //! mean or average value max@0: template max@0: inline max@0: eT max@0: running_stat::mean() const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return r_mean; max@0: } max@0: max@0: max@0: max@0: //! variance max@0: template max@0: inline max@0: typename running_stat::T max@0: running_stat::var(const uword norm_type) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const T N = counter.value(); max@0: max@0: if(N > T(1)) max@0: { max@0: if(norm_type == 0) max@0: { max@0: return r_var; max@0: } max@0: else max@0: { max@0: const T N_minus_1 = counter.value_minus_1(); max@0: return (N_minus_1/N) * r_var; max@0: } max@0: } max@0: else max@0: { max@0: return T(0); max@0: } max@0: } max@0: max@0: max@0: max@0: //! standard deviation max@0: template max@0: inline max@0: typename running_stat::T max@0: running_stat::stddev(const uword norm_type) const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return std::sqrt( (*this).var(norm_type) ); max@0: } max@0: max@0: max@0: max@0: //! minimum value max@0: template max@0: inline max@0: eT max@0: running_stat::min() const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return min_val; max@0: } max@0: max@0: max@0: max@0: //! maximum value max@0: template max@0: inline max@0: eT max@0: running_stat::max() const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return max_val; max@0: } max@0: max@0: max@0: max@0: //! number of samples so far max@0: template max@0: inline max@0: typename get_pod_type::result max@0: running_stat::count() const max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: return counter.value(); max@0: } max@0: max@0: max@0: max@0: //! update statistics to reflect new sample max@0: template max@0: inline max@0: void max@0: running_stat_aux::update_stats(running_stat& x, const eT sample) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename running_stat::T T; max@0: max@0: const T N = x.counter.value(); max@0: max@0: if(N > T(0)) max@0: { max@0: if(sample < x.min_val) max@0: { max@0: x.min_val = sample; max@0: } max@0: max@0: if(sample > x.max_val) max@0: { max@0: x.max_val = sample; max@0: } max@0: max@0: const T N_plus_1 = x.counter.value_plus_1(); max@0: const T N_minus_1 = x.counter.value_minus_1(); max@0: max@0: // note: variance has to be updated before the mean max@0: max@0: const eT tmp = sample - x.r_mean; max@0: max@0: x.r_var = N_minus_1/N * x.r_var + (tmp*tmp)/N_plus_1; max@0: max@0: x.r_mean = x.r_mean + (sample - x.r_mean)/N_plus_1; max@0: //x.r_mean = (N/N_plus_1)*x.r_mean + sample/N_plus_1; max@0: //x.r_mean = (x.r_mean + sample/N) * N/N_plus_1; max@0: } max@0: else max@0: { max@0: x.r_mean = sample; max@0: x.min_val = sample; max@0: x.max_val = sample; max@0: max@0: // r_var is initialised to zero max@0: // in the constructor and reset() max@0: } max@0: max@0: x.counter++; max@0: } max@0: max@0: max@0: max@0: //! update statistics to reflect new sample (version for complex numbers) max@0: template max@0: inline max@0: void max@0: running_stat_aux::update_stats(running_stat< std::complex >& x, const T sample) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: running_stat_aux::update_stats(x, std::complex(sample)); max@0: } max@0: max@0: max@0: max@0: //! alter statistics to reflect new sample (version for complex numbers) max@0: template max@0: inline max@0: void max@0: running_stat_aux::update_stats(running_stat< std::complex >& x, const std::complex& sample) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename std::complex eT; max@0: max@0: const T sample_norm = std::norm(sample); max@0: const T N = x.counter.value(); max@0: max@0: if(N > T(0)) max@0: { max@0: if(sample_norm < x.min_val_norm) max@0: { max@0: x.min_val_norm = sample_norm; max@0: x.min_val = sample; max@0: } max@0: max@0: if(sample_norm > x.max_val_norm) max@0: { max@0: x.max_val_norm = sample_norm; max@0: x.max_val = sample; max@0: } max@0: max@0: const T N_plus_1 = x.counter.value_plus_1(); max@0: const T N_minus_1 = x.counter.value_minus_1(); max@0: max@0: x.r_var = N_minus_1/N * x.r_var + std::norm(sample - x.r_mean)/N_plus_1; max@0: max@0: x.r_mean = x.r_mean + (sample - x.r_mean)/N_plus_1; max@0: //x.r_mean = (N/N_plus_1)*x.r_mean + sample/N_plus_1; max@0: //x.r_mean = (x.r_mean + sample/N) * N/N_plus_1; max@0: } max@0: else max@0: { max@0: x.r_mean = sample; max@0: x.min_val = sample; max@0: x.max_val = sample; max@0: x.min_val_norm = sample_norm; max@0: x.max_val_norm = sample_norm; max@0: max@0: // r_var is initialised to zero max@0: // in the constructor and reset() max@0: } max@0: max@0: x.counter++; max@0: } max@0: max@0: max@0: max@0: //! @}