00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef OPENMS_MATH_STATISTICS_HISTOGRAM_H
00028 #define OPENMS_MATH_STATISTICS_HISTOGRAM_H
00029
00030
00031 #include <OpenMS/CONCEPT/Types.h>
00032 #include <OpenMS/CONCEPT/Exception.h>
00033
00034
00035 #include <vector>
00036 #include <cmath>
00037 #include <limits>
00038 #include <iostream>
00039
00040 namespace OpenMS
00041 {
00042 namespace Math
00043 {
00044
00054 template<typename ValueType=UInt, typename BinSizeType=Real>
00055 class Histogram
00056 {
00057 public:
00058
00060 typedef typename std::vector<ValueType>::const_iterator ConstIterator;
00061
00065
00066 Histogram()
00067 : min_(0),
00068 max_(0),
00069 bin_size_(0)
00070 {
00071 }
00072
00074 Histogram(const Histogram& histogram)
00075 : min_(histogram.min_),
00076 max_(histogram.max_),
00077 bin_size_(histogram.bin_size_),
00078 bins_(histogram.bins_)
00079 {
00080 }
00081
00083 Histogram(BinSizeType min, BinSizeType max, BinSizeType bin_size) throw(Exception::OutOfRange)
00084 : min_(min),
00085 max_(max),
00086 bin_size_(bin_size)
00087 {
00088 if (bin_size_ <= 0)
00089 {
00090 throw(Exception::OutOfRange(__FILE__, __LINE__, __PRETTY_FUNCTION__));
00091 }
00092 else
00093 {
00094
00095 if (max_ != min_)
00096 {
00097 bins_ = std::vector<ValueType>(UInt(ceil((double(max_)-double(min_))/double(bin_size_))),0);
00098 }
00099 else
00100 {
00101 bins_ = std::vector<ValueType>(1, 0);
00102 }
00103 }
00104 }
00105
00107 ~Histogram()
00108 {
00109 }
00111
00113 BinSizeType min() const
00114 {
00115 return min_;
00116 }
00117
00119 BinSizeType max() const
00120 {
00121 return max_;
00122 }
00123
00125 ValueType maxValue() const
00126 {
00127 return *(std::max_element(bins_.begin(), bins_.end()));
00128 }
00129
00131 ValueType minValue() const
00132 {
00133 return *(std::min_element(bins_.begin(), bins_.end()));
00134 }
00135
00137 BinSizeType binSize() const
00138 {
00139 return bin_size_;
00140 }
00141
00143 UInt size() const
00144 {
00145 return bins_.size();
00146 }
00147
00149 ValueType operator [] (UInt index) const throw(Exception::IndexOverflow)
00150 {
00151 if (index >= bins_.size())
00152 {
00153 throw Exception::IndexOverflow(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00154 }
00155 return bins_[index];
00156 }
00157
00159 BinSizeType centerOfBin(UInt bin_index) const throw(Exception::IndexOverflow)
00160 {
00161 if (bin_index >= bins_.size())
00162 {
00163 throw Exception::IndexOverflow(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00164 }
00165
00166 return min_+((BinSizeType)bin_index+0.5)*bin_size_;
00167 }
00168
00170 ValueType binValue(BinSizeType val) const throw(Exception::OutOfRange)
00171 {
00172 return bins_[valToBin_(val)];
00173 }
00174
00176 void inc(BinSizeType val, ValueType increment=1) throw(Exception::OutOfRange)
00177 {
00178 bins_[valToBin_(val)]+=increment;
00179 }
00180
00182 void reset(BinSizeType min, BinSizeType max, BinSizeType bin_size) throw(Exception::OutOfRange)
00183 {
00184 if (bin_size <= 0)
00185 {
00186 throw Exception::OutOfRange(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00187 }
00188 else
00189 {
00190 min_ = min;
00191 max_ = max;
00192 bin_size_ = bin_size;
00193
00194 bins_.clear();
00195 bins_.resize(UInt(ceil((max_-min_)/bin_size_)),0);
00196 }
00197 }
00198
00202
00203 bool operator == (const Histogram& histogram) const
00204 {
00205 return (min_ == histogram.min_ &&
00206 max_ == histogram.max_ &&
00207 bin_size_ == histogram.bin_size_ &&
00208 bins_ == histogram.bins_);
00209 }
00210
00212 bool operator != (const Histogram& histogram) const
00213 {
00214 return !operator==(histogram);
00215 }
00216
00218 Histogram& operator = (const Histogram& histogram)
00219 {
00220 if (&histogram == this) return *this;
00221
00222 min_ = histogram.min_;
00223 max_ = histogram.max_;
00224 bin_size_ = histogram.bin_size_;
00225 bins_ = histogram.bins_;
00226
00227 return *this;
00228 }
00230
00234
00235 inline ConstIterator begin() const { return bins_.begin(); }
00236
00238 inline ConstIterator end() const { return bins_.end(); }
00240
00242 void applyLogTransformation(Real multiplier)
00243 {
00244 for (typename std::vector<ValueType>::iterator it = bins_.begin(); it!=bins_.end(); ++it)
00245 {
00246 *it = (ValueType)(multiplier*log((Real)(*it+1.0f)));
00247 }
00248 }
00249
00250 protected:
00252 BinSizeType min_;
00254 BinSizeType max_;
00256 BinSizeType bin_size_;
00258 std::vector<ValueType> bins_;
00260 UInt valToBin_(BinSizeType val) const throw (Exception::OutOfRange)
00261 {
00262 if (val < min_ || val > max_)
00263 {
00264 throw Exception::OutOfRange(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00265 }
00266 if (val == max_)
00267 {
00268 return (bins_.size()-1);
00269 }
00270 else
00271 {
00272 return (UInt) floor ( (double(val)-double(min_)) / (double(max_)-double(min_)) * bins_.size() );
00273 }
00274 }
00275 };
00276
00278 template<typename ValueType, typename BinSizeType>
00279 std::ostream& operator << (std::ostream& os, const Histogram<ValueType,BinSizeType>& hist)
00280 {
00281 for(UInt i=0; i<hist.size(); ++i)
00282 {
00283 os << hist.centerOfBin(i) << " " << hist[i] << std::endl;
00284 }
00285 return os;
00286 }
00287
00288 }
00289
00290 }
00291
00292 #endif // OPENMS_MATH_STATISTICS_HISTOGRAM_H