|
[yoda-svn] r250 - in trunk: include/YODA src testsblackhole at projects.hepforge.org blackhole at projects.hepforge.orgTue Aug 16 12:20:14 BST 2011
Author: mkawalec Date: Tue Aug 16 12:20:14 2011 New Revision: 250 Log: Refactored Bin2D to only hold a reasonable amount of points. Fixed bin merger algorithm. Fixed some minor bugs. Notice the 3-fold speed improvement resulting from smaller bins being moved around the memory. Modified: trunk/include/YODA/Axis2D.h trunk/include/YODA/Bin2D.h trunk/include/YODA/Histo2D.h trunk/src/Bin2D.cc trunk/tests/TestHisto2D.cc Modified: trunk/include/YODA/Axis2D.h ============================================================================== --- trunk/include/YODA/Axis2D.h Tue Aug 16 10:36:38 2011 (r249) +++ trunk/include/YODA/Axis2D.h Tue Aug 16 12:20:14 2011 (r250) @@ -8,6 +8,7 @@ #include "YODA/Utils/cachedvector.h" #include "YODA/Utils/MathUtils.h" #include "YODA/Dbn2D.h" + #include <string> #include <cassert> #include <cmath> @@ -143,8 +144,6 @@ { temp += bin(_binHashSparse.first[y].second[x].first); bin(_binHashSparse.first[y].second[x].first).isReal = false; - - /// @todo The bin that was just added must be changed to virtual! } } } @@ -162,7 +161,7 @@ /// inner subcaches and half of this amount in the outer (grid boundary) /// subcaches. This makes isGriddy() a very, very fast function. /// @todo Is the name appropriate? - int isGriddy() const + bool isGriddy() const { /// Check if the number of edges parallel to X axis @@ -171,11 +170,11 @@ for(unsigned int i=1; i < _binHashSparse.first.size(); i++) { if(i == _binHashSparse.first.size() - 1) { if(_binHashSparse.first[i].second.size() != sizeX) { - return -1; + return false; } } else if(_binHashSparse.first[i].second.size() != 2*sizeX) { - return -1; + return false; } } @@ -184,14 +183,14 @@ for(unsigned int i=1; i < _binHashSparse.second.size(); i++) { if(i!= _binHashSparse.second.size() - 1) { if(2*sizeY != _binHashSparse.second[i].second.size()) { - return -1; + return false; } } else if(_binHashSparse.second[i].second.size() != sizeY) return -1; } /// If everything is proper, announce it. - return 0; + return true; } /// Return a total number of bins in a Histo @@ -755,21 +754,22 @@ if(_bins[i].yMin() < lowEdgeY) lowEdgeY = _bins[i].yMin(); if(_bins[i].yMax() > highEdgeY) highEdgeY = _bins[i].yMax(); } - + + cout << "LowX: " << lowEdgeX << " LowY: " << lowEdgeY << " HighX: " << highEdgeX << " HighY: " << highEdgeY << endl; _lowEdgeX = lowEdgeX; _highEdgeX = highEdgeX; _lowEdgeY = lowEdgeY; _highEdgeY = highEdgeY; } - /// @brief BIn index finder + /// @brief Bin index finder /// Looks through all the bins to see which /// one contains the point of interest. int _findBinIndex(double coordX, double coordY) const { for(size_t i=0; i < _bins.size(); i++) { - if(_bins[i].lowEdgeX() <= coordX && _bins[i].highEdgeX() >= coordX && - _bins[i].lowEdgeY() <= coordY && _bins[i].highEdgeY() >= coordY && + if(_bins[i].xMin() <= coordX && _bins[i].xMax() >= coordX && + _bins[i].yMin() <= coordY && _bins[i].yMax() >= coordY && _bins[i].isReal) return i; } return -1; Modified: trunk/include/YODA/Bin2D.h ============================================================================== --- trunk/include/YODA/Bin2D.h Tue Aug 16 10:36:38 2011 (r249) +++ trunk/include/YODA/Bin2D.h Tue Aug 16 12:20:14 2011 (r250) @@ -49,7 +49,15 @@ /// @name Modifiers //@{ - const vector<Segment> edges() const { return _edges;} + const vector<Segment> edges() const { + vector<Segment> ret; + ret.push_back(make_pair(make_pair(xMin(), yMin()), make_pair(xMin(), yMax()))); + ret.push_back(make_pair(make_pair(xMin(), yMax()), make_pair(xMax(), yMax()))); + ret.push_back(make_pair(make_pair(xMax(), yMin()), make_pair(xMax(), yMax()))); + ret.push_back(make_pair(make_pair(xMin(), yMin()), make_pair(xMax(), yMin()))); + + return ret; + } /// Reset all bin data virtual void reset() { @@ -67,14 +75,14 @@ /// Get the low x edge of the bin. double lowEdgeX() const { - return _edges[0].first.first; + return _edges.first.first; } /// Synonym for lowEdgeX() double xMin() const { return lowEdgeX(); } /// Get the low y edge of the bin. double lowEdgeY() const { - return _edges[0].first.second; + return _edges.first.second; } /// Synonym for lowEdgeY() @@ -87,26 +95,26 @@ //@{ /// Get the high x edge of the bin. double highEdgeX() const { - return _edges[1].second.first; + return _edges.second.first; } /// Synonym for highEdgeX() double xMax() const { return highEdgeX(); } /// Get the high y edge of the bin. double highEdgeY() const { - return _edges[1].second.second; + return _edges.second.second; } /// Synonym for highEdgeY() double yMax() const { return highEdgeY(); } /// Width of the bin in y double widthY() const { - return _edges[0].second.second - _edges[0].first.second; + return yMax() - yMin(); } /// Width of the bin in x double widthX() const { - return _edges[1].second.first - _edges[0].first.first; + return _edges.second.first - _edges.first.first; } //@} @@ -219,15 +227,15 @@ Bin2D& subtract(const Bin2D& b); - std::vector<Segment> _edges; + Segment _edges; Dbn2D _dbn; /// Boundaries setter void _setBounds(double xMin, double yMin, double xMax, double yMax) { - _edges[0] = make_pair(make_pair(xMin, yMin), make_pair(xMin, yMax)); - _edges[1] = make_pair(make_pair(xMin, yMax), make_pair(xMax, yMax)); - _edges[2] = make_pair(make_pair(xMax, yMin), make_pair(xMax, yMax)); - _edges[3] = make_pair(make_pair(xMin, yMin), make_pair(xMax, yMin)); + _edges.first.first = xMin; + _edges.first.second = yMin; + _edges.second.first = xMax; + _edges.second.second = yMax; } }; Modified: trunk/include/YODA/Histo2D.h ============================================================================== --- trunk/include/YODA/Histo2D.h Tue Aug 16 10:36:38 2011 (r249) +++ trunk/include/YODA/Histo2D.h Tue Aug 16 12:20:14 2011 (r250) @@ -290,6 +290,8 @@ /// @todo Need to check that there is a continuous row for this y /// @todo Change the name! Histo1D cutterX(double atY, const std::string& path="", const std::string& title="") { + if(!_axis.isGriddy()) throw GridError("I cannot cut a Histo2D that is not a grid!"); + if (atY < lowEdgeY() || atY > highEdgeY()) throw RangeError("Y is outside the grid"); vector<HistoBin1D> tempBins; @@ -298,12 +300,11 @@ const Dbn1D dbn(first.numEntries(), first.sumW(), first.sumW2(), first.sumWX(), first.sumWX2()); tempBins.push_back(HistoBin1D(first.lowEdgeX(), first.highEdgeX(), dbn)); - for (double i = first.xMax() + first.widthX()/2; i < highEdgeX(); i += first.widthX()) { + for (double i = first.midpoint().first + first.widthX(); i < highEdgeX(); i += first.widthX()) { const HistoBin2D& b2 = binByCoord(i, atY); const Dbn1D dbn2(b2.numEntries(), b2.sumW(), b2.sumW2(), b2.sumWX(), b2.sumWX2()); tempBins.push_back(HistoBin1D(b2.lowEdgeX(), b2.highEdgeX(), dbn2)); } - /// @todo Think about the total, underflow and overflow distributions /// @todo Create total dbn from input bins return Histo1D(tempBins, Dbn1D(), Dbn1D(), Dbn1D(), path, title); @@ -317,6 +318,8 @@ /// @todo Need to check that there is a continuous column for this x /// @todo Change the name! Histo1D cutterY(double atX, const std::string& path="", const std::string& title="") { + if(!_axis.isGriddy()) throw GridError("I cannot cut a Histo2D that is not a grid!"); + if (atX < lowEdgeX() || atX > highEdgeX()) throw RangeError("X is outside the grid"); vector<HistoBin1D> tempBins; @@ -325,7 +328,7 @@ const Dbn1D dbn(first.numEntries(), first.sumW(), first.sumW2(), first.sumWX(), first.sumWX2()); tempBins.push_back(HistoBin1D(first.lowEdgeY(), first.highEdgeY(), dbn)); - for (double i = first.yMax() + first.widthY()/2; i < highEdgeY(); i += first.widthY()) { + for (double i = first.midpoint().second + first.widthY(); i < highEdgeY(); i += first.widthY()) { const HistoBin2D& b2 = binByCoord(atX, i); const Dbn1D dbn2(b2.numEntries(), b2.sumW(), b2.sumW2(), b2.sumWX(), b2.sumWX2()); tempBins.push_back(HistoBin1D(b2.lowEdgeY(), b2.highEdgeY(), dbn2)); Modified: trunk/src/Bin2D.cc ============================================================================== --- trunk/src/Bin2D.cc Tue Aug 16 10:36:38 2011 (r249) +++ trunk/src/Bin2D.cc Tue Aug 16 12:20:14 2011 (r250) @@ -1,5 +1,6 @@ #include "YODA/Bin2D.h" #include "YODA/HistoBin1D.h" +#include "YODA/Exceptions.h" #include <cassert> #include <cmath> @@ -11,51 +12,41 @@ namespace YODA { Bin2D::Bin2D(double lowedgeX, double lowedgeY, double highedgeX, double highedgeY) { - assert(lowedgeX <= highedgeX && lowedgeY <= highedgeY); + if(lowedgeX > highedgeX || lowedgeY > highedgeY) throw RangeError("The bins are wrongly defined!"); - /// @todo Why store with so much redundancy? - pair<pair<double,double>, pair<double,double> > edge1 = - make_pair(make_pair(lowedgeX, lowedgeY), make_pair(lowedgeX, highedgeY)); - pair<pair<double,double>, pair<double,double> > edge2 = - make_pair(make_pair(lowedgeX, highedgeY), make_pair(highedgeX, highedgeY)); - pair<pair<double,double>, pair<double,double> > edge3 = - make_pair(make_pair(highedgeX, lowedgeY), make_pair(highedgeX, highedgeY)); - pair<pair<double,double>, pair<double,double> > edge4 = - make_pair(make_pair(lowedgeX, lowedgeY), make_pair(highedgeX, lowedgeY)); - - _edges.push_back(edge1); - _edges.push_back(edge2); - _edges.push_back(edge3); - _edges.push_back(edge4); + _edges.first.first = lowedgeX; + _edges.first.second = lowedgeY; + _edges.second.first = highedgeX; + _edges.second.second = highedgeY; isReal = true; } Bin2D::Bin2D(std::vector<std::pair<std::pair<double,double>, std::pair<double,double> > > edges) { - assert(edges.size() == 4); - _edges.push_back(edges[0]); - _edges.push_back(edges[1]); - _edges.push_back(edges[2]); - _edges.push_back(edges[3]); + if(edges.size() != 4) throw RangeError("The edge vector does not define a full rectangle!"); + + _edges.first.first = edges[0].first.first; + _edges.first.second = edges[0].first.second; + _edges.second.first = edges[1].second.first; + _edges.second.second = edges[1].second.second; isReal = true; } - void Bin2D::scaleXY(double scaleX, double scaleY) { - for (size_t i = 0; i < _edges.size(); ++i) { - _edges[i].first.first *= scaleX; - _edges[i].second.first *= scaleX; - _edges[i].first.second *= scaleY; - _edges[i].second.second *= scaleY; - } + _edges.first.first *= scaleX; + _edges.second.first *= scaleX; + + _edges.first.second *= scaleY; + _edges.second.second *= scaleY; + _dbn.scaleXY(scaleX, scaleY); } std::pair<double,double> Bin2D::midpoint() const { return make_pair((double)(xMax() - xMin())/2 + xMin(), (double)(yMax() - yMin())/2 + yMin()); - } + } Bin2D& Bin2D::subtract(const Bin2D& b) { /// Automatically resize if adding a bin that does not have the same location Modified: trunk/tests/TestHisto2D.cc ============================================================================== --- trunk/tests/TestHisto2D.cc Tue Aug 16 10:36:38 2011 (r249) +++ trunk/tests/TestHisto2D.cc Tue Aug 16 12:20:14 2011 (r250) @@ -46,7 +46,6 @@ cout << "Time to create 40K bins: " << tE - tS << "s" << endl; printStats(h); - h.mergeBins(1, 100); cout << h.numBinsTotal() << endl; h.addBin(0.1, 0.1, 0.2, 0.2); @@ -162,16 +161,20 @@ } /// Addition/Subtraction: - Histo2D first(100, 0, 100, 100, 0, 100); + cout << "Creating histos to be added/substracted/divided:" << endl; + + Histo2D first(10, 0, 100, 10, 0, 100); first.fill(1,1,1); first.fill(23,1,1); - Histo2D second(100, 0, 100, 100, 0, 100); + Histo2D second(10, 0, 100, 10, 0, 100); second.fill(1,1,1); + cout << "Adding/Substracting/Dividing" << endl; Histo2D added(first+second); Histo2D subtracted(first-second); Scatter3D divided(first/second); + cout << "Done!" << endl; printStats(added); printStats(subtracted); @@ -188,12 +191,12 @@ return -1; } if(!fuzzyEquals(sampleHisto.sumW2(false), 1.51588e+10)) { - cout << "Something is wrong with weight squared!" << endl; + cout << "Something is wrong with weight squared! It is: " << sampleHisto.sumW2(false)<< endl; return -1; } Histo1D atY(sampleHisto.cutterX(0)); - cout << atY.sumW(false) << " " <<atY.numBins() << endl; + cout << atY.sumW(false) << " " <<sampleHisto.sumW(false) << endl; if(!fuzzyEquals(atY.sumW(false), sampleHisto.sumW(false))){ cout << "Something is wrong with weights when cut parallell to X axis." << endl; return -1; @@ -214,5 +217,14 @@ return -1; } + cout << "Testing bin merger:" << endl; + gettimeofday(&startTime, NULL); + h.mergeBins(0, 20000); + gettimeofday(&endTime, NULL); + tS = (startTime.tv_sec*1000000 + startTime.tv_usec)/(double)1000000; + tE = (endTime.tv_sec*1000000 + endTime.tv_usec)/(double)1000000; + + cout << "Time to merge 20k bins: " << tE - tS << "s" << endl; + return EXIT_SUCCESS; }
More information about the yoda-svn mailing list |