|
[Rivet-svn] r2029 - in trunk: . include/Rivetblackhole at projects.hepforge.org blackhole at projects.hepforge.orgFri Nov 6 01:46:46 GMT 2009
Author: buckley Date: Fri Nov 6 01:46:46 2009 New Revision: 2029 Log: Adding Cmp<double> template specialisation, using fuzzyEquals() Modified: trunk/ChangeLog trunk/include/Rivet/Cmp.hh Modified: trunk/ChangeLog ============================================================================== --- trunk/ChangeLog Fri Nov 6 01:46:10 2009 (r2028) +++ trunk/ChangeLog Fri Nov 6 01:46:46 2009 (r2029) @@ -1,3 +1,7 @@ +2009-11-06 Andy Buckley <andy at insectnation.org> + + * Adding Cmp<double> specialisation, using fuzzyEquals(). + 2009-11-05 Hendrik Hoeth <hendrik.hoeth at cern.ch> * Fixing histogram division code. Modified: trunk/include/Rivet/Cmp.hh ============================================================================== --- trunk/include/Rivet/Cmp.hh Fri Nov 6 01:46:10 2009 (r2028) +++ trunk/include/Rivet/Cmp.hh Fri Nov 6 01:46:46 2009 (r2029) @@ -39,12 +39,12 @@ //@{ /// The default constructor. Cmp(const T& t1, const T& t2) - : value(UNDEFINED), objects(&t1, &t2) { } + : _value(UNDEFINED), _objects(&t1, &t2) { } /// The copy constructor. template <typename U> Cmp(const Cmp<U>& x) - : value(x.operator int()), objects(0, 0) { } + : _value(x.operator int()), _objects(0, 0) { } /// The destructor is not virtual since this is not intended to be a base class. ~Cmp() { }; @@ -52,7 +52,7 @@ /// The assignment operator. template <typename U> const Cmp<T>& operator=(const Cmp<U>& x) { - value = x.operator int(); + _value = x.operator int(); return *this; } //@} @@ -61,15 +61,15 @@ /// Automatically convert to an integer. operator int() const { - compare(); - return value; + _compare(); + return _value; } /// If this state is equivalent, set this state to the state of \a c. template <typename U> const Cmp<T>& operator||(const Cmp<U>& c) const { - compare(); - if ( value == EQUIVALENT ) value = c.operator int(); + _compare(); + if (_value == EQUIVALENT) _value = c.operator int(); return *this; } @@ -77,20 +77,20 @@ private: /// Perform the actual comparison if necessary. - void compare() const { - if ( value == UNDEFINED ) { + void _compare() const { + if (_value == UNDEFINED) { less<T> l; - if ( l(*objects.first, *objects.second) ) value = ORDERED; - else if ( l(*objects.second, *objects.first) ) value = UNORDERED; - else value = EQUIVALENT; + if ( l(*_objects.first, *_objects.second) ) _value = ORDERED; + else if ( l(*_objects.second, *_objects.first) ) _value = UNORDERED; + else _value = EQUIVALENT; } } /// The state of this object. - mutable int value; + mutable int _value; /// The objects to be compared. - pair<const T*, const T*> objects; + pair<const T*, const T*> _objects; }; @@ -126,12 +126,14 @@ //@{ /// The default constructor. Cmp(const Projection& p1, const Projection& p2) - : value(UNDEFINED), objects(&p1, &p2) { } + : _value(UNDEFINED), _objects(&p1, &p2) + { } /// The copy constructor. template <typename U> Cmp(const Cmp<U>& x) - : value(x.operator int()), objects(0, 0) { } + : _value(x.operator int()), _objects(0, 0) + { } /// The destructor is not virtual since this is not intended to be a base class. ~Cmp() { }; @@ -139,7 +141,7 @@ /// The assignment operator. template <typename U> const Cmp<Projection>& operator=(const Cmp<U>& x) { - value = x.operator int(); + _value = x.operator int(); return *this; } //@} @@ -148,32 +150,32 @@ /// Automatically convert to an integer. operator int() const { - compare(); - return value; + _compare(); + return _value; } - /// If this state is equaivalent, set this state to the state of \a c. + /// If this state is equivalent, set this state to the state of \a c. template <typename U> const Cmp<Projection>& operator||(const Cmp<U>& c) const { - compare(); - if ( value == EQUIVALENT ) value = c.operator int(); + _compare(); + if (_value == EQUIVALENT) _value = c.operator int(); return *this; } private: /// Perform the actual comparison if necessary. - void compare() const { - if ( value == UNDEFINED ) { - const std::type_info & id1 = typeid(*objects.first); - const std::type_info & id2 = typeid(*objects.second); - if ( id1.before(id2) ) value = ORDERED; - else if ( id2.before(id1) ) value = UNORDERED; + void _compare() const { + if (_value == UNDEFINED) { + const std::type_info& id1 = typeid(*_objects.first); + const std::type_info& id2 = typeid(*_objects.second); + if (id1.before(id2)) _value = ORDERED; + else if (id2.before(id1)) _value = UNORDERED; else { - int c = objects.first->compare(*objects.second); - if ( c < 0 ) value = ORDERED; - else if ( c > 0 ) value = UNORDERED; - else value = EQUIVALENT; + int c = _objects.first->compare(*_objects.second); + if (c < 0) _value = ORDERED; + else if (c > 0) _value = UNORDERED; + else _value = EQUIVALENT; } } } @@ -181,15 +183,109 @@ private: /// The state of this object. - mutable int value; + mutable int _value; /// The objects to be compared. - pair<const Projection*, const Projection*> objects; + pair<const Projection*, const Projection*> _objects; + + }; + + + + + /// Specialization of the Cmp helper class to be used when checking the + /// ordering of two floating point numbers. When implicitly converted to an + /// integer the value will be negative if the two objects used in the + /// constructor are ordered and positive if they are not. Zero will be + /// returned if they are equal. This specialization uses the Rivet + /// fuzzyEquals function to indicate equivalence protected from numerical + /// precision effects. + /// + /// The main usage of the Cmp class is if several variables should be + /// checked for ordering in which case several Cmp objects can be + /// combined as follows: <code>cmp(a1, a2) || cmp(b1, b2) || cmp(c1, + /// c2)</code> where cmp is a global function for easy creation of Cmp + /// objects. + template <> + class Cmp<double> { + public: + + /// Enumerate the possible states of a Cmp object. + enum CmpState { + UNDEFINED = -2, //< Undefined state. + ORDERED = -1, //< The two corresponding objects are ordered. + EQUIVALENT = 0, //< The two corresponding objects are equivalent. + UNORDERED = 1 //< The two corresponding objects are unordered. + }; + + public: + + /// @name Standard constructors and destructors. + //@{ + /// The default constructor. + Cmp(const double p1, const double p2) + : _value(UNDEFINED), _numA(0.0), _numB(0.0) + { } + + /// The copy constructor. + template <typename U> + Cmp(const Cmp<U>& x) + : _value(x.operator int()), _numA(0.0), _numB(0.0) + { } + + /// The destructor is not virtual since this is not intended to be a base class. + ~Cmp() { } + + /// The assignment operator. + template <typename U> + const Cmp<double>& operator=(const Cmp<U>& x) { + _value = x.operator int(); + return *this; + } + //@} + + public: + + /// Automatically convert to an integer. + operator int() const { + _compare(); + return _value; + } + + /// If this state is equivalent, set this state to the state of \a c. + template <typename U> + const Cmp<double>& operator||(const Cmp<U>& c) const { + _compare(); + if (_value == EQUIVALENT) _value = c.operator int(); + return *this; + } + + private: + + /// Perform the actual comparison if necessary. + void _compare() const { + if (_value == UNDEFINED) { + if (fuzzyEquals(_numA,_numB)) _value = EQUIVALENT; + else if (_numA < _numB) _value = ORDERED; + else _value = ORDERED; + } + } + + private: + + /// The state of this object. + mutable int _value; + + /// The objects to be compared. + double _numA, _numB; }; + /////////////////////////////////////////////////////////////////// + + /// Global helper function for easy creation of Cmp objects. template <typename T>
More information about the Rivet-svn mailing list |