Added utilities directory, this contains state, parser etc.

This commit is contained in:
mac 2000-03-22 14:04:03 +00:00
commit 81751e279f
9 changed files with 1383 additions and 0 deletions

View file

@ -0,0 +1,71 @@
/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
-----------------------------------------------------------------------------
compatibility.h
File to store some compiler specific stuff in. Currently handles, or
least tries to handle the min() max() problems when using MSVC
(c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 2000
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
*/
#ifndef COMPAT_H
#define COMPAT_H
#include <string>
#include <iostream>
#ifdef _MSC_VER
/*
Maarten: added this code here because Mirkosoft has the
nasty habit of #define min and max in stdlib.h (and windows.h)
I'm trying to undo this horrible macro magic (microsoft yet macrohard)
here. Sure hope it works
*/
#include <stdlib.h>
#ifdef min
#undef min
#undef max // as they come in pairs
#endif
// add min and max to std...
namespace std
{
template <class T> const T& min(const T& a, const T& b)
{
if(a < b)
return a;
// else
return b;
}
template <class T> const T& max(const T& a, const T& b)
{
if(a > b)
return a;
// else
return b;
}
}
#endif // _MSC_VER
#endif

64
eo/src/utils/eoData.h Normal file
View file

@ -0,0 +1,64 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
-----------------------------------------------------------------------------
eoData.h
Some numeric limits and types and things like that; with #ifdefs to keep
compatibility
(c) GeNeura Team & Maarten Keijzer, 1998, 1999, 2000
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
*/
#ifndef EODATA_H
#define EODATA_H
//-----------------------------------------------------------------------------
#include <vector> // vector
#include <set> // set
#include <string> // string
using namespace std;
#ifdef _MSC_VER
#include <limits> // MAXDOUBLE
#define MAXFLOAT numeric_limits<float>::max()
#define MINFLOAT numeric_limits<float>::min()
#define MAXDOUBLE numeric_limits<double>::max()
#define MAXINT numeric_limits<int>::max()
#else
#include <float.h>
#include <limits.h>
#ifndef _WIN32 // should be the define for UN*X flavours: _POSIX??
#include <values.h>
#endif
#ifndef MAXFLOAT
#define MAXFLOAT (float)1e127
#define MAXDOUBLE (double)1.79769313486231570e+308
#define MAXINT 2147483647
#endif
#endif
#ifndef _MSC_VER
#include <math.h>
#define _isnan isnan
#endif
//-----------------------------------------------------------------------------
#endif EODATA_H

192
eo/src/utils/eoParam.h Normal file
View file

@ -0,0 +1,192 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoParam.h
// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000
/*
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
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifndef eoParam_h
#define eoParam_h
//-----------------------------------------------------------------------------
#include <string>
#include <strstream>
/**
eoParam: Base class for monitoring and parsing parameters
*/
class eoParam
{
public:
/** Empty constructor - called from outside any parser
*/
eoParam ()
: repLongName(""), repDescription(""), repDefault(""),
repShortHand(0), repRequired(false){}
/**
* Construct a Param.
* @param _longName Long name of the argument
* @param _default The default value
* @param _description Description of the parameter. What is useful for.
* @param _shortName Short name of the argument (Optional)
* @param _required If it is a necessary parameter or not
*/
eoParam (std::string _longName, std::string _default,
std::string _description, char _shortName = 0, bool _required = false)
: repShortHand(_shortName), repLongName(_longName),
repDescription(_description ), repDefault(_default),
repRequired( _required) {}
/**
* Virtual destructor is needed.
*/
virtual ~eoParam () {};
/**
* Pure virtual function to get the value out.
*/
virtual std::string getValue ( void ) const = 0;
/**
* Pure virtual function to set the value
*/
virtual void setValue(std::string _value) = 0 ;
/**
* Returns the short name.
*/
char shortName ( void ) const { return repShortHand; };
/**
* Returns the long name.
*/
const std::string& longName ( void ) const { return repLongName; };
/**
* Returns the description of the argument
*/
const std::string& description ( void ) const { return repDescription; };
/**
* Returns the default value of the argument
*/
const std::string& defValue ( void ) const { return repDefault; };
/**
* Sets the default value of the argument,
*/
void defValue ( std::string str ) { repDefault = str; };
/**
* Returns the value of the param as a string
*/
/**
* Returns if required or not.
*/
bool required ( void ) const { return repRequired; };
private:
std::string repLongName;
std::string repDefault;
std::string repDescription;
char repShortHand;
bool repRequired;
};
/**
eoValueParam<ValueType>: templatized derivation of eoParam. Can be used to contain
any scalar value type. It makes use of std::strstream to get and set values. This
should be changed to std::stringstream when that class is available in g++.
*/
template <class ValueType>
class eoValueParam : public eoParam
{
public :
eoValueParam(void) : eoParam() {}
/**
* Construct a Param.
* @param _defaultValue The default value
* @param _longName Long name of the argument
* @param _description Description of the parameter. What is useful for.
* @param _shortName Short name of the argument (Optional)
* @param _required If it is a necessary parameter or not
*/
eoValueParam (ValueType _defaultValue,
std::string _longName,
std::string _description,
char _shortHand = 0,
bool _required = false)
: repValue(_defaultValue), eoParam(_longName, "", _description, _shortHand, _required)
{
eoParam::defValue(getValue());
}
ValueType& value() { return repValue; }
ValueType value() const { return repValue; }
std::string getValue(void) const
{
std::ostrstream os;
os << repValue;
os << std::ends;
return os.str();
}
void setValue(std::string _value)
{
std::istrstream is(_value.c_str());
is >> repValue;
}
private :
ValueType repValue;
};
/*template <class ContainerType>
class eoContainerParam : public eoParam
{
public :
eoContainerParam (ContainerType& value, string _shortName, string _longName,
string _default,
string _description,
bool _required,
bool _change )
: value(_value), eoParam(_shortName, _longName, _description, _default, _required, _change)
{}
// void setValue(const string & _value)
// {
// std::istringstream is(_value);
// copy(istream_iterator<Container::value_type>(is), istream_iterator<Container::value_type>(), back_inserter(value));
// }
private :
ContainerType& value;
};*/
#endif

232
eo/src/utils/eoParser.cpp Normal file
View file

@ -0,0 +1,232 @@
#include <algorithm>
#include <fstream>
#include <iomanip>
#include "eoParser.h"
using namespace std;
std::ostream& printSectionHeader(std::ostream& os, std::string section)
{
os << '\n' << setw(10) << "###### " << setw(20) << section << setw(10) << " ######\n";
return os;
}
eoParser::eoParser ( int _argc, char **_argv , string _programDescription, string _lFileParamName, char _shortHand) :
programName( _argv[0]),
programDescription( _programDescription),
parameterFile("", _lFileParamName, "Load using a configuration file", _shortHand),
needHelp(false, "help", "Prints this message", 'h')
{
strstream stream;
for (int i = 1; i < _argc; ++i)
{
stream << _argv[i] << '\n';
}
readFrom(stream);
processParam(parameterFile);
processParam(needHelp);
if (parameterFile.getValue() != parameterFile.defValue())
{
ifstream is (parameterFile.getValue().c_str());
readFrom(is);
}
}
void eoParser::processParam(eoParam& param, std::string section)
{
doRegisterParam(param); // plainly register it
params.insert(make_pair(section, &param));
}
void eoParser::doRegisterParam(eoParam& param) const
{
if (param.required() && !isItThere(param))
{
throw runtime_error("required parameter missing");
}
pair<bool, string> value = getValue(param);
if (value.first)
{
if (value.second == "") // it is there, but no value is given, default to "1"
value.second = "1"; // for bool
param.setValue(value.second);
}
}
pair<bool, string> eoParser::getValue(eoParam& _param) const
{
pair<bool, string> result(false, "");
if (_param.shortName() != 0)
{
map<char, string>::const_iterator it = shortNameMap.find(_param.shortName());
if (it != shortNameMap.end())
{
result.second = it->second;
result.first = true;
return result;
}
}
map<string, string>::const_iterator it = longNameMap.find(_param.longName());
if (it != longNameMap.end())
{
result.second = it->second;
result.first = true;
return result;
}
// else (TODO: check environment, just long names)
return result;
}
void eoParser::updateParameters() const
{
typedef MultiMapType::const_iterator It;
for (It p = params.begin(); p != params.end(); ++p)
{
doRegisterParam(*p->second);
}
}
void eoParser::readFrom(istream& is)
{
string str;
while (is >> str)
{
if (str[0] == '#')
{ // skip the rest of the line
string tempStr;
getline(is, tempStr);
}
if (str[0] == '-')
{
if (str.size() < 2)
{
eoWarning("Missing parameter");
needHelp.value() = true;
return;
}
if (str[1] == '-') // two consecutive dashes
{
string::iterator equalLocation = find(str.begin() + 2, str.end(), '=');
string value;
if (equalLocation == str.end())
{ // TODO: it should be the next string
value = "";
}
else
{
value = string(equalLocation + 1, str.end());
}
string name(str.begin() + 2, equalLocation);
longNameMap[name] = value;
}
else // it should be a char
{
string value(str.begin() + 2, str.end());
shortNameMap[str[1]] = value;
}
}
}
updateParameters();
}
void eoParser::printOn(ostream& os) const
{
typedef MultiMapType::const_iterator It;
It p = params.begin();
std::string section = p->first;
printSectionHeader(os, section);
//print every param with its value
for (; p != params.end(); ++p)
{
std::string newSection = p->first;
if (newSection != section)
{
section = newSection;
printSectionHeader(os, section);
}
eoParam* param = p->second;
string str = "--" + param->longName() + "=" + param->getValue();
os << left << setw(40) << str;
os << " # " << '-' << param->shortName() << " : " << param->description();
if (param->required())
{
os << " REQUIRED ";
}
os << '\n';
}
}
void eoParser::printHelp(ostream& os)
{
// print program name and description
os << this->programName <<": "<< programDescription << "\n\n";
// print the usage when calling the program from the command line
os << "Usage: "<< programName<<" [Options]\n";
// only short usage!
os << "Options of the form \"-ShortName value\" or \"--LongName value\"" << endl;
os << "Where:"<<endl;
typedef MultiMapType::const_iterator It;
It p = params.begin();
std::string section = p->first;
printSectionHeader(os, section);
//print every param with its value
for (; p != params.end(); ++p)
{
std::string newSection = p->first;
if (newSection != section)
{
section = newSection;
printSectionHeader(os, section);
}
if (p->second->shortName())
os << "-" << p->second->shortName() << ", ";
os << "--" <<p->second->longName() <<":\t"
<< p->second->description() ;
os << "\n" << setw(20) << ( (p->second->required())?"Required":"Optional" );
os <<". By default: "<<p->second->defValue() << '\n';
} // for p
os << '\n';
}

136
eo/src/utils/eoParser.h Normal file
View file

@ -0,0 +1,136 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoParser.h
// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000
/*
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
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifndef eoParser_h
#define eoParser_h
#include <map>
#include <string>
#include <map>
#include "eoParam.h"
#include "eoObject.h"
#include "eoPersistent.h"
/**
eoParameterLoader is an abstract class that can be used as a base for your own
parameter loading and saving. The command line parser eoParser is derived from
this class.
*/
class eoParameterLoader
{
public :
/** Need a virtual destructor */
virtual ~eoParameterLoader() {}
/**
* processParam is used to register a parameter and set its value if it is known
*
* @param param the parameter to process
* @param section the section where this parameter belongs
*/
virtual void processParam(eoParam& param, std::string section = "") = 0;
};
void eoWarning(std::string str)
{
cout << str << '\n';
}
/**
eoParser: command line parser and configuration file reader
This class is persistent, so it can be stored and reloaded to restore
parameter settings.
*/
class eoParser : public eoParameterLoader, public eoObject, public eoPersistent
{
public:
/**
* Constructor
* a complete constructor that reads the command line an optionally reads
* a configuration file.
*
* myEo --param-file=param.rc will then load using the parameter file param.rc
*
* @param _argc, _ argv command line arguments
* @param _programDescription Description of the work the program does
* @param _lFileParamName Name of the parameter specifying the configuration file (--param-file)
* @param _shortHand Single charachter shorthand for specifying the configuration file
*/
eoParser ( int _argc, char **_argv , string _programDescription = "",
string _lFileParamName = "param-file", char _shortHand = 'p');
/**
Processes the parameter and puts it in the appropriate section for readability
*/
void processParam(eoParam& param, std::string section = "");
void readFrom(istream& is);
void printOn(ostream& os) const;
/// className for readibility
std::string className(void) const { return "Parser"; }
/// true if the user made an error or asked for help
bool userNeedsHelp(void) const { return needHelp.value(); }
/**
* Prints an automatic help in the specified output using the information
* provided by parameters
*/
void printHelp(ostream& os);
string ProgramName() { return programName; }
private:
void doRegisterParam(eoParam& param) const;
bool isItThere(eoParam& _param) const { return getValue(_param).first; }
std::pair<bool, string> getValue(eoParam& _param) const;
void updateParameters() const;
typedef std::multimap<std::string, eoParam*> MultiMapType;
MultiMapType params;
string programName;
string programDescription;
map<char, string> shortNameMap;
map<string, string> longNameMap;
eoValueParam<string> parameterFile;
eoValueParam<bool> needHelp;
};
#endif

5
eo/src/utils/eoRNG.cpp Normal file
View file

@ -0,0 +1,5 @@
#include <ctime>
#include "eoRNG.h"
eoRng rng((uint32) time(0));

452
eo/src/utils/eoRNG.h Normal file
View file

@ -0,0 +1,452 @@
/*
* Random number generator adapted from (see comments below)
*
* The random number generator is modified into a class
* by Maarten Keijzer (mak@dhi.dk). Also added the Box-Muller
* transformation to generate normal deviates.
*
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
*/
/* ************ DOCUMENTATION IN ORIGINAL FILE *********************/
// This is the ``Mersenne Twister'' random number generator MT19937, which
// generates pseudorandom integers uniformly distributed in 0..(2^32 - 1)
// starting from any odd seed in 0..(2^32 - 1). This version is a recode
// by Shawn Cokus (Cokus@math.washington.edu) on March 8, 1998 of a version by
// Takuji Nishimura (who had suggestions from Topher Cooper and Marc Rieffel in
// July-August 1997).
//
// Effectiveness of the recoding (on Goedel2.math.washington.edu, a DEC Alpha
// running OSF/1) using GCC -O3 as a compiler: before recoding: 51.6 sec. to
// generate 300 million random numbers; after recoding: 24.0 sec. for the same
// (i.e., 46.5% of original time), so speed is now about 12.5 million random
// number generations per second on this machine.
//
// According to the URL <http://www.math.keio.ac.jp/~matumoto/emt.html>
// (and paraphrasing a bit in places), the Mersenne Twister is ``designed
// with consideration of the flaws of various existing generators,'' has
// a period of 2^19937 - 1, gives a sequence that is 623-dimensionally
// equidistributed, and ``has passed many stringent tests, including the
// die-hard test of G. Marsaglia and the load test of P. Hellekalek and
// S. Wegenkittl.'' It is efficient in memory usage (typically using 2506
// to 5012 bytes of static data, depending on data type sizes, and the code
// is quite short as well). It generates random numbers in batches of 624
// at a time, so the caching and pipelining of modern systems is exploited.
// It is also divide- and mod-free.
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Library 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 Library General Public License for more details. You should have
// received a copy of the GNU Library 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.
//
// The code as Shawn received it included the following notice:
//
// Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. When
// you use this, send an e-mail to <matumoto@math.keio.ac.jp> with
// an appropriate reference to your work.
//
// It would be nice to CC: <Cokus@math.washington.edu> when you write.
//
//
// uint32 must be an unsigned integer type capable of holding at least 32
// bits; exactly 32 should be fastest, but 64 is better on an Alpha with
// GCC at -O3 optimization so try your options and see what's best for you
//
/* ************ END DOCUMENTATION IN ORIGINAL FILE *********************/
#ifndef EO_RANDOM_NUMBER_GENERATOR
#define EO_RANDOM_NUMBER_GENERATOR
#include <eoPersistent.h>
#include <eoObject.h>
// TODO: check for various compilers if this is exactly 32 bits
// Unfortunately MSVC's preprocessor does not comprehends sizeof()
// so neat preprocessing tricks will not work
typedef unsigned long uint32; // Compiler and platform dependent!
//-----------------------------------------------------------------------------
// eoRng
//-----------------------------------------------------------------------------
/**
eoRng is a persitent class that uses the ``Mersenne Twister'' random number generator MT19937
for generating random numbers. The various member functions implement useful functions
for evolutionary algorithms. Included are: rand(), random(), flip() and normal().
Note for people porting EO to other platforms: please make sure that the typedef
uint32 in the file eoRng.h is exactly 32 bits long. It may be longer, but not
shorter. If it is longer, file compatibility between EO on different platforms
may be broken.
*/
class eoRng : public eoObject, public eoPersistent
{
public :
/**
ctor takes a random seed; if you want another seed, use reseed
@see reseed
*/
eoRng(uint32 s) : state(0), next(0), left(-1), cached(false), N(624), M(397), K(0x9908B0DFU) {
state = new uint32[N+1];
initialize(s);
}
~eoRng(void)
{
delete [] state;
}
/**
Re-initializes the Random Number Generator.
*/
void reseed(uint32 s)
{
initialize(s);
}
/**
uniform(m = 1.0) returns a random double in the range [0, m)
*/
double uniform(double m = 1.0)
{ // random number between [0, m]
return m * double(rand()) / double(rand_max());
}
/**
random() returns a random integer in the range [0, m)
*/
uint32 random(uint32 m)
{
return uint32(uniform() * double(m));
}
/**
flip() tosses a biased coin such that flip(x/100.0) will
returns true x% of the time
*/
bool flip(float bias)
{
return uniform() < bias;
}
/**
normal() zero mean gaussian deviate with standard deviation of 1
*/
double normal(void); // gaussian mutation, stdev 1
/**
normal(stdev) zero mean gaussian deviate with user defined standard deviation
*/
double normal(double stdev)
{
return stdev * normal();
}
/**
normal(mean, stdev) user defined mean gaussian deviate with user defined standard deviation
*/
double normal(double mean, double stdev)
{
return mean + normal(stdev);
}
/**
rand() returns a random number in the range [0, rand_max)
*/
uint32 rand();
/**
rand_max() the maximum returned by rand()
*/
uint32 rand_max(void) const { return (uint32) 0xffffffff; }
/**
roulette_wheel(vec, total = 0) does a roulette wheel selection
on the input vector vec. If the total is not supplied, it is
calculated. It returns an integer denoting the selected argument.
*/
template <class T>
int roulette_wheel(const std::vector<T>& vec, T total = 0)
{
if (total == 0)
{ // count
for (unsigned i = 0; i < vec.size(); ++i)
total += vec[i];
}
float change = uniform() * total;
int i = 0;
while (change > 0)
{
change -= vec[i++];
}
return --i;
}
///
void printOn(ostream& _os) const
{
for (int i = 0; i < N; ++i)
{
_os << state[i] << ' ';
}
_os << int(next - state) << ' ';
_os << left << ' ' << cached << ' ' << cacheValue;
}
///
void readFrom(istream& _is)
{
for (int i = 0; i < N; ++i)
{
_is >> state[i];
}
int n;
_is >> n;
next = state + n;
_is >> left;
_is >> cached;
_is >> cacheValue;
}
private :
uint32 restart(void);
void initialize(uint32 seed);
uint32* state; // the array for the state
uint32* next;
int left;
bool cached;
float cacheValue;
const int N;
const int M;
const uint32 K; // a magic constant
/**
Private copy ctor and assignment operator to make sure that
nobody accidentally copies the random number generator.
If you want similar RNG's, make two RNG's and initialize
them with the same seed.
*/
eoRng (const eoRng&); // no implementation
eoRng& operator=(const eoRng&); // dito
};
/**
The one and only global eoRng object
*/
extern eoRng rng;
/**
The class uniform_generator can be used in the STL generate function
to easily generate random floats and doubles between [0, _max). _max
defaults to 1.0
*/
template <class T = double> class uniform_generator
{
public :
uniform_generator(T _max = T(1.0), eoRng& _rng = rng) : maxim(_max), uniform(_rng) {}
virtual T operator()(void) { return (T) uniform.uniform(maxim); }
private :
T maxim;
eoRng& uniform;
};
/**
The class random_generator can be used in the STL generate function
to easily generate random ints between [0, _max).
*/
template <class T = uint32> class random_generator
{
public :
random_generator(int _max, eoRng& _rng = rng) : maxim(_max), random(_rng) {}
virtual T operator()(void) { return (T) random.random(max); }
private :
T maxim;
eoRng& random;
};
/**
The class normal_generator can be used in the STL generate function
to easily generate gaussian distributed floats and doubles. The user
can supply a standard deviation which defaults to 1.
*/
template <class T = double> class normal_generator
{
public :
normal_generator(T _stdev = T(1.0), eoRng& _rng = rng) : stdev(_stdev), normal(_rng) {}
virtual T operator()(void) { return (T) normal.normal(stdev); }
private :
T stdev;
eoRng& normal;
};
// Implementation of some eoRng members.... Don't mind the mess, it does work.
#define hiBit(u) ((u) & 0x80000000U) // mask all but highest bit of u
#define loBit(u) ((u) & 0x00000001U) // mask all but lowest bit of u
#define loBits(u) ((u) & 0x7FFFFFFFU) // mask the highest bit of u
#define mixBits(u, v) (hiBit(u)|loBits(v)) // move hi bit of u to hi bit of v
inline void eoRng::initialize(uint32 seed)
{
//
// We initialize state[0..(N-1)] via the generator
//
// x_new = (69069 * x_old) mod 2^32
//
// from Line 15 of Table 1, p. 106, Sec. 3.3.4 of Knuth's
// _The Art of Computer Programming_, Volume 2, 3rd ed.
//
// Notes (SJC): I do not know what the initial state requirements
// of the Mersenne Twister are, but it seems this seeding generator
// could be better. It achieves the maximum period for its modulus
// (2^30) iff x_initial is odd (p. 20-21, Sec. 3.2.1.2, Knuth); if
// x_initial can be even, you have sequences like 0, 0, 0, ...;
// 2^31, 2^31, 2^31, ...; 2^30, 2^30, 2^30, ...; 2^29, 2^29 + 2^31,
// 2^29, 2^29 + 2^31, ..., etc. so I force seed to be odd below.
//
// Even if x_initial is odd, if x_initial is 1 mod 4 then
//
// the lowest bit of x is always 1,
// the next-to-lowest bit of x is always 0,
// the 2nd-from-lowest bit of x alternates ... 0 1 0 1 0 1 0 1 ... ,
// the 3rd-from-lowest bit of x 4-cycles ... 0 1 1 0 0 1 1 0 ... ,
// the 4th-from-lowest bit of x has the 8-cycle ... 0 0 0 1 1 1 1 0 ... ,
// ...
//
// and if x_initial is 3 mod 4 then
//
// the lowest bit of x is always 1,
// the next-to-lowest bit of x is always 1,
// the 2nd-from-lowest bit of x alternates ... 0 1 0 1 0 1 0 1 ... ,
// the 3rd-from-lowest bit of x 4-cycles ... 0 0 1 1 0 0 1 1 ... ,
// the 4th-from-lowest bit of x has the 8-cycle ... 0 0 1 1 1 1 0 0 ... ,
// ...
//
// The generator's potency (min. s>=0 with (69069-1)^s = 0 mod 2^32) is
// 16, which seems to be alright by p. 25, Sec. 3.2.1.3 of Knuth. It
// also does well in the dimension 2..5 spectral tests, but it could be
// better in dimension 6 (Line 15, Table 1, p. 106, Sec. 3.3.4, Knuth).
//
// Note that the random number user does not see the values generated
// here directly since restart() will always munge them first, so maybe
// none of all of this matters. In fact, the seed values made here could
// even be extra-special desirable if the Mersenne Twister theory says
// so-- that's why the only change I made is to restrict to odd seeds.
//
left = -1;
register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = state;
register int j;
for(left=0, *s++=x, j=N; --j;
*s++ = (x*=69069U) & 0xFFFFFFFFU);
}
inline uint32 eoRng::restart(void)
{
register uint32 *p0=state, *p2=state+2, *pM=state+M, s0, s1;
register int j;
left=N-1, next=state+1;
for(s0=state[0], s1=state[1], j=N-M+1; --j; s0=s1, s1=*p2++)
*p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
for(pM=state, j=M; --j; s0=s1, s1=*p2++)
*p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
s1=state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
s1 ^= (s1 >> 11);
s1 ^= (s1 << 7) & 0x9D2C5680U;
s1 ^= (s1 << 15) & 0xEFC60000U;
return(s1 ^ (s1 >> 18));
}
inline uint32 eoRng::rand(void)
{
uint32 y;
if(--left < 0)
return(restart());
y = *next++;
y ^= (y >> 11);
y ^= (y << 7) & 0x9D2C5680U;
y ^= (y << 15) & 0xEFC60000U;
return(y ^ (y >> 18));
}
inline double eoRng::normal(void)
{
if (cached)
{
cached = false;
return cacheValue;
}
float rSquare, factor, var1, var2;
do
{
var1 = 2.0 * uniform() - 1.0;
var2 = 2.0 * uniform() - 1.0;
rSquare = var1 * var1 + var2 * var2;
}
while (rSquare >= 1.0 || rSquare == 0.0);
factor = sqrt(-2.0 * log(rSquare) / rSquare);
cacheValue = var1 * factor;
cached = true;
return (var2 * factor);
}
#endif

147
eo/src/utils/eoState.cpp Normal file
View file

@ -0,0 +1,147 @@
#ifdef _MSC_VER
#pragma warning(disable:4786)
#endif
#include <algorithm>
#include <fstream>
#include <strstream>
#include "eoState.h"
#include "eoObject.h"
#include "eoPersistent.h"
using namespace std;
void removeComment(string& str, string comment)
{
string::size_type pos = str.find(comment);
if (pos != string::npos)
{
str.erase(pos, str.size());
}
}
bool is_section(const string& str, string& name)
{
string::size_type pos = str.find("\\section{");
if (pos == string::npos)
return false;
//else
string::size_type end = str.find("}");
if (end == string::npos)
return false;
// else
name = str.substr(pos + 9, end-9);
return true;
}
void eoState::registerObject(eoPersistent& registrant)
{
string name = createObjectName(dynamic_cast<eoObject*>(&registrant));
objectMap[name] = &registrant;
}
void eoState::load(const string& _filename)
{
ifstream is (_filename.c_str());
if (is.fail())
{
string str = "Could not open file " + _filename;
throw runtime_error(str);
}
string str;
string name;
getline(is, str);
while(is)
{ // parse section header
if (is_section(str, name))
{
string fullString;
ObjectMap::iterator it = objectMap.find(name);
if (it == objectMap.end())
{ // ignore
while (getline(is, str))
{
if (is_section(str, name))
break;
}
}
else
{
eoPersistent* object = it->second;
// now we have the object, get lines, remove comments etc.
string fullstring;
while (getline(is, str))
{
if (is_section(str, name))
break;
removeComment(str, getCommentString());
fullstring += str + "\n";
}
istrstream the_stream(fullstring.c_str(), fullstring.size());
object->readFrom(the_stream);
}
}
}
}
void eoState::save(const string& filename)
{
ofstream os(filename.c_str());
for (ObjectMap::iterator it = objectMap.begin(); it != objectMap.end(); ++it)
{
os << "\\section{" << it->first << "}\n";
it->second->printOn(os);
os << '\n';
}
}
string eoState::createObjectName(eoObject* obj)
{
if (obj == 0)
{
ostrstream os;
os << objectMap.size();
return os.str();
}
// else
string name = obj->className();
ObjectMap::const_iterator it = objectMap.find(name);
unsigned count = 1;
while (it != objectMap.end())
{
ostrstream os;
os << obj->className().c_str() << count++ << ends;
name = os.str();
it = objectMap.find(name);
}
return name;
}

84
eo/src/utils/eoState.h Normal file
View file

@ -0,0 +1,84 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoState.h
// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000
/*
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
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifndef eoState_h
#define eoState_h
#include <stdexcept>
#include <string>
#include <map>
class eoObject;
class eoPersistent;
/**
* eoState can be used to register derivants of eoPersistent. It will
* then in turn implement the persistence framework through members load
* and save, that will call readFrom and printOn for the registrated objects.
*/
class eoState
{
public :
/**
* Object registration function, note that it does not take ownership!
*/
void registerObject(eoPersistent& registrant);
/**
* Loading error thrown when nothing seems to work.
*/
struct loading_error : public std::runtime_error
{
loading_error(std::string huh = "Error while loading") : std::runtime_error(huh) {}
};
std::string getCommentString(void) const { return "#"; }
/**
* Reads the file specified
*
* @param _filename the name of the file to load from
*/
void load(const std::string& _filename);
/**
* Saves the state in file specified
*
* @param _filename the name of the file to save into
*/
void save(const std::string& _filename);
private :
std::string createObjectName(eoObject* obj);
// first is Persistent, second is the raw data associated with it.
typedef std::map<std::string, eoPersistent*> ObjectMap;
ObjectMap objectMap;
};
#endif //eoState_h