#ifndef _mean_n_
#define _mean_n_

#include "./utils/vector.h"
#include "./utils/matrix.h"
#include "./core/omp_config.h"

namespace numerics{
	
	template <typename T>
	T vecmean(utils::Vector<T>& a) {

		T mean(T{0});

		const uint64_t N = a.size();


	    for (uint64_t i = 0; i < N; ++i) {
            mean += a[i];
	    }
	    mean /= (static_cast<T>(N));
	    return mean;
	}

	template <typename T>
	T vecmean_isequal(utils::Vector<T>& a, utils::Vector<T>& b, T tol=1e-12) {

		uint64_t count = T{0};

		const uint64_t N = a.size();

		if (a.size() != b.size()){
			throw std::runtime_error("vecmean_equal: dimension mismatch");
		}


	    for (uint64_t i = 0; i < N; ++i) {
	    	if ((a[i]-b[i]) < tol){
	    		count += 1;
	    	}
	    }
	    return static_cast<T>(count)/static_cast<T>(N);
	}
	template <typename Td, typename Ti>
	Td vecmean_equal(utils::Vector<Ti>& a, utils::Vector<Ti>& b) {

		Ti count = Ti{0};

		const uint64_t N = a.size();

		if (a.size() != b.size()){
			throw std::runtime_error("vecmean_equal: dimension mismatch");
		}


	    for (uint64_t i = 0; i < N; ++i) {
	    	if (a[i]==b[i]){
	    		count += Ti{1};
	    	}
	    }
	    return static_cast<Td>(count)/static_cast<Td>(N);
	}

} // namespace numerics

#endif // _mean_n_