pomp
Inference for partially observed Markov processes
Toggle main menu visibility
Main Page
Data Structures
Data Structures
Data Structure Index
Data Fields
All
Variables
Files
File List
Globals
All
_
a
b
c
d
e
f
g
i
k
l
m
n
o
p
r
s
t
u
v
w
x
y
Functions
_
a
b
d
e
f
g
i
l
m
n
o
p
r
s
t
w
Variables
_
a
c
f
m
n
o
p
r
s
Typedefs
a
b
g
l
m
n
p
s
t
u
Enumerations
Enumerator
Macros
a
c
e
f
k
m
n
r
s
t
u
v
w
x
y
•
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Pages
Loading...
Searching...
No Matches
sobolseq.c
Go to the documentation of this file.
1
// -*- C++ -*-
2
/* Copyright (c) 2007 Massachusetts Institute of Technology
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining
5
* a copy of this software and associated documentation files (the
6
* "Software"), to deal in the Software without restriction, including
7
* without limitation the rights to use, copy, modify, merge, publish,
8
* distribute, sublicense, and/or sell copies of the Software, and to
9
* permit persons to whom the Software is furnished to do so, subject to
10
* the following conditions:
11
*
12
* The above copyright notice and this permission notice shall be
13
* included in all copies or substantial portions of the Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
*/
23
24
/* Generation of Sobol sequences in up to 1111 dimensions, based on the
25
algorithms described in:
26
P. Bratley and B. L. Fox, Algorithm 659, ACM Trans.
27
Math. Soft. 14 (1), 88-100 (1988),
28
as modified by:
29
S. Joe and F. Y. Kuo, ACM Trans. Math. Soft 29 (1), 49-57 (2003).
30
31
Note that the code below was written without even looking at the
32
Fortran code from the TOMS paper, which is only semi-free (being
33
under the restrictive ACM copyright terms). Then I went to the
34
Fortran code and took out the table of primitive polynomials and
35
starting direction #'s ... since this is just a table of numbers
36
generated by a deterministic algorithm, it is not copyrightable.
37
(Obviously, the format of these tables then necessitated some
38
slight modifications to the code.)
39
40
For the test integral of Joe and Kuo (see the main() program
41
below), I get exactly the same results for integrals up to 1111
42
dimensions compared to the table of published numbers (to the 5
43
published significant digits).
44
45
This is not to say that the authors above should not be credited for
46
their clear description of the algorithm (and their tabulation of
47
the critical numbers). Please cite them. Just that I needed
48
a free/open-source implementation. */
49
50
/* AAK Notes:
51
I have removed the dependence on the NLOPT headers and on "stdint.h".
52
The assumption is (according to R_ext/Random.h) that Int32 is a 32-bit
53
integer. The fall-back to pseudo-random numbers for sequences of length
54
greater than 2^32-1 has also been removed. This case generates an error.
55
*/
56
57
#include "
internal.h
"
58
59
typedef
Int32
uint32_t
;
60
typedef
struct
nlopt_soboldata_s
*
nlopt_sobol
;
61
static
nlopt_sobol
nlopt_sobol_create
(
unsigned
sdim
);
62
static
void
nlopt_sobol_destroy
(
nlopt_sobol
s
);
63
static
void
nlopt_sobol_skip
(
nlopt_sobol
s
,
unsigned
n
,
double
*
x
);
64
65
typedef
struct
nlopt_soboldata_s
{
66
unsigned
sdim
;
/* dimension of sequence being generated */
67
uint32_t
*
mdata
;
/* array of length 32 * sdim */
68
uint32_t
*
m
[32];
/* more convenient pointers to mdata, of direction #s */
69
uint32_t
*
x
;
/* previous x = x_n, array of length sdim */
70
unsigned
*
b
;
/* position of fixed point in x[i] is after bit b[i] */
71
uint32_t
n
;
/* number of x's generated so far */
72
}
soboldata
;
65
typedef
struct
nlopt_soboldata_s
{
…
};
73
74
/* Return position (0, 1, ...) of rightmost (least-significant) zero bit in n.
75
*
76
* This code uses a 32-bit version of algorithm to find the rightmost
77
* one bit in Knuth, _The Art of Computer Programming_, volume 4A
78
* (draft fascicle), section 7.1.3, "Bitwise tricks and
79
* techniques."
80
*
81
* Assumes n has a zero bit, i.e. n < 2^32 - 1.
82
*
83
*/
84
static
unsigned
rightzero32
(
uint32_t
n)
85
{
86
const
uint32_t
a = 0x05f66a47;
/* magic number, found by brute force */
87
static
const
unsigned
decode[32] = {0,1,2,26,23,3,15,27,24,21,19,4,12,16,28,6,31,25,22,14,20,18,11,5,30,13,17,10,29,9,8,7};
88
n = ~n;
/* change to rightmost-one problem */
89
n = a * (n & (-n));
/* store in n to make sure mult. is 32 bits */
90
return
decode[n >> 27];
91
}
84
static
unsigned
rightzero32
(
uint32_t
n) {
…
}
92
93
/* generate the next term x_{n+1} in the Sobol sequence, as an array
94
x[sdim] of numbers in (0,1). Returns 1 on success, 0 on failure
95
(if too many #'s generated) */
96
static
int
sobol_gen
(
soboldata
*sd,
double
*x)
97
{
98
unsigned
c, b, i, sdim;
99
100
if
(sd->
n
== 4294967295U)
return
0;
/* n == 2^32 - 1 ... we would
101
need to switch to a 64-bit version
102
to generate more terms. */
103
c =
rightzero32
(sd->
n
++);
104
sdim = sd->
sdim
;
105
for
(i = 0; i < sdim; ++i) {
106
b = sd->
b
[i];
107
if
(b >= c) {
108
sd->
x
[i] ^= sd->
m
[c][i] << (b - c);
109
x[i] = ((double) (sd->
x
[i])) / (1U << (b+1));
110
}
111
else
{
112
sd->
x
[i] = (sd->
x
[i] << (c - b)) ^ sd->
m
[c][i];
113
sd->
b
[i] = c;
114
x[i] = ((double) (sd->
x
[i])) / (1U << (c+1));
115
}
116
}
117
return
1;
118
}
96
static
int
sobol_gen
(
soboldata
*sd,
double
*x) {
…
}
119
120
#include "
soboldata.h
"
121
122
static
int
sobol_init
(
soboldata
*sd,
unsigned
sdim)
123
{
124
unsigned
i,j;
125
126
if
(!sdim || sdim >
MAXDIM
)
return
0;
127
128
sd->
mdata
= (
uint32_t
*) R_Calloc(sdim*32,
uint32_t
);
129
if
(!sd->
mdata
)
return
0;
130
131
for
(j = 0; j < 32; ++j) {
132
sd->
m
[j] = sd->
mdata
+ j * sdim;
133
sd->
m
[j][0] = 1;
/* special-case Sobol sequence */
134
}
135
for
(i = 1; i < sdim; ++i) {
136
uint32_t
a =
sobol_a
[i-1];
137
unsigned
d = 0, k;
138
139
while
(a) {
140
++d;
141
a >>= 1;
142
}
143
d--;
/* d is now degree of poly */
144
145
/* set initial values of m from table */
146
for
(j = 0; j < d; ++j)
147
sd->
m
[j][i] =
sobol_minit
[j][i-1];
148
149
/* fill in remaining values using recurrence */
150
for
(j = d; j < 32; ++j) {
151
a =
sobol_a
[i-1];
152
sd->
m
[j][i] = sd->
m
[j - d][i];
153
for
(k = 0; k < d; ++k) {
154
sd->
m
[j][i] ^= ((a & 1) * sd->
m
[j-d+k][i]) << (d-k);
155
a >>= 1;
156
}
157
}
158
}
159
160
sd->
x
= (
uint32_t
*) R_Calloc(sdim,
uint32_t
);
161
if
(!sd->
x
) { R_Free(sd->
mdata
);
return
0; }
162
163
sd->
b
= (
unsigned
*) R_Calloc(sdim,
unsigned
);
164
if
(!sd->
b
) { R_Free(sd->
x
); R_Free(sd->
mdata
);
return
0; }
165
166
for
(i = 0; i < sdim; ++i) {
167
sd->
x
[i] = 0;
168
sd->
b
[i] = 0;
169
}
170
171
sd->
n
= 0;
172
sd->
sdim
= sdim;
173
174
return
1;
175
}
122
static
int
sobol_init
(
soboldata
*sd,
unsigned
sdim) {
…
}
176
177
static
void
sobol_destroy
(
soboldata
*sd)
178
{
179
R_Free(sd->
mdata
);
180
R_Free(sd->
x
);
181
R_Free(sd->
b
);
182
}
177
static
void
sobol_destroy
(
soboldata
*sd) {
…
}
183
184
/************************************************************************/
185
/* NLopt API to Sobol sequence creation, which hides soboldata structure
186
behind an opaque pointer */
187
188
static
nlopt_sobol
nlopt_sobol_create
(
unsigned
sdim)
189
{
190
nlopt_sobol
s = (
nlopt_sobol
) R_Calloc(1,
soboldata
);
191
if
(!s)
return
0;
192
if
(!
sobol_init
(s, sdim)) { R_Free(s);
return
NULL; }
193
return
s;
194
}
188
static
nlopt_sobol
nlopt_sobol_create
(
unsigned
sdim) {
…
}
195
196
static
void
nlopt_sobol_destroy
(
nlopt_sobol
s)
197
{
198
if
(s) {
199
sobol_destroy
(s);
200
R_Free(s);
201
}
202
}
196
static
void
nlopt_sobol_destroy
(
nlopt_sobol
s) {
…
}
203
204
/* next vector x[sdim] in Sobol sequence, with each x[i] in (0,1) */
205
// void nlopt_sobol_next01 (nlopt_sobol s, double *x)
206
// {
207
// if (!sobol_gen(s, x))
208
// err("too many points requested");
209
// }
210
211
/* next vector in Sobol sequence, scaled to (lb[i], ub[i]) interval */
212
// void nlopt_sobol_next (nlopt_sobol s, double *x,
213
// const double *lb, const double *ub)
214
// {
215
// unsigned i, sdim;
216
// nlopt_sobol_next01(s, x);
217
// for (sdim = s->sdim, i = 0; i < sdim; ++i)
218
// x[i] = lb[i] + (ub[i] - lb[i]) * x[i];
219
// }
220
221
/* if we know in advance how many points (n) we want to compute, then
222
adopt the suggestion of the Joe and Kuo paper, which in turn
223
is taken from Acworth et al (1998), of skipping a number of
224
points equal to the largest power of 2 smaller than n */
225
static
void
nlopt_sobol_skip
(
nlopt_sobol
s,
unsigned
n,
double
*x)
226
{
227
if
(s) {
228
unsigned
k = 1;
229
while
(k*2 < n) k *= 2;
230
while
(k-- > 0)
sobol_gen
(s, x);
231
}
232
}
225
static
void
nlopt_sobol_skip
(
nlopt_sobol
s,
unsigned
n,
double
*x) {
…
}
233
234
SEXP
sobol_sequence
(SEXP dim, SEXP length)
235
{
236
SEXP data;
237
unsigned
int
d = (
unsigned
int) INTEGER(dim)[0];
238
unsigned
int
n = (
unsigned
int) INTEGER(length)[0];
239
double
*dp;
240
unsigned
int
k;
241
nlopt_sobol
s =
nlopt_sobol_create
((
unsigned
int
) d);
242
if
(s==0)
err
(
"dimension is too high"
);
243
PROTECT(data = allocMatrix(REALSXP,d,n)); dp = REAL(data);
244
nlopt_sobol_skip
(s,n,dp);
245
for
(k = 1; k < n; k++)
sobol_gen
(s,dp+k*d);
246
nlopt_sobol_destroy
(s);
247
UNPROTECT(1);
248
return
(data);
249
}
234
SEXP
sobol_sequence
(SEXP dim, SEXP length) {
…
}
internal.h
err
#define err(...)
Definition
pomp.h:21
soboldata.h
MAXDIM
#define MAXDIM
Definition
soboldata.h:34
sobol_a
static const uint32_t sobol_a[MAXDIM-1]
Definition
soboldata.h:40
sobol_minit
static const uint32_t sobol_minit[MAXDEG+1][MAXDIM-1]
Definition
soboldata.h:150
nlopt_sobol_destroy
static void nlopt_sobol_destroy(nlopt_sobol s)
Definition
sobolseq.c:196
nlopt_sobol_create
static nlopt_sobol nlopt_sobol_create(unsigned sdim)
Definition
sobolseq.c:188
sobol_init
static int sobol_init(soboldata *sd, unsigned sdim)
Definition
sobolseq.c:122
uint32_t
Int32 uint32_t
Definition
sobolseq.c:59
soboldata
struct nlopt_soboldata_s soboldata
rightzero32
static unsigned rightzero32(uint32_t n)
Definition
sobolseq.c:84
nlopt_sobol_skip
static void nlopt_sobol_skip(nlopt_sobol s, unsigned n, double *x)
Definition
sobolseq.c:225
sobol_sequence
SEXP sobol_sequence(SEXP dim, SEXP length)
Definition
sobolseq.c:234
sobol_destroy
static void sobol_destroy(soboldata *sd)
Definition
sobolseq.c:177
sobol_gen
static int sobol_gen(soboldata *sd, double *x)
Definition
sobolseq.c:96
nlopt_sobol
struct nlopt_soboldata_s * nlopt_sobol
Definition
sobolseq.c:60
nlopt_soboldata_s
Definition
sobolseq.c:65
nlopt_soboldata_s::b
unsigned * b
Definition
sobolseq.c:70
nlopt_soboldata_s::sdim
unsigned sdim
Definition
sobolseq.c:66
nlopt_soboldata_s::x
uint32_t * x
Definition
sobolseq.c:69
nlopt_soboldata_s::mdata
uint32_t * mdata
Definition
sobolseq.c:67
nlopt_soboldata_s::n
uint32_t n
Definition
sobolseq.c:71
nlopt_soboldata_s::m
uint32_t * m[32]
Definition
sobolseq.c:68
src
sobolseq.c
Generated by
1.9.8