/*-------------------------------------------------------------------------------------*/ /* 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 Point.hpp \brief Custom class for points (headers) \author Sebastien Le Digabel \date 2010-04-05 \see Point.cpp */ #ifndef __POINT__ #define __POINT__ /// Avoids warnings on std::inner_product with visual C++. #define _SCL_SECURE_NO_WARNINGS #include #include #include "Double.hpp" namespace NOMAD { /// \c accumulate operator for \c squared_norm(). struct squared_norm_op { /** This function returns \c d1+d2^2 and is designed as an \c accumulate operator. \param d1 The NOMAD::Double \c d1 -- \b IN. \param d2 The NOMAD::Double \c d2 -- \b IN. \return A third NOMAD::Double equal to \c d1+d2^2. */ NOMAD::Double operator () ( const NOMAD::Double & d1 , const NOMAD::Double & d2 ) { return d1 + d2.pow2(); } }; /// \c accumulate operator for \c size_of(). struct size_of_op { /** This function returns \c i+size_of(d) and is designed as an \c accumulate operator. \param i The integer \c i -- \b IN. \param d The NOMAD::Double \c d -- \b IN. \return An integer equal to \c i+size_of(d). */ int operator () ( int i , const NOMAD::Double & d ) { return i + d.size_of(); } }; /// Custom class for points. /** Coordinates are NOMAD::Double objects. */ class Point { private: #ifdef MEMORY_DEBUG static int _cardinality; ///< Number of NOMAD::Point objects in memory. static int _max_cardinality; ///< Max number of NOMAD::Point objects in memory. #endif /** Max number of coordinates to display. Default to 20, debug value at -1 (no limit). */ static int _display_limit; int _n; ///< Dimension of the point. NOMAD::Double * _coords; ///< Coordinates of the point. public: /*-------------------------------------------------------------------*/ /// Exception class for a bad access with NOMAD::Point objects. class Bad_Access : public NOMAD::Exception { public: /// Constructor. Bad_Access ( const std::string & file , int line , const std::string & msg ) : NOMAD::Exception ( file , line , msg ) {} }; /// Exception class for NOMAD::Point objects that are not defined. 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 input errors with NOMAD::Point objects. class Bad_Input : public NOMAD::Exception { public: /// Constructor. Bad_Input ( const std::string & file , int line , const std::string & msg ) : NOMAD::Exception ( file , line , msg ) {} }; /// Exception class for bad operations with NOMAD::Point objects. class Bad_Operation : public NOMAD::Exception { public: /// Constructor. Bad_Operation ( const std::string & file , int line , const std::string & msg ) : NOMAD::Exception ( file , line , msg ) {} }; /*-------------------------------------------------------------------*/ #ifdef MEMORY_DEBUG /// Access to the number of NOMAD::Point objects in memory. /** \return The number of NOMAD::Point objects in memory. */ static int get_cardinality ( void ) { return Point::_cardinality; } /// Access to the max number of NOMAD::Point objects in memory. /** \return The max number of NOMAD::Point objects in memory. */ static int get_max_cardinality ( void ) { return Point::_max_cardinality; } #endif /// Constructor. /** \param n Dimension of the point -- \b IN --\b optional (default = 0). \param d Initial value for all coordinates -- \b IN -- \b optional (default = undefined real). */ explicit Point ( int n = 0 , const NOMAD::Double & d = NOMAD::Double() ); /// Copy constructor. /** \param p The copied object -- \b IN. */ Point ( const Point & p ); /// Affectation operator. /** \param p The right-hand side object -- \b IN. \return \c *this as the result of the affectation. */ const Point & operator = ( const Point & p ); /// Destructor. virtual ~Point ( void ); /// Change the NOMAD::Point dimension. /** Sets also all coordinates to d. \param n New dimension -- \b IN --\b optional (default = 0). \param d Initial value for all coordinates -- \b IN -- \b optional (default = undefined real). */ void reset ( int n = 0 , const NOMAD::Double & d = NOMAD::Double() ); /// Clear the point. virtual void clear ( void ) { reset(); } /// Change the NOMAD::Point dimension. /** The values are kept. \param n New dimension of the point -- \b IN. */ void resize ( int n ); /// Set a new display limit. /** \param dl An integer for the new display limit -- \b IN. */ static void set_display_limit ( int dl ) { Point::_display_limit = dl; } /// Access to the display limit. /** \return The display limit. */ static int get_display_limit ( void ) { return Point::_display_limit; } /// Const operator \c []. /** \param i The index (0 for the first element) -- \b IN. \return The \c (i+1)th coordinate. */ const NOMAD::Double & operator [] ( int i ) const; /// Non-const operator \c []. /** \param i The index (0 for the first element) -- \b IN. \return The \c (i+1)th coordinate. */ NOMAD::Double & operator [] ( int i ); /// Size of the point in memory. /** \return An integer for the size of the point in bytes. */ virtual int size_of ( void ) const { return std::accumulate ( _coords , _coords+_n , static_cast(sizeof(_n)) , size_of_op() ); } /// Access to the dimension of the point. /** \return The dimension of the point. */ int size ( void ) const { return _n; } /// Test if the point is empty (dimension equal to zero). /** \return A boolean equal to \c true if the point is empty. */ bool empty ( void ) const { return _n==0; } /// Set all the coordinates to a specifi value. /** \param d The value for all coordinates -- \b IN. */ void set ( const NOMAD::Double & d ) const { std::fill ( _coords , _coords+_n , d ); } /// Set the coordinates with an array of reals. /** \param n Dimension of the point -- \b IN. \param a Array of size \c n of reals -- \b IN. */ void set ( int n , const NOMAD::Double * a ); /// Check if all the coordinates are defined. /** \return A boolean equal to \c true if all the coordinates are defined. */ bool is_complete ( void ) const; /// Check if at least one coordinate is defined. /** This virtual method is redefined in class NOMAD::Direction. \return A boolean equal to \c true if at least one coordinate is defined. */ virtual bool is_defined ( void ) const; /// Count the number of defined values. /** \return The number of values that are defined. */ int nb_defined ( void ) const; /// Squared norm of the point. /** \return A NOMAD::Double with the squared norm of the point. */ const NOMAD::Double squared_norm ( void ) const { return std::accumulate ( _coords , _coords+_n , NOMAD::Double(0.0) , squared_norm_op() ); } /// Norm of the point. /** \return A NOMAD::Double with the norm of the point. */ const NOMAD::Double norm ( void ) const { return squared_norm().sqrt(); } /// Dot product with another point \c x. /** \param x The other point \c x -- \b IN. \return The dot product \c *this \c . \c x. */ const NOMAD::Double dot_product ( const Point & x ) const { return std::inner_product ( _coords , _coords+_n , x._coords , NOMAD::Double(0.0) ); } /// Angle with another point \c x. /** \param x The other point \c x -- \b IN. \return The angle between \c *this and \c x. */ const NOMAD::Double get_angle ( const Point & x ) const; /// Mutiplication with a scalar. /** - This implements \c *this \c = \c d \c * \c *this. - The current object \c *this is modified. \param d The scalar -- \b IN. \return The point times \c d. */ const Point & operator *= ( const NOMAD::Double & d ); /// Multiplication with another point. /** - The multiplication is done coordinate by coordinate. - The current object \c *this is not modified. \param p The other point -- \b IN. \return A third point equal to \c *this \c .* \c p. */ const Point operator * ( const Point & p ) const; /// Division with another point. /** - The division is done coordinate by coordinate. - The current object \c *this is not modified. \param p The other point -- \b IN. \return A third point equal to \c *this \c ./ \c p. */ const Point operator / ( const Point & p ) const; /// Addition with another point. /** The current object \c *this is not modified. \param p The other point -- \b IN. \return A third point equal to \c *this \c + \c p. */ const Point operator + ( const Point & p ) const; /// Substraction with another point. /** The current object \c *this is not modified. \param p The other point -- \b IN. \return A third point equal to \c *this \c - \c p. */ const Point operator - ( const Point & p ) const; /// Negation. /** The current object \c *this is not modified. \return A new point equal to \c -*this. */ const Point operator - ( void ) const; /// Comparison operator \c <. /** \param p The right-hand side object -- \b IN. \return A boolean equal to \c true if \c *this \c < \c p. */ virtual bool operator < ( const Point & p ) const; /// Comparison operator \c ==. /** \param p The right-hand side object -- \b IN. \return A boolean equal to \c true if \c *this \c == \c p. */ bool operator == ( const Point & p ) const; /// Comparison operator \c !=. /** \param p The right-hand side object -- \b IN. \return A boolean equal to \c true if \c *this \c != \c p. */ bool operator != ( const Point & p ) const { return !(*this == p); } /// The same as operator \c < but with consideration of undefined values. /** \param p The right-hand side object -- \b IN. \return A boolean equal to \c true if \c *this \c < \c p. */ bool comp_with_undef ( const Point & p ) const; /// Projection to the mesh. /** Projection to the mesh of size delta ( \c *this \c = \c ref \c + \c k \c * \c delta ). \param ref Reference for projection -- \b IN. \param delta Mesh size parameter -- \b IN. \param lb Lower bound -- \b IN -- \b optional (default = undefined NOMAD::Point). \param ub Upper bound -- \b IN -- \b optional (default = undefined NOMAD::Point). */ void project_to_mesh ( const Point & ref , const Point & delta , const Point & lb = Point() , const Point & ub = Point() ); /// Display. /** \param out The NOMAD::Display object -- \b IN. \param sep A string that is used as a separator between the coordinates -- \b IN --\b optional (default = one space). \param w An integer indicating a width for the display of each coordinate -- \b IN -- \b optional (default = -1, no limit). \param lim Max number of coordinates to display -- \b IN -- \b optional (default = -1, no limit). */ virtual void display ( const NOMAD::Display & out , const std::string & sep = " " , int w = -1 , int lim = -1 ) const; }; /*---------------------------------------------------------------------------*/ /// Display a NOMAD::Point object. /** \param out The NOMAD::Display object -- \b IN. \param p The NOMAD::Point object to be displayed -- \b IN. \return The NOMAD::Display object. */ inline const NOMAD::Display & operator << ( const NOMAD::Display & out , const NOMAD::Point & p ) { p.display ( out , " " , 2 , NOMAD::Point::get_display_limit() ); return out; } /// Input. /** - Allows the input of NOMAD::Double objects with operator \c >>. - Can read undefined coordinates (parameter \c UNDEF_STR with default \c "-".) - Example: \code NOMAD::Point x(3); std::cout << "Enter x (3 coordinates): "; std::cin >> x; std::cout << "x is equal to " << x << std::endl; \endcode \param in A \c std::istream object (can be a file) -- \b IN/OUT. \param p The NOMAD::Point object to be read -- \b OUT. \return The modified \c std::istream object. */ std::istream & operator >> ( std::istream & in , Point & p ); } #endif