00001
00007 #ifndef __VALUEGEN_H__
00008 #define __VALUEGEN_H__
00009
00010 #ifdef ANSI_COMPATIBLE
00011
00012 #include "ind_types.h"
00013 #endif
00014
00015 #ifndef NO_VALGEN_STRINGS
00016
00017 #include "stringparser.h"
00018 #endif
00019
00020 #include "vgen.h"
00021
00022
00023
00024
00025
00026
00028 typedef double (*randomgen_fnPtr) ( double mean, double radius );
00029
00035 inline double uniform_distribution( double mean=0.5, double radius=0.5)
00036 { return mean + 2.0*radius*(shuffled_rand() - 0.5); }
00037
00038
00039
00045 inline double normal_distribution( double mean=0.0, double radius=1.0)
00046 { return mean + radius*(sqrt((-2.0) * log(shuffled_rand())) * cos(2*M_PI * shuffled_rand())); }
00047
00048
00049
00050
00051
00052
00053
00092 template<class T=double>
00093 class ValueGenerator : public ValueGen {
00094 public:
00095
00096 ValueGenerator() : val(0), vp(&val) { }
00097 ValueGenerator(T value) : val(value), vp(&val) { }
00098 ValueGenerator(T* value_pointer) : vp(value_pointer) { }
00100 #ifndef NO_VALGEN_STRINGS
00101 ValueGenerator(StringArgs& args)
00102 : val(0), vp(&val)
00103 { args.next(T(0),vp); }
00104 #endif
00105
00106 ValueGenerator(const ValueGenerator& other)
00107 : ValueGen(), val(other.value()),
00108
00109 vp( (other.vp==&other.val)? &val : other.vp ) { }
00110 virtual ~ValueGenerator() { }
00111
00112
00114 void operator= (T new_value) { *vp=new_value; }
00115
00117 T* valueptr() const { return vp; }
00118
00119
00120
00121
00122
00124 T value() const { return *vp; }
00125
00126
00129
00130 virtual bool next() { return true; }
00131 virtual void reset() { }
00132
00134 virtual ValueGenerator<T>* clone() const
00135 { return new ValueGenerator(*this); };
00136
00138 virtual void relink(T* ptr) { if (vp != &val) vp = ptr; }
00140
00141 private:
00143 T val;
00145 T* vp;
00146 };
00147
00148
00150 typedef ValueGenerator<double> DGen;
00151
00152
00154 template<class T=double, randomgen_fnPtr random_fn=uniform_distribution>
00155 class ValueGenerator_Random : public ValueGenerator<T> {
00156 T v,m,r;
00157
00158 T* mp;
00159 T* rp;
00161 public:
00162 ValueGenerator_Random(T mean, T radius=0)
00163 : ValueGenerator<T>(&v), v(mean), m(mean), r(radius), mp(&m), rp(&r) { }
00164
00165 ValueGenerator_Random(T* mean_ptr, T* radius_ptr)
00166 : ValueGenerator<T>(&v), v(*mean_ptr), mp(mean_ptr), rp(radius_ptr) { }
00167
00168 #ifndef NO_VALGEN_STRINGS
00169 ValueGenerator_Random(StringArgs& args)
00170 : ValueGenerator<T>(&v), v(0), m(0), r(0), mp(&m), rp(&r) {
00171 args.next(T(0),mp); v = *mp;
00172 args.next(T(0),rp);
00173 }
00174 #endif
00175
00176 ValueGenerator_Random(const ValueGenerator_Random& other)
00177 : ValueGenerator<T>(&v), v(other.v), m(other.m), r(other.r),
00178 mp( (other.mp==&other.m)? &m : other.mp ),
00179 rp( (other.rp==&other.r)? &r : other.rp ) { }
00181 virtual bool next()
00182 { v = random_fn( *mp, *rp ); return true; }
00183
00184 virtual void reset() { v=*mp; }
00185
00186 virtual ValueGenerator<T>* clone() const { return new ValueGenerator_Random(*this); };
00187 };
00188
00189
00190
00201 template<class T=double, randomgen_fnPtr random_fn=uniform_distribution, bool crop=true>
00202 class ValueGenerator_Correlate
00203 : public ValueGenerator<T> {
00204 T v, lb, ub, range;
00205 T* mp;
00206 T* uncorr_p;
00208 public:
00210 ValueGenerator_Correlate(T* master_value_ptr, T* uncorrelation_ptr,
00211 T lower_bound, T upper_bound)
00212 : ValueGenerator<T>(&v), v(*master_value_ptr),
00213 lb(lower_bound), ub(upper_bound), range(upper_bound-lower_bound),
00214 mp(master_value_ptr), uncorr_p(uncorrelation_ptr) { }
00215
00216 #ifndef NO_VALGEN_STRINGS
00217 ValueGenerator_Correlate(StringArgs& args, T* ref=0)
00218 : ValueGenerator<T>(&v), v(0), lb(0), ub(0), mp(ref? ref : &v), uncorr_p(&v) {
00219 00220 00221 00222 00223 00224 00225 00226 00227 00228 00229
00230 if (!ref) args.next(v,mp);
00231 args.next(v,uncorr_p);
00232 lb = args.next(T(0));
00233 ub = args.next(T(0));
00234
00235 v = *mp;
00236 range = ub-lb;
00237 }
00238 #endif
00239
00240 ValueGenerator_Correlate(const ValueGenerator_Correlate& other)
00241 : ValueGenerator<T>(&v), v(other.v), lb(other.lb), ub(other.ub), range(other.range),
00242 mp(other.mp), uncorr_p( other.uncorr_p) { }
00244 virtual bool next() {
00245 const T uncorr_radius = range*(*uncorr_p);
00246
00247
00248 if (crop) {
00249 const T low = std::max(lb,*mp-uncorr_radius);
00250 const T high = std::min(ub,*mp+uncorr_radius);
00251 const T radius = (high-low)/2;
00252 const T mean = low+radius;
00253 v = random_fn(mean, radius);
00254 }
00255 else
00256 v = random_fn(*mp, uncorr_radius);
00257
00258 return true;
00259 }
00260
00261 virtual void reset() { v=*mp; }
00262
00263 virtual ValueGenerator<T>* clone() const { return new ValueGenerator_Correlate(*this); };
00264 };
00265
00266
00267
00269 template<class T=double>
00270 class ValueGenerator_Increment : public ValueGenerator<T> {
00271 T v,s,inc;
00272
00273 public:
00274 ValueGenerator_Increment(T init_value, T increment=1)
00275 : ValueGenerator<T>(&v), v(init_value), s(init_value), inc(increment) { }
00276
00277 #ifndef NO_VALGEN_STRINGS
00278
00279 ValueGenerator_Increment(StringArgs& args)
00280 : ValueGenerator<T>(&v), v(0), s(0), inc(1) {
00281 s = args.next(T(0));
00282 v = s;
00283 inc = args.next(T(1));
00284 }
00285 #endif
00286
00287 ValueGenerator_Increment(const ValueGenerator_Increment& other)
00288 : ValueGenerator<T>(&v), v(other.v), s(other.s), inc(other.inc) { }
00290 virtual bool next() { v += inc; return true; }
00291 virtual void reset() { v = s; }
00292
00293 virtual ValueGenerator<T>* clone() const { return new ValueGenerator_Increment(*this); };
00294 };
00295
00296
00297
00302 #ifndef NO_VALGEN_STRINGS
00303
00304 template<class T=double>
00305 class ValueGenerator_Expression : public ValueGenerator<T> {
00306 const StringParser* p;
00307 T v;
00308 string expr;
00309
00310 public:
00311 ValueGenerator_Expression(string expression, const StringParser& parser)
00312 : ValueGenerator<T>(&v), p(parser.clone()), v(p->parse(expression,v)), expr(expression) { }
00313
00314 ValueGenerator_Expression(StringArgs& args)
00315 : ValueGenerator<T>(&v), p(args.p.clone()), v(0), expr("") {
00316 expr = args.next(string(""));
00317 p->parse(expr,v);
00318 }
00319
00320 ValueGenerator_Expression(const ValueGenerator_Expression& other)
00321 : ValueGenerator<T>(&v), p(other.p->clone()), v(other.v), expr(other.expr) { }
00323 ~ValueGenerator_Expression() { delete p; }
00324
00325 virtual bool next() { p->parse(expr,v); return true; }
00326
00327 virtual void reset() { next(); }
00328
00329 virtual ValueGenerator<T>* clone() const
00330 { return new ValueGenerator_Expression(*this); };
00331 };
00332 #endif
00333
00334
00335
00336
00337
00338
00339
00340
00341 #ifndef NO_VALGEN_STRINGS
00342
00343
00348 template<class T=double>
00349 class VGenFactory {
00350 public:
00351 VGenFactory() { };
00352 virtual ~VGenFactory() { }
00353
00361 virtual ValueGenerator<T>* create(StringArgs args) const =0;
00362
00364 virtual ValueGenerator<T>* create(StringArgs args, T* ref) const =0;
00365
00366 protected:
00369 virtual void error(const string&) const { }
00372 virtual void warning(const string&) const { }
00373 };
00374
00375
00376
00384 template<class T=double,
00385 randomgen_fnPtr urf=uniform_distribution,
00386 randomgen_fnPtr nrf=normal_distribution>
00387
00388 class ValueGeneratorFactory : public VGenFactory<T> {
00389 public:
00390 ValueGeneratorFactory() : VGenFactory<T>() { }
00391 virtual ~ValueGeneratorFactory() { }
00392
00394 virtual ValueGenerator<T>* create(StringArgs args) const {
00395
00396
00397 if (args.empty()) {
00398 warning("ValueGenerator: empty expression");
00399 return new ValueGenerator<T>;
00400 }
00401
00402
00403 else if (args.oneremaining())
00404 return new ValueGenerator<T>(args);
00405
00406
00407 else {
00408 const string& vgclass = args.next(string(""));
00409
00410 if (vgclass=="Random") { return new ValueGenerator_Random<T,urf>( args); }
00411 else if (vgclass=="Normal") { return new ValueGenerator_Random<T,nrf>( args); }
00412 else if (vgclass=="Increment") { return new ValueGenerator_Increment<T>( args); }
00413 else if (vgclass=="Expression") { return new ValueGenerator_Expression<T>( args); }
00414 else if (vgclass=="Correlate") { return new ValueGenerator_Correlate<T,urf,true> ( args); }
00415 else {
00416 error("ValueGenerator: Don't know about type `" + vgclass + "'");
00417 return new ValueGenerator<T>;
00418 }
00419 }
00420 }
00421
00422
00424 virtual ValueGenerator<T>* create(StringArgs args, T* ref) const {
00425 if (args.nextis(string("Uncorrelate"))) {
00426
00427 if (ref) return new ValueGenerator_Correlate<T,urf,true>(args,ref);
00428 else {
00429
00430 T dummyf;
00431 ValueGenerator_Correlate<T,urf,true> dummy(args,&dummyf);
00432 }
00433 }
00434 if (ref) return new ValueGenerator<T>(ref);
00435
00436
00437 return create(args);
00438 }
00439 };
00440 #endif
00441
00442
00443
00444
00445 #endif