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 

Generated on Tue Sep 16 22:00:22 2008 for Robotsystem of the Robot Group Leipzig by  doxygen 1.4.7