00001
00007 #ifndef __VALUEGEN_H__
00008 #define __VALUEGEN_H__
00009
00010 #ifndef NO_VALGEN_STRINGS
00011
00012
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
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
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; }
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
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; }
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; }
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(); }
00409
00410 virtual ValueGenerator<T>* clone() const { return new self(*this); };
00411 };
00412 #endif
00413
00414
00415
00416
00417
00418
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
00482 if (args.empty()) {
00483 warning("ValueGenerator: empty expression");
00484 return new ValueGenerator<T>;
00485 }
00486
00487
00488 else if (args.oneremaining())
00489 return new ValueGenerator<T>(args);
00490
00491
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
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
00522 T dummyf;
00523 ValueGenerator_Opposite<T> dummy(args,&dummyf);
00524 }
00525 }
00526 if (ref) return new ValueGenerator<T>(ref);
00527
00528
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
00544 template<class T, class urf, class nrf> Msg::LevelHandler<>**
00545 ValueGeneratorFactory<T,urf,nrf>::mhp=&(Msg::LevelHandler<>::default_instance());
00546
00547 #endif