libfbm  0.1
Simulation of multi-dimensional stationary Gaussian processes and fractional Brownian motion.
 All Classes Namespaces Functions Friends
libfbm.hpp
1 
246 #ifndef __libfbm_hpp__
247 #define __libfbm_hpp__
248 
249 #include <vector>
250 #include <string>
251 
252 #include <gsl/gsl_rng.h>
253 
258 #define LIBFBM_MAX_DIM 8
259 
260 namespace libfbm
261 {
264  {
265  public:
267 
268  virtual void setSeed(unsigned long int seed) = 0;
269  virtual double next() = 0;
270  virtual RandomGenerator *clone() const = 0;
272  virtual ~RandomGenerator();
273 
274  private:
276  const RandomGenerator& operator=(const RandomGenerator&);
277  };
278 
282  {
283  public:
285  UniformRandomGenerator(unsigned long int seed, const gsl_rng_type* type);
287 
289 
291 
292  void setSeed(unsigned long int seed);
293  double next();
294  RandomGenerator *clone() const;
295 
296  private:
297  gsl_rng *rng;
298  };
299 
302  {
303  public:
310 
312 
314 
315  void setSeed(unsigned long int seed);
316  double next();
317  RandomGenerator *clone() const;
318 
319  private:
320  RandomGenerator *urg;
321  double gval2;
322  };
323 
327  class _Cache
328  {
329  public:
330  _Cache(const std::string& cacheDir, const std::string& cacheName, size_t cacheSize);
331  ~_Cache();
332 
333  bool load();
334  void store(const std::vector<double>& data);
335 
336  size_t size() const { return cacheSize; }
337 
338  bool inMemory() const { return !data.empty(); }
339 
340  private:
341  std::vector<double> data;
342  FILE *fp;
343  std::string cacheDir;
344  std::string cacheName;
345  size_t cacheSize;
346 
347  _Cache(const _Cache& copy);
348  const _Cache& operator=(const _Cache& copy);
349 
350  friend class _CacheReader;
351  };
352 
355  class _CacheReader
356  {
357  public:
358  _CacheReader(_Cache& cache, size_t bufferSize);
359 
360  inline double operator[](size_t i)
361  {
362  if ( !buf.empty() && (i < bufpos || i - bufpos >= buf.size()) )
363  load(i);
364  return data[i - bufpos];
365  }
366 
367  private:
368  _Cache& cache;
369  std::vector<double> buf;
370  size_t bufpos;
371  double *data;
372 
373  void load(size_t i);
374  };
379  class zvec
380  {
381  public:
382  inline zvec(size_t dim) : clen(dim) { }
383 
384  inline int& operator[](size_t i) { return c[i]; }
385  inline const int& operator[](size_t i) const { return c[i]; }
386 
387  inline size_t size() const { return clen; }
388 
391  inline bool increment(int base)
392  {
393  for ( size_t i = 0; i < size(); i++ )
394  {
395  if ( c[i] < base - 1 )
396  {
397  for ( size_t j = 0; j < i; j++ )
398  c[j] = 0;
399  c[i]++;
400  return true;
401  }
402  }
403  return false;
404  }
405 
409  inline bool increment(const zvec& dim)
410  {
411  for ( size_t i = 0; i < size(); i++ )
412  {
413  if ( c[i] < dim[i] - 1 )
414  {
415  for ( size_t j = 0; j < i; j++ )
416  c[j] = 0;
417  c[i]++;
418  return true;
419  }
420  }
421  return false;
422  }
423 
427  inline bool increment_but(const zvec& dim, size_t hold)
428  {
429  for ( size_t i = 0; i < size(); i++ )
430  {
431  if ( i == hold )
432  continue;
433  if ( c[i] < dim[i] - 1 )
434  {
435  for ( size_t j = 0; j < i; j++ )
436  c[j] = 0;
437  c[i]++;
438  return true;
439  }
440  }
441  return false;
442  }
443 
445  inline size_t index(size_t base) const
446  {
447  size_t ret = 0;
448  size_t mul = 1;
449  for ( size_t i = 0; i < size(); i++ )
450  {
451  ret += c[i] * mul;
452  mul *= base;
453  }
454  return ret;
455  }
456 
458  inline size_t index(const zvec& dim) const
459  {
460  size_t ret = 0;
461  size_t mul = 1;
462  for ( size_t i = 0; i < size(); i++ )
463  {
464  ret += c[i] * mul;
465  mul *= dim[i];
466  }
467  return ret;
468  }
469 
471  inline void zero()
472  {
473  for ( size_t i = 0; i < size(); i++ )
474  c[i] = 0;
475  }
476 
477  friend inline zvec operator+(const zvec& l, const zvec& r)
478  {
479  zvec ret(l.size());
480  for ( size_t i = 0; i < l.size(); i++ )
481  ret[i] = l[i] + r[i];
482  return ret;
483  }
484 
485  friend inline zvec operator-(const zvec& l, const zvec& r)
486  {
487  zvec ret(l.size());
488  for ( size_t i = 0; i < l.size(); i++ )
489  ret[i] = l[i] - r[i];
490  return ret;
491  }
492 
493  friend inline zvec operator*(int f, const zvec& v)
494  {
495  zvec ret(v.size());
496  for ( size_t i = 0; i < v.size(); i++ )
497  ret[i] = f * v[i];
498  return ret;
499  }
500 
501  friend inline zvec operator*(const zvec& v, int f)
502  {
503  zvec ret(v.size());
504  for ( size_t i = 0; i < v.size(); i++ )
505  ret[i] = f * v[i];
506  return ret;
507  }
508 
509  private:
510  int c[LIBFBM_MAX_DIM];
511  size_t clen;
512  };
513 
514  class Field;
515 
527  {
528  public:
535  SGPContext(const zvec& fieldDim, const zvec& userDim, const std::string& cacheName);
536  virtual ~SGPContext();
537 
538  virtual double cov(const zvec& p) = 0;
542  void setRandomGenerator(const RandomGenerator& newRng);
544 
546  inline const zvec& getDim() const { return userDim; }
548  inline const zvec& getFieldDim() const { return fieldDim; }
549  inline double nextRng() const { return rng->next(); }
550 
552  void setCacheDir(const std::string& cacheDir);
553 
555  inline size_t badEigenCount() const { return bec; }
556 
561  void initCache(bool forceRecalc = false);
562 
563  protected:
567  virtual void postProcess(Field& field);
568 
574  inline void setScaleResult(double f) { scaleResult = f; }
575 
576 
577  private:
578  zvec fieldDim, userDim;
579  _Cache *cache;
580  std::string cacheDir;
581  std::string cacheName;
582  RandomGenerator *rng;
583  size_t bec;
584  double scaleResult;
585 
586  friend class Field;
587 
588  SGPContext(const SGPContext&);
589  const SGPContext& operator=(const SGPContext&);
590  };
591 
593  class FGNContext : public SGPContext
594  {
595  public:
596  FGNContext(double H, const zvec& dim);
597 
598  double cov(const zvec& zvec);
599 
600  private:
601  double H;
602  };
603 
610  class FWSContext : public FGNContext
611  {
612  public:
613  FWSContext(double H, const zvec& dim) : FGNContext(H, dim) { }
614 
615  protected:
616  void postProcess(Field& field);
617  };
618 
624  class Field
625  {
626  public:
639  Field(SGPContext& context, bool allowCorrelated = false);
640  ~Field();
641 
648  void setBufferSize(size_t bufferSize);
649 
660  void generate();
661 
663  void clear();
664 
668  inline double operator()(const zvec& p) const
669  {
670  size_t index = (size_t)2 * p[0];
671  for ( size_t i = 1; i < p.size(); i++ )
672  index += muls[i] * p[i];
673  return datap[index];
674  }
675  inline double operator()(size_t x) const
676  { return datap[2 * x]; }
677  inline double operator()(size_t x, size_t y) const
678  { return datap[2 * x + muls[1] * y]; }
679  inline double operator()(size_t x, size_t y, size_t z) const
680  { return datap[2 * x + muls[1] * y + muls[2] * z]; }
681  inline double operator()(size_t x, size_t y, size_t z, size_t u) const
682  { return datap[2 * x + muls[1] * y + muls[2] * z + muls[3] * u]; }
683  inline double operator()(size_t x, size_t y, size_t z, size_t u, size_t v) const
684  { return datap[2 * x + muls[1] * y + muls[2] * z + muls[3] * u + muls[4] * v]; }
685 
691  void integrate();
692 
694  inline const zvec& getDim() const { return context.getDim(); }
695 
697  inline double& at(const zvec& p)
698  {
699  size_t index = 2 * p[0];
700  for ( size_t i = 1; i < p.size(); i++ )
701  index += muls[i] * p[i];
702  return datap[index];
703  }
704 
705  inline const double& at(const zvec& p) const
706  {
707  size_t index = 2 * p[0];
708  for ( size_t i = 1; i < p.size(); i++ )
709  index += muls[i] * p[i];
710  return datap[index];
711  }
712 
718  inline const size_t *getStrides() const { return muls; }
719 
720  private:
721  SGPContext& context;
722  bool allowCorrelated;
723  size_t bufferSize;
724  std::vector<double> Z;
725  zvec psel;
726  double *datap;
727  size_t muls[LIBFBM_MAX_DIM];
728 
729  Field(const Field&);
730  const Field& operator=(const Field&);
731  };
732 
739  class SGPTester
740  {
741  public:
743  void test(SGPContext& context, size_t printInterval = 1);
744  };
745 
756  {
757  public:
764  FBMSteinContext(double H, size_t dim, size_t size, double Rhint = -1, bool mapDim = true);
765 
766  double cov(const zvec& zvec);
767 
768  protected:
769  void postProcess(Field& field);
770 
771  public:
772  void disablePostProcessing();
773 
775  double getR() const { return R; }
776 
783  static size_t userSize2FieldSize(size_t size, double R);
785  static size_t fieldSize2UserSize(size_t size, double R);
792  static double getRForH(double H, double Rhint = -1);
793 
794  private:
795  double H;
796  double R;
797  double beta, c0, c2;
798  double Rscale;
799  bool pp;
800  };
801 };
802 
803 #endif // !__libfbm_hpp__
804