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.13  2006/08/04 15:16:13  martius
00024  *   documentation
00025  *
00026  *   Revision 1.12  2006/07/14 12:23:59  martius
00027  *   selforg becomes HEAD
00028  *
00029  *   Revision 1.10.6.1  2005/11/22 14:55:21  martius
00030  *   added math.h
00031  *
00032  *   Revision 1.10  2005/10/06 17:07:16  martius
00033  *   removed MAXINT
00034  *
00035  *   Revision 1.9  2005/09/11 11:20:21  martius
00036  *   virtual destructors
00037  *
00038  *   Revision 1.8  2005/08/22 20:32:29  martius
00039  *   sine noise has phaseShift
00040  *
00041  *   Revision 1.7  2005/08/06 20:47:54  martius
00042  *   Commented
00043  *
00044  *   Revision 1.6  2005/08/03 20:31:40  martius
00045  *   sinenoise
00046  *   no random initialisation anymore
00047  *
00048  *   Revision 1.5  2005/07/21 15:11:19  martius
00049  *   normalised noise strength for colored noise
00050  *
00051  *   Revision 1.4  2005/07/14 16:07:12  fhesse
00052  *   cmath included
00053  *
00054  *   Revision 1.3  2005/07/06 16:05:34  martius
00055  *   noise generator is splitted into sub classes with a common interface
00056  *
00057  *   Revision 1.2  2005/06/15 16:04:56  martius
00058  *   de-templatified
00059  *                                                                 *
00060  ***************************************************************************/
00061 #ifndef __NOISEGENERATOR_H
00062 #define __NOISEGENERATOR_H
00063 
00064 #include <stdlib.h>
00065 #include <time.h>
00066 #include <math.h>
00067 
00068 /** Interface and basic class for noise generator.
00069     It is suitable for single noise channels but also multidimensional noise. 
00070  */
00071 class NoiseGenerator{
00072 public:
00073   NoiseGenerator() {
00074     dimension=0;
00075   };    
00076 
00077   virtual ~NoiseGenerator(){}
00078 
00079   /** initialization with the the given dimension for multidimensional noise
00080       @see add()
00081    */
00082   virtual void init(unsigned int dimension) {
00083     this->dimension = dimension;
00084   };
00085 
00086   /** generate somehow distributed random number parameterized with min and max.
00087       valid only for ONE random number, use \ref add() for 
00088       adding this kind of noise to several channels
00089    */
00090   virtual double generate(double min, double max) = 0; 
00091 
00092   /** adds multidimensional noise to the value field.
00093       Generic implementation calls generate for each channel.
00094       Overload this if you need different behavior.
00095       @param value field where noise is added. Must have length dimension (\ref init())
00096       @param p1 first parameter for random number distribution
00097       @param p2 second parameter for random number distribution
00098    */
00099   virtual void add(double *value, double p1, double p2){
00100     for (unsigned int i = 0; i < dimension; i++){
00101       value[i]+=generate(p1,p2);
00102     }    
00103   }
00104 
00105 protected:
00106   //generates white (no averaging) uniformly distributed random number between "min" and "max"  
00107   double uniform(double min=-0.1, double max=0.1){
00108     return( (double(rand())/RAND_MAX)*(max-min)+min);
00109   }
00110   unsigned int dimension;
00111 };
00112 
00113 /// generates white (no averaging) uniformly distributed random number between "min" and "max"  
00114 class WhiteUniformNoise : public NoiseGenerator{
00115 public:
00116   WhiteUniformNoise(){}
00117   virtual ~WhiteUniformNoise(){}
00118   virtual double generate(double min, double max) {
00119     return uniform(min,max);
00120   }; 
00121 };
00122 
00123 /// generates white and normal distributed random numbers. p1: mean, p2: variance
00124 class WhiteNormalNoise : public NoiseGenerator{
00125 public:
00126   WhiteNormalNoise(){}
00127   virtual ~WhiteNormalNoise(){}
00128   virtual double generate(double mean, double variance) {
00129     double x1=uniform(0, 1);
00130     double x2=uniform(0, 1);
00131     return( (sqrt(-2*log(x1)) *cos(2*M_PI*x2))  * variance + mean) ; 
00132   };
00133 };
00134 
00135 /// generated colored noise. This is obtained by using time average of uniform distributed noise.
00136 class ColorUniformNoise : public NoiseGenerator{
00137 public:
00138   /** @param tau time averaging factor (1/window)
00139       (1: smoothing (white) 0.1: strong color, 0 no noise anymore
00140   */
00141   ColorUniformNoise(double tau=0.3)
00142     : tau(tau){
00143     mean1channel=0.0;
00144     mean=0;
00145     // we can consider the distribution as a sum of individual distributions.
00146     // following the central limit theorem the variance is 1/sqrt(n)*V 
00147     // we assume n=1/tau
00148     factor=sqrt(1/(tau+0.01)); 
00149   }
00150   virtual ~ColorUniformNoise(){}
00151   virtual void init(unsigned int dimension){
00152     NoiseGenerator::init(dimension);
00153     mean = (double*)malloc(sizeof(double) * dimension);    
00154     for (unsigned int i=0; i<dimension; i++){
00155         mean[i]=0.0;
00156     }   
00157   }
00158 
00159   virtual double generate(double min, double max) {
00160     
00161     mean1channel+=tau * (uniform(min*factor,  max*factor) - mean1channel);
00162     return(mean1channel);
00163   } 
00164 
00165   /** adds multidimensional noise to the value field.
00166       @param value field where noise is added. Must have length dimension (\ref init())
00167       @param min lower bound of interval
00168       @param max upper bound of interval 
00169    */
00170   virtual void add(double *value, double min, double max){
00171     for (unsigned int i = 0; i < dimension; i++){     
00172       mean[i]+=tau * (uniform(min*factor,  max*factor) - mean[i]);
00173       value[i]+=mean[i];
00174     }    
00175   }   
00176 
00177 protected:
00178   double tau; // smoothing paramter
00179   double* mean;  
00180   double mean1channel;
00181   double factor;
00182 };
00183 
00184 /// like ColorUniformNoise but averaging over normal distributed noise instead.
00185 class ColorNormalNoise : public WhiteNormalNoise{
00186 public:
00187   ColorNormalNoise(double tau=0.3)
00188     : tau(tau){
00189     mean = 0;
00190     mean1channel=0.0;
00191     // we can consider the distribution as a sum of individual distributions.
00192     // following the central limit theorem the variance is 1/sqrt(n)*V 
00193     // we assume n=1/tau
00194     factor=sqrt(1/(tau+0.01)); 
00195   }
00196 
00197   virtual ~ColorNormalNoise(){}
00198 
00199   virtual void init(unsigned int dimension){
00200     WhiteNormalNoise::init(dimension);
00201     mean = (double*)malloc(sizeof(double) * dimension);    
00202     for (unsigned int i=0; i<dimension; i++){
00203         mean[i]=0.0;
00204     }   
00205   }
00206 
00207   virtual double generate(double variance, double meanvalue) {
00208     mean1channel += tau * WhiteNormalNoise::generate(variance*factor, meanvalue) - mean1channel;
00209     return(mean1channel);
00210   } 
00211 
00212   /** adds multidimensional noise to the value field.
00213       @param value field where noise is added. Must have length dimension (\ref init())
00214       @param variance variance of normal distribution
00215       @param meanvalue mean value  of normal distribution
00216    */
00217   virtual void add(double *value, double variance, double meanvalue){
00218     for (unsigned int i = 0; i < dimension; i++){     
00219       mean[i]+=tau * (WhiteNormalNoise::generate(variance*factor, meanvalue) - mean[i]);
00220       value[i]+=mean[i];
00221     }    
00222   }   
00223 
00224 protected:
00225   double tau; // smoothing paramter
00226   double* mean;  
00227   double mean1channel;
00228   double factor;
00229 };
00230 
00231 /// Sine wave noise. Produces a 90 degree phase shifted sine wave or white noise
00232 class SineWhiteNoise : public NoiseGenerator{
00233 public:
00234   /** @param omega anglerate
00235       @param amplitude amplitude of the sine wave in respect to the noise strength
00236       @param phaseShift phase shift between channels in rad
00237       @param channels number of channel for sine noise (and the rest get white noise)
00238    */
00239   SineWhiteNoise(double omega, double amplitude, double phaseShift = M_PI/2, 
00240                  unsigned int channels = 0xFFFF)
00241     : omega(omega), amplitude(amplitude)
00242     , channels(channels), phaseShift(phaseShift){
00243     t=0;
00244   }
00245 
00246   virtual ~SineWhiteNoise(){}
00247 
00248   virtual double generate(double min, double max) {        
00249     t ++;
00250     return uniform(min,  max) + sin(t*omega)*amplitude*(max-min);
00251   } 
00252 
00253   /** adds multidimensional noise to the value field.
00254       @param value field where noise is added. Must have length dimension (\ref init())
00255       @param min lower bound of interval
00256       @param max upper bound of interval 
00257    */
00258   virtual void add(double *value, double min, double max){
00259 
00260     for (unsigned int i = 0; i < dimension; i++){     
00261       if(i < channels)
00262         value[i]+=sin(t*omega+i*phaseShift)*amplitude*(max-min);
00263       value[i]+=uniform(min,  max);
00264     }    
00265     t ++;
00266   }   
00267   void setOmega(double omega){
00268     this->omega=omega;
00269   }
00270   void setPhaseShift(double phaseShift){
00271     this->phaseShift=phaseShift;
00272   }
00273   
00274 protected:
00275   long int t;        // time
00276   double omega;     // angle velocity
00277   double amplitude; // factor for noise strength  
00278   unsigned int channels;     // number of channels with sine
00279   double phaseShift; // phase shift
00280 
00281 };
00282 
00283 
00284 #endif
00285 

Generated on Mon Aug 7 16:40:14 2006 for Robotsystem of the Robot Group Leipzig by  doxygen 1.4.7