Robot Simulator of the Robotics Group for Self-Organization of Control: noisegenerator.h Source File

- Main Page
- Namespaces
- Classes
- Files
- Directories
- Related Pages
- Examples

- Search for |

- File List
- File Members

# noisegenerator.h

Go to the documentation of this file.

    00001 /***************************************************************************
    00002  *   Copyright (C) 2005 by Robot Group Leipzig                             *
    00003  *    martius@informatik.uni-leipzig.de                                    *
    00004  *    fhesse@informatik.uni-leipzig.de                                     *
    00005  *    der@informatik.uni-leipzig.de                                        *
    00006  *                                                                         *
    00007  *   This program is free software; you can redistribute it and/or modify  *
    00008  *   it under the terms of the GNU General Public License as published by  *
    00009  *   the Free Software Foundation; either version 2 of the License, or     *
    00010  *   (at your option) any later version.                                   *
    00011  *                                                                         *
    00012  *   This program is distributed in the hope that it will be useful,       *
    00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
    00015  *   GNU General Public License for more details.                          *
    00016  *                                                                         *
    00017  *   You should have received a copy of the GNU General Public License     *
    00018  *   along with this program; if not, write to the                         *
    00019  *   Free Software Foundation, Inc.,                                       *
    00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
    00021  *                                                                         *
    00022  *   $Log: noisegenerator.h,v $
    00023  *   Revision 1.9  2009/07/30 06:17:46  jhoffmann
    00024  *   Bugfix: remove memory leak when internal random generator is used
    00025  *
    00026  *   Revision 1.8  2009/03/31 15:46:40  martius
    00027  *   ColorUniform noise has functions to get and set tau
    00028  *
    00029  *   Revision 1.7  2009/03/26 19:15:29  martius
    00030  *   NoNoise added (important for WiringSequence, to avoid multiple noise)
    00031  *
    00032  *   Revision 1.6  2009/01/22 16:51:14  martius
    00033  *   sinenoise is now scaled with noise strength
    00034  *
    00035  *   Revision 1.5  2008/05/30 11:58:27  martius
    00036  *   use cmath instead of math.h
    00037  *
    00038  *   Revision 1.4  2008/05/07 16:45:52  martius
    00039  *   code cosmetics and documentation
    00040  *
    00041  *   Revision 1.3  2008/04/18 14:00:38  guettler
    00042  *   fixed compile bug (assert.h was not included)
    00043  *
    00044  *   Revision 1.2  2008/04/17 14:54:45  martius
    00045  *   randomGen added, which is a random generator with long period and an
    00046  *    internal state. Each Agent has an instance and passed it to the controller
    00047  *    and the wiring. This is good for
    00048  *   a) repeatability on agent basis,
    00049  *   b) parallel execution as done in ode_robots
    00050  *
    00051  *   Revision 1.1  2008/04/16 12:40:58  martius
    00052  *   moved to utils
    00053  *
    00054  *   Revision 1.17  2007/12/07 10:58:02  der
    00055  *   NoiseGenerator: method signature of add and generate changed!
    00056  *   IMNS: added cfactor parameter
    00057  *
    00058  *   Revision 1.16  2007/12/06 18:17:14  der
    00059  *   corrected WhiteNormalNoise. parameters are now min and max.
    00060  *
    00061  *   Revision 1.15  2006/12/11 14:00:09  martius
    00062  *   colornoise is more colorful (tau = 0.5)
    00063  *   variance for colornoise is invariant of tau now
    00064  *
    00065  *   Revision 1.14  2006/10/09 12:37:54  martius
    00066  *   variance was wrong since it was sigma (std deviation)
    00067  *
    00068  *   Revision 1.13  2006/08/04 15:16:13  martius
    00069  *   documentation
    00070  *
    00071  *   Revision 1.12  2006/07/14 12:23:59  martius
    00072  *   selforg becomes HEAD
    00073  *
    00074  *   Revision 1.10.6.1  2005/11/22 14:55:21  martius
    00075  *   added math.h
    00076  *
    00077  *   Revision 1.10  2005/10/06 17:07:16  martius
    00078  *   removed MAXINT
    00079  *
    00080  *   Revision 1.9  2005/09/11 11:20:21  martius
    00081  *   virtual destructors
    00082  *
    00083  *   Revision 1.8  2005/08/22 20:32:29  martius
    00084  *   sine noise has phaseShift
    00085  *
    00086  *   Revision 1.7  2005/08/06 20:47:54  martius
    00087  *   Commented
    00088  *
    00089  *   Revision 1.6  2005/08/03 20:31:40  martius
    00090  *   sinenoise
    00091  *   no random initialisation anymore
    00092  *
    00093  *   Revision 1.5  2005/07/21 15:11:19  martius
    00094  *   normalised noise strength for colored noise
    00095  *
    00096  *   Revision 1.4  2005/07/14 16:07:12  fhesse
    00097  *   cmath included
    00098  *
    00099  *   Revision 1.3  2005/07/06 16:05:34  martius
    00100  *   noise generator is splitted into sub classes with a common interface
    00101  *
    00102  *   Revision 1.2  2005/06/15 16:04:56  martius
    00103  *   de-templatified
    00104  *                                                                 *
    00105  ***************************************************************************/
    00106 #ifndef __NOISEGENERATOR_H
    00107 #define __NOISEGENERATOR_H
    00108
    00109 #include <stdlib.h>
    00110 #include <time.h>
    00111 #include <cmath>
    00112 #include <assert.h>
    00113
    00114 #include "randomgenerator.h"
    00115
    00116 /** Interface and basic class for noise generator.
    00117     It is suitable for single noise channels but also multidimensional noise.
    00118  */
    00119 class NoiseGenerator{
    00120 public:
    00121   NoiseGenerator()
    00122   {
    00123     dimension   = 0;
    00124     randGen     = 0;
    00125     ownRandGen  = false;
    00126   };
    00127
    00128   virtual ~NoiseGenerator()
    00129   {
    00130     if (this->ownRandGen && this->randGen)
    00131     {
    00132       delete this->randGen;
    00133       this->randGen     = 0;
    00134       this->ownRandGen  = false;
    00135     }
    00136   }
    00137
    00138   /** initialization with the the given dimension for multidimensional noise
    00139       @param dimension dimensionality of vectors to be used by add
    00140       @param randGen pointer to a random generator. If zero a new one generated internally
    00141       @see add()
    00142    */
    00143   virtual void init(unsigned int dimension, RandGen* randGen=0)
    00144   {
    00145     this->dimension = dimension;
    00146     if(randGen)
    00147       this->randGen=randGen;
    00148
    00149     else {
    00150       this->randGen=new RandGen();
    00151       this->randGen->init(rand());
    00152       this->ownRandGen=true;
    00153     }
    00154   };
    00155
    00156   /** generate somehow distributed random number parameterized with min and max.
    00157       valid only for ONE random number, use \ref add() for
    00158       adding this kind of noise to several channels
    00159    */
    00160   virtual double generate() = 0;
    00161
    00162   /** adds multidimensional noise to the value field.
    00163       Generic implementation calls generate for each channel.
    00164       Overload this if you need different behavior.
    00165       @param value field where noise is added. Must have length dimension (\ref init())
    00166    */
    00167   virtual void add(double *value, double noiseStrength){
    00168     for (unsigned int i = 0; i < dimension; i++){
    00169       value[i]+=generate()*noiseStrength;
    00170     }
    00171   }
    00172
    00173 protected:
    00174   //generates white (no averaging) uniformly distributed random number between "min" and "max"
    00175   double uniform(double min=-0.1, double max=0.1){
    00176     assert(randGen);
    00177     return( randGen->rand()*(max-min)+min);
    00178   }
    00179   //generates white uniformly distributed random number between in [0,1)
    00180   double uniform01(){
    00181     assert(randGen);
    00182     return randGen->rand();
    00183   }
    00184   unsigned int dimension;
    00185   RandGen* randGen;
    00186   bool ownRandGen;
    00187 };
    00188
    00189 /// generates no noise
    00190 class NoNoise : public NoiseGenerator{
    00191 public:
    00192   NoNoise() {}
    00193   virtual ~NoNoise(){}
    00194   virtual double generate() {
    00195     return 0;
    00196   };
    00197 };
    00198
    00199
    00200 /// generates white (no averaging) uniformly distributed random number between "min" and "max"
    00201 class WhiteUniformNoise : public NoiseGenerator{
    00202 public:
    00203   WhiteUniformNoise() {}
    00204   virtual ~WhiteUniformNoise(){}
    00205   virtual double generate() {
    00206     return uniform(-1,1);
    00207   };
    00208
    00209 };
    00210
    00211 /// generates white and normal distributed random numbers. p1: mean, p2: standard deviation
    00212 /// new parameter definition: p1: min, p2: max. the mean and standard deviation are calculated by this values
    00213 class WhiteNormalNoise : public NoiseGenerator{
    00214 public:
    00215   WhiteNormalNoise(){}
    00216   virtual ~WhiteNormalNoise(){}
    00217   virtual double generate() {
    00218     double x1=uniform01();
    00219     double x2=uniform01();
    00220     return( (sqrt(-2*log(x1)) *cos(2*M_PI*x2)));
    00221   };
    00222   // original version
    00223   //  virtual double generate(double mean, double stddev) {
    00224   //    double x1=uniform(0, 1);
    00225   //    double x2=uniform(0, 1);
    00226   //    return( (sqrt(-2*log(x1)) *cos(2*M_PI*x2))  * stddev + mean) ;
    00227   //  }
    00228
    00229 };
    00230
    00231 /// generated colored noise. This is obtained by using time average of uniform distributed noise.
    00232 class ColorUniformNoise : public NoiseGenerator{
    00233 public:
    00234   /** @param tau time averaging factor (1/window)
    00235       (1: smoothing (white) 0.1: strong color, 0 no noise anymore
    00236   */
    00237   ColorUniformNoise(double tau=0.05)
    00238     : tau(tau){
    00239     sqrttau = sqrt(tau);
    00240     mean1channel=0.0;
    00241     mean=0;
    00242   }
    00243   virtual ~ColorUniformNoise(){ if(mean) free(mean);}
    00244   virtual void init(unsigned int dimension, RandGen* randGen=0){
    00245     NoiseGenerator::init(dimension, randGen);
    00246     mean = (double*)malloc(sizeof(double) * dimension);
    00247     for (unsigned int i=0; i<dimension; i++){
    00248         mean[i]=0.0;
    00249     }
    00250   }
    00251
    00252   virtual double generate() {
    00253     mean1channel+=  sqrttau *  uniform(-1,  +1) - tau *  mean1channel;
    00254     return(mean1channel);
    00255   }
    00256
    00257   /** adds multidimensional noise to the value field.
    00258       @param value field where noise is added. Must have length dimension (\ref init())
    00259       @param min lower bound of interval
    00260       @param max upper bound of interval
    00261    */
    00262   virtual void add(double *value, double noiseStrength){
    00263     for (unsigned int i = 0; i < dimension; i++){
    00264       mean[i]+= sqrttau * uniform(-1,  +1)*noiseStrength - tau *  mean[i];
    00265       value[i]+=mean[i];
    00266     }
    00267   }
    00268
    00269   double getTau(){ return tau;}
    00270   void setTau(double newTau){
    00271     if(newTau >=0 && newTau <= 1){
    00272       tau=newTau;
    00273       sqrttau = sqrt(tau);
    00274     }
    00275   }
    00276
    00277 protected:
    00278   double tau; // smoothing paramter
    00279   double sqrttau; // square root of smoothing parameter
    00280   double* mean;
    00281   double mean1channel;
    00282 };
    00283
    00284 /// like ColorUniformNoise but averaging over normal distributed noise instead.
    00285 class ColorNormalNoise : public WhiteNormalNoise{
    00286 public:
    00287   ColorNormalNoise(double tau=0.05)
    00288     : tau(tau){
    00289     sqrttau = sqrt(tau);
    00290     mean = 0;
    00291     mean1channel=0.0;
    00292   }
    00293
    00294   virtual ~ColorNormalNoise(){if(mean) free(mean);}
    00295
    00296   virtual void init(unsigned int dimension, RandGen* randGen=0){
    00297     WhiteNormalNoise::init(dimension, randGen);
    00298     mean = (double*)malloc(sizeof(double) * dimension);
    00299     for (unsigned int i=0; i<dimension; i++){
    00300         mean[i]=0.0;
    00301     }
    00302   }
    00303
    00304   virtual double generate() { //double stddev, double meanvalue) {
    00305     mean1channel += sqrttau * WhiteNormalNoise::generate() - tau*mean1channel;
    00306     return(mean1channel);
    00307   }
    00308
    00309   virtual void add(double *value, double noiseStrength) {
    00310     for (unsigned int i = 0; i < dimension; i++){
    00311       mean[i]+=sqrttau * WhiteNormalNoise::generate()*noiseStrength - tau*mean[i];
    00312       value[i]+=mean[i];
    00313     }
    00314   }
    00315
    00316 protected:
    00317   double tau; // smoothing paramter
    00318   double sqrttau; // square root of smoothing parameter
    00319   double* mean;
    00320   double mean1channel;
    00321   double factor;
    00322 };
    00323
    00324 /// Sine wave noise. Produces a 90 degree phase shifted sine wave or white noise
    00325 class SineWhiteNoise : public NoiseGenerator{
    00326 public:
    00327   /** @param omega anglerate
    00328       @param amplitude weighting of sine wave against noise strength
    00329       @param phaseShift phase shift between channels in rad
    00330       @param channels number of channel for sine noise (and the rest get white noise)
    00331    */
    00332   SineWhiteNoise(double omega, double amplitude, double phaseShift = M_PI/2,
    00333                  unsigned int channels = 0xFFFF)
    00334     : omega(omega), amplitude(amplitude)
    00335     , channels(channels), phaseShift(phaseShift){
    00336     t=0;
    00337   }
    00338
    00339   virtual ~SineWhiteNoise(){}
    00340
    00341   virtual double generate() {
    00342     t ++;
    00343     return (1-amplitude)*uniform(-1,  1) + sin(t*omega)*amplitude;
    00344   }
    00345
    00346   /** adds multidimensional noise to the value field.
    00347       @param value field where noise is added. Must have length dimension (\ref init())
    00348    */
    00349   virtual void add(double *value, double noiseStrength) { // min, double max){
    00350
    00351     for (unsigned int i = 0; i < dimension; i++){
    00352       if(i < channels){
    00353         value[i]+=sin(t*omega+i*phaseShift)*amplitude*noiseStrength;
    00354         value[i]+=(1-amplitude)*uniform(-1,  1)*noiseStrength;
    00355       }else{
    00356         value[i]+=uniform(-1,  1)*noiseStrength;
    00357       }
    00358     }
    00359     t ++;
    00360   }
    00361   void setOmega(double omega){
    00362     this->omega=omega;
    00363   }
    00364   void setPhaseShift(double phaseShift){
    00365     this->phaseShift=phaseShift;
    00366   }
    00367
    00368 protected:
    00369   long int t;        // time
    00370   double omega;     // angle velocity
    00371   double amplitude; // factor for noise strength
    00372   unsigned int channels;     // number of channels with sine
    00373   double phaseShift; // phase shift
    00374
    00375 };
    00376
    00377
    00378 #endif
    00379