Bing change in eoRealBounds: it is now deriving from eoPersistent.
More important, the eoRealVectorBounds, vectorized version (a vector<eoRealBounds *> has also become an eoPersistent object and now derives from an eoRealBaseVectorBounds class. A useful consequence (and actual motivatino) was to be able to have soem eoValueParam<eoRealVectorBounds> with all possibilities for input (see doc for Lesson4 in the tutorial for the syntax).
This commit is contained in:
parent
42cb1981d5
commit
09388c8ed5
10 changed files with 779 additions and 412 deletions
|
|
@ -1,7 +1,172 @@
|
|||
#include <ctime>
|
||||
#include <strstream>
|
||||
#include "eoRealBounds.h"
|
||||
#include "eoRealVectorBounds.h"
|
||||
|
||||
// the global dummy bounds
|
||||
// (used for unbounded variables when bounds are required)
|
||||
eoRealNoBounds eoDummyRealNoBounds;
|
||||
eoRealVectorNoBounds eoDummyVectorNoBounds;
|
||||
eoRealVectorNoBounds eoDummyVectorNoBounds(0);
|
||||
|
||||
///////////// helper read functions - could be somewhere else
|
||||
|
||||
// removes leading delimiters - return false if nothing else left
|
||||
bool remove_leading(std::string & _s, const string _delim)
|
||||
{
|
||||
size_t posDebToken = _s.find_first_not_of(_delim);
|
||||
if (posDebToken >= _s.size())
|
||||
return false;
|
||||
_s = _s.substr(posDebToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
double read_double(std::string _s)
|
||||
{
|
||||
istrstream is(_s.c_str());
|
||||
double r;
|
||||
is >> r;
|
||||
return r;
|
||||
}
|
||||
|
||||
int read_int(std::string _s)
|
||||
{
|
||||
istrstream is(_s.c_str());
|
||||
int i;
|
||||
is >> i;
|
||||
return i;
|
||||
}
|
||||
|
||||
// need to rewrite copy ctor and assignement operator because of ownedBounds
|
||||
eoRealVectorBounds::eoRealVectorBounds(const eoRealVectorBounds & _b):
|
||||
eoRealBaseVectorBounds(_b)
|
||||
{
|
||||
factor = _b.factor;
|
||||
ownedBounds = _b.ownedBounds;
|
||||
// duplicate all pointers!
|
||||
if (ownedBounds.size()>0)
|
||||
for (unsigned i=0; i<ownedBounds.size(); i++)
|
||||
ownedBounds[i] = ownedBounds[i]->dup();
|
||||
}
|
||||
|
||||
|
||||
// the readFrom method of eoRealVectorNoBounds:
|
||||
// only calls the readFrom(string) - for param reading
|
||||
void eoRealVectorBounds::readFrom(istream& _is)
|
||||
{
|
||||
string value;
|
||||
_is >> value;
|
||||
readFrom(value);
|
||||
return;
|
||||
}
|
||||
|
||||
void eoRealVectorBounds::readFrom(std::string _value)
|
||||
{
|
||||
// keep track of old size - to adjust in the end
|
||||
unsigned oldSize = size();
|
||||
// clean-up before filling in
|
||||
if (ownedBounds.size()>0)
|
||||
for (unsigned i = 0; i < ownedBounds.size(); ++i)
|
||||
{
|
||||
delete ownedBounds[i];
|
||||
}
|
||||
ownedBounds.resize(0);
|
||||
factor.resize(0);
|
||||
resize(0);
|
||||
|
||||
// now read
|
||||
string delim(",; ");
|
||||
while (_value.size()>0)
|
||||
{
|
||||
if (!remove_leading(_value, delim)) // only delimiters were left
|
||||
break;
|
||||
// look for opening char
|
||||
size_t posDeb = _value.find_first_of("[(");
|
||||
cout << posDeb << endl;
|
||||
if (posDeb >= _value.size()) // nothing left to read (though probably a syntax error there)
|
||||
{
|
||||
break;
|
||||
}
|
||||
// ending char
|
||||
string closeChar = (_value[posDeb] == '(' ? string(")") : string("]") );
|
||||
|
||||
size_t posFin = _value.find_first_of(string(closeChar));
|
||||
if (posFin >= _value.size())
|
||||
throw runtime_error("Syntax error when reading bounds");
|
||||
|
||||
// y a-t-il un nbre devant
|
||||
unsigned count = 1;
|
||||
if (posDeb > 0) // something before opening
|
||||
{
|
||||
string sCount = _value.substr(0, posDeb);
|
||||
count = read_int(sCount);
|
||||
if (count <= 0)
|
||||
throw runtime_error("Syntax error when reading bounds");
|
||||
}
|
||||
|
||||
// the bounds
|
||||
string sBounds = _value.substr(posDeb+1, posFin-posDeb-1);
|
||||
// and remove from original string
|
||||
_value = _value.substr(posFin+1);
|
||||
|
||||
remove_leading(sBounds, delim);
|
||||
size_t posDelim = sBounds.find_first_of(delim);
|
||||
if (posDelim >= sBounds.size())
|
||||
throw runtime_error("Syntax error when reading bounds");
|
||||
|
||||
bool minBounded=false, maxBounded=false;
|
||||
double minBound=0, maxBound=0;
|
||||
|
||||
// min bound
|
||||
string sMinBounds = sBounds.substr(0,posDelim);
|
||||
if (sMinBounds != string("-inf"))
|
||||
{
|
||||
minBounded = true;
|
||||
minBound = read_double(sMinBounds);
|
||||
}
|
||||
|
||||
// max bound
|
||||
size_t posEndDelim = sBounds.find_first_not_of(delim,posDelim);
|
||||
|
||||
string sMaxBounds = sBounds.substr(posEndDelim);
|
||||
if (sMaxBounds != string("+inf"))
|
||||
{
|
||||
maxBounded = true;
|
||||
maxBound = read_double(sMaxBounds);
|
||||
}
|
||||
|
||||
// now create the eoRealBounds objects
|
||||
eoRealBounds *ptBounds;
|
||||
if (minBounded && maxBounded)
|
||||
ptBounds = new eoRealInterval(minBound, maxBound);
|
||||
else if (!minBounded && !maxBounded) // no bound at all
|
||||
ptBounds = new eoRealNoBounds;
|
||||
else if (!minBounded && maxBounded)
|
||||
ptBounds = new eoRealAboveBound(maxBound);
|
||||
else if (minBounded && !maxBounded)
|
||||
ptBounds = new eoRealBelowBound(minBound);
|
||||
// store it for memory management
|
||||
ownedBounds.push_back(ptBounds);
|
||||
// push the count
|
||||
factor.push_back(count);
|
||||
// and add count of it to the actual bounds
|
||||
for (unsigned i=0; i<count; i++)
|
||||
push_back(ptBounds);
|
||||
}
|
||||
// now adjust the size to the initial value
|
||||
adjust_size(oldSize);
|
||||
}
|
||||
|
||||
/** Eventually increases the size by duplicating last bound */
|
||||
void eoRealVectorBounds::adjust_size(unsigned _dim)
|
||||
{
|
||||
if ( size() < _dim )
|
||||
{
|
||||
// duplicate last bound
|
||||
unsigned missing = _dim-size();
|
||||
eoRealBounds * ptBounds = back();
|
||||
for (unsigned i=0; i<missing; i++)
|
||||
push_back(ptBounds);
|
||||
// update last factor (warning: can be > 1 already!)
|
||||
factor[factor.size()-1] += missing;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,20 +69,10 @@ eoRealNoBounds the "unbounded bounds" (-infinity, +infinity)
|
|||
eoRealBelowBound the half-bounded interval [min, +infinity)
|
||||
eoRealAboveBound the half-bounded interval (-infinity, max]
|
||||
|
||||
Vector type:
|
||||
------------
|
||||
Class eoRealVectorBounds implements the vectorized version:
|
||||
it is basically a vector of eoRealBounds * and forwards all request
|
||||
to the elements of the vector.
|
||||
|
||||
This file also contains te 2 global variables eoDummyRealNoBounds and
|
||||
eoDummyVectorNoBounds that are used as defaults in ctors (i.e. when no
|
||||
bounds are given, it is assumed unbounded values)
|
||||
|
||||
TODO: have an eoRealBounds.cpp with the longuish parts of the code
|
||||
(and the 2 global variables).
|
||||
THis file also contains the declaration of *the* global object that
|
||||
is the unbounded bound
|
||||
*/
|
||||
class eoRealBounds
|
||||
class eoRealBounds : public eoPersistent
|
||||
{
|
||||
public:
|
||||
virtual ~eoRealBounds(){}
|
||||
|
|
@ -133,6 +123,9 @@ public:
|
|||
* @exception if unbounded
|
||||
*/
|
||||
virtual double uniform(eoRng & _rng = eo::rng) = 0;
|
||||
|
||||
/** for memory managements - ugly */
|
||||
virtual eoRealBounds * dup() = 0;
|
||||
};
|
||||
|
||||
/** A default class for unbounded variables
|
||||
|
|
@ -167,6 +160,34 @@ public:
|
|||
{
|
||||
throw logic_error("Trying to generate uniform values in unbounded eoRealBounds");
|
||||
}
|
||||
|
||||
// methods from eoPersistent
|
||||
/**
|
||||
* Read object.
|
||||
* @param _is A istream.
|
||||
* but reading should not be done here, because of bound problems
|
||||
* see eoRealVectorBounds
|
||||
*/
|
||||
virtual void readFrom(istream& _is)
|
||||
{
|
||||
throw runtime_error("Should not use eoRealBounds::readFrom");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write object. It's called printOn since it prints the object on a stream.
|
||||
* @param _os A ostream.
|
||||
*/
|
||||
virtual void printOn(ostream& _os) const
|
||||
{
|
||||
_os << "[-inf,+inf]";
|
||||
}
|
||||
|
||||
/** for memory managements - ugly */
|
||||
virtual eoRealBounds * dup()
|
||||
{
|
||||
return new eoRealNoBounds(*this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// one object for all - see eoRealBounds.cpp
|
||||
|
|
@ -255,6 +276,33 @@ public :
|
|||
return;
|
||||
}
|
||||
|
||||
// methods from eoPersistent
|
||||
/**
|
||||
* Read object.
|
||||
* @param _is A istream.
|
||||
* but reading should not be done here, because of bound problems
|
||||
* see eoRealVectorBounds
|
||||
*/
|
||||
virtual void readFrom(istream& _is)
|
||||
{
|
||||
throw runtime_error("Should not use eoRealInterval::readFrom");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write object. It's called printOn since it prints the object on a stream.
|
||||
* @param _os A ostream.
|
||||
*/
|
||||
virtual void printOn(ostream& _os) const
|
||||
{
|
||||
_os << "[" << repMinimum << "," << repMaximum << "]";
|
||||
}
|
||||
|
||||
/** for memory managements - ugly */
|
||||
virtual eoRealBounds * dup()
|
||||
{
|
||||
return new eoRealInterval(*this);
|
||||
}
|
||||
|
||||
private :
|
||||
double repMinimum;
|
||||
double repMaximum;
|
||||
|
|
@ -323,6 +371,34 @@ public :
|
|||
_r = repMinimum;
|
||||
return;
|
||||
}
|
||||
|
||||
// methods from eoPersistent
|
||||
/**
|
||||
* Read object.
|
||||
* @param _is A istream.
|
||||
* but reading should not be done here, because of bound problems
|
||||
* see eoRealVectorBounds
|
||||
*/
|
||||
virtual void readFrom(istream& _is)
|
||||
{
|
||||
throw runtime_error("Should not use eoRealBelowBound::readFrom");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write object. It's called printOn since it prints the object on a stream.
|
||||
* @param _os A ostream.
|
||||
*/
|
||||
virtual void printOn(ostream& _os) const
|
||||
{
|
||||
_os << "[" << repMinimum << ",+inf]";
|
||||
}
|
||||
|
||||
/** for memory managements - ugly */
|
||||
virtual eoRealBounds * dup()
|
||||
{
|
||||
return new eoRealBelowBound(*this);
|
||||
}
|
||||
|
||||
private :
|
||||
double repMinimum;
|
||||
};
|
||||
|
|
@ -391,273 +467,35 @@ public :
|
|||
return;
|
||||
}
|
||||
|
||||
// methods from eoPersistent
|
||||
/**
|
||||
* Read object.
|
||||
* @param _is A istream.
|
||||
* but reading should not be done here, because of bound problems
|
||||
* see eoRealVectorBounds
|
||||
*/
|
||||
virtual void readFrom(istream& _is)
|
||||
{
|
||||
throw runtime_error("Should not use eoRealAboveBound::readFrom");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write object. It's called printOn since it prints the object on a stream.
|
||||
* @param _os A ostream.
|
||||
*/
|
||||
virtual void printOn(ostream& _os) const
|
||||
{
|
||||
_os << "[-inf," << repMaximum << "]";
|
||||
}
|
||||
|
||||
/** for memory managements - ugly */
|
||||
virtual eoRealBounds * dup()
|
||||
{
|
||||
return new eoRealAboveBound(*this);
|
||||
}
|
||||
|
||||
private :
|
||||
double repMaximum;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// The Vectorized versions
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
Class eoRealVectorBounds implements the vectorized version:
|
||||
it is basically a vector of eoRealBounds * and forwards all request
|
||||
to the elements of the vector.
|
||||
Probably it would have been cleaner if there had been an empty base class
|
||||
from which eoRealVectorBounds AND eoRealVectorNoBounds would have derived.
|
||||
This is because I started to write eoRealVectorNoBounds as a
|
||||
vector<eoRealBounds *> whose compoenents would have been eoRealNoBounds
|
||||
but then realize that you don't necessarily have the dimension
|
||||
when construction this vector - hence I added the eoRealVectorNoBounds ...
|
||||
Anyone with extra time in his agenda is welcome to change that :-)
|
||||
*/
|
||||
class eoRealVectorBounds : public vector<eoRealBounds *>
|
||||
{
|
||||
public:
|
||||
// virtual desctructor (to avoid warning?)
|
||||
virtual ~eoRealVectorBounds(){}
|
||||
|
||||
/** Default Ctor. I don't like it, as it leaves NULL pointers around
|
||||
*/
|
||||
eoRealVectorBounds(unsigned _dim=0) : vector<eoRealBounds *>(_dim) {}
|
||||
|
||||
/** Simple bounds = minimum and maximum (allowed)
|
||||
*/
|
||||
eoRealVectorBounds(unsigned _dim, double _min, double _max) :
|
||||
vector<eoRealBounds *>(_dim, new eoRealInterval(_min, _max))
|
||||
{
|
||||
if (_max-_min<=0)
|
||||
throw std::logic_error("Void range in eoRealVectorBounds");
|
||||
}
|
||||
|
||||
/** Ctor: same bonds for everybody, given as an eoRealBounds
|
||||
*/
|
||||
eoRealVectorBounds(unsigned _dim, eoRealBounds & _bounds) :
|
||||
vector<eoRealBounds *>(_dim, &_bounds)
|
||||
{}
|
||||
|
||||
/** Ctor: different bonds for different variables, vectors of double
|
||||
*/
|
||||
eoRealVectorBounds(vector<double> _min, vector<double> _max)
|
||||
{
|
||||
if (_max.size() != _min.size())
|
||||
throw std::logic_error("Dimensions don't match in eoRealVectorBounds");
|
||||
for (unsigned i=0; i<_min.size(); i++)
|
||||
{
|
||||
push_back( new eoRealInterval(_min[i], _max[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/** Ctor, particular case of dim-2
|
||||
*/
|
||||
eoRealVectorBounds(eoRealBounds & _xbounds, eoRealBounds & _ybounds) :
|
||||
vector<eoRealBounds *>(0)
|
||||
{
|
||||
push_back( &_xbounds);
|
||||
push_back( &_ybounds);
|
||||
}
|
||||
|
||||
/** test: is i_th component bounded
|
||||
*/
|
||||
virtual bool isBounded(unsigned _i)
|
||||
{
|
||||
return (*this)[_i]->isBounded();
|
||||
}
|
||||
|
||||
/** test: bounded iff all are bounded
|
||||
*/
|
||||
virtual bool isBounded(void)
|
||||
{
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
if (! (*this)[i]->isBounded())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Self-test: true iff i_th component has no bounds at all
|
||||
*/
|
||||
virtual bool hasNoBoundAtAll(unsigned _i)
|
||||
{
|
||||
return (*this)[_i]->hasNoBoundAtAll();
|
||||
}
|
||||
|
||||
/** Self-test: true iff all components have no bound at all
|
||||
*/
|
||||
virtual bool hasNoBoundAtAll(void)
|
||||
{
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
if (! (*this)[i]->hasNoBoundAtAll())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool isMinBounded(unsigned _i)
|
||||
{ return (*this)[_i]->isMinBounded();} ;
|
||||
|
||||
virtual bool isMaxBounded(unsigned _i)
|
||||
{ return (*this)[_i]->isMaxBounded();} ;
|
||||
|
||||
/** Folds a real value back into the bounds - i_th component
|
||||
*/
|
||||
virtual void foldsInBounds(unsigned _i, double & _r)
|
||||
{
|
||||
(*this)[_i]->foldsInBounds(_r);
|
||||
}
|
||||
|
||||
/** Folds all variables of a vector of real values into the bounds
|
||||
*/
|
||||
virtual void foldsInBounds(vector<double> & _v)
|
||||
{
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
{
|
||||
(*this)[i]->foldsInBounds(_v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Truncates a real value to the bounds - i_th component
|
||||
*/
|
||||
virtual void truncate(unsigned _i, double & _r)
|
||||
{
|
||||
(*this)[_i]->truncate(_r);
|
||||
}
|
||||
|
||||
/** truncates all variables of a vector of real values to the bounds
|
||||
*/
|
||||
virtual void truncate(vector<double> & _v)
|
||||
{
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
{
|
||||
(*this)[i]->truncate(_v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** test: is i_th component within the bounds?
|
||||
*/
|
||||
virtual bool isInBounds(unsigned _i, double _r)
|
||||
{ return (*this)[_i]->isInBounds(_r); }
|
||||
|
||||
/** test: are ALL components within the bounds?
|
||||
*/
|
||||
virtual bool isInBounds(vector<double> _v)
|
||||
{
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
if (! isInBounds(i, _v[i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Accessors: will raise an exception if these do not exist
|
||||
*/
|
||||
virtual double minimum(unsigned _i) {return (*this)[_i]->minimum();}
|
||||
virtual double maximum(unsigned _i) {return (*this)[_i]->maximum();}
|
||||
virtual double range(unsigned _i) {return (*this)[_i]->range();}
|
||||
|
||||
/** Computes the average range
|
||||
* An exception will be raised if one of the component is unbounded
|
||||
*/
|
||||
virtual double averageRange()
|
||||
{
|
||||
double r=0.0;
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
r += range(i);
|
||||
return r/size();
|
||||
}
|
||||
|
||||
/** Generates a random number in i_th range
|
||||
* An exception will be raised if one of the component is unbounded
|
||||
*/
|
||||
virtual double uniform(unsigned _i, eoRng & _rng = eo::rng)
|
||||
{
|
||||
double r= (*this)[_i]->uniform();
|
||||
return r;
|
||||
}
|
||||
|
||||
/** fills a vector with uniformly chosen variables in bounds
|
||||
* An exception will be raised if one of the component is unbounded
|
||||
*/
|
||||
void uniform(vector<double> & _v, eoRng & _rng = eo::rng)
|
||||
{
|
||||
_v.resize(size());
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
{
|
||||
_v[i] = uniform(i, _rng);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** the dummy unbounded eoRealVectorBounds: usefull if you don't need bounds!
|
||||
* everything is inlined.
|
||||
* Warning: we do need this class, and not only a vector<eoRealNoBounds *>
|
||||
*/
|
||||
class eoRealVectorNoBounds: public eoRealVectorBounds
|
||||
{
|
||||
public:
|
||||
// virtual desctructor (to avoid warning?)
|
||||
virtual ~eoRealVectorNoBounds(){}
|
||||
|
||||
/**
|
||||
* Ctor: nothing to do, but beware of dimension: call base class ctor
|
||||
*/
|
||||
eoRealVectorNoBounds(unsigned _dim=0) : eoRealVectorBounds(_dim)
|
||||
{
|
||||
// avoid NULL pointers, even though they shoudl (at the moment) never be used!
|
||||
if (_dim)
|
||||
for (unsigned i=0; i<_dim; i++)
|
||||
operator[](i)=&eoDummyRealNoBounds;
|
||||
}
|
||||
|
||||
|
||||
virtual bool isBounded(unsigned) {return false;}
|
||||
virtual bool isBounded(void) {return false;}
|
||||
|
||||
virtual bool hasNoBoundAtAll(unsigned) {return true;}
|
||||
virtual bool hasNoBoundAtAll(void) {return true;}
|
||||
|
||||
virtual bool isMinBounded(unsigned) {return false;}
|
||||
virtual bool isMaxBounded(unsigned) {return false;}
|
||||
|
||||
virtual void foldsInBounds(unsigned, double &) {return;}
|
||||
virtual void foldsInBounds(vector<double> &) {return;}
|
||||
|
||||
virtual void truncate(unsigned, double &) {return;}
|
||||
virtual void truncate(vector<double> &) {return;}
|
||||
|
||||
virtual bool isInBounds(unsigned, double) {return true;}
|
||||
virtual bool isInBounds(vector<double>) {return true;}
|
||||
|
||||
// accessors
|
||||
virtual double minimum(unsigned)
|
||||
{
|
||||
throw logic_error("Trying to get minimum of eoRealVectorNoBounds");
|
||||
}
|
||||
virtual double maximum(unsigned)
|
||||
{
|
||||
throw logic_error("Trying to get maximum of eoRealVectorNoBounds");
|
||||
}
|
||||
virtual double range(unsigned)
|
||||
{
|
||||
throw logic_error("Trying to get range of eoRealVectorNoBounds");
|
||||
}
|
||||
|
||||
virtual double averageRange()
|
||||
{
|
||||
throw logic_error("Trying to get average range of eoRealVectorNoBounds");
|
||||
}
|
||||
|
||||
// random generators
|
||||
virtual double uniform(unsigned, eoRng & _rng = eo::rng)
|
||||
{
|
||||
throw logic_error("No uniform distribution on eoRealVectorNoBounds");
|
||||
}
|
||||
|
||||
// fills a vector with uniformly chosen variables in bounds
|
||||
void uniform(vector<double> &, eoRng & _rng = eo::rng)
|
||||
{
|
||||
throw logic_error("No uniform distribution on eoRealVectorNoBounds");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// one object for all - see eoRealBounds.cpp
|
||||
extern eoRealVectorNoBounds eoDummyVectorNoBounds;
|
||||
#endif
|
||||
|
|
|
|||
413
eo/src/utils/eoRealVectorBounds.h
Normal file
413
eo/src/utils/eoRealVectorBounds.h
Normal file
|
|
@ -0,0 +1,413 @@
|
|||
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// eoRealVectorBounds.h
|
||||
// (c) Marc Schoenauer 2001, Maarten Keijzer 2000, GeNeura Team, 1998
|
||||
/*
|
||||
This library 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 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
||||
Marc.Schoenauer@polytechnique.fr
|
||||
mak@dhi.dk
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _eoRealVectorBounds_h
|
||||
#define _eoRealVectorBounds_h
|
||||
|
||||
#include <stdexcept> // exceptions!
|
||||
#include <utils/eoRNG.h>
|
||||
#include <utils/eoRealBounds.h>
|
||||
|
||||
/**
|
||||
\defgroup EvolutionStrategies
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
Vector type for bounds (see eoRealBounds.h for scalar types)
|
||||
------------
|
||||
Class eoRealVectorBounds implements the vectorized version:
|
||||
it is basically a vector of eoRealBounds * and forwards all request
|
||||
to the elements of the vector.
|
||||
|
||||
This file also contains the global variables and eoDummyVectorNoBounds
|
||||
that are used as defaults in ctors (i.e. when no
|
||||
bounds are given, it is assumed unbounded values)
|
||||
|
||||
THe 2 main classes defined here are
|
||||
|
||||
eoRealBaseVectorBounds, base class that handles all useful functions
|
||||
eoRealVectorBounds which derives from the preceding *and* eoPersistent
|
||||
and also has a mechanism for memory handling of the pointers
|
||||
it has to allocate
|
||||
*/
|
||||
class eoRealBaseVectorBounds : public vector<eoRealBounds *>
|
||||
{
|
||||
public:
|
||||
// virtual desctructor (to avoid warning?)
|
||||
virtual ~eoRealBaseVectorBounds(){}
|
||||
|
||||
/** Default Ctor.
|
||||
*/
|
||||
eoRealBaseVectorBounds() : vector<eoRealBounds *>(0) {}
|
||||
|
||||
/** Ctor: same bounds for everybody, given as an eoRealBounds
|
||||
*/
|
||||
eoRealBaseVectorBounds(unsigned _dim, eoRealBounds & _bounds) :
|
||||
vector<eoRealBounds *>(_dim, &_bounds)
|
||||
{}
|
||||
|
||||
/** Ctor, particular case of dim-2
|
||||
*/
|
||||
eoRealBaseVectorBounds(eoRealBounds & _xbounds, eoRealBounds & _ybounds) :
|
||||
vector<eoRealBounds *>(0)
|
||||
{
|
||||
push_back( &_xbounds);
|
||||
push_back( &_ybounds);
|
||||
}
|
||||
|
||||
/** test: is i_th component bounded
|
||||
*/
|
||||
virtual bool isBounded(unsigned _i)
|
||||
{
|
||||
return (*this)[_i]->isBounded();
|
||||
}
|
||||
|
||||
/** test: bounded iff all are bounded
|
||||
*/
|
||||
virtual bool isBounded(void)
|
||||
{
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
if (! (*this)[i]->isBounded())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Self-test: true iff i_th component has no bounds at all
|
||||
*/
|
||||
virtual bool hasNoBoundAtAll(unsigned _i)
|
||||
{
|
||||
return (*this)[_i]->hasNoBoundAtAll();
|
||||
}
|
||||
|
||||
/** Self-test: true iff all components have no bound at all
|
||||
*/
|
||||
virtual bool hasNoBoundAtAll(void)
|
||||
{
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
if (! (*this)[i]->hasNoBoundAtAll())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool isMinBounded(unsigned _i)
|
||||
{ return (*this)[_i]->isMinBounded();} ;
|
||||
|
||||
virtual bool isMaxBounded(unsigned _i)
|
||||
{ return (*this)[_i]->isMaxBounded();} ;
|
||||
|
||||
/** Folds a real value back into the bounds - i_th component
|
||||
*/
|
||||
virtual void foldsInBounds(unsigned _i, double & _r)
|
||||
{
|
||||
(*this)[_i]->foldsInBounds(_r);
|
||||
}
|
||||
|
||||
/** Folds all variables of a vector of real values into the bounds
|
||||
*/
|
||||
virtual void foldsInBounds(vector<double> & _v)
|
||||
{
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
{
|
||||
(*this)[i]->foldsInBounds(_v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Truncates a real value to the bounds - i_th component
|
||||
*/
|
||||
virtual void truncate(unsigned _i, double & _r)
|
||||
{
|
||||
(*this)[_i]->truncate(_r);
|
||||
}
|
||||
|
||||
/** truncates all variables of a vector of real values to the bounds
|
||||
*/
|
||||
virtual void truncate(vector<double> & _v)
|
||||
{
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
{
|
||||
(*this)[i]->truncate(_v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** test: is i_th component within the bounds?
|
||||
*/
|
||||
virtual bool isInBounds(unsigned _i, double _r)
|
||||
{ return (*this)[_i]->isInBounds(_r); }
|
||||
|
||||
/** test: are ALL components within the bounds?
|
||||
*/
|
||||
virtual bool isInBounds(vector<double> _v)
|
||||
{
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
if (! isInBounds(i, _v[i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Accessors: will raise an exception if these do not exist
|
||||
*/
|
||||
virtual double minimum(unsigned _i) {return (*this)[_i]->minimum();}
|
||||
virtual double maximum(unsigned _i) {return (*this)[_i]->maximum();}
|
||||
virtual double range(unsigned _i) {return (*this)[_i]->range();}
|
||||
|
||||
/** Computes the average range
|
||||
* An exception will be raised if one of the component is unbounded
|
||||
*/
|
||||
virtual double averageRange()
|
||||
{
|
||||
double r=0.0;
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
r += range(i);
|
||||
return r/size();
|
||||
}
|
||||
|
||||
/** Generates a random number in i_th range
|
||||
* An exception will be raised if one of the component is unbounded
|
||||
*/
|
||||
virtual double uniform(unsigned _i, eoRng & _rng = eo::rng)
|
||||
{
|
||||
double r= (*this)[_i]->uniform();
|
||||
return r;
|
||||
}
|
||||
|
||||
/** fills a vector with uniformly chosen variables in bounds
|
||||
* An exception will be raised if one of the component is unbounded
|
||||
*/
|
||||
void uniform(vector<double> & _v, eoRng & _rng = eo::rng)
|
||||
{
|
||||
_v.resize(size());
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
{
|
||||
_v[i] = uniform(i, _rng);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write object. It's called printOn since it prints the object on a stream.
|
||||
* @param _os A ostream.
|
||||
*/
|
||||
virtual void printOn(ostream& _os) const
|
||||
{
|
||||
for (unsigned i=0; i<size(); i++)
|
||||
{
|
||||
operator[](i)->printOn(_os);
|
||||
_os << ";";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/** Now a derived class, for parser reading
|
||||
* It holds some of the bounds (and destroy them when dying)
|
||||
*/
|
||||
class eoRealVectorBounds : public eoRealBaseVectorBounds, public eoPersistent
|
||||
{
|
||||
public:
|
||||
/** Default Ctor will call base class default ctor
|
||||
*/
|
||||
eoRealVectorBounds():eoRealBaseVectorBounds() {}
|
||||
|
||||
/** Ctor: same bounds for everybody, given as an eoRealBounds
|
||||
*/
|
||||
eoRealVectorBounds(unsigned _dim, eoRealBounds & _bounds) :
|
||||
eoRealBaseVectorBounds(_dim, _bounds), factor(1,_dim), ownedBounds(0)
|
||||
{}
|
||||
|
||||
/** Ctor, particular case of dim-2
|
||||
*/
|
||||
eoRealVectorBounds(eoRealBounds & _xbounds, eoRealBounds & _ybounds) :
|
||||
eoRealBaseVectorBounds(_xbounds, _ybounds), factor(1,2), ownedBounds(0)
|
||||
{}
|
||||
|
||||
/** Simple bounds = minimum and maximum (allowed)
|
||||
*/
|
||||
eoRealVectorBounds(unsigned _dim, double _min, double _max) :
|
||||
eoRealBaseVectorBounds(), factor(1, _dim), ownedBounds(0)
|
||||
{
|
||||
if (_max-_min<=0)
|
||||
throw std::logic_error("Void range in eoRealVectorBounds");
|
||||
eoRealBounds *ptBounds = new eoRealInterval(_min, _max);
|
||||
// handle memory once
|
||||
ownedBounds.push_back(ptBounds);
|
||||
// same bound for everyone
|
||||
for (unsigned int i=0; i<_dim; i++)
|
||||
push_back(ptBounds);
|
||||
}
|
||||
|
||||
/** Ctor: different bounds for different variables, vectors of double
|
||||
*/
|
||||
eoRealVectorBounds(vector<double> _min, vector<double> _max) :
|
||||
factor(_min.size(), 1), ownedBounds(0)
|
||||
{
|
||||
if (_max.size() != _min.size())
|
||||
throw std::logic_error("Dimensions don't match in eoRealVectorBounds");
|
||||
// the bounds
|
||||
eoRealBounds *ptBounds;
|
||||
for (unsigned i=0; i<_min.size(); i++)
|
||||
{
|
||||
ptBounds = new eoRealInterval(_min[i], _max[i]);
|
||||
ownedBounds.push_back(ptBounds);
|
||||
push_back(ptBounds);
|
||||
}
|
||||
}
|
||||
|
||||
/** Dtor: destroy all ownedBounds - BUG ???*/
|
||||
virtual ~eoRealVectorBounds()
|
||||
{
|
||||
// cout << "Dtor, avec size = " << ownedBounds.size() << endl;
|
||||
// for (unsigned i = 0; i < ownedBounds.size(); ++i)
|
||||
// {
|
||||
// delete ownedBounds[i];
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
// methods from eoPersistent
|
||||
/**
|
||||
* Read object from a stream
|
||||
* only calls the readFrom(string) - for param reading
|
||||
* @param _is A istream.
|
||||
*/
|
||||
virtual void readFrom(istream& _is) ;
|
||||
|
||||
/**
|
||||
* Read object from a string
|
||||
* @param _is A istream.
|
||||
*/
|
||||
virtual void readFrom(string _s) ;
|
||||
|
||||
/** overload printOut method to save space */
|
||||
virtual void printOn(ostream& _os) const
|
||||
{
|
||||
if (factor[0]>1)
|
||||
_os << factor[0] ;
|
||||
operator[](0)->printOn(_os);
|
||||
|
||||
// other bounds
|
||||
unsigned int index=factor[0];
|
||||
if (factor.size()>1)
|
||||
for (unsigned i=1; i<factor.size(); i++)
|
||||
{
|
||||
_os << ";";
|
||||
if (factor[i] > 1)
|
||||
_os << factor[i];
|
||||
operator[](index)->printOn(_os);
|
||||
index += factor[i];
|
||||
}
|
||||
}
|
||||
|
||||
/** Eventually increases the size by duplicating last bound */
|
||||
void adjust_size(unsigned _dim);
|
||||
|
||||
/** need to rewrite copy ctor and assignement operator
|
||||
* because of ownedBounds */
|
||||
eoRealVectorBounds(const eoRealVectorBounds &);
|
||||
|
||||
private:// WARNING: there is no reason for both vector below
|
||||
//to be synchronized in any manner
|
||||
vector<unsigned int> factor; // list of nb of "grouped" bounds
|
||||
vector<eoRealBounds *> ownedBounds;
|
||||
// keep this one private
|
||||
eoRealVectorBounds& operator=(const eoRealVectorBounds&);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
/** the dummy unbounded eoRealVectorBounds: usefull if you don't need bounds!
|
||||
* everything is inlined.
|
||||
* Warning: we do need this class, and not only a vector<eoRealNoBounds *>
|
||||
*/
|
||||
class eoRealVectorNoBounds: public eoRealVectorBounds
|
||||
{
|
||||
public:
|
||||
// virtual desctructor (to avoid warning?)
|
||||
virtual ~eoRealVectorNoBounds(){}
|
||||
|
||||
/**
|
||||
* Ctor: nothing to do, but beware of dimension: call base class ctor
|
||||
*/
|
||||
eoRealVectorNoBounds(unsigned _dim) :
|
||||
eoRealVectorBounds( (_dim?_dim:1), eoDummyRealNoBounds)
|
||||
{}
|
||||
|
||||
|
||||
virtual bool isBounded(unsigned) {return false;}
|
||||
virtual bool isBounded(void) {return false;}
|
||||
|
||||
virtual bool hasNoBoundAtAll(unsigned) {return true;}
|
||||
virtual bool hasNoBoundAtAll(void) {return true;}
|
||||
|
||||
virtual bool isMinBounded(unsigned) {return false;}
|
||||
virtual bool isMaxBounded(unsigned) {return false;}
|
||||
|
||||
virtual void foldsInBounds(unsigned, double &) {return;}
|
||||
virtual void foldsInBounds(vector<double> &) {return;}
|
||||
|
||||
virtual void truncate(unsigned, double &) {return;}
|
||||
virtual void truncate(vector<double> &) {return;}
|
||||
|
||||
virtual bool isInBounds(unsigned, double) {return true;}
|
||||
virtual bool isInBounds(vector<double>) {return true;}
|
||||
|
||||
// accessors
|
||||
virtual double minimum(unsigned)
|
||||
{
|
||||
throw logic_error("Trying to get minimum of eoRealVectorNoBounds");
|
||||
}
|
||||
virtual double maximum(unsigned)
|
||||
{
|
||||
throw logic_error("Trying to get maximum of eoRealVectorNoBounds");
|
||||
}
|
||||
virtual double range(unsigned)
|
||||
{
|
||||
throw logic_error("Trying to get range of eoRealVectorNoBounds");
|
||||
}
|
||||
|
||||
virtual double averageRange()
|
||||
{
|
||||
throw logic_error("Trying to get average range of eoRealVectorNoBounds");
|
||||
}
|
||||
|
||||
// random generators
|
||||
virtual double uniform(unsigned, eoRng & _rng = eo::rng)
|
||||
{
|
||||
throw logic_error("No uniform distribution on eoRealVectorNoBounds");
|
||||
}
|
||||
|
||||
// fills a vector with uniformly chosen variables in bounds
|
||||
void uniform(vector<double> &, eoRng & _rng = eo::rng)
|
||||
{
|
||||
throw logic_error("No uniform distribution on eoRealVectorNoBounds");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// one object for all - see eoRealBounds.cpp
|
||||
extern eoRealVectorNoBounds eoDummyVectorNoBounds;
|
||||
#endif
|
||||
Reference in a new issue