Go to the documentation of this file.00001 #ifndef ErrorPropogationTypes_h
00002 #define ErrorPropogationTypes_h
00003
00004 #include "boost/operators.hpp"
00005 #include <cmath>
00006
00007 class count_t :
00008 boost::addable<count_t,
00009 boost::incrementable<count_t,
00010 boost::totally_ordered<count_t,
00011 boost::equivalent<count_t> > > > {
00012
00013 private:
00014 unsigned long count;
00015 public:
00016 count_t() : count(0) {}
00017 count_t(unsigned long n) : count(n) {}
00018 bool operator<(const count_t& R) const { return count < R.count;}
00019 count_t operator++() {++count; return *this;}
00020 count_t operator+=(const count_t& R) {count += R.count; return *this;}
00021 unsigned long operator()() const {return count;}
00022 unsigned long error2() const {return count;}
00023 double error() const {return sqrt(count);}
00024 double relative_error() const {return 1/sqrt(count);}
00025 };
00026
00027 template <class charT, class traits>
00028 inline
00029 std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits>& strm, const count_t& f)
00030 { strm << f() << "("<< f.error()<< ")"; return strm;}
00031
00032 template<class T>
00033 class stats_t :
00034 boost::arithmetic1<stats_t<T>,
00035 boost::arithmetic2<stats_t<T>, T,
00036 boost::partially_ordered<stats_t<T>,
00037 boost::partially_ordered<stats_t<T>,count_t,
00038 boost::equality_comparable<stats_t<T>,
00039 boost::equality_comparable<stats_t<T>,count_t> > > > > > {
00040 private:
00041 T value, err2;
00042 public:
00043 stats_t() : value(0), err2(1) {}
00044 stats_t(count_t c) : value(c()), err2(c.error2()) {}
00045 stats_t(T q, T e2) : value(q), err2(e2) {}
00046 static stats_t from_relative_uncertainty2(T q, T re2) { return stats_t(q,q*q*re2);}
00047
00048 bool operator<(const stats_t& R) const { return value < R.value ;}
00049 bool operator<(const count_t& R) const { return value < R() ;}
00050 bool operator==(const stats_t& R) const { return value == R.value && err2 == R.err2;}
00051 bool operator==(const count_t& R) const { return value == R() && err2 == R.error2();}
00052
00053 stats_t operator+=(const stats_t& R) { value += R.value; err2 += R.err2; return *this;}
00054 stats_t operator-=(const stats_t& R) { value -= R.value; err2 += R.err2; return *this;}
00055 stats_t operator*=(const stats_t& R) { err2 = R.err2*value*value + err2*R.value*R.value; value *= R.value; return *this;}
00056 stats_t operator/=(const stats_t& R) { value /= R.value; err2 = (err2 + value*value*R.err2) / (R.value*R.value); return *this;}
00057
00058 stats_t operator+=(const T& r) { value += r; return *this;}
00059 stats_t operator-=(const T& r) { value -= r; return *this;}
00060 stats_t operator*=(const T& r) { value *= r; err2 *= r*r; return *this;}
00061 stats_t operator/=(const T& r) { value /= r; err2 /= r*r; return *this;}
00062
00063 stats_t inverse() const { return stats_t(1./value, err2/pow(value,4));}
00064
00065 T operator()() const {return value;}
00066 T error2() const {return err2;}
00067 T error() const {return sqrt(err2);}
00068 T relative_error() const {return sqrt(err2)/value;}
00069 T sigmaFrom(const T& x) const {return fabs(value-x)/error();}
00070 };
00071
00072 template <class charT, class traits, class T> inline
00073 std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits>& strm, const stats_t<T>& f)
00074 { strm << f() << "("<< f.error()<< ")"; return strm; }
00075
00076 #endif