Robotsystem of the Robot Group Leipzig: 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.5  2008/05/30 11:58:27  martius
    00024  *   use cmath instead of math.h
    00025  *
    00026  *   Revision 1.4  2008/05/07 16:45:52  martius
    00027  *   code cosmetics and documentation
    00028  *
    00029  *   Revision 1.3  2008/04/18 14:00:38  guettler
    00030  *   fixed compile bug (assert.h was not included)
    00031  *
    00032  *   Revision 1.2  2008/04/17 14:54:45  martius
    00033  *   randomGen added, which is a random generator with long period and an
    00034  *    internal state. Each Agent has an instance and passed it to the controller
    00035  *    and the wiring. This is good for
    00036  *   a) repeatability on agent basis,
    00037  *   b) parallel execution as done in ode_robots
    00038  *
    00039  *   Revision 1.1  2008/04/16 12:40:58  martius
    00040  *   moved to utils
    00041  *
    00042  *   Revision 1.17  2007/12/07 10:58:02  der
    00043  *   NoiseGenerator: method signature of add and generate changed!
    00044  *   IMNS: added cfactor parameter
    00045  *
    00046  *   Revision 1.16  2007/12/06 18:17:14  der
    00047  *   corrected WhiteNormalNoise. parameters are now min and max.
    00048  *
    00049  *   Revision 1.15  2006/12/11 14:00:09  martius
    00050  *   colornoise is more colorful (tau = 0.5)
    00051  *   variance for colornoise is invariant of tau now
    00052  *
    00053  *   Revision 1.14  2006/10/09 12:37:54  martius
    00054  *   variance was wrong since it was sigma (std deviation)
    00055  *
    00056  *   Revision 1.13  2006/08/04 15:16:13  martius
    00057  *   documentation
    00058  *
    00059  *   Revision 1.12  2006/07/14 12:23:59  martius
    00060  *   selforg becomes HEAD
    00061  *
    00062  *   Revision 1.10.6.1  2005/11/22 14:55:21  martius
    00063  *   added math.h
    00064  *
    00065  *   Revision 1.10  2005/10/06 17:07:16  martius
    00066  *   removed MAXINT
    00067  *
    00068  *   Revision 1.9  2005/09/11 11:20:21  martius
    00069  *   virtual destructors
    00070  *
    00071  *   Revision 1.8  2005/08/22 20:32:29  martius
    00072  *   sine noise has phaseShift
    00073  *
    00074  *   Revision 1.7  2005/08/06 20:47:54  martius
    00075  *   Commented
    00076  *
    00077  *   Revision 1.6  2005/08/03 20:31:40  martius
    00078  *   sinenoise
    00079  *   no random initialisation anymore
    00080  *
    00081  *   Revision 1.5  2005/07/21 15:11:19  martius
    00082  *   normalised noise strength for colored noise
    00083  *
    00084  *   Revision 1.4  2005/07/14 16:07:12  fhesse
    00085  *   cmath included
    00086  *
    00087  *   Revision 1.3  2005/07/06 16:05:34  martius
    00088  *   noise generator is splitted into sub classes with a common interface
    00089  *
    00090  *   Revision 1.2  2005/06/15 16:04:56  martius
    00091  *   de-templatified
    00092  *                                                                 *
    00093  ***************************************************************************/
    00094 #ifndef __NOISEGENERATOR_H
    00095 #define __NOISEGENERATOR_H
    00096
    00097 #include <stdlib.h>
    00098 #include <time.h>
    00099 #include <cmath>
    00100 #include <assert.h>
    00101
    00102 #include "randomgenerator.h"
    00103
    00104 /** Interface and basic class for noise generator.
    00105     It is suitable for single noise channels but also multidimensional noise.
    00106  */
    00107 class NoiseGenerator{
    00108 public:
    00109   NoiseGenerator() {
    00110     dimension=0;
    00111     randGen=0;
    00112   };
    00113
    00114   virtual ~NoiseGenerator(){}
    00115
    00116   /** initialization with the the given dimension for multidimensional noise
    00117       @param dimension dimensionality of vectors to be used by add
    00118       @param randGen pointer to a random generator. If zero a new one generated internally
    00119       @see add()
    00120    */
    00121   virtual void init(unsigned int dimension, RandGen* randGen=0) {
    00122     this->dimension = dimension;
    00123     if(randGen) this->randGen=randGen;
    00124     else {
    00125       this->randGen=new RandGen();
    00126       this->randGen->init(rand());
    00127     }
    00128   };
    00129
    00130   /** generate somehow distributed random number parameterized with min and max.
    00131       valid only for ONE random number, use \ref add() for
    00132       adding this kind of noise to several channels
    00133    */
    00134   virtual double generate() = 0;
    00135
    00136   /** adds multidimensional noise to the value field.
    00137       Generic implementation calls generate for each channel.
    00138       Overload this if you need different behavior.
    00139       @param value field where noise is added. Must have length dimension (\ref init())
    00140    */
    00141   virtual void add(double *value, double noiseStrength){
    00142     for (unsigned int i = 0; i < dimension; i++){
    00143       value[i]+=generate()*noiseStrength;
    00144     }
    00145   }
    00146
    00147 protected:
    00148   //generates white (no averaging) uniformly distributed random number between "min" and "max"
    00149   double uniform(double min=-0.1, double max=0.1){
    00150     assert(randGen);
    00151     return( randGen->rand()*(max-min)+min);
    00152   }
    00153   //generates white uniformly distributed random number between in [0,1)
    00154   double uniform01(){
    00155     assert(randGen);
    00156     return randGen->rand();
    00157   }
    00158   unsigned int dimension;
    00159   RandGen* randGen;
    00160 };
    00161
    00162 /// generates white (no averaging) uniformly distributed random number between "min" and "max"
    00163 class WhiteUniformNoise : public NoiseGenerator{
    00164 public:
    00165   WhiteUniformNoise() {}
    00166   virtual ~WhiteUniformNoise(){}
    00167   virtual double generate() {
    00168     return uniform(-1,1);
    00169   };
    00170
    00171 };
    00172
    00173 /// generates white and normal distributed random numbers. p1: mean, p2: standard deviation
    00174 /// new parameter definition: p1: min, p2: max. the mean and standard deviation are calculated by this values
    00175 class WhiteNormalNoise : public NoiseGenerator{
    00176 public:
    00177   WhiteNormalNoise(){}
    00178   virtual ~WhiteNormalNoise(){}
    00179   virtual double generate() {
    00180     double x1=uniform01();
    00181     double x2=uniform01();
    00182     return( (sqrt(-2*log(x1)) *cos(2*M_PI*x2)));
    00183   };
    00184   // original version
    00185   //  virtual double generate(double mean, double stddev) {
    00186   //    double x1=uniform(0, 1);
    00187   //    double x2=uniform(0, 1);
    00188   //    return( (sqrt(-2*log(x1)) *cos(2*M_PI*x2))  * stddev + mean) ;
    00189   //  }
    00190
    00191 };
    00192
    00193 /// generated colored noise. This is obtained by using time average of uniform distributed noise.
    00194 class ColorUniformNoise : public NoiseGenerator{
    00195 public:
    00196   /** @param tau time averaging factor (1/window)
    00197       (1: smoothing (white) 0.1: strong color, 0 no noise anymore
    00198   */
    00199   ColorUniformNoise(double tau=0.05)
    00200     : tau(tau){
    00201     sqrttau = sqrt(tau);
    00202     mean1channel=0.0;
    00203     mean=0;
    00204   }
    00205   virtual ~ColorUniformNoise(){ if(mean) free(mean);}
    00206   virtual void init(unsigned int dimension, RandGen* randGen=0){
    00207     NoiseGenerator::init(dimension, randGen);
    00208     mean = (double*)malloc(sizeof(double) * dimension);
    00209     for (unsigned int i=0; i<dimension; i++){
    00210         mean[i]=0.0;
    00211     }
    00212   }
    00213
    00214   virtual double generate() {
    00215     mean1channel+=  sqrttau *  uniform(-1,  +1) - tau *  mean1channel;
    00216     return(mean1channel);
    00217   }
    00218
    00219   /** adds multidimensional noise to the value field.
    00220       @param value field where noise is added. Must have length dimension (\ref init())
    00221       @param min lower bound of interval
    00222       @param max upper bound of interval
    00223    */
    00224   virtual void add(double *value, double noiseStrength){
    00225     for (unsigned int i = 0; i < dimension; i++){
    00226       mean[i]+= sqrttau * uniform(-1,  +1)*noiseStrength - tau *  mean[i];
    00227       value[i]+=mean[i];
    00228     }
    00229   }
    00230
    00231 protected:
    00232   double tau; // smoothing paramter
    00233   double sqrttau; // square root of smoothing parameter
    00234   double* mean;
    00235   double mean1channel;
    00236 };
    00237
    00238 /// like ColorUniformNoise but averaging over normal distributed noise instead.
    00239 class ColorNormalNoise : public WhiteNormalNoise{
    00240 public:
    00241   ColorNormalNoise(double tau=0.05)
    00242     : tau(tau){
    00243     sqrttau = sqrt(tau);
    00244     mean = 0;
    00245     mean1channel=0.0;
    00246   }
    00247
    00248   virtual ~ColorNormalNoise(){if(mean) free(mean);}
    00249
    00250   virtual void init(unsigned int dimension, RandGen* randGen=0){
    00251     WhiteNormalNoise::init(dimension, randGen);
    00252     mean = (double*)malloc(sizeof(double) * dimension);
    00253     for (unsigned int i=0; i<dimension; i++){
    00254         mean[i]=0.0;
    00255     }
    00256   }
    00257
    00258   virtual double generate() { //double stddev, double meanvalue) {
    00259     mean1channel += sqrttau * WhiteNormalNoise::generate() - tau*mean1channel;
    00260     return(mean1channel);
    00261   }
    00262
    00263   virtual void add(double *value, double noiseStrength) {
    00264     for (unsigned int i = 0; i < dimension; i++){
    00265       mean[i]+=sqrttau * WhiteNormalNoise::generate()*noiseStrength - tau*mean[i];
    00266       value[i]+=mean[i];
    00267     }
    00268   }
    00269
    00270 protected:
    00271   double tau; // smoothing paramter
    00272   double sqrttau; // square root of smoothing parameter
    00273   double* mean;
    00274   double mean1channel;
    00275   double factor;
    00276 };
    00277
    00278 /// Sine wave noise. Produces a 90 degree phase shifted sine wave or white noise
    00279 class SineWhiteNoise : public NoiseGenerator{
    00280 public:
    00281   /** @param omega anglerate
    00282       @param amplitude amplitude of the sine wave in respect to the noise strength
    00283       @param phaseShift phase shift between channels in rad
    00284       @param channels number of channel for sine noise (and the rest get white noise)
    00285    */
    00286   SineWhiteNoise(double omega, double amplitude, double phaseShift = M_PI/2,
    00287                  unsigned int channels = 0xFFFF)
    00288     : omega(omega), amplitude(amplitude)
    00289     , channels(channels), phaseShift(phaseShift){
    00290     t=0;
    00291   }
    00292
    00293   virtual ~SineWhiteNoise(){}
    00294
    00295   virtual double generate() {
    00296     t ++;
    00297     return uniform(-1,  1) + sin(t*omega)*amplitude*2;
    00298   }
    00299
    00300   /** adds multidimensional noise to the value field.
    00301       @param value field where noise is added. Must have length dimension (\ref init())
    00302    */
    00303   virtual void add(double *value, double noiseStrength) { // min, double max){
    00304
    00305     for (unsigned int i = 0; i < dimension; i++){
    00306       if(i < channels)
    00307         value[i]+=sin(t*omega+i*phaseShift)*amplitude*2;
    00308       value[i]+=uniform(-1,  1);
    00309     }
    00310     t ++;
    00311   }
    00312   void setOmega(double omega){
    00313     this->omega=omega;
    00314   }
    00315   void setPhaseShift(double phaseShift){
    00316     this->phaseShift=phaseShift;
    00317   }
    00318
    00319 protected:
    00320   long int t;        // time
    00321   double omega;     // angle velocity
    00322   double amplitude; // factor for noise strength
    00323   unsigned int channels;     // number of channels with sine
    00324   double phaseShift; // phase shift
    00325
    00326 };
    00327
    00328
    00329 #endif
    00330