/*-------------------------------------------------------------------------------------*/ /* NOMAD - Nonlinear Optimization by Mesh Adaptive Direct search - version 3.6.1 */ /* */ /* Copyright (C) 2001-2012 Mark Abramson - the Boeing Company, Seattle */ /* Charles Audet - Ecole Polytechnique, Montreal */ /* Gilles Couture - Ecole Polytechnique, Montreal */ /* John Dennis - Rice University, Houston */ /* Sebastien Le Digabel - Ecole Polytechnique, Montreal */ /* Christophe Tribes - Ecole Polytechnique, Montreal */ /* */ /* funded in part by AFOSR and Exxon Mobil */ /* */ /* Author: Sebastien Le Digabel */ /* */ /* Contact information: */ /* Ecole Polytechnique de Montreal - GERAD */ /* C.P. 6079, Succ. Centre-ville, Montreal (Quebec) H3C 3A7 Canada */ /* e-mail: nomad@gerad.ca */ /* phone : 1-514-340-6053 #6928 */ /* fax : 1-514-340-5665 */ /* */ /* This program is free software: you can redistribute it and/or modify it under the */ /* terms of the GNU Lesser General Public License as published by the Free Software */ /* Foundation, either version 3 of the License, or (at your option) any later */ /* version. */ /* */ /* This program is distributed in the hope that it will be useful, but WITHOUT ANY */ /* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A */ /* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License along */ /* with this program. If not, see . */ /* */ /* You can find information on the NOMAD software at www.gerad.ca/nomad */ /*-------------------------------------------------------------------------------------*/ /** \file Double.hpp \brief Custom class for double-precision reals (headers) \author Sebastien Le Digabel \date 2010-04-02 \see Double.cpp */ #ifndef __NOMAD_DOUBLE__ #define __NOMAD_DOUBLE__ #include "Exception.hpp" #include "Display.hpp" namespace NOMAD { /// Custom class for double-precision reals. /** - Allows comparisons on reals with custom precision. - Deals with undefined values. - Use \c value() to access the true \c double value. */ class Double { private: #ifdef MEMORY_DEBUG static int _cardinality; ///< Number of NOMAD::Double objects in memory. static int _max_cardinality; ///< Max number of NOMAD::Double objects in memory. #endif double _value; ///< The value of the number. bool _defined; ///< \c true if the number has a defined value. static double _epsilon; ///< Desired precision on comparisons. static std::string _inf_str; ///< Infinity string. static std::string _undef_str; ///< Undefined value string. public: /*-------------------------------------------------------------------*/ /// Exception class for undefined NOMAD::Double objects. class Not_Defined : public NOMAD::Exception { public: /// Constructor. Not_Defined ( const std::string & file , int line , const std::string & msg ) : NOMAD::Exception ( file , line , msg ) {} }; /// Exception class for divisons by zero with NOMAD::Double objects. class Invalid_Value : public NOMAD::Exception { public: /// Constructor. Invalid_Value ( const std::string & file , int line , const std::string & msg ) : NOMAD::Exception ( file , line , msg ) {} }; /*-------------------------------------------------------------------*/ #ifdef MEMORY_DEBUG /// Access to the number of NOMAD::Double objects in memory. /** \return The number of NOMAD::Double objects in memory. */ static int get_cardinality ( void ) { return NOMAD::Double::_cardinality; } /// Access to the max number of NOMAD::Double objects in memory. /** \return The max number of NOMAD::Double objects in memory. */ static int get_max_cardinality ( void ) { return NOMAD::Double::_max_cardinality; } #endif /// Constructor #1. explicit Double ( void ); /// Constructor #2. /** From a \c double. \param v The \c double -- \b IN. */ Double ( double v ); /// Copy constructor. /** \param d The copied object -- \b IN. */ Double ( const Double & d ); /// Destructor. virtual ~Double ( void ); /// Function \c atof (conversion from a string to a real). /** The value is determined by a string. \param s The string -- \b IN. \return A boolean equal to \c true if the string was valid. */ bool atof ( const std::string & s ); /// Function \c atof (conversion from a string to a real) with a relative value. /** The value is determined by a string that may begin with \c 'r' to indicate a proportion (relative value). \param s The string -- \b IN. \param relative A boolean indicating if the conversion was relative -- \b OUT. \return A boolean equal to \c true if the string was valid. */ bool relative_atof ( const std::string & s , bool & relative ); /// Reset the Double. void clear ( void ) { _value = 0.0; _defined = false; } /// Reset the Double. void reset ( void ) { clear(); } /// Affectation operator #1. /** \param d The right-hand side object -- \b IN. \return \c *this as the result of the affectation. */ Double & operator = ( const Double & d ); /// Affectation operator #2. /** \param r The right-hand side \c double -- \b IN. \return \c *this as the result of the affectation. */ Double & operator = ( double r ); /// Access to the \c double value. /** \return The \c double value. */ double value ( void ) const; /// Is the value defined ? /** \return A boolean equal to \c true if the NOMAD::Double is defined. */ bool is_defined ( void ) const { return _defined; } /// Is the value an integer ? /** \return A boolean equal to \c true if the NOMAD::Double is an integer. */ bool is_integer ( void ) const; /// Is the value binary ? /** \return A boolean equal to \c true if the NOMAD::Double is in {0,1}. */ bool is_binary ( void ) const; /// Sizeof. /** The size of an object in memory. \return An integer value for the size in bytes. */ int size_of ( void ) const { return sizeof(_defined) + sizeof(_value); } /// Access to the NOMAD::Double precision. /** \return A \c double for the precision. */ static double get_epsilon ( void ) { return Double::_epsilon; } /// Set the NOMAD::Double precision. /** \param eps The precision -- \b IN. */ static void set_epsilon ( double eps ); /// Access to the undefined value string. /** \return A \c std::string for the undefined value string. */ static std::string get_undef_str ( void ) { return Double::_undef_str; } /// Set the NOMAD::Double undefined value string. /** \param undef_str The undefined value string -- \b IN. */ static void set_undef_str ( const std::string & undef_str ) { NOMAD::Double::_undef_str = undef_str; } /// Access to the infinity string. /** \return A \c std::string for the infinity string. */ static std::string get_inf_str ( void ) { return Double::_inf_str; } /// Set the NOMAD::Double infinity string. /** \param inf_str The infinity string -- \b IN. */ static void set_inf_str ( const std::string & inf_str ) { NOMAD::Double::_inf_str = inf_str; } /// Rounding. /** \return An integer with the rounding result. */ int round ( void ) const; /// Ceil. /** \return A NOMAD::double with the rounding result. */ const Double ceil ( void ) const; /// Floor. /** \return A NOMAD::double with the rounding result. */ const Double floor ( void ) const; /// Absolute value. /** \return Another NOMAD::Double equal to max{\c -*this,\c *this}. */ const Double abs ( void ) const; /// Square. /** \return Another NOMAD::Double equal to \c *this \c * \c *this. */ const Double pow2 ( void ) const; /// Square root. /** \return Another NOMAD::Double equal to \c (*this)^0.5. */ const Double sqrt ( void ) const; /// Relative error with another NOMAD::Double. /** \param x The other real -- \b IN. \return A new object with the relative error value in \c [0;1]. */ const Double rel_err ( const Double & x ) const; /// Operator \c ++ (prefix position). /** Allows \c ++d; \return The NOMAD::Double plus 1. */ Double & operator++ ( void ); /// Operator \c ++ (suffix position). /** Allows \c d++; \return A copy of the NOMAD::Double before incrementation. */ Double operator++ ( int n ); /// Operator \c -- (prefix position). /** Allows \c --d; \return The NOMAD::Double minus 1. */ Double & operator-- ( void ); /// Operator \c -- (suffix position). /** Allows \c d--; \return A copy of the NOMAD::Double before decrementation. */ Double operator-- ( int n ); /// Operator \c +=. /** Allows \c d \c += \c d1. \param d1 The increment -- \b IN. \return The NOMAD::Double plus \c d1. */ const Double & operator += ( const Double & d1 ); /// Operator \c -=. /** Allows \c d \c -= \c d1. \param d1 The decrement -- \b IN. \return The NOMAD::Double minus \c d1. */ const Double & operator -= ( const Double & d1 ); /// Operator \c *=. /** Allows \c d \c *= \c d1. \param d1 The factor -- \b IN. \return The NOMAD::Double times \c d1. */ const Double & operator *= ( const Double & d1 ); /// Operator \c /=. /** Allows \c d \c /= \c d1. Throws a NOMAD::Exception::Invalid_Value if \c d1==0. \param d1 The denominator -- \b IN. \return The NOMAD::Double divided by \c d1. */ const Double & operator /= ( const Double & d1 ); /// Comparison <. /** The same as operator \c < but with consideration of undefined values. When comparing \c d1 and \c d2, \c (d1>. - Can read undefined values (parameter \c UNDEF_STR with default \c "-".) - Example: \code NOMAD::Double d1 , d2; std::cout << "Enter d1 and d2: "; std::cin >> d1 >> d2; std::cout << "d1 and d2 are equal to " << d1 << " and " << d2 << std::endl; \endcode \param in A \c std::istream object (can be a file) -- \b IN/OUT. \param d The NOMAD::Double object to be read -- \b OUT. \return The modified \c std::istream object. */ std::istream & operator >> ( std::istream & in , Double & d ); /// Inverse operator. /** Allows operations such as \c d \c = \c -d. \param d The NOMAD::Double to be inversed -- \b IN. \return A new NOMAD::Double as the result of the operation. */ inline const Double operator - ( const Double & d ) { return NOMAD::Double (-d.value()); } /// Operator \c + for two NOMAD::Double objects. /** Allows operations such as \c d \c = \c d1 \c + \c d2. \param d1 The first NOMAD::Double -- \b IN. \param d2 The second NOMAD::Double -- \b IN. \return A third NOMAD::Double as the result of the operation. */ inline const Double operator + ( const Double & d1 , const Double & d2 ) { return NOMAD::Double ( d1.value() + d2.value() ); } /// Operator \c - for two NOMAD::Double objects. /** Allows operations such as \c d \c = \c d1 \c - \c d2. \param d1 The first NOMAD::Double -- \b IN. \param d2 The second NOMAD::Double -- \b IN. \return A third NOMAD::Double as the result of the operation. */ inline const Double operator - ( const Double & d1 , const Double & d2 ) { return NOMAD::Double (d1.value() - d2.value()); } /// Operator \c * for two NOMAD::Double objects. /** Allows operations such as \c d \c = \c d1 \c * \c d2. \param d1 The first NOMAD::Double -- \b IN. \param d2 The second NOMAD::Double -- \b IN. \return A third NOMAD::Double as the result of the operation. */ inline const Double operator * ( const Double & d1 , const Double & d2 ) { return NOMAD::Double ( d1.value() * d2.value() ); } /// Operator \c / for two NOMAD::Double objects. /** Allows operations such as \c d \c = \c d1 \c / \c d2. \param d1 The first NOMAD::Double -- \b IN. \param d2 The second NOMAD::Double -- \b IN. \return A third NOMAD::Double as the result of the operation. */ const Double operator / ( const Double & d1 , const Double & d2 ); /// Comparison operator \c ==. /** Allows the comparison \c d1 \c == \c d2. \param d1 The first NOMAD::Double -- \b IN. \param d2 The second NOMAD::Double -- \b IN. \return A boolean equal to true if \c d1 \c == \c d2. */ inline bool operator == ( const Double & d1 , const Double & d2 ) { return fabs ( d1.value() - d2.value() ) < NOMAD::Double::get_epsilon(); } /// Comparison operator \c !=. /** Allows the comparison \c d1 \c != \c d2. \param d1 The first NOMAD::Double -- \b IN. \param d2 The second NOMAD::Double -- \b IN. \return A boolean equal to true if \c d1 \c != \c d2. */ inline bool operator != ( const Double & d1 , const Double & d2 ) { return !(d1==d2); } /// Comparison operator \c <. /** Allows the comparison \c d1 \c < \c d2. \param d1 The first NOMAD::Double -- \b IN. \param d2 The second NOMAD::Double -- \b IN. \return A boolean equal to true if \c d1 \c < \c d2. */ inline bool operator < ( const Double & d1 , const Double & d2 ) { return d1.value() < d2.value() - NOMAD::Double::get_epsilon(); } /// Comparison operator \c >. /** Allows the comparison \c d1 \c > \c d2. \param d1 The first NOMAD::Double -- \b IN. \param d2 The second NOMAD::Double -- \b IN. \return A boolean equal to true if \c d1 \c > \c d2. */ inline bool operator > ( const Double & d1 , const Double & d2 ) { return d1.value() > d2.value() + NOMAD::Double::get_epsilon(); } /// Comparison operator \c <=. /** Allows the comparison \c d1 \c <= \c d2. \param d1 The first NOMAD::Double -- \b IN. \param d2 The second NOMAD::Double -- \b IN. \return A boolean equal to true if \c d1 \c <= \c d2. */ inline bool operator <= ( const Double & d1 , const Double & d2 ) { return !(d1>d2); } /// Comparison operator \c >=. /** Allows the comparison \c d1 \c >= \c d2. \param d1 The first NOMAD::Double -- \b IN. \param d2 The second NOMAD::Double -- \b IN. \return A boolean equal to true if \c d1 \c >= \c d2. */ inline bool operator >= ( const Double & d1 , const Double & d2 ) { return !(d1