X-Git-Url: http://git.treefish.org/~alex/phys/latlib.git/blobdiff_plain/2c7e8d0d8fdb233087376cc62752fdc45646c8c8..a5f05e337d18c193ac57b4da0013d1cdc69f8faa:/obstat.hpp diff --git a/obstat.hpp b/obstat.hpp new file mode 100644 index 0000000..d66467b --- /dev/null +++ b/obstat.hpp @@ -0,0 +1,128 @@ +#ifndef OBSTAT_HPP +#define OBSTAT_HPP + +#include +#include +#include +#include + +using namespace std; + +template +class obstat +{ +public: + void addMeas(const obstype& val); + void addMeas(obstype val[], int valsize); + + void computeEasy(const string& compid="one", const int& ival=0) { mean(compid, &measurements, ival); } + + void computeJack(const string& compid, double (*func)(vector< vector > *vals, void *para)=NULL, void *para=NULL); + void computeJack(double (*func)(vector< vector > *vals, void *para)=NULL, void *para=NULL) { computeJack("one",func,para); } + + double getMean(const string& compid="one") { return computations[compid].val; } + double getErr(const string& compid="one") { return computations[compid].err; } + + void reset(); + +private: + struct result{ + double val; + double err; + }; + + vector< vector > measurements; + map computations; + + void mean(const string& compid, vector< vector > *meas, const int& ival); + void mean(const string& compid, vector< vector > *meas, const int& ival); +}; + + +template +void obstat::reset() +{ + computations.clear(); + measurements.clear(); +} + +template +void obstat::addMeas(const obstype& val) +{ + measurements.push_back( vector(1,val) ); +} + +template +void obstat::addMeas(obstype val[], int valsize) +{ + vector tmpvec; + for(int i=0; i +void obstat::mean(const string& compid, vector< vector > *meas, const int& ival) +{ + computations[compid].val = 0; + computations[compid].err = 0; + + int nmeas = meas->size(); + + for(vector< vector >::iterator measIt = meas->begin(); measIt != meas->end(); ++measIt) + computations[compid].val += (*measIt)[ival]; + computations[compid].val /= nmeas; + + for(vector< vector >::iterator measIt = meas->begin(); measIt != meas->end(); ++measIt) + computations[compid].err += pow( (*measIt)[ival] - computations[compid].val, 2 ); + computations[compid].err = sqrt( computations[compid].err ) / nmeas; +} + +template +void obstat::mean(const string& compid, vector< vector > *meas, const int& ival) +{ + computations[compid].val = 0; + computations[compid].err = 0; + + int nmeas = meas->size(); + + for(vector< vector >::iterator measIt = meas->begin(); measIt != meas->end(); ++measIt) + computations[compid].val += (*measIt)[ival]; + computations[compid].val /= nmeas; + + for(vector< vector >::iterator measIt = meas->begin(); measIt != meas->end(); ++measIt) + computations[compid].err += pow( (*measIt)[ival] - computations[compid].val, 2 ); + computations[compid].err = sqrt( computations[compid].err ) / nmeas; +} + +template +void obstat::computeJack(const string& compid, double (*func)(vector< vector > *vals, void *para), void *para) +{ + int nmeas=measurements.size(); + double manymeans[nmeas]; + + computations[compid].val = 0; + computations[compid].err = 0; + + int imeas=0; + for(typename vector< vector >::iterator removedIt = measurements.begin(); removedIt != measurements.end(); ++removedIt, imeas++) + { + vector removed = *removedIt; + + *removedIt = measurements.back(); + measurements.pop_back(); + + manymeans[imeas] = func(&measurements, para); + computations[compid].val += manymeans[imeas]; + + measurements.push_back( *removedIt ); + *removedIt = removed; + } + computations[compid].val /= nmeas; + + for(int imean=0; imean