/* LICENSE:
  =========================================================================
    CMPack'04 Source Code Release for OPEN-R SDK 1.1.5-r2 for ERS7
    Copyright (C) 2004 Multirobot Lab [Project Head: Manuela Veloso]
    School of Computer Science, Carnegie Mellon University
    All rights reserved.
  ========================================================================= */

#ifndef INCLUDED_Sampler_h
#define INCLUDED_Sampler_h

#include "../../headers/Geometry.h"

#include "../../headers/random.h"

#include "Primitives.h"
#include "Sample.h"

class OnFieldProbEvaluator : public ProbEvaluator {
public:
  virtual void calc_prob(double *prob,const Sample *samp,bool scaled);
  virtual void calc_exp_prob(double *exp_prob,bool scaled);
  virtual void calc_energy(double *energy,const Sample *samp);
  virtual void calc_energy_der(Sample *der,const Sample *samp);
};

class NearOldValueProbEvaluator : public ProbEvaluator {
public:
  Sample dev; // deviations

  virtual void calc_prob(double *prob,const Sample *samp,bool scaled);
  virtual void calc_exp_prob(double *exp_prob,bool scaled);
  virtual void calc_energy(double *energy,const Sample *samp);
  virtual void calc_energy_der(Sample *der,const Sample *samp);
};

class Sampler {
private:
  Random random;

  int sample_steps;
  int AcceptCnt;
  int TotalCnt;

  void eval_sample_prob(double *prob,const Sample *samp);
  void eval_sample_energy(double *energy,const Sample *samp);
  void eval_sample_energy_der(Sample *der,const Sample *samp);

  void sim_sample(Sample *samp,Sample *momentum,double time_step_magnitude,bool forward);
  void hybrid_mcmc_update_sample(Sample *samp,double time_step_magnitude);
  void step_sample(Sample *samp,double time_step_magnitude);
public:
  int NumSamples;

  Sample *samples;
  ProbEvaluator *evals[100];
  int num_evals;

  void init();
  // init data structures in samples
  void init_samples();
  // set samples to uniform distribution
  void randomize_samples();
  void step_samples(int step_cnt);
};

#endif
