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 

Generated on Fri Oct 30 16:29:01 2009 for Robot Simulator of the Robotics Group for Self-Organization of Control by  doxygen 1.4.7