// ===================================================================
// $Id: halton.h,v 1.1 1999/11/04 12:14:05 havran Exp $
//
// halton.h
//   Generating Hammersley and Halton low-discrepancy sequences especially
//   usefull for sampling to avoid aliasing.
//
//   For 1D case, and 2D case(two-dimensional plane and sphere surface).
//
// REPLACEMENT_STRING
//
// Initial coding by Vlastimil Havran, 1999
// ===================================================================

#ifndef __HALTON_H__
#define __HALTON_H__

// forward declarations
class CVector2D;
class CVector3D;

// --------------------------------------------------------------------------
// General algorithm to generate Halton sequence for any base
// Generated value is in the range x = [0.0 - 1.0]
class CHalton
{
public:
  // constructor
  CHalton(int newSeed = 0, int newBase = 2):
    seed(newSeed), base(newBase) { }

  // generates value in the range <0.0, 1.0>

  // for seed in this class
  double NextValue() {
    return Value(seed++);
  }
  // for a given class
  double Value(int newSeed) const;
  void SetSeed(int newSeed) {
    seed = newSeed;
  }
  void SetBase(int newBase) {
    base = newBase;
  }
protected:
  int seed;
  int base;
};

inline double
CHalton::Value(int seed) const
{
  double h = 0.0;
  double f;
  double factor;

  f = factor = 1.0 / (double)base;

  while (seed > 0) {
    h += (double)(seed % base) * factor;
    seed /= base;
    factor *= f;
  }

  return h;
}


// --------------------------------------------------------------------------
// Special algorithm to generate Halton sequence for base = 2
// Generated value is in the range x = [0.0 - 1.0]
class CHalton2
{
public:
  // constructor
  CHalton2(int newSeed = 0):
    seed(newSeed) { }

  // generates the value in the range <0.0, 1.0>
  double NextValue() {
    return Value(seed++);
  }
  double Value(int newSeed) const;
  void SetSeed(int newSeed) {
    seed = newSeed;
  }
protected:
  int seed;
};


// --------------------------------------------------------------------------
// Special algorithm to generate Halton sequence for base = 3
// Generated value is in the range x = [0.0 - 1.0]
class CHalton3
{
public:
  // constructor
  CHalton3(int newSeed = 0):
    seed(newSeed) { }

  // generates the value in the range <0.0, 1.0>
  double NextValue() {
    return Value(seed++);
  }
  double Value(int newSeed) const;
  void SetSeed(int newSeed) {
    seed = newSeed;
  }
protected:
  int seed;
};


// --------------------------------------------------------------------------
// Special algorithm to generate Halton sequence for base = 5
// Generated value is in the range x = [0.0 - 1.0]
class CHalton5
{
public:
  // constructor
  CHalton5(int newSeed = 0):
    seed(newSeed) { }

  // generates the value in the range <0.0, 1.0>
  double NextValue() {
    return Value(seed++);
  }
  double Value(int newSeed) const;
  void SetSeed(int newSeed) {
    seed = newSeed;
  }
protected:
  int seed;
};


// --------------------------------------------------------------------------
// Special algorithm to generate Halton sequence for base = 7
// Generated value is in the range x = [0.0 - 1.0]
class CHalton7
{
public:
  // constructor
  CHalton7(int newSeed = 0):
    seed(newSeed) { }

  // generates the value in the range <0.0, 1.0>
  double NextValue() {
    return Value(seed++);
  }
  double Value(int newSeed) const;
  void SetSeed(int newSeed) {
    seed = newSeed;
  }
protected:
  int seed;
};


/*// -----------------------------------------------------------------------
// General algorithm to generate Halton sequence for any base
// Generated value is in the range x = [0.0 - 1.0]
class CHalton
{
public:
  // constructor
  CHalton(int newSeed = 0, int newBase = 2):
    seed(newSeed), base(newBase) { }
  // generates value in the range <0.0, 1.0>

  // for seed in this class
  double NextValue() {
    return Value(seed++);
  }
  // for a given class
  double Value(int newSeed) const;
  void SetSeed(int newSeed) {
    seed = newSeed;
  }
  void SetBase(int newBase) {
    base = newBase;
  }
protected:
  int seed;
  int base;
};

inline double
CHalton::Value(int seed) const
{
  double h = 0.0;
  double f;
  double factor;

  f = factor = 1.0 / (double)base;

  while (seed > 0) {
    h += (double)(seed % base) * factor;
    seed /= base;
    factor *= f;
  }

  return h;
}
*/




#endif // __HALTON_H__

