Chris@49: // Copyright (C) 2009-2011 NICTA (www.nicta.com.au) Chris@49: // Copyright (C) 2009-2011 Conrad Sanderson Chris@49: // Chris@49: // This Source Code Form is subject to the terms of the Mozilla Public Chris@49: // License, v. 2.0. If a copy of the MPL was not distributed with this Chris@49: // file, You can obtain one at http://mozilla.org/MPL/2.0/. Chris@49: Chris@49: Chris@49: //! \addtogroup running_stat_vec Chris@49: //! @{ Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: running_stat_vec::~running_stat_vec() Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: running_stat_vec::running_stat_vec(const bool in_calc_cov) Chris@49: : calc_cov(in_calc_cov) Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: running_stat_vec::running_stat_vec(const running_stat_vec& in_rsv) Chris@49: : calc_cov (in_rsv.calc_cov) Chris@49: , counter (in_rsv.counter) Chris@49: , r_mean (in_rsv.r_mean) Chris@49: , r_var (in_rsv.r_var) Chris@49: , r_cov (in_rsv.r_cov) Chris@49: , min_val (in_rsv.min_val) Chris@49: , max_val (in_rsv.max_val) Chris@49: , min_val_norm(in_rsv.min_val_norm) Chris@49: , max_val_norm(in_rsv.max_val_norm) Chris@49: { Chris@49: arma_extra_debug_sigprint_this(this); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: const running_stat_vec& Chris@49: running_stat_vec::operator=(const running_stat_vec& in_rsv) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(calc_cov) = in_rsv.calc_cov; Chris@49: Chris@49: counter = in_rsv.counter; Chris@49: r_mean = in_rsv.r_mean; Chris@49: r_var = in_rsv.r_var; Chris@49: r_cov = in_rsv.r_cov; Chris@49: min_val = in_rsv.min_val; Chris@49: max_val = in_rsv.max_val; Chris@49: min_val_norm = in_rsv.min_val_norm; Chris@49: max_val_norm = in_rsv.max_val_norm; Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! update statistics to reflect new sample Chris@49: template Chris@49: template Chris@49: arma_hot Chris@49: inline Chris@49: void Chris@49: running_stat_vec::operator() (const Base::result, T1>& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: //typedef typename get_pod_type::result T; Chris@49: Chris@49: const unwrap tmp(X.get_ref()); Chris@49: const Mat& sample = tmp.M; Chris@49: Chris@49: if( sample.is_empty() ) Chris@49: { Chris@49: return; Chris@49: } Chris@49: Chris@49: if( sample.is_finite() == false ) Chris@49: { Chris@49: arma_warn(true, "running_stat_vec: sample ignored as it has non-finite elements"); Chris@49: return; Chris@49: } Chris@49: Chris@49: running_stat_vec_aux::update_stats(*this, sample); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! update statistics to reflect new sample (version for complex numbers) Chris@49: template Chris@49: template Chris@49: arma_hot Chris@49: inline Chris@49: void Chris@49: running_stat_vec::operator() (const Base::result>, T1>& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: //typedef typename std::complex::result> eT; Chris@49: Chris@49: const unwrap tmp(X.get_ref()); Chris@49: const Mat& sample = tmp.M; Chris@49: Chris@49: if( sample.is_empty() ) Chris@49: { Chris@49: return; Chris@49: } Chris@49: Chris@49: if( sample.is_finite() == false ) Chris@49: { Chris@49: arma_warn(true, "running_stat_vec: sample ignored as it has non-finite elements"); Chris@49: return; Chris@49: } Chris@49: Chris@49: running_stat_vec_aux::update_stats(*this, sample); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! set all statistics to zero Chris@49: template Chris@49: inline Chris@49: void Chris@49: running_stat_vec::reset() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: counter.reset(); Chris@49: Chris@49: r_mean.reset(); Chris@49: r_var.reset(); Chris@49: r_cov.reset(); Chris@49: Chris@49: min_val.reset(); Chris@49: max_val.reset(); Chris@49: Chris@49: min_val_norm.reset(); Chris@49: max_val_norm.reset(); Chris@49: Chris@49: r_var_dummy.reset(); Chris@49: r_cov_dummy.reset(); Chris@49: Chris@49: tmp1.reset(); Chris@49: tmp2.reset(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! mean or average value Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: running_stat_vec::mean() const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return r_mean; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! variance Chris@49: template Chris@49: inline Chris@49: const Mat::result>& Chris@49: running_stat_vec::var(const uword norm_type) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const T N = counter.value(); Chris@49: Chris@49: if(N > T(1)) Chris@49: { Chris@49: if(norm_type == 0) Chris@49: { Chris@49: return r_var; Chris@49: } Chris@49: else Chris@49: { Chris@49: const T N_minus_1 = counter.value_minus_1(); Chris@49: Chris@49: r_var_dummy = (N_minus_1/N) * r_var; Chris@49: Chris@49: return r_var_dummy; Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: r_var_dummy.zeros(r_mean.n_rows, r_mean.n_cols); Chris@49: Chris@49: return r_var_dummy; Chris@49: } Chris@49: Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! standard deviation Chris@49: template Chris@49: inline Chris@49: Mat::result> Chris@49: running_stat_vec::stddev(const uword norm_type) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const T N = counter.value(); Chris@49: Chris@49: if(N > T(1)) Chris@49: { Chris@49: if(norm_type == 0) Chris@49: { Chris@49: return sqrt(r_var); Chris@49: } Chris@49: else Chris@49: { Chris@49: const T N_minus_1 = counter.value_minus_1(); Chris@49: Chris@49: return sqrt( (N_minus_1/N) * r_var ); Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: return Mat(); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! covariance Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: running_stat_vec::cov(const uword norm_type) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(calc_cov == true) Chris@49: { Chris@49: const T N = counter.value(); Chris@49: Chris@49: if(N > T(1)) Chris@49: { Chris@49: if(norm_type == 0) Chris@49: { Chris@49: return r_cov; Chris@49: } Chris@49: else Chris@49: { Chris@49: const T N_minus_1 = counter.value_minus_1(); Chris@49: Chris@49: r_cov_dummy = (N_minus_1/N) * r_cov; Chris@49: Chris@49: return r_cov_dummy; Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: r_cov_dummy.zeros(r_mean.n_rows, r_mean.n_cols); Chris@49: Chris@49: return r_cov_dummy; Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: r_cov_dummy.reset(); Chris@49: Chris@49: return r_cov_dummy; Chris@49: } Chris@49: Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! vector with minimum values Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: running_stat_vec::min() const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return min_val; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! vector with maximum values Chris@49: template Chris@49: inline Chris@49: const Mat& Chris@49: running_stat_vec::max() const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return max_val; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! number of samples so far Chris@49: template Chris@49: inline Chris@49: typename get_pod_type::result Chris@49: running_stat_vec::count() const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: return counter.value(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: // Chris@49: Chris@49: Chris@49: Chris@49: //! update statistics to reflect new sample Chris@49: template Chris@49: inline Chris@49: void Chris@49: running_stat_vec_aux::update_stats(running_stat_vec& x, const Mat& sample) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: typedef typename running_stat_vec::T T; Chris@49: Chris@49: const T N = x.counter.value(); Chris@49: Chris@49: if(N > T(0)) Chris@49: { Chris@49: arma_debug_assert_same_size(x.r_mean, sample, "running_stat_vec(): dimensionality mismatch"); Chris@49: Chris@49: const uword n_elem = sample.n_elem; Chris@49: const eT* sample_mem = sample.memptr(); Chris@49: eT* r_mean_mem = x.r_mean.memptr(); Chris@49: T* r_var_mem = x.r_var.memptr(); Chris@49: eT* min_val_mem = x.min_val.memptr(); Chris@49: eT* max_val_mem = x.max_val.memptr(); Chris@49: Chris@49: const T N_plus_1 = x.counter.value_plus_1(); Chris@49: const T N_minus_1 = x.counter.value_minus_1(); Chris@49: Chris@49: if(x.calc_cov == true) Chris@49: { Chris@49: Mat& tmp1 = x.tmp1; Chris@49: Mat& tmp2 = x.tmp2; Chris@49: Chris@49: tmp1 = sample - x.r_mean; Chris@49: Chris@49: if(sample.n_cols == 1) Chris@49: { Chris@49: tmp2 = tmp1*trans(tmp1); Chris@49: } Chris@49: else Chris@49: { Chris@49: tmp2 = trans(tmp1)*tmp1; Chris@49: } Chris@49: Chris@49: x.r_cov *= (N_minus_1/N); Chris@49: x.r_cov += tmp2 / N_plus_1; Chris@49: } Chris@49: Chris@49: Chris@49: for(uword i=0; i max_val_mem[i]) Chris@49: { Chris@49: max_val_mem[i] = val; Chris@49: } Chris@49: Chris@49: const eT r_mean_val = r_mean_mem[i]; Chris@49: const eT tmp = val - r_mean_val; Chris@49: Chris@49: r_var_mem[i] = N_minus_1/N * r_var_mem[i] + (tmp*tmp)/N_plus_1; Chris@49: Chris@49: r_mean_mem[i] = r_mean_val + (val - r_mean_val)/N_plus_1; Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample is not a vector"); Chris@49: Chris@49: x.r_mean.set_size(sample.n_rows, sample.n_cols); Chris@49: Chris@49: x.r_var.zeros(sample.n_rows, sample.n_cols); Chris@49: Chris@49: if(x.calc_cov == true) Chris@49: { Chris@49: x.r_cov.zeros(sample.n_elem, sample.n_elem); Chris@49: } Chris@49: Chris@49: x.min_val.set_size(sample.n_rows, sample.n_cols); Chris@49: x.max_val.set_size(sample.n_rows, sample.n_cols); Chris@49: Chris@49: Chris@49: const uword n_elem = sample.n_elem; Chris@49: const eT* sample_mem = sample.memptr(); Chris@49: eT* r_mean_mem = x.r_mean.memptr(); Chris@49: eT* min_val_mem = x.min_val.memptr(); Chris@49: eT* max_val_mem = x.max_val.memptr(); Chris@49: Chris@49: Chris@49: for(uword i=0; i Chris@49: inline Chris@49: void Chris@49: running_stat_vec_aux::update_stats(running_stat_vec< std::complex >& x, const Mat& sample) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const Mat< std::complex > tmp = conv_to< Mat< std::complex > >::from(sample); Chris@49: Chris@49: running_stat_vec_aux::update_stats(x, tmp); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! alter statistics to reflect new sample (version for complex numbers) Chris@49: template Chris@49: inline Chris@49: void Chris@49: running_stat_vec_aux::update_stats(running_stat_vec< std::complex >& x, const Mat< std::complex >& sample) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: typedef typename std::complex eT; Chris@49: Chris@49: const T N = x.counter.value(); Chris@49: Chris@49: if(N > T(0)) Chris@49: { Chris@49: arma_debug_assert_same_size(x.r_mean, sample, "running_stat_vec(): dimensionality mismatch"); Chris@49: Chris@49: const uword n_elem = sample.n_elem; Chris@49: const eT* sample_mem = sample.memptr(); Chris@49: eT* r_mean_mem = x.r_mean.memptr(); Chris@49: T* r_var_mem = x.r_var.memptr(); Chris@49: eT* min_val_mem = x.min_val.memptr(); Chris@49: eT* max_val_mem = x.max_val.memptr(); Chris@49: T* min_val_norm_mem = x.min_val_norm.memptr(); Chris@49: T* max_val_norm_mem = x.max_val_norm.memptr(); Chris@49: Chris@49: const T N_plus_1 = x.counter.value_plus_1(); Chris@49: const T N_minus_1 = x.counter.value_minus_1(); Chris@49: Chris@49: if(x.calc_cov == true) Chris@49: { Chris@49: Mat& tmp1 = x.tmp1; Chris@49: Mat& tmp2 = x.tmp2; Chris@49: Chris@49: tmp1 = sample - x.r_mean; Chris@49: Chris@49: if(sample.n_cols == 1) Chris@49: { Chris@49: tmp2 = arma::conj(tmp1)*strans(tmp1); Chris@49: } Chris@49: else Chris@49: { Chris@49: tmp2 = trans(tmp1)*tmp1; //tmp2 = strans(conj(tmp1))*tmp1; Chris@49: } Chris@49: Chris@49: x.r_cov *= (N_minus_1/N); Chris@49: x.r_cov += tmp2 / N_plus_1; Chris@49: } Chris@49: Chris@49: Chris@49: for(uword i=0; i max_val_norm_mem[i]) Chris@49: { Chris@49: max_val_norm_mem[i] = val_norm; Chris@49: max_val_mem[i] = val; Chris@49: } Chris@49: Chris@49: const eT& r_mean_val = r_mean_mem[i]; Chris@49: Chris@49: r_var_mem[i] = N_minus_1/N * r_var_mem[i] + std::norm(val - r_mean_val)/N_plus_1; Chris@49: Chris@49: r_mean_mem[i] = r_mean_val + (val - r_mean_val)/N_plus_1; Chris@49: } Chris@49: Chris@49: } Chris@49: else Chris@49: { Chris@49: arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample is not a vector"); Chris@49: Chris@49: x.r_mean.set_size(sample.n_rows, sample.n_cols); Chris@49: Chris@49: x.r_var.zeros(sample.n_rows, sample.n_cols); Chris@49: Chris@49: if(x.calc_cov == true) Chris@49: { Chris@49: x.r_cov.zeros(sample.n_elem, sample.n_elem); Chris@49: } Chris@49: Chris@49: x.min_val.set_size(sample.n_rows, sample.n_cols); Chris@49: x.max_val.set_size(sample.n_rows, sample.n_cols); Chris@49: Chris@49: x.min_val_norm.set_size(sample.n_rows, sample.n_cols); Chris@49: x.max_val_norm.set_size(sample.n_rows, sample.n_cols); Chris@49: Chris@49: Chris@49: const uword n_elem = sample.n_elem; Chris@49: const eT* sample_mem = sample.memptr(); Chris@49: eT* r_mean_mem = x.r_mean.memptr(); Chris@49: eT* min_val_mem = x.min_val.memptr(); Chris@49: eT* max_val_mem = x.max_val.memptr(); Chris@49: T* min_val_norm_mem = x.min_val_norm.memptr(); Chris@49: T* max_val_norm_mem = x.max_val_norm.memptr(); Chris@49: Chris@49: for(uword i=0; i