Skip to content
Snippets Groups Projects
SobolSequence.cpp 2.09 KiB
Newer Older
//-------------------------------------------------------------------
// Includes
//-------------------------------------------------------------------
#include "MantidKernel/SobolSequence.h"
#include <stdexcept>

namespace Mantid {
namespace Kernel {
/**
 * Constructor taking the number of dimensions for the sequence
 */
SobolSequence::SobolSequence(const unsigned int ndims)
    : QuasiRandomNumberSequence(ndims), m_gslGenerator(nullptr),
      m_savedGenerator(nullptr) {
  setNumberOfDimensions(ndims);
}
/**
 * Destructor
 */
SobolSequence::~SobolSequence() { deleteCurrentGenerator(); }
/**
 * Returns the next number in the sequence
 * @returns A double giving the next number in the Sobol sequence for the
 * current dimension
 */
void SobolSequence::generateNextPoint() {
  std::vector<double> &point = getNextPointCache();
  gsl_qrng_get(m_gslGenerator, point.data());
}
/**
 * Reset state back to the start of the sequence
 */
void SobolSequence::restart() { gsl_qrng_init(m_gslGenerator); }
/// Saves the current state of the generator
void SobolSequence::save() {
  m_savedGenerator = gsl_qrng_clone(m_gslGenerator);
}
/// Restores the generator to the last saved point, or the beginning if nothing
/// has been saved
void SobolSequence::restore() {
  if (m_savedGenerator) {
    gsl_qrng_memcpy(m_gslGenerator, m_savedGenerator);
  } else {
    restart();
  }
}
/**
 * Sets the number of dimensions for the generator. Note this destroys
 * any previous state information including any saved state
 */
void SobolSequence::setNumberOfDimensions(const unsigned int ndims) {
  gsl_qrng *generator =
      gsl_qrng_alloc(gsl_qrng_sobol, static_cast<unsigned int>(ndims));
  if (generator) {
    deleteCurrentGenerator();
    m_gslGenerator = generator;
  } else {
    throw std::invalid_argument(
        "SobolSequence::setNumberOfDimensions - "
        "Error initializing sequence, insufficient memory.");
  }
}
/**
 * Frees resources allocated by current generator
 */
void SobolSequence::deleteCurrentGenerator() {
  gsl_qrng_free(m_gslGenerator);
  if (m_savedGenerator) {
    gsl_qrng_free(m_savedGenerator);