ROOT   Reference Guide
SparseData.cxx
Go to the documentation of this file.
1// @(#)root/mathcore:$Id$
2// Author: David Gonzalez Maline Wed Aug 28 15:33:03 2009
3
4/**********************************************************************
5 * *
6 * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7 * *
8 * *
9 **********************************************************************/
10
11// Implementation file for class BinData
12
13#include <iostream>
14#include <iterator>
15#include <algorithm>
16
17#include <vector>
18#include <list>
19
20#include <stdexcept>
21
22#include <cmath>
23#include <limits>
24
25#include "Fit/BinData.h"
26#include "Fit/SparseData.h"
27
28using namespace std;
29
30namespace ROOT {
31
32 namespace Fit {
33
34 //This class is a helper. It represents a bin in N
35 //dimensions. The change in the name is to avoid name collision.
36 class Box
37 {
38 public:
39 // Creates a Box with limits specified by the vectors and
40 // content=value and error=error
41 Box(const vector<double>& min, const vector<double>& max,
42 const double value = 0.0, const double error = 1.0):
43 fMin(min), fMax(max), fVal(value), fError(error)
44 { }
45
46 // Compares to Boxes to see if they are equal in all its
47 // variables. This is to be used by the std::find algorithm
48 bool operator==(const Box& b)
49 { return (fMin == b.fMin) && (fMax == b.fMax)
50 && (fVal == b.fVal) && (fError == b.fError); }
51
52 // Get the list of minimum coordinates
53 const vector<double>& GetMin() const { return fMin; }
54 // Get the list of maximum coordinates
55 const vector<double>& GetMax() const { return fMax; }
56 // Get the value of the Box
57 double GetVal() const { return fVal; }
58 // Get the error of the Box
59 double GetError() const { return fError; }
60
61 // Add an amount to the content of the Box
62 void AddVal(const double value) { fVal += value; }
63
64 friend class BoxContainer;
65 friend ostream& operator <<(ostream& os, const Box& b);
66
67 private:
68 vector<double> fMin;
69 vector<double> fMax;
70 double fVal;
71 double fError;
72 };
73
74 // This class is just a helper to be used in std::for_each to
75 // simplify the code later. It's just a definition of a method
76 // that will discern whether a Box is included into another one
78 {
79 private:
80 const Box& fBox;
81 public:
82 //Constructs the BoxContainer object with a Box that is meant
83 //to include another one that will be provided later
84 BoxContainer(const Box& b): fBox(b) {}
85
86 bool operator() (const Box& b1)
87 { return operator()(fBox, b1); }
88
89 // Looks if b2 is included in b1
90 bool operator() (const Box& b1, const Box& b2)
91 {
92 bool isIn = true;
93 vector<double>::const_iterator boxit = b2.fMin.begin();
94 vector<double>::const_iterator bigit = b1.fMax.begin();
95 while ( isIn && boxit != b2.fMin.end() )
96 {
97 if ( (*boxit) >= (*bigit) ) isIn = false;
98 ++boxit;
99 ++bigit;
100 }
101
102 boxit = b2.fMax.begin();
103 bigit = b1.fMin.begin();
104 while ( isIn && boxit != b2.fMax.end() )
105 {
106 if ( (*boxit) <= (*bigit) ) isIn = false;
107 ++boxit;
108 ++bigit;
109 }
110
111 return isIn;
112 }
113 };
114
115 // Another helper class to be used in std::for_each to simplify
116 // the code later. It implements the operator() to know if a
117 // specified Box is big enough to contain any 'space' inside.
119 {
120 public:
121 AreaComparer(vector<double>::iterator iter):
122 fThereIsArea(true),
123 fIter(iter),
124 fLimit(8 * std::numeric_limits<double>::epsilon())
125 {};
126
127 void operator() (double value)
128 {
129 if ( fabs(value- (*fIter)) < fLimit )
130// if ( TMath::AreEqualRel(value, (*fIter), fLimit) )
131 fThereIsArea = false;
132
133 ++fIter;
134 }
135
136 bool IsThereArea() { return fThereIsArea; }
137
138 private:
140 vector<double>::iterator fIter;
141 double fLimit;
142 };
143
144
145 // This is the key of the SparseData structure. This method
146 // will, by recursion, divide the area passed as an argument in
147 // min and max into pieces to insert the Box defined by bmin and
148 // bmax. It will do so from the highest dimension until it gets
149 // to 1 and create the corresponding boxes to divide the
150 // original space.
151 void DivideBox( const vector<double>& min, const vector<double>& max,
152 const vector<double>& bmin, const vector<double>& bmax,
153 const unsigned int size, const unsigned int n,
154 list<Box>& l, const double val, const double error)
155 {
156 vector<double> boxmin(min);
157 vector<double> boxmax(max);
158
159 boxmin[n] = min[n];
160 boxmax[n] = bmin[n];
161 if ( for_each(boxmin.begin(), boxmin.end(), AreaComparer(boxmax.begin())).IsThereArea() )
162 l.push_back(Box(boxmin, boxmax));
163
164 boxmin[n] = bmin[n];
165 boxmax[n] = bmax[n];
166 if ( n == 0 )
167 {
168 if ( for_each(boxmin.begin(), boxmin.end(), AreaComparer(boxmax.begin())).IsThereArea() )
169 l.push_back(Box(boxmin, boxmax, val, error));
170 }
171 else
172 DivideBox(boxmin, boxmax, bmin, bmax, size, n-1, l, val, error);
173
174 boxmin[n] = bmax[n];
175 boxmax[n] = max[n];
176 if ( for_each(boxmin.begin(), boxmin.end(), AreaComparer(boxmax.begin())).IsThereArea() )
177 l.push_back(Box(boxmin, boxmax));
178 }
179
181 {
182 public:
183 void PushBack(Box& box) { fProxy.push_back(box); }
184 list<Box>::iterator Begin() { return fProxy.begin(); }
185 list<Box>::iterator End() { return fProxy.end(); }
186 void Remove(list<Box>::iterator it) { fProxy.erase(it); }
187 list<Box>& GetList() { return fProxy; }
188 private:
189 list<Box> fProxy;
190 };
191
192
193 SparseData::SparseData(vector<double>& min, vector<double>& max)
194 {
195 // Creates a SparseData covering the range defined by min
196 // and max. For this it will create an empty Box for that
197 // range.
198 Box originalBox(min, max);
199 fList = std::make_unique<ProxyListBox>();
200 fList->PushBack(originalBox);
201 }
202
203 SparseData::SparseData(const unsigned int dim, double min[], double max[])
204 {
205 // Creates a SparseData covering the range defined by min
206 // and max. For this it will create an empty Box for that
207 // range.
208 vector<double> minv(min,min+dim);
209 vector<double> maxv(max,max+dim);
210 Box originalBox(minv, maxv);
211 fList = std::make_unique<ProxyListBox>();
212 fList->PushBack(originalBox);
213 }
214
216 FitData(rhs)
217 {
218 fList = std::make_unique<ProxyListBox>(*rhs.fList);
219 }
221 {
222 FitData::operator=( rhs );
223 fList = std::make_unique<ProxyListBox>(*rhs.fList);
224 return *this;
225 }
226
228
229 unsigned int SparseData::NPoints() const
230 {
231 // Returns the number of points stored, including the 0 ones.
232 return fList->GetList().size();
233 }
234
235 unsigned int SparseData::NDim() const
236 {
237 // Returns the number of dimension of the SparseData object.
238 return fList->Begin()->GetMin().size();
239 }
240
241 void SparseData::Add(std::vector<double>& min, std::vector<double>& max,
242 const double content, const double error)
243 {
244 // Add a box to the stored ones. For that, it will look for
245 // the box that contains the new data and either replace it
246 // or updated it.
247
248 // Little box is the new Bin to be added
249 Box littleBox(min, max);
250 list<Box>::iterator it;
251 // So we look for the Bin already in the list that contains
252 // littleBox
253 it = std::find_if(fList->Begin(), fList->End(), BoxContainer(littleBox));
254 if ( it != fList->End() )
255// cout << "Found: " << *it << endl;
256 ;
257 else {
258 cout << "SparseData::Add -> FAILED! box not found! " << endl;
259 cout << littleBox << endl;
260 return; // Does not add the box, as it is part of the
261 // underflow/overflow bin
262 }
263 // If it happens to have a value, then we add the value,
264 if ( it->GetVal() )
265 it->AddVal( content );
266 else
267 {
268 // otherwise, we divide the container!
269 DivideBox(it->GetMin(), it->GetMax(),
270 littleBox.GetMin(), littleBox.GetMax(),
271 it->GetMin().size(), it->GetMin().size() - 1,
272 fList->GetList(), content, error );
273 // and remove it from the list
274 fList->Remove(it);
275 }
276 }
277
278 void SparseData::GetPoint(const unsigned int i,
279 std::vector<double>& min, std::vector<double>&max,
280 double& content, double& error)
281 {
282 // Get the point number i. This is a method to explore the
283 // data stored in the class.
284
285 unsigned int counter = 0;
286 list<Box>::iterator it = fList->Begin();
287 while ( it != fList->End() && counter != i ) {
288 ++it;
289 ++counter;
290 }
291
292 if ( (it == fList->End()) || (counter != i) )
293 throw std::out_of_range("SparseData::GetPoint");
294
295 min = it->GetMin();
296 max = it->GetMax();
297 content = it->GetVal();
298 error = it->GetError();
299 }
300
302 {
303 // Debug method to print a list with all the data stored.
304 copy(fList->Begin(), fList->End(), ostream_iterator<Box>(cout, "\n------\n"));
305 }
306
307
309 {
310 // Created the corresponding BinData
311
312 list<Box>::iterator it = fList->Begin();
313 const unsigned int dim = it->GetMin().size();
314
315 bd.Initialize(fList->GetList().size(), dim);
316 // Visit all the stored Boxes
317 for ( ; it != fList->End(); ++it )
318 {
319 vector<double> mid(dim);
320 // fill up the vector with the mid point of the Bin
321 for ( unsigned int i = 0; i < dim; ++i)
322 {
323 mid[i] = ((it->GetMax()[i] - it->GetMin()[i]) /2) + it->GetMin()[i];
324 }
325 // And store it into the BinData structure
326 bd.Add(&mid[0], it->GetVal(), it->GetError());
327 }
328 }
329
331 {
332 // Created the corresponding BinData as with the Integral
333 // option.
334
335 list<Box>::iterator it = fList->Begin();
336
337 bd.Initialize(fList->GetList().size(), it->GetMin().size());
338 // Visit all the stored Boxes
339 for ( ; it != fList->End(); ++it )
340 {
341 //Store the minimum value
342 bd.Add(&(it->GetMin()[0]), it->GetVal(), it->GetError());
343 //and the maximum
345 }
346 }
347
349 {
350 // Created the corresponding BinData, but it does not include
351 // all the data with value equal to 0.
352
353 list<Box>::iterator it = fList->Begin();
354 const unsigned int dim = it->GetMin().size();
355
356 bd.Initialize(fList->GetList().size(), dim);
357 // Visit all the stored Boxes
358 for ( ; it != fList->End(); ++it )
359 {
360 // if the value is zero, jump to the next
361 if ( it->GetVal() == 0 ) continue;
362 vector<double> mid(dim);
363 // fill up the vector with the mid point of the Bin
364 for ( unsigned int i = 0; i < dim; ++i)
365 {
366 mid[i] = ((it->GetMax()[i] - it->GetMin()[i]) /2) + it->GetMin()[i];
367 }
368 // And store it into the BinData structure
369 bd.Add(&mid[0], it->GetVal(), it->GetError());
370 }
371 }
372
373 // Just for debugging pourposes
374 ostream& operator <<(ostream& os, const ROOT::Fit::Box& b)
375 {
376 os << "min: ";
377 copy(b.GetMin().begin(), b.GetMin().end(), ostream_iterator<double>(os, " "));
378 os << "max: ";
379 copy(b.GetMax().begin(), b.GetMax().end(), ostream_iterator<double>(os, " "));
380 os << "val: " << b.GetVal();
381
382 return os;
383 }
384 } // end namespace Fit
385
386} // end namespace ROOT
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
void operator()(double value)
Definition: SparseData.cxx:127
AreaComparer(vector< double >::iterator iter)
Definition: SparseData.cxx:121
vector< double >::iterator fIter
Definition: SparseData.cxx:140
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition: BinData.h:52
void AddBinUpEdge(const double *xup)
add the bin width data, a pointer to an array with the bin upper edge information.
Definition: BinData.cxx:615
void Add(double x, double y)
add one dim data with only coordinate and values
Definition: BinData.cxx:410
void Initialize(unsigned int newPoints, unsigned int dim=1, ErrorType err=kValueError)
Preallocate a data set with given size, dimension and error type.
Definition: BinData.h:122
bool operator()(const Box &b1)
Definition: SparseData.cxx:86
BoxContainer(const Box &b)
Definition: SparseData.cxx:84
vector< double > fMin
Definition: SparseData.cxx:68
vector< double > fMax
Definition: SparseData.cxx:69
const vector< double > & GetMax() const
Definition: SparseData.cxx:55
void AddVal(const double value)
Definition: SparseData.cxx:62
friend ostream & operator<<(ostream &os, const Box &b)
Definition: SparseData.cxx:374
double GetVal() const
Definition: SparseData.cxx:57
bool operator==(const Box &b)
Definition: SparseData.cxx:48
Box(const vector< double > &min, const vector< double > &max, const double value=0.0, const double error=1.0)
Definition: SparseData.cxx:41
const vector< double > & GetMin() const
Definition: SparseData.cxx:53
double GetError() const
Definition: SparseData.cxx:59
Base class for all the fit data types: Stores the coordinates and the DataOptions.
Definition: FitData.h:56
FitData & operator=(const FitData &rhs)
Definition: FitData.cxx:218
list< Box >::iterator Begin()
Definition: SparseData.cxx:184
void PushBack(Box &box)
Definition: SparseData.cxx:183
void Remove(list< Box >::iterator it)
Definition: SparseData.cxx:186
list< Box > & GetList()
Definition: SparseData.cxx:187
list< Box >::iterator End()
Definition: SparseData.cxx:185
SparseData class representing the data of a THNSparse histogram The data needs to be converted to a B...
Definition: SparseData.h:35
std::unique_ptr< ProxyListBox > fList
Definition: SparseData.h:76
void Add(std::vector< double > &min, std::vector< double > &max, const double content, const double error=1.0)
Adds a new bin specified by the vectors.
Definition: SparseData.cxx:241
unsigned int NDim() const
Returns the dimension of the object (bins)
Definition: SparseData.cxx:235
void GetPoint(const unsigned int i, std::vector< double > &min, std::vector< double > &max, double &content, double &error)
Definition: SparseData.cxx:278
unsigned int NPoints() const
Returns the number of points stored.
Definition: SparseData.cxx:229
void GetBinDataNoZeros(BinData &) const
Same as before, but including zero content bins.
Definition: SparseData.cxx:348
SparseData & operator=(const SparseData &rhs)
Assignment operator.
Definition: SparseData.cxx:220
void PrintList() const
Debug method to print the list of bins stored.
Definition: SparseData.cxx:301
void GetBinData(BinData &) const
Transforms the data into a ROOT::Fit::BinData structure.
Definition: SparseData.cxx:308
SparseData(std::vector< double > &min, std::vector< double > &max)
Constructor with a vector.
Definition: SparseData.cxx:193
~SparseData() override
Destructor.
Definition: SparseData.cxx:227
void GetBinDataIntegral(BinData &) const
Same as before, but returning a BinData with integral format (containing bin edges)
Definition: SparseData.cxx:330
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: fillpatterns.C:1
const Int_t n
Definition: legend1.C:16
TFitResultPtr Fit(FitObject *h1, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption, const char *goption, ROOT::Fit::DataRange &range)
Definition: HFitImpl.cxx:133
void DivideBox(const vector< double > &min, const vector< double > &max, const vector< double > &bmin, const vector< double > &bmax, const unsigned int size, const unsigned int n, list< Box > &l, const double val, const double error)
Definition: SparseData.cxx:151
ostream & operator<<(ostream &os, const ROOT::Fit::Box &b)
Definition: SparseData.cxx:374
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
TLine l
Definition: textangle.C:4
double epsilon
Definition: triangle.c:618