00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <iostream>
00014 #include <iterator>
00015 #include <algorithm>
00016
00017 #include <vector>
00018 #include <list>
00019
00020 #include <stdexcept>
00021
00022 #include <cmath>
00023 #include <limits>
00024
00025
00026 #include "Fit/SparseData.h"
00027
00028 using namespace std;
00029
00030 namespace ROOT {
00031
00032 namespace Fit {
00033
00034
00035
00036 class Box
00037 {
00038 public:
00039
00040
00041 Box(const vector<double>& min, const vector<double>& max,
00042 const double value = 0.0, const double error = 1.0):
00043 fMin(min), fMax(max), fVal(value), fError(error)
00044 { }
00045
00046
00047
00048 bool operator==(const Box& b)
00049 { return (fMin == b.fMin) && (fMax == b.fMax)
00050 && (fVal == b.fVal) && (fError == b.fError); }
00051
00052
00053 const vector<double>& GetMin() const { return fMin; }
00054
00055 const vector<double>& GetMax() const { return fMax; }
00056
00057 double GetVal() const { return fVal; }
00058
00059 double GetError() const { return fError; }
00060
00061
00062 void AddVal(const double value) { fVal += value; }
00063
00064 friend class BoxContainer;
00065 friend ostream& operator <<(ostream& os, const Box& b);
00066
00067 private:
00068 vector<double> fMin;
00069 vector<double> fMax;
00070 double fVal;
00071 double fError;
00072 };
00073
00074
00075
00076
00077 class BoxContainer
00078 {
00079 private:
00080 const Box& fBox;
00081 public:
00082
00083
00084 BoxContainer(const Box& b): fBox(b) {}
00085
00086 bool operator() (const Box& b1)
00087 { return operator()(fBox, b1); }
00088
00089
00090 bool operator() (const Box& b1, const Box& b2)
00091 {
00092 bool isIn = true;
00093 vector<double>::const_iterator boxit = b2.fMin.begin();
00094 vector<double>::const_iterator bigit = b1.fMax.begin();
00095 while ( isIn && boxit != b2.fMin.end() )
00096 {
00097 if ( (*boxit) >= (*bigit) ) isIn = false;
00098 boxit++;
00099 bigit++;
00100 }
00101
00102 boxit = b2.fMax.begin();
00103 bigit = b1.fMin.begin();
00104 while ( isIn && boxit != b2.fMax.end() )
00105 {
00106 if ( (*boxit) <= (*bigit) ) isIn = false;
00107 boxit++;
00108 bigit++;
00109 }
00110
00111 return isIn;
00112 }
00113 };
00114
00115
00116
00117
00118 class AreaComparer
00119 {
00120 public:
00121 AreaComparer(vector<double>::iterator iter):
00122 fThereIsArea(true),
00123 fIter(iter),
00124 fLimit(8 * std::numeric_limits<double>::epsilon())
00125 {};
00126
00127 void operator() (double value)
00128 {
00129 if ( fabs(value- (*fIter)) < fLimit )
00130
00131 fThereIsArea = false;
00132
00133 fIter++;
00134 }
00135
00136 bool IsThereArea() { return fThereIsArea; }
00137
00138 private:
00139 bool fThereIsArea;
00140 vector<double>::iterator fIter;
00141 double fLimit;
00142 };
00143
00144
00145
00146
00147
00148
00149
00150
00151 void DivideBox( const vector<double>& min, const vector<double>& max,
00152 const vector<double>& bmin, const vector<double>& bmax,
00153 const unsigned int size, const unsigned int n,
00154 list<Box>& l, const double val, const double error)
00155 {
00156 vector<double> boxmin(min);
00157 vector<double> boxmax(max);
00158
00159 boxmin[n] = min[n];
00160 boxmax[n] = bmin[n];
00161 if ( for_each(boxmin.begin(), boxmin.end(), AreaComparer(boxmax.begin())).IsThereArea() )
00162 l.push_back(Box(boxmin, boxmax));
00163
00164 boxmin[n] = bmin[n];
00165 boxmax[n] = bmax[n];
00166 if ( n == 0 )
00167 {
00168 if ( for_each(boxmin.begin(), boxmin.end(), AreaComparer(boxmax.begin())).IsThereArea() )
00169 l.push_back(Box(boxmin, boxmax, val, error));
00170 }
00171 else
00172 DivideBox(boxmin, boxmax, bmin, bmax, size, n-1, l, val, error);
00173
00174 boxmin[n] = bmax[n];
00175 boxmax[n] = max[n];
00176 if ( for_each(boxmin.begin(), boxmin.end(), AreaComparer(boxmax.begin())).IsThereArea() )
00177 l.push_back(Box(boxmin, boxmax));
00178 }
00179
00180 class ProxyListBox
00181 {
00182 public:
00183 void PushBack(Box& box) { fProxy.push_back(box); }
00184 list<Box>::iterator Begin() { return fProxy.begin(); }
00185 list<Box>::iterator End() { return fProxy.end(); }
00186 void Remove(list<Box>::iterator it) { fProxy.erase(it); }
00187 list<Box>& GetList() { return fProxy; }
00188 private:
00189 list<Box> fProxy;
00190 };
00191
00192
00193 SparseData::SparseData(vector<double>& min, vector<double>& max)
00194 {
00195
00196
00197
00198 Box originalBox(min, max);
00199 fList = new ProxyListBox();
00200 fList->PushBack(originalBox);
00201 }
00202
00203 SparseData::SparseData(const unsigned int dim, double min[], double max[])
00204 {
00205
00206
00207
00208 vector<double> minv(min,min+dim);
00209 vector<double> maxv(max,max+dim);
00210 Box originalBox(minv, maxv);
00211 fList = new ProxyListBox();
00212 fList->PushBack(originalBox);
00213 }
00214
00215 SparseData::~SparseData()
00216 { delete fList; }
00217
00218 unsigned int SparseData::NPoints() const
00219 {
00220
00221 return fList->GetList().size();
00222 }
00223
00224 unsigned int SparseData::NDim() const
00225 {
00226
00227 return fList->Begin()->GetMin().size();
00228 }
00229
00230 void SparseData::Add(std::vector<double>& min, std::vector<double>& max,
00231 const double content, const double error)
00232 {
00233
00234
00235
00236
00237
00238 Box littleBox(min, max);
00239 list<Box>::iterator it;
00240
00241
00242 it = std::find_if(fList->Begin(), fList->End(), BoxContainer(littleBox));
00243 if ( it != fList->End() )
00244
00245 ;
00246 else {
00247 cout << "SparseData::Add -> FAILED! box not found! " << endl;
00248 cout << littleBox << endl;
00249 return;
00250
00251 }
00252
00253 if ( it->GetVal() )
00254 it->AddVal( content );
00255 else
00256 {
00257
00258 DivideBox(it->GetMin(), it->GetMax(),
00259 littleBox.GetMin(), littleBox.GetMax(),
00260 it->GetMin().size(), it->GetMin().size() - 1,
00261 fList->GetList(), content, error );
00262
00263 fList->Remove(it);
00264 }
00265 }
00266
00267 void SparseData::GetPoint(const unsigned int i,
00268 std::vector<double>& min, std::vector<double>&max,
00269 double& content, double& error)
00270 {
00271
00272
00273
00274 unsigned int counter = 0;
00275 list<Box>::iterator it = fList->Begin();
00276 while ( it != fList->End() && counter != i ) {
00277 ++it;
00278 ++counter;
00279 }
00280
00281 if ( (it == fList->End()) || (counter != i) )
00282 throw std::out_of_range("SparseData::GetPoint");
00283
00284 min = it->GetMin();
00285 max = it->GetMax();
00286 content = it->GetVal();
00287 error = it->GetError();
00288 }
00289
00290 void SparseData::PrintList() const
00291 {
00292
00293 copy(fList->Begin(), fList->End(), ostream_iterator<Box>(cout, "\n------\n"));
00294 }
00295
00296
00297 void SparseData::GetBinData(BinData& bd) const
00298 {
00299
00300
00301 list<Box>::iterator it = fList->Begin();
00302 const unsigned int dim = it->GetMin().size();
00303
00304 bd.Initialize(fList->GetList().size(), dim);
00305
00306 for ( ; it != fList->End(); ++it )
00307 {
00308 vector<double> mid(dim);
00309
00310 for ( unsigned int i = 0; i < dim; ++i)
00311 {
00312 mid[i] = ((it->GetMax()[i] - it->GetMin()[i]) /2) + it->GetMin()[i];
00313 }
00314
00315 bd.Add(&mid[0], it->GetVal(), it->GetError());
00316 }
00317 }
00318
00319 void SparseData::GetBinDataIntegral(BinData& bd) const
00320 {
00321
00322
00323
00324 list<Box>::iterator it = fList->Begin();
00325
00326 bd.Initialize(fList->GetList().size(), it->GetMin().size());
00327
00328 for ( ; it != fList->End(); ++it )
00329 {
00330
00331 bd.Add(&(it->GetMin()[0]), it->GetVal(), it->GetError());
00332
00333 bd.AddBinUpEdge(&(it->GetMax()[0]));
00334 }
00335 }
00336
00337 void SparseData::GetBinDataNoZeros(BinData& bd) const
00338 {
00339
00340
00341
00342 list<Box>::iterator it = fList->Begin();
00343 const unsigned int dim = it->GetMin().size();
00344
00345 bd.Initialize(fList->GetList().size(), dim);
00346
00347 for ( ; it != fList->End(); ++it )
00348 {
00349
00350 if ( it->GetVal() == 0 ) continue;
00351 vector<double> mid(dim);
00352
00353 for ( unsigned int i = 0; i < dim; ++i)
00354 {
00355 mid[i] = ((it->GetMax()[i] - it->GetMin()[i]) /2) + it->GetMin()[i];
00356 }
00357
00358 bd.Add(&mid[0], it->GetVal(), it->GetError());
00359 }
00360 }
00361
00362
00363 ostream& operator <<(ostream& os, const ROOT::Fit::Box& b)
00364 {
00365 os << "min: ";
00366 copy(b.GetMin().begin(), b.GetMin().end(), ostream_iterator<double>(os, " "));
00367 os << "max: ";
00368 copy(b.GetMax().begin(), b.GetMax().end(), ostream_iterator<double>(os, " "));
00369 os << "val: " << b.GetVal();
00370
00371 return os;
00372 }
00373 }
00374
00375 }