forked from npshub/mantid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SobolSequence.cpp
79 lines (71 loc) · 2.42 KB
/
SobolSequence.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
//-------------------------------------------------------------------
// Includes
//-------------------------------------------------------------------
#include "MantidKernel/SobolSequence.h"
#include <stdexcept>
namespace Mantid::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);
}
}
} // namespace Mantid::Kernel