Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

valuegen.h

Go to the documentation of this file.
00001 
00007 #ifndef __VALUEGEN_H__
00008 #define __VALUEGEN_H__
00009 
00010 #ifndef NO_VALGEN_STRINGS
00011 /* Optional: support for reading expressions from strings
00012    and showing state as a string */
00013 #include "stringutils.h"
00014 #include "msg.h"
00015 #endif
00016 
00017 #include "vgen.h"
00018 #include "allocatingpointer.h"
00019 #include "shuffledrand.h"
00020 #include "mathconstants.h"
00021 
00022 /******************************************************************************/
00023 /* General-purpose random-value generators for various distributions          */
00024 /******************************************************************************/
00025 
00026 
00027 namespace Distributions {
00028 
00034 struct uniform {
00035   double operator() ( double mean=0.5, double radius=0.5)
00036     {  return mean + 2.0*radius*(shuffled_rand() - 0.5); }
00037 };
00038 
00039 
00040 
00046 struct normal {
00047   double operator() ( double mean=0.0, double radius=1.0)
00048     {  return mean + radius*(sqrt((-2.0) * log(shuffled_rand())) * cos(2*(Math::pi) * shuffled_rand()));  }
00049 };
00050 
00051 }
00052 
00053 
00054 /******************************************************************************/
00055 /* ValueGenerator objects                                                     */
00056 /******************************************************************************/
00095 template<class T=double>
00096 class ValueGenerator : public ValueGen {
00097   typedef ValueGenerator<T> self;
00098   AllocatingPointer<T> v;
00099   
00100 public:
00102   ValueGenerator(T  value=T()) : v(value)  { }
00103 
00105   ValueGenerator(T* value)     : v(value) { }
00106   
00107 #ifndef NO_VALGEN_STRINGS
00108   ValueGenerator(StringArgs& args) {  args.next(T(),v.valueptrref());  }
00109 
00120   virtual string stringrep() const
00121     {  return String::stringrep(value());  }
00122 #endif
00123 
00124   virtual ~ValueGenerator() { }
00125 
00127   T operator*() const {  return *v;  }
00128 
00130   T value() const { return *v; }
00131 
00133   T* valueptr() const {  return v.valueptr();  }
00134 
00137   virtual void relink(T* ptr) {  v.relink(ptr);  }
00138   
00139   virtual bool next()  { return true; }
00140   virtual void reset() { }
00141 
00143   virtual ValueGenerator<T>* clone() const { return new self(*this); };
00145 };
00146 
00147 
00149 typedef ValueGenerator<double> DGen;
00150 
00151 
00152 
00154 template<class T=double, class RandomGen=Distributions::uniform>
00155 class ValueGenerator_Random : public ValueGenerator<T> {
00156   typedef ValueGenerator_Random<T,RandomGen> self;
00157   T v; 
00158   AllocatingPointer<T> m,r;
00159 
00160 public:
00164   ValueGenerator_Random(T mean, T radius=0)
00165     : ValueGenerator<T>(&v), v(mean),   m(mean),  r(radius) { }
00166 
00168   ValueGenerator_Random(T* mean, T* radius)
00169     : ValueGenerator<T>(&v), v(*mean), m(mean), r(radius) { }
00170 
00171 #ifndef NO_VALGEN_STRINGS
00172   ValueGenerator_Random(StringArgs& args) : ValueGenerator<T>(&v) {
00173     args.next(T(),m.valueptrref()); v = *m;
00174     args.next(T(),r.valueptrref());
00175   }
00176 
00179   virtual string stringrep() const
00180     {  return "Random " + String::stringrep(*m) + " " + String::stringrep(*r);  }
00181 #endif
00182 
00184   ValueGenerator_Random(const self& other)
00185     : ValueGenerator<T>(&v), v(other.v), m(other.m), r(other.r)  { }
00186 
00187   virtual bool next()
00188     {  v = RandomGen()( *m, *r ); return true; }
00189 
00190   virtual void reset() { v=*m; } // Resets to mean value
00191   
00192   virtual ValueGenerator<T>* clone() const { return new ValueGenerator_Random(*this); };
00193 };
00194 
00195 
00196 
00208 template<class T=double, class RandomGen=Distributions::uniform, bool crop=true>
00209 class ValueGenerator_Correlate : public ValueGenerator<T> {
00210   typedef ValueGenerator_Correlate<T,RandomGen,crop> self;
00211   T v; 
00212   AllocatingPointer<T> lb,ub,m,uncorr;
00213 
00214 public:
00216   ValueGenerator_Correlate(T* master_value_ptr, T* uncorrelation_ptr,
00217                            T lower_bound, T upper_bound)
00218     : ValueGenerator<T>(&v), v(*master_value_ptr),
00219     lb(lower_bound), ub(upper_bound),
00220     m(master_value_ptr), uncorr(uncorrelation_ptr) { }
00221 
00222 #ifndef NO_VALGEN_STRINGS
00223 
00229   ValueGenerator_Correlate(StringArgs& args, T* ref=0)
00230     : ValueGenerator<T>(&v) {
00231     if (ref) m=ref;
00232     else     args.next(v,m.valueptrref());
00233     args.next(v,uncorr.valueptrref());
00234     args.next(T(),lb.valueptrref());
00235     args.next(T(),ub.valueptrref());
00236     
00237     v = *m;  
00238   }
00239   
00240   virtual string stringrep() const {
00241     return "Correlate " +
00242       String::stringrep(*m) + " " +
00243       String::stringrep(*uncorr) + " " +
00244       String::stringrep(*lb) + " " +
00245       String::stringrep(*ub);
00246   }
00247 #endif
00248   
00249   ValueGenerator_Correlate(const self& other)
00250     : ValueGenerator<T>(&v), v(other.v), lb(other.lb), ub(other.ub),
00251       m(other.m), uncorr( other.uncorr)  { } 
00253   virtual bool next() {
00254     const T uncorr_radius = (*ub-*lb)*(*uncorr);
00255 
00256     /* This conditional will presumably be optimized away */
00257     if (crop) {
00258       const T low    = std::max(*lb,*m-uncorr_radius);
00259       const T high   = std::min(*ub,*m+uncorr_radius);
00260       const T radius = (high-low)/2;
00261       const T mean   = low+radius;
00262       v = RandomGen()(mean, radius);
00263     }
00264     else
00265       v = RandomGen()(*m, uncorr_radius);
00266     return true;
00267   }
00268 
00269   virtual void reset() { v=*m; } // Resets to master value
00270 
00271   virtual ValueGenerator<T>* clone() const { return new self(*this); }
00272 };
00273 
00274 
00275 
00291 template<class T=double>
00292 class ValueGenerator_Opposite : public ValueGenerator<T> {
00293   typedef ValueGenerator_Opposite<T> self;
00294   T v; 
00295   T f;
00296   AllocatingPointer<T> m;
00297 
00298 public:
00300   ValueGenerator_Opposite(T* master_value_ptr, T factor=1)
00301     : ValueGenerator<T>(&v), v(1-*master_value_ptr), f(factor), m(master_value_ptr) { }
00302 
00303 #ifndef NO_VALGEN_STRINGS
00304 
00311   ValueGenerator_Opposite(StringArgs& args, T* ref=0)
00312     : ValueGenerator<T>(&v) {
00313     if (ref) m=ref;
00314     else     args.next(v,m.valueptrref());
00315     f=args.next(T(1));
00316     
00317     reset();  
00318   }
00319   
00320   virtual string stringrep() const {
00321     return "Opposite " +
00322       String::stringrep(f) + "-" +
00323       String::stringrep(*m);
00324   }
00325 #endif
00326   
00327   ValueGenerator_Opposite(const self& other)
00328     : ValueGenerator<T>(&v), v(other.v), f(other.f), m(other.m) { } 
00330   virtual bool next() {  reset();  return true;  }
00331   virtual void reset() { v = f-*m; }
00332   virtual ValueGenerator<T>* clone() const { return new self(*this); }
00333 };
00334 
00335 
00336 
00338 template<class T=double>
00339 class ValueGenerator_Increment : public ValueGenerator<T> {
00340   typedef ValueGenerator_Increment<T> self;
00341   T v; 
00342   AllocatingPointer<T> s,inc;
00343 
00344 public:
00345   ValueGenerator_Increment(T  init_value, T  increment=1)
00346     : ValueGenerator<T>(&v), v(init_value), s(init_value), inc(increment) { }
00347 
00348   ValueGenerator_Increment(T* init_value, T* increment)
00349     : ValueGenerator<T>(&v), v(*init_value), s(init_value), inc(increment) { }
00350 
00351 #ifndef NO_VALGEN_STRINGS
00352 
00353   ValueGenerator_Increment(StringArgs& args)
00354     : ValueGenerator<T>(&v), inc(1) {
00355     s   = args.next(T());
00356     v   = *s;
00357     inc = args.next(T(1));
00358   }
00359 
00360   virtual string stringrep() const
00361     { return "Increment " + String::stringrep(*s) + " " + String::stringrep(*inc);  }
00362 #endif
00363   
00364   ValueGenerator_Increment(const self& other)
00365     : ValueGenerator<T>(&v), v(other.v), s(other.s), inc(other.inc) { } 
00367   virtual bool next()  { v += *inc; return true; }
00368   virtual void reset() { v  = *s; } // Resets to starting value
00369 
00370   virtual ValueGenerator<T>* clone() const { return new self(*this); };
00371 };
00372 
00373 
00374 
00379 #ifndef NO_VALGEN_STRINGS
00380 
00381 template<class T=double>
00382 class ValueGenerator_Expression : public ValueGenerator<T> {
00383   typedef ValueGenerator_Expression<T> self;
00384   const StringParser* p;
00385   T v; 
00386   string expr;
00387   
00388 public:
00389   ValueGenerator_Expression(string expression, const StringParser& parser)
00390     : ValueGenerator<T>(&v), p(parser.clone()), v(p->parse(expression,v)), expr(expression) { }
00391   
00392   ValueGenerator_Expression(StringArgs& args)
00393     : ValueGenerator<T>(&v), p(args.p.clone()), v(0), expr("") {
00394       expr = args.next(string(""));
00395       p->parse(expr,v);
00396     }
00397   
00398   virtual string stringrep() const
00399     { return "Expression " + expr;  }
00400 
00401   ValueGenerator_Expression(const self& other)
00402     : ValueGenerator<T>(&v), p(other.p->clone()), v(other.v), expr(other.expr) { } 
00404   ~ValueGenerator_Expression() {  delete p;  }
00405   
00406   virtual bool next() {  p->parse(expr,v); return true; }
00407   
00408   virtual void reset() { next(); } // Resets to current value of expr
00409 
00410   virtual ValueGenerator<T>* clone() const { return new self(*this); };
00411 };
00412 #endif
00413 
00414 
00415 
00416 
00417 /******************************************************************************/
00418 /* ValueGeneratorFactory                                                      */
00419 /******************************************************************************/
00420 
00421 #ifndef NO_VALGEN_STRINGS
00422 
00423 
00428 template<class T=double>
00429 class VGenFactory {
00430 public:
00431   VGenFactory()          { };
00432   virtual ~VGenFactory() { }
00433 
00441   virtual ValueGenerator<T>* create(StringArgs args) const =0;
00442 
00444   virtual ValueGenerator<T>* create(StringArgs args, T* ref) const =0;
00445   
00446 protected:
00452   virtual void error(const string&) const {  }
00455   virtual void warning(const string&) const {  }
00456 };
00457 
00458 
00459 
00468 template<class T=double,
00469          class urf=Distributions::uniform,
00470          class nrf=Distributions::normal>
00471 class ValueGeneratorFactory : public VGenFactory<T> {
00472 public:
00473   ValueGeneratorFactory(Msg::LevelHandler<>** mhp_i=&(Msg::LevelHandler<>::default_instance()))
00474     : VGenFactory<T>() {  mhp = mhp_i;  };
00475   
00476   virtual ~ValueGeneratorFactory() { }
00477   
00479   virtual ValueGenerator<T>* create(StringArgs args) const {
00480     
00481     /* Empty string is invalid */
00482     if (args.empty()) {
00483       warning("ValueGenerator: empty expression");
00484       return new ValueGenerator<T>;
00485     }
00486     
00487     /* Convenient shorthand: A single item specifies a numeric constant */
00488     else if (args.oneremaining())
00489       return new ValueGenerator<T>(args);
00490     
00491     /* Anything else should be the name of the ValueGenerator followed by its arguments */
00492     else {
00493       const string& vgclass  = args.next(string(""));
00494 
00495       if      (vgclass=="Random")     {  return new ValueGenerator_Random<T,urf>(          args);  }
00496       else if (vgclass=="Normal")     {  return new ValueGenerator_Random<T,nrf>(          args);  }
00497       else if (vgclass=="Increment")  {  return new ValueGenerator_Increment<T>(           args);  }
00498       else if (vgclass=="Expression") {  return new ValueGenerator_Expression<T>(          args);  }
00499       else if (vgclass=="Correlate")  {  return new ValueGenerator_Correlate<T,urf,true> ( args);  }
00500       else {
00501         error("ValueGenerator: Don't know about type `" + vgclass + "'");
00502         return new ValueGenerator<T>;
00503       }
00504     }
00505   }
00506 
00507 
00509   virtual ValueGenerator<T>* create(StringArgs args, T* ref) const {
00510     if (args.nextis(string("Uncorrelate"))) {
00511       if (ref) return new ValueGenerator_Correlate<T,urf,true>(args,ref);
00512       else {
00513         /* Swallow unneeded args */
00514         T dummyf;
00515         ValueGenerator_Correlate<T,urf,true> dummy(args,&dummyf);
00516       }
00517     }
00518     else if (args.nextis(string("Opposite"))) {
00519       if (ref) return new ValueGenerator_Opposite<T>(args,ref);
00520       else {
00521         /* Swallow unneeded args */
00522         T dummyf;
00523         ValueGenerator_Opposite<T> dummy(args,&dummyf);
00524       }
00525     }
00526     if (ref) return new ValueGenerator<T>(ref);
00527     
00528     /* Otherwise just construct and return a normal ValueGenerator */
00529     return create(args);
00530   }
00531 protected:
00532   void error   (const string& s) const {  message(Msg::Error,s);    }
00533   void warning (const string& s) const {  message(Msg::Warning,s);  }
00534 
00535 private:
00536   static Msg::LevelHandler<>** mhp;  
00537   static void message(Msg::MessageLevel m, const string& s)
00538     {  if (mhp && *mhp) (**mhp)(m,s);  }
00539 };
00540 #endif
00541 
00542 
00543 /* Static variables */
00544 template<class T, class urf, class nrf> Msg::LevelHandler<>**
00545 ValueGeneratorFactory<T,urf,nrf>::mhp=&(Msg::LevelHandler<>::default_instance());
00546 
00547 #endif

Generated on Mon Jan 20 02:35:45 2003 for RF-LISSOM by doxygen1.3-rc2