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_vec max@0: //! @{ max@0: max@0: max@0: max@0: template max@0: running_stat_vec::~running_stat_vec() 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_vec::running_stat_vec(const bool in_calc_cov) max@0: : calc_cov(in_calc_cov) 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_vec::running_stat_vec(const running_stat_vec& in_rsv) max@0: : calc_cov (in_rsv.calc_cov) max@0: , counter (in_rsv.counter) max@0: , r_mean (in_rsv.r_mean) max@0: , r_var (in_rsv.r_var) max@0: , r_cov (in_rsv.r_cov) max@0: , min_val (in_rsv.min_val) max@0: , max_val (in_rsv.max_val) max@0: , min_val_norm(in_rsv.min_val_norm) max@0: , max_val_norm(in_rsv.max_val_norm) max@0: { max@0: arma_extra_debug_sigprint_this(this); max@0: } max@0: max@0: max@0: max@0: template max@0: const running_stat_vec& max@0: running_stat_vec::operator=(const running_stat_vec& in_rsv) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: access::rw(calc_cov) = in_rsv.calc_cov; max@0: max@0: counter = in_rsv.counter; max@0: r_mean = in_rsv.r_mean; max@0: r_var = in_rsv.r_var; max@0: r_cov = in_rsv.r_cov; max@0: min_val = in_rsv.min_val; max@0: max_val = in_rsv.max_val; max@0: min_val_norm = in_rsv.min_val_norm; max@0: max_val_norm = in_rsv.max_val_norm; max@0: max@0: return *this; max@0: } max@0: max@0: max@0: max@0: //! update statistics to reflect new sample max@0: template max@0: template max@0: arma_hot max@0: inline max@0: void max@0: running_stat_vec::operator() (const Base::result, T1>& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: //typedef typename get_pod_type::result T; max@0: max@0: const unwrap tmp(X.get_ref()); max@0: const Mat& sample = tmp.M; max@0: max@0: if( sample.is_empty() ) max@0: { max@0: return; max@0: } max@0: max@0: if( sample.is_finite() == false ) max@0: { max@0: arma_warn(true, "running_stat_vec: sample ignored as it has non-finite elements"); max@0: return; max@0: } max@0: max@0: running_stat_vec_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: template max@0: arma_hot max@0: inline max@0: void max@0: running_stat_vec::operator() (const Base::result>, T1>& X) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: //typedef typename std::complex::result> eT; max@0: max@0: const unwrap tmp(X.get_ref()); max@0: const Mat& sample = tmp.M; max@0: max@0: if( sample.is_empty() ) max@0: { max@0: return; max@0: } max@0: max@0: if( sample.is_finite() == false ) max@0: { max@0: arma_warn(true, "running_stat_vec: sample ignored as it has non-finite elements"); max@0: return; max@0: } max@0: max@0: running_stat_vec_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_vec::reset() max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: counter.reset(); max@0: max@0: r_mean.reset(); max@0: r_var.reset(); max@0: r_cov.reset(); max@0: max@0: min_val.reset(); max@0: max_val.reset(); max@0: max@0: min_val_norm.reset(); max@0: max_val_norm.reset(); max@0: max@0: r_var_dummy.reset(); max@0: r_cov_dummy.reset(); max@0: max@0: tmp1.reset(); max@0: tmp2.reset(); max@0: } max@0: max@0: max@0: max@0: //! mean or average value max@0: template max@0: inline max@0: const Mat& max@0: running_stat_vec::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: const Mat::result>& max@0: running_stat_vec::var(const uword norm_type) 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: max@0: r_var_dummy = (N_minus_1/N) * r_var; max@0: max@0: return r_var_dummy; max@0: } max@0: } max@0: else max@0: { max@0: r_var_dummy.zeros(r_mean.n_rows, r_mean.n_cols); max@0: max@0: return r_var_dummy; max@0: } max@0: max@0: } max@0: max@0: max@0: max@0: //! standard deviation max@0: template max@0: inline max@0: Mat::result> max@0: running_stat_vec::stddev(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 sqrt(r_var); max@0: } max@0: else max@0: { max@0: const T N_minus_1 = counter.value_minus_1(); max@0: max@0: return sqrt( (N_minus_1/N) * r_var ); max@0: } max@0: } max@0: else max@0: { max@0: return Mat(); max@0: } max@0: } max@0: max@0: max@0: max@0: //! covariance max@0: template max@0: inline max@0: const Mat& max@0: running_stat_vec::cov(const uword norm_type) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: if(calc_cov == true) 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_cov; max@0: } max@0: else max@0: { max@0: const T N_minus_1 = counter.value_minus_1(); max@0: max@0: r_cov_dummy = (N_minus_1/N) * r_cov; max@0: max@0: return r_cov_dummy; max@0: } max@0: } max@0: else max@0: { max@0: r_cov_dummy.zeros(r_mean.n_rows, r_mean.n_cols); max@0: max@0: return r_cov_dummy; max@0: } max@0: } max@0: else max@0: { max@0: r_cov_dummy.reset(); max@0: max@0: return r_cov_dummy; max@0: } max@0: max@0: } max@0: max@0: max@0: max@0: //! vector with minimum values max@0: template max@0: inline max@0: const Mat& max@0: running_stat_vec::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: //! vector with maximum values max@0: template max@0: inline max@0: const Mat& max@0: running_stat_vec::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_vec::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: // 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_vec_aux::update_stats(running_stat_vec& x, const Mat& sample) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: typedef typename running_stat_vec::T T; max@0: max@0: const T N = x.counter.value(); max@0: max@0: if(N > T(0)) max@0: { max@0: arma_debug_assert_same_size(x.r_mean, sample, "running_stat_vec(): dimensionality mismatch"); max@0: max@0: const uword n_elem = sample.n_elem; max@0: const eT* sample_mem = sample.memptr(); max@0: eT* r_mean_mem = x.r_mean.memptr(); max@0: T* r_var_mem = x.r_var.memptr(); max@0: eT* min_val_mem = x.min_val.memptr(); max@0: eT* max_val_mem = x.max_val.memptr(); 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: if(x.calc_cov == true) max@0: { max@0: Mat& tmp1 = x.tmp1; max@0: Mat& tmp2 = x.tmp2; max@0: max@0: tmp1 = sample - x.r_mean; max@0: max@0: if(sample.n_cols == 1) max@0: { max@0: tmp2 = tmp1*trans(tmp1); max@0: } max@0: else max@0: { max@0: tmp2 = trans(tmp1)*tmp1; max@0: } max@0: max@0: x.r_cov *= (N_minus_1/N); max@0: x.r_cov += tmp2 / N_plus_1; max@0: } max@0: max@0: max@0: for(uword i=0; i max_val_mem[i]) max@0: { max@0: max_val_mem[i] = val; max@0: } max@0: max@0: const eT r_mean_val = r_mean_mem[i]; max@0: const eT tmp = val - r_mean_val; max@0: max@0: r_var_mem[i] = N_minus_1/N * r_var_mem[i] + (tmp*tmp)/N_plus_1; max@0: max@0: r_mean_mem[i] = r_mean_val + (val - r_mean_val)/N_plus_1; max@0: } max@0: } max@0: else max@0: { max@0: arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample is not a vector"); max@0: max@0: x.r_mean.set_size(sample.n_rows, sample.n_cols); max@0: max@0: x.r_var.zeros(sample.n_rows, sample.n_cols); max@0: max@0: if(x.calc_cov == true) max@0: { max@0: x.r_cov.zeros(sample.n_elem, sample.n_elem); max@0: } max@0: max@0: x.min_val.set_size(sample.n_rows, sample.n_cols); max@0: x.max_val.set_size(sample.n_rows, sample.n_cols); max@0: max@0: max@0: const uword n_elem = sample.n_elem; max@0: const eT* sample_mem = sample.memptr(); max@0: eT* r_mean_mem = x.r_mean.memptr(); max@0: eT* min_val_mem = x.min_val.memptr(); max@0: eT* max_val_mem = x.max_val.memptr(); max@0: max@0: max@0: for(uword i=0; i max@0: inline max@0: void max@0: running_stat_vec_aux::update_stats(running_stat_vec< std::complex >& x, const Mat& sample) max@0: { max@0: arma_extra_debug_sigprint(); max@0: max@0: const Mat< std::complex > tmp = conv_to< Mat< std::complex > >::from(sample); max@0: max@0: running_stat_vec_aux::update_stats(x, tmp); 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_vec_aux::update_stats(running_stat_vec< std::complex >& x, const Mat< 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 N = x.counter.value(); max@0: max@0: if(N > T(0)) max@0: { max@0: arma_debug_assert_same_size(x.r_mean, sample, "running_stat_vec(): dimensionality mismatch"); max@0: max@0: const uword n_elem = sample.n_elem; max@0: const eT* sample_mem = sample.memptr(); max@0: eT* r_mean_mem = x.r_mean.memptr(); max@0: T* r_var_mem = x.r_var.memptr(); max@0: eT* min_val_mem = x.min_val.memptr(); max@0: eT* max_val_mem = x.max_val.memptr(); max@0: T* min_val_norm_mem = x.min_val_norm.memptr(); max@0: T* max_val_norm_mem = x.max_val_norm.memptr(); 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: if(x.calc_cov == true) max@0: { max@0: Mat& tmp1 = x.tmp1; max@0: Mat& tmp2 = x.tmp2; max@0: max@0: tmp1 = sample - x.r_mean; max@0: max@0: if(sample.n_cols == 1) max@0: { max@0: tmp2 = arma::conj(tmp1)*strans(tmp1); max@0: } max@0: else max@0: { max@0: tmp2 = trans(tmp1)*tmp1; //tmp2 = strans(conj(tmp1))*tmp1; max@0: } max@0: max@0: x.r_cov *= (N_minus_1/N); max@0: x.r_cov += tmp2 / N_plus_1; max@0: } max@0: max@0: max@0: for(uword i=0; i max_val_norm_mem[i]) max@0: { max@0: max_val_norm_mem[i] = val_norm; max@0: max_val_mem[i] = val; max@0: } max@0: max@0: const eT& r_mean_val = r_mean_mem[i]; max@0: max@0: r_var_mem[i] = N_minus_1/N * r_var_mem[i] + std::norm(val - r_mean_val)/N_plus_1; max@0: max@0: r_mean_mem[i] = r_mean_val + (val - r_mean_val)/N_plus_1; max@0: } max@0: max@0: } max@0: else max@0: { max@0: arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample is not a vector"); max@0: max@0: x.r_mean.set_size(sample.n_rows, sample.n_cols); max@0: max@0: x.r_var.zeros(sample.n_rows, sample.n_cols); max@0: max@0: if(x.calc_cov == true) max@0: { max@0: x.r_cov.zeros(sample.n_elem, sample.n_elem); max@0: } max@0: max@0: x.min_val.set_size(sample.n_rows, sample.n_cols); max@0: x.max_val.set_size(sample.n_rows, sample.n_cols); max@0: max@0: x.min_val_norm.set_size(sample.n_rows, sample.n_cols); max@0: x.max_val_norm.set_size(sample.n_rows, sample.n_cols); max@0: max@0: max@0: const uword n_elem = sample.n_elem; max@0: const eT* sample_mem = sample.memptr(); max@0: eT* r_mean_mem = x.r_mean.memptr(); max@0: eT* min_val_mem = x.min_val.memptr(); max@0: eT* max_val_mem = x.max_val.memptr(); max@0: T* min_val_norm_mem = x.min_val_norm.memptr(); max@0: T* max_val_norm_mem = x.max_val_norm.memptr(); max@0: max@0: for(uword i=0; i