// ===================================================================
// $Id: detrnd.h,v 1.2 2003/11/04 15:27:18 havran Exp $
//
// detrnd.h:
//    A set of function to generate random number given a seed and
//    dimension for multidimensional setting. Thus deterministic
//    random generator.
//
// Class: CMultDimRNDGen_ANSIC, CMultDimRNDGen_Halton
//
// Licence and usage conditions in November 2003:
// This file can be used and modified only with written permission of
// Vlastimil Havran, Pohodli 27, 57001 Litomysl, the Czech Republic.
// This library is granted to be used by Polina Kondratieva within
// her MPI HIWI job working on BRDFLIB library. The usage condition
// may change in the next version of the library. At the moment,
// the library development is supported by Max-Planck-Institut for
// Informatik, Stuhlsatzenhausweg 85, 66123 Saarbruecken Germany
// See WWW: http://www.mpi-sb.mpg.de
// REPLACEMENT_STRING
//
// Initial coding by Vlastimil Havran, October 2003.
//
// Given to BRDFLIB project for the Polina Kondratieva's
// HIWI JOB assignment in November 2003.

#ifndef __DETRND_H__
#define __DETRND_H__

#include "configh.h"
#include "detrndba.h"
#include "rnd.h"

__BEGIN_BRDFLIB_HEADER

//-------------------------------------------------------------------------
// Random generator based on traditional random generator by ANSI C random()
// generator, reimplemented not to interfere with the math.h calls!
// Based on the code written by University of California, Berkeley.
// This completely ignores the dimension during generation
//-------------------------------------------------------------------------
class CMultDimRNDGen_ANSIC:
  public CMultDimRNDGen
{
protected:
  unsigned long _seed;
public:
  // Constructor
  CMultDimRNDGen_ANSIC();

  // Destructor - explicitely virtual
  virtual ~CMultDimRNDGen_ANSIC() {}

  // Sets the new seed for the next call of Rand01d(int dimension)
  virtual void SetSeed(unsigned long newSeed);

  // Generate a random number given the dimension in range [0;1f).
  // Ignores the dimension information.
  virtual double Rand01d(int dimension);
 
  // Returns the maximum dimension that can be used for this generator
  virtual int MaxDimension() const { return 100000;}
};


//-------------------------------------------------------------------------
// Halton QMC generator
//-------------------------------------------------------------------------
class CMultDimRNDGen_Halton:
  public CMultDimRNDGen
{
protected:
  enum {MAXDIM = 78};
  // the table of prime numbers for first 78 dimensions
  static int prime_numbers[MAXDIM];

  unsigned long int _seed;
  unsigned int base;
public:
  // Constructor
  CMultDimRNDGen_Halton();

  // Sets the new seed for the next call of Rand01d(int dimension)
  virtual void SetSeed(unsigned long newSeed) {
    assert(newSeed > 0); // This check is necessary !
    _seed = newSeed;
  }

  // Generate a random number given a dimension. The seed is given
  // by the generator from the previous call. So after the running
  // this call the seed is updated. In case you want to generate
  // for the same seed and different dimension, function SetSeed should
  // be called again having as the parameter the same seed !
  virtual double Rand01d(int dimension);
  
  // Returns the maximum dimension that can be used for this generator
  virtual int MaxDimension() const { return MAXDIM-1;}
};

__END_BRDFLIB_HEADER

#endif // __DETRND_H__

