36 #ifndef VIGRA_HISTOGRAM_HXX 
   37 #define VIGRA_HISTOGRAM_HXX 
   40 #include "array_vector.hxx" 
   81         vigra_precondition(mi < ma,
 
   82             "HistogramOptions::setMinMax(): min < max required.");
 
   92         vigra_precondition(c > 0,
 
   93             "HistogramOptions::setBinCount(): binCount > 0 required.");
 
  102             "HistogramOptions::regionAutoInit(): you must not call setMinMax() when auto initialization is desired.");
 
  111             "HistogramOptions::globalAutoInit(): you must not call setMinMax() when auto initialization is desired.");
 
  124 template <
class DataType, 
class BinType>
 
  130     double scale_, scaleInverse_;
 
  133     HistogramView(DataType 
const & min, DataType 
const & max, 
int binCount, 
 
  134                   BinType * bins = 0, 
int stride = 1)
 
  139       scale_(double(binCount) / (max - min)),
 
  140       scaleInverse_(1.0 / scale_)
 
  143     HistogramView & setData(BinType * bins , 
int stride = 1)
 
  150     HistogramView & reset()
 
  153             for(
int k=0; k<size_; ++k)
 
  154                 *(bins_ +k*stride_) = BinType();
 
  158     void getBinCenters(ArrayVector<DataType> * centers)
 const 
  160         for(
int k=0; k < size_; ++k)
 
  162             (*centers)[k] = mapItemInverse(k + 0.5) ;
 
  176     BinType 
const & operator[](
int k)
 const 
  178         return *(bins_ + k*stride_);
 
  181     double mapItem(DataType 
const & d)
 const 
  183         return scale_ * (d - offset_);
 
  186     DataType mapItemInverse(
double d)
 const 
  188         return DataType(d * scaleInverse_ + offset_);
 
  191     void add(DataType 
const & d, BinType weight = NumericTraits<BinType>::one())
 
  193         get(int(mapItem(d))) += weight;
 
  198     BinType & 
get(
int index)
 
  204         return *(bins_ + index*stride_);
 
  209 class TrapezoidKernel
 
  212     typedef T value_type;
 
  214     T operator[](
double f)
 const 
  217             return 0.5*(f + 1.5);
 
  219             return 0.5*(1.5 - f);
 
  223     double radius()
 const 
  228     T findMaximum(
double l, 
double c, 
double r)
 const 
  230         double curv = -2.0*c + r + l;
 
  233         double extr = 0.5*(l-r) / curv;
 
  250     bool findMode(
double l, 
double c, 
double r, 
double * m)
 const 
  252         double curv = -2.0*c + r + l;
 
  255         *m = 0.5*(l-r) / curv;
 
  256         if(*m < -0.5 || *m > 0.5)
 
  262 template <
class DataType, 
class KernelType>
 
  263 class KernelHistogramView
 
  264 : 
public HistogramView<DataType, typename KernelType::value_type>
 
  271     typedef typename KernelType::value_type BinType;
 
  272     typedef HistogramView<DataType, BinType> BaseType;
 
  274     KernelHistogramView(DataType 
const & min, DataType 
const & max, 
int binCount, 
 
  275                         BinType * bins = 0, 
int stride = 1)
 
  276     : BaseType(min, max, binCount, bins, stride),
 
  277       radius_(kernel_.radius()-0.5) 
 
  280     void add(DataType 
const & d, BinType weight = NumericTraits<BinType>::one())
 
  282         double mapped = this->mapItem(d);
 
  283         double f = mapped - 
std::floor(mapped) - kernel_.radius();
 
  284         int center = int(mapped);
 
  286         for(
int k=center+radius_; k>=center-radius_; --k, f += 1.0)
 
  288             this->
get(k) += weight*kernel_[f];
 
  292     DataType findMode()
 const 
  294         double mmax = 0, vmax = 0, m;
 
  296         for(
int k=0; k<this->size(); ++k)
 
  301             double c = (*this)[k];
 
  302             double r = k < this->size() - 1
 
  305             if(kernel_.findMode(l, c, r, &m))
 
  307                 double v = l*kernel_[m+1.0] + c*kernel_[m] + r*kernel_[m-1.0];
 
  315         return this->mapItemInverse(mmax);
 
  318     template <
class Array>
 
  319     void findModes(Array * modes)
 
  322         for(
int k=0; k<this->size(); ++k)
 
  327             double c = (*this)[k];
 
  328             double r = k < this->size() - 1
 
  331             if(kernel_.findMode(l, c, r, &m))
 
  333                 double v = l*kernel_[m+1.0] + c*kernel_[m] + r*kernel_[m-1.0];
 
  334                 modes->push_back(std::make_pair(this->mapItemInverse(m + k + 0.5), v));
 
  340 template <
class DataType, 
class BinType>
 
  342 : 
public HistogramView<DataType, BinType>
 
  345     typedef HistogramView<DataType, BinType> BaseType;
 
  346     ArrayVector<BinType> data_;
 
  349     Histogram(DataType 
const & min, DataType 
const & max, 
int binCount, 
 
  350                   BinType *  = 0, 
int  = 1)
 
  351     : BaseType(min, max, binCount),
 
  354         this->setData(&data_[0]);
 
  357     Histogram 
const & reset()
 
  359         this->setData(&data_[0]);
 
  367 #endif // VIGRA_HISTOGRAM_HXX 
HistogramOptions & regionAutoInit()
Definition: histogram.hxx:99
HistogramOptions & setBinCount(int c)
Definition: histogram.hxx:90
HistogramOptions()
Definition: histogram.hxx:71
bool validMinMax() const 
Definition: histogram.hxx:118
int binCount
Total number of bins in the histogram. 
Definition: histogram.hxx:60
void add(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r, FixedPoint< IntBits3, FracBits3 > &result)
addition with enforced result type. 
Definition: fixedpoint.hxx:561
HistogramOptions & setMinMax(double mi, double ma)
Definition: histogram.hxx:79
HistogramOptions & globalAutoInit()
Definition: histogram.hxx:108
bool local_auto_init
If true, range mapping bounds are defined by minimum and maximum of the data. 
Definition: histogram.hxx:63
double maximum
Upper bound for linear range mapping from values to indices. 
Definition: histogram.hxx:57
int floor(FixedPoint< IntBits, FracBits > v)
rounding down. 
Definition: fixedpoint.hxx:667
double minimum
Lower bound for linear range mapping from values to indices. 
Definition: histogram.hxx:54
Set histogram options. 
Definition: histogram.hxx:49