vegas 6.2__cp311-cp311-win_amd64.whl → 6.2.1__cp311-cp311-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of vegas might be problematic. Click here for more details.
- vegas/__init__.py +16 -16
- vegas/_vegas.c +30581 -32759
- vegas/_vegas.cp311-win_amd64.pyd +0 -0
- vegas/_vegas.pxd +18 -23
- vegas/_vegas.pyx +201 -180
- vegas/_version.py +1 -1
- {vegas-6.2.dist-info → vegas-6.2.1.dist-info}/METADATA +3 -3
- vegas-6.2.1.dist-info/RECORD +12 -0
- {vegas-6.2.dist-info → vegas-6.2.1.dist-info}/WHEEL +1 -1
- vegas-6.2.dist-info/RECORD +0 -12
- {vegas-6.2.dist-info → vegas-6.2.1.dist-info}/LICENSE.txt +0 -0
- {vegas-6.2.dist-info → vegas-6.2.1.dist-info}/top_level.txt +0 -0
vegas/_vegas.pyx
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# c#ython: profile=True
|
|
3
3
|
|
|
4
4
|
# Created by G. Peter Lepage (Cornell University) in 12/2013.
|
|
5
|
-
# Copyright (c) 2013-
|
|
5
|
+
# Copyright (c) 2013-25 G. Peter Lepage.
|
|
6
6
|
#
|
|
7
7
|
# This program is free software: you can redistribute it and/or modify
|
|
8
8
|
# it under the terms of the GNU General Public License as published by
|
|
@@ -14,13 +14,10 @@
|
|
|
14
14
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
15
|
# GNU General Public License for more details.
|
|
16
16
|
|
|
17
|
-
cimport
|
|
18
|
-
cimport numpy
|
|
19
|
-
from libc.math cimport floor, log, abs, tanh, erf, exp, sqrt, lgamma
|
|
17
|
+
from libc.math cimport floor, log, abs, tanh, erf, exp, sqrt
|
|
20
18
|
|
|
21
19
|
import collections
|
|
22
20
|
import copy
|
|
23
|
-
import functools
|
|
24
21
|
import inspect
|
|
25
22
|
import math
|
|
26
23
|
import multiprocessing
|
|
@@ -34,18 +31,13 @@ import warnings
|
|
|
34
31
|
import numpy
|
|
35
32
|
import gvar
|
|
36
33
|
|
|
37
|
-
if numpy.version.version >= '2.0':
|
|
38
|
-
FLOAT_TYPE = numpy.float64
|
|
39
|
-
else:
|
|
40
|
-
FLOAT_TYPE = numpy.float_
|
|
41
|
-
|
|
42
34
|
cdef double TINY = 10 ** (sys.float_info.min_10_exp + 50) # smallest and biggest
|
|
43
35
|
cdef double HUGE = 10 ** (sys.float_info.max_10_exp - 50) # with extra headroom
|
|
44
36
|
cdef double EPSILON = sys.float_info.epsilon * 1e4 # roundoff error threshold (see Schubert and Gertz Table 2)
|
|
45
37
|
|
|
46
38
|
# AdaptiveMap is used by Integrator
|
|
47
39
|
cdef class AdaptiveMap:
|
|
48
|
-
""" Adaptive map ``y->x(y)`` for multidimensional ``y`` and ``x``.
|
|
40
|
+
r""" Adaptive map ``y->x(y)`` for multidimensional ``y`` and ``x``.
|
|
49
41
|
|
|
50
42
|
An :class:`AdaptiveMap` defines a multidimensional map ``y -> x(y)``
|
|
51
43
|
from the unit hypercube, with ``0 <= y[d] <= 1``, to an arbitrary
|
|
@@ -118,7 +110,7 @@ cdef class AdaptiveMap:
|
|
|
118
110
|
``ninc=None``, leaves the grid unchanged.
|
|
119
111
|
"""
|
|
120
112
|
def __init__(self, grid, ninc=None):
|
|
121
|
-
cdef
|
|
113
|
+
cdef Py_ssize_t i, d, dim
|
|
122
114
|
cdef double griddi
|
|
123
115
|
if isinstance(grid, AdaptiveMap):
|
|
124
116
|
self.ninc = numpy.array(grid.ninc)
|
|
@@ -149,8 +141,8 @@ cdef class AdaptiveMap:
|
|
|
149
141
|
def __get__(self):
|
|
150
142
|
return self.grid.shape[0]
|
|
151
143
|
|
|
152
|
-
def region(self,
|
|
153
|
-
""" x-space region.
|
|
144
|
+
def region(self, Py_ssize_t d=-1):
|
|
145
|
+
r""" x-space region.
|
|
154
146
|
|
|
155
147
|
``region(d)`` returns a tuple ``(xl,xu)`` specifying the ``x``-space
|
|
156
148
|
interval covered by the map in direction ``d``. A list containing
|
|
@@ -163,7 +155,7 @@ cdef class AdaptiveMap:
|
|
|
163
155
|
|
|
164
156
|
def extract_grid(self):
|
|
165
157
|
" Return a list of lists specifying the map's grid. "
|
|
166
|
-
cdef
|
|
158
|
+
cdef Py_ssize_t d
|
|
167
159
|
grid = []
|
|
168
160
|
for d in range(self.dim):
|
|
169
161
|
ng = self.ninc[d] + 1
|
|
@@ -171,18 +163,18 @@ cdef class AdaptiveMap:
|
|
|
171
163
|
return grid
|
|
172
164
|
|
|
173
165
|
def __reduce__(self):
|
|
174
|
-
""" Capture state for pickling. """
|
|
166
|
+
r""" Capture state for pickling. """
|
|
175
167
|
return (AdaptiveMap, (self.extract_grid(),))
|
|
176
168
|
|
|
177
169
|
def settings(self, ngrid=5):
|
|
178
|
-
""" Create string with information about grid nodes.
|
|
170
|
+
r""" Create string with information about grid nodes.
|
|
179
171
|
|
|
180
172
|
Creates a string containing the locations of the nodes
|
|
181
173
|
in the map grid for each direction. Parameter
|
|
182
174
|
``ngrid`` specifies the maximum number of nodes to print
|
|
183
175
|
(spread evenly over the grid).
|
|
184
176
|
"""
|
|
185
|
-
cdef
|
|
177
|
+
cdef Py_ssize_t d
|
|
186
178
|
ans = []
|
|
187
179
|
if ngrid > 0:
|
|
188
180
|
for d in range(self.dim):
|
|
@@ -211,15 +203,15 @@ cdef class AdaptiveMap:
|
|
|
211
203
|
return self(y)
|
|
212
204
|
|
|
213
205
|
def make_uniform(self, ninc=None):
|
|
214
|
-
""" Replace the grid with a uniform grid.
|
|
206
|
+
r""" Replace the grid with a uniform grid.
|
|
215
207
|
|
|
216
208
|
The new grid has ``ninc[d]`` (or ``ninc``, if it is a number)
|
|
217
209
|
increments along each direction if ``ninc`` is specified.
|
|
218
210
|
If ``ninc=None`` (default), the new grid has the same number
|
|
219
211
|
of increments in each direction as the old grid.
|
|
220
212
|
"""
|
|
221
|
-
cdef
|
|
222
|
-
cdef
|
|
213
|
+
cdef Py_ssize_t i, d
|
|
214
|
+
cdef Py_ssize_t dim = self.grid.shape[0]
|
|
223
215
|
cdef double[:] tmp
|
|
224
216
|
cdef double[:, ::1] new_grid
|
|
225
217
|
if ninc is None:
|
|
@@ -235,8 +227,8 @@ cdef class AdaptiveMap:
|
|
|
235
227
|
"no of increments < 1 in AdaptiveMap -- %s"
|
|
236
228
|
% str(ninc)
|
|
237
229
|
)
|
|
238
|
-
new_inc = numpy.empty((dim, max(ninc)),
|
|
239
|
-
new_grid = numpy.empty((dim, new_inc.shape[1] + 1),
|
|
230
|
+
new_inc = numpy.empty((dim, max(ninc)), float)
|
|
231
|
+
new_grid = numpy.empty((dim, new_inc.shape[1] + 1), float)
|
|
240
232
|
for d in range(dim):
|
|
241
233
|
tmp = numpy.linspace(self.grid[d, 0], self.grid[d, self.ninc[d]], ninc[d] + 1)
|
|
242
234
|
for i in range(ninc[d] + 1):
|
|
@@ -249,7 +241,7 @@ cdef class AdaptiveMap:
|
|
|
249
241
|
self.clear()
|
|
250
242
|
|
|
251
243
|
def __call__(self, y):
|
|
252
|
-
""" Return ``x`` values corresponding to ``y``.
|
|
244
|
+
r""" Return ``x`` values corresponding to ``y``.
|
|
253
245
|
|
|
254
246
|
``y`` can be a single ``dim``-dimensional point, or it
|
|
255
247
|
can be an array ``y[i,j, ..., d]`` of such points (``d=0..dim-1``).
|
|
@@ -261,17 +253,17 @@ cdef class AdaptiveMap:
|
|
|
261
253
|
if y is None:
|
|
262
254
|
y = gvar.RNG.random(size=self.dim)
|
|
263
255
|
else:
|
|
264
|
-
y = numpy.asarray(y,
|
|
256
|
+
y = numpy.asarray(y, float)
|
|
265
257
|
y_shape = y.shape
|
|
266
258
|
y.shape = -1, y.shape[-1]
|
|
267
259
|
x = 0 * y
|
|
268
|
-
jac = numpy.empty(y.shape[0],
|
|
260
|
+
jac = numpy.empty(y.shape[0], float)
|
|
269
261
|
self.map(y, x, jac)
|
|
270
262
|
x.shape = y_shape
|
|
271
263
|
return x
|
|
272
264
|
|
|
273
265
|
def jac1d(self, y):
|
|
274
|
-
""" Return the map's Jacobian at ``y`` for each direction.
|
|
266
|
+
r""" Return the map's Jacobian at ``y`` for each direction.
|
|
275
267
|
|
|
276
268
|
``y`` can be a single ``dim``-dimensional point, or it
|
|
277
269
|
can be an array ``y[i,j,...,d]`` of such points (``d=0..dim-1``).
|
|
@@ -279,15 +271,15 @@ cdef class AdaptiveMap:
|
|
|
279
271
|
(one-dimensional) Jacobian (``dx[d]/dy[d]``) corresponding
|
|
280
272
|
to ``y[i,j,...,d]``.
|
|
281
273
|
"""
|
|
282
|
-
cdef
|
|
283
|
-
cdef
|
|
274
|
+
cdef Py_ssize_t dim = self.grid.shape[0]
|
|
275
|
+
cdef Py_ssize_t i, d, ninc, ny, iy
|
|
284
276
|
cdef double y_ninc, dy_ninc
|
|
285
277
|
cdef double[:,::1] jac
|
|
286
278
|
y = numpy.asarray(y)
|
|
287
279
|
y_shape = y.shape
|
|
288
280
|
y.shape = -1, y.shape[-1]
|
|
289
281
|
ny = y.shape[0]
|
|
290
|
-
jac = numpy.empty(y.shape,
|
|
282
|
+
jac = numpy.empty(y.shape, float)
|
|
291
283
|
for i in range(ny):
|
|
292
284
|
for d in range(dim):
|
|
293
285
|
ninc = self.ninc[d]
|
|
@@ -303,7 +295,7 @@ cdef class AdaptiveMap:
|
|
|
303
295
|
return ans
|
|
304
296
|
|
|
305
297
|
def jac(self, y):
|
|
306
|
-
""" Return the map's Jacobian at ``y``.
|
|
298
|
+
r""" Return the map's Jacobian at ``y``.
|
|
307
299
|
|
|
308
300
|
``y`` can be a single ``dim``-dimensional point, or it
|
|
309
301
|
can be an array ``y[i,j,...,d]`` of such points (``d=0..dim-1``).
|
|
@@ -320,9 +312,9 @@ cdef class AdaptiveMap:
|
|
|
320
312
|
double[:, ::1] y,
|
|
321
313
|
double[:, ::1] x,
|
|
322
314
|
double[::1] jac,
|
|
323
|
-
|
|
315
|
+
Py_ssize_t ny=-1
|
|
324
316
|
):
|
|
325
|
-
""" Map y to x, where jac is the Jacobian (``dx/dy``).
|
|
317
|
+
r""" Map y to x, where jac is the Jacobian (``dx/dy``).
|
|
326
318
|
|
|
327
319
|
``y[j, d]`` is an array of ``ny`` ``y``-values for direction ``d``.
|
|
328
320
|
``x[j, d]`` is filled with the corresponding ``x`` values,
|
|
@@ -344,9 +336,9 @@ cdef class AdaptiveMap:
|
|
|
344
336
|
and ``j=0...ny-1``. ``ny`` is set to ``y.shape[0]`` if it is
|
|
345
337
|
omitted (or negative).
|
|
346
338
|
"""
|
|
347
|
-
cdef
|
|
348
|
-
cdef
|
|
349
|
-
cdef
|
|
339
|
+
cdef Py_ssize_t ninc
|
|
340
|
+
cdef Py_ssize_t dim = self.inc.shape[0]
|
|
341
|
+
cdef Py_ssize_t i, iy, d
|
|
350
342
|
cdef double y_ninc, dy_ninc, tmp_jac
|
|
351
343
|
if ny < 0:
|
|
352
344
|
ny = y.shape[0]
|
|
@@ -372,9 +364,9 @@ cdef class AdaptiveMap:
|
|
|
372
364
|
double[:, ::1] x,
|
|
373
365
|
double[:, ::1] y,
|
|
374
366
|
double[::1] jac,
|
|
375
|
-
|
|
367
|
+
Py_ssize_t nx=-1
|
|
376
368
|
):
|
|
377
|
-
""" Map x to y, where jac is the Jacobian (``dx/dy``).
|
|
369
|
+
r""" Map x to y, where jac is the Jacobian (``dx/dy``).
|
|
378
370
|
|
|
379
371
|
``y[j, d]`` is an array of ``ny`` ``y``-values for direction ``d``.
|
|
380
372
|
``x[j, d]`` is filled with the corresponding ``x`` values,
|
|
@@ -396,10 +388,10 @@ cdef class AdaptiveMap:
|
|
|
396
388
|
and ``j=0...nx-1``. ``nx`` is set to ``x.shape[0]`` if it is
|
|
397
389
|
omitted (or negative).
|
|
398
390
|
"""
|
|
399
|
-
cdef
|
|
400
|
-
cdef
|
|
401
|
-
cdef
|
|
402
|
-
cdef
|
|
391
|
+
cdef Py_ssize_t ninc
|
|
392
|
+
cdef Py_ssize_t dim = self.inc.shape[0]
|
|
393
|
+
cdef Py_ssize_t[:] iy
|
|
394
|
+
cdef Py_ssize_t i, iyi, d
|
|
403
395
|
cdef double y_ninc, dy_ninc, tmp_jac
|
|
404
396
|
if nx < 0:
|
|
405
397
|
nx = x.shape[0]
|
|
@@ -430,9 +422,9 @@ cdef class AdaptiveMap:
|
|
|
430
422
|
self,
|
|
431
423
|
double[:, ::1] y,
|
|
432
424
|
double[::1] f,
|
|
433
|
-
|
|
425
|
+
Py_ssize_t ny=-1,
|
|
434
426
|
):
|
|
435
|
-
""" Add training data ``f`` for ``y``-space points ``y``.
|
|
427
|
+
r""" Add training data ``f`` for ``y``-space points ``y``.
|
|
436
428
|
|
|
437
429
|
Accumulates training data for later use by ``self.adapt()``.
|
|
438
430
|
Grid increments will be made smaller in regions where
|
|
@@ -450,14 +442,14 @@ cdef class AdaptiveMap:
|
|
|
450
442
|
and ``j=0...ny-1``. ``ny`` is set to ``y.shape[0]`` if it is
|
|
451
443
|
omitted (or negative).
|
|
452
444
|
"""
|
|
453
|
-
cdef
|
|
454
|
-
cdef
|
|
455
|
-
cdef
|
|
456
|
-
cdef
|
|
445
|
+
cdef Py_ssize_t ninc
|
|
446
|
+
cdef Py_ssize_t dim = self.inc.shape[0]
|
|
447
|
+
cdef Py_ssize_t iy
|
|
448
|
+
cdef Py_ssize_t i, d
|
|
457
449
|
if self.sum_f is None:
|
|
458
450
|
shape = (self.inc.shape[0], self.inc.shape[1])
|
|
459
|
-
self.sum_f = numpy.zeros(shape,
|
|
460
|
-
self.n_f = numpy.zeros(shape,
|
|
451
|
+
self.sum_f = numpy.zeros(shape, float)
|
|
452
|
+
self.n_f = numpy.zeros(shape, float) + TINY
|
|
461
453
|
if ny < 0:
|
|
462
454
|
ny = y.shape[0]
|
|
463
455
|
elif ny > y.shape[0]:
|
|
@@ -473,7 +465,7 @@ cdef class AdaptiveMap:
|
|
|
473
465
|
|
|
474
466
|
# @cython.boundscheck(False)
|
|
475
467
|
def adapt(self, double alpha=0.0, ninc=None):
|
|
476
|
-
""" Adapt grid to accumulated training data.
|
|
468
|
+
r""" Adapt grid to accumulated training data.
|
|
477
469
|
|
|
478
470
|
``self.adapt(...)`` projects the training data onto
|
|
479
471
|
each axis independently and maps it into ``x`` space.
|
|
@@ -508,10 +500,10 @@ cdef class AdaptiveMap:
|
|
|
508
500
|
cdef double[:, ::1] new_grid
|
|
509
501
|
cdef double[::1] avg_f, tmp_f
|
|
510
502
|
cdef double sum_f, acc_f, f_ninc
|
|
511
|
-
cdef
|
|
512
|
-
cdef
|
|
513
|
-
cdef
|
|
514
|
-
cdef
|
|
503
|
+
cdef Py_ssize_t old_ninc
|
|
504
|
+
cdef Py_ssize_t dim = self.grid.shape[0]
|
|
505
|
+
cdef Py_ssize_t i, j
|
|
506
|
+
cdef Py_ssize_t[:] new_ninc
|
|
515
507
|
|
|
516
508
|
# initialization
|
|
517
509
|
if ninc is None:
|
|
@@ -525,12 +517,12 @@ cdef class AdaptiveMap:
|
|
|
525
517
|
if min(new_ninc) < 1:
|
|
526
518
|
raise ValueError('ninc < 1: ' + str(list(new_ninc)))
|
|
527
519
|
if max(new_ninc) == 1:
|
|
528
|
-
new_grid = numpy.empty((dim, 2),
|
|
520
|
+
new_grid = numpy.empty((dim, 2), float)
|
|
529
521
|
for d in range(dim):
|
|
530
522
|
new_grid[d, 0] = self.grid[d, 0]
|
|
531
523
|
new_grid[d, 1] = self.grid[d, self.ninc[d]]
|
|
532
524
|
self.grid = numpy.asarray(new_grid)
|
|
533
|
-
self.inc = numpy.empty((dim, 1),
|
|
525
|
+
self.inc = numpy.empty((dim, 1), float)
|
|
534
526
|
self.ninc = numpy.array(dim * [1], dtype=numpy.intp)
|
|
535
527
|
for d in range(dim):
|
|
536
528
|
self.inc[d, 0] = self.grid[d, 1] - self.grid[d, 0]
|
|
@@ -538,10 +530,10 @@ cdef class AdaptiveMap:
|
|
|
538
530
|
return
|
|
539
531
|
|
|
540
532
|
# smooth and regrid
|
|
541
|
-
new_grid = numpy.empty((dim, max(new_ninc) + 1),
|
|
542
|
-
avg_f = numpy.ones(self.inc.shape[1],
|
|
533
|
+
new_grid = numpy.empty((dim, max(new_ninc) + 1), float)
|
|
534
|
+
avg_f = numpy.ones(self.inc.shape[1], float) # default = uniform
|
|
543
535
|
if alpha > 0 and max(self.ninc) > 1:
|
|
544
|
-
tmp_f = numpy.empty(self.inc.shape[1],
|
|
536
|
+
tmp_f = numpy.empty(self.inc.shape[1], float)
|
|
545
537
|
for d in range(dim):
|
|
546
538
|
old_ninc = self.ninc[d]
|
|
547
539
|
if alpha != 0 and old_ninc > 1:
|
|
@@ -607,7 +599,7 @@ cdef class AdaptiveMap:
|
|
|
607
599
|
self.n_f = None
|
|
608
600
|
|
|
609
601
|
def show_grid(self, ngrid=40, axes=None, shrink=False, plotter=None):
|
|
610
|
-
""" Display plots showing the current grid.
|
|
602
|
+
r""" Display plots showing the current grid.
|
|
611
603
|
|
|
612
604
|
Args:
|
|
613
605
|
ngrid (int): The number of grid nodes in each
|
|
@@ -734,7 +726,7 @@ cdef class AdaptiveMap:
|
|
|
734
726
|
return plt
|
|
735
727
|
|
|
736
728
|
def adapt_to_samples(self, x, f, nitn=5, alpha=1.0, nproc=1):
|
|
737
|
-
""" Adapt map to data ``{x, f(x)}``.
|
|
729
|
+
r""" Adapt map to data ``{x, f(x)}``.
|
|
738
730
|
|
|
739
731
|
Replace grid with one that is optimized for integrating
|
|
740
732
|
function ``f(x)``. New grid is found iteratively
|
|
@@ -774,7 +766,7 @@ cdef class AdaptiveMap:
|
|
|
774
766
|
on the machine (equivalent to ``nproc=os.cpu_count()``).
|
|
775
767
|
Default value is ``nproc=1``. (Requires Python 3.3 or later.)
|
|
776
768
|
"""
|
|
777
|
-
cdef
|
|
769
|
+
cdef Py_ssize_t i, tmp_ninc, old_ninc
|
|
778
770
|
x = numpy.ascontiguousarray(x)
|
|
779
771
|
if len(x.shape) != 2 or x.shape[1] != self.dim:
|
|
780
772
|
raise ValueError('incompatible shape of x: {}'.format(x.shape))
|
|
@@ -840,7 +832,7 @@ cdef class AdaptiveMap:
|
|
|
840
832
|
return (numpy.asarray(map.sum_f), numpy.asarray(map.n_f))
|
|
841
833
|
|
|
842
834
|
cdef class Integrator(object):
|
|
843
|
-
""" Adaptive multidimensional Monte Carlo integration.
|
|
835
|
+
r""" Adaptive multidimensional Monte Carlo integration.
|
|
844
836
|
|
|
845
837
|
:class:`vegas.Integrator` objects make Monte Carlo
|
|
846
838
|
estimates of multidimensional functions ``f(x)``
|
|
@@ -1147,7 +1139,7 @@ cdef class Integrator(object):
|
|
|
1147
1139
|
self.sum_sigf = numpy.sum(self.sigf)
|
|
1148
1140
|
self.nstrat = numpy.array(map.nstrat)
|
|
1149
1141
|
else:
|
|
1150
|
-
self.sigf = numpy.array([],
|
|
1142
|
+
self.sigf = numpy.array([], float) # reset sigf (dummy)
|
|
1151
1143
|
self.sum_sigf = HUGE
|
|
1152
1144
|
args = dict(Integrator.defaults)
|
|
1153
1145
|
if 'map' in args:
|
|
@@ -1174,11 +1166,11 @@ cdef class Integrator(object):
|
|
|
1174
1166
|
self.sigf_h5.close()
|
|
1175
1167
|
os.unlink(fname)
|
|
1176
1168
|
self.sigf_h5 = None
|
|
1177
|
-
self.sigf = numpy.array([],
|
|
1169
|
+
self.sigf = numpy.array([], float) # reset sigf (dummy)
|
|
1178
1170
|
self.sum_sigf = HUGE
|
|
1179
1171
|
|
|
1180
1172
|
def __reduce__(Integrator self not None):
|
|
1181
|
-
""" Capture state for pickling. """
|
|
1173
|
+
r""" Capture state for pickling. """
|
|
1182
1174
|
odict = dict()
|
|
1183
1175
|
for k in Integrator.defaults:
|
|
1184
1176
|
if k in ['map']:
|
|
@@ -1189,11 +1181,11 @@ cdef class Integrator(object):
|
|
|
1189
1181
|
return (Integrator, (self.map,), odict)
|
|
1190
1182
|
|
|
1191
1183
|
def __setstate__(Integrator self not None, odict):
|
|
1192
|
-
""" Set state for unpickling. """
|
|
1184
|
+
r""" Set state for unpickling. """
|
|
1193
1185
|
self.set(odict)
|
|
1194
1186
|
|
|
1195
1187
|
def _set_map(self, map):
|
|
1196
|
-
""" install new map, create xsample """
|
|
1188
|
+
r""" install new map, create xsample """
|
|
1197
1189
|
if isinstance(map, AdaptiveMap):
|
|
1198
1190
|
self.map = AdaptiveMap(map)
|
|
1199
1191
|
self.xsample = numpy.empty(self.map.dim, dtype=float)
|
|
@@ -1240,7 +1232,7 @@ cdef class Integrator(object):
|
|
|
1240
1232
|
|
|
1241
1233
|
|
|
1242
1234
|
def set(Integrator self not None, ka={}, **kargs):
|
|
1243
|
-
""" Reset default parameters in integrator.
|
|
1235
|
+
r""" Reset default parameters in integrator.
|
|
1244
1236
|
|
|
1245
1237
|
Usage is analogous to the constructor
|
|
1246
1238
|
for |Integrator|: for example, ::
|
|
@@ -1376,7 +1368,7 @@ cdef class Integrator(object):
|
|
|
1376
1368
|
# need to recalculate stratification distribution for beta>0
|
|
1377
1369
|
# unless a new sigf was set
|
|
1378
1370
|
old_val['sigf'] = self.sigf
|
|
1379
|
-
self.sigf = numpy.array([],
|
|
1371
|
+
self.sigf = numpy.array([], float) # reset sigf (dummy)
|
|
1380
1372
|
self.sum_sigf = HUGE
|
|
1381
1373
|
self.nstrat = nstrat
|
|
1382
1374
|
|
|
@@ -1399,11 +1391,11 @@ cdef class Integrator(object):
|
|
|
1399
1391
|
|
|
1400
1392
|
# neval_batch = self.nhcube_batch * avg_neval_hcube
|
|
1401
1393
|
nsigf = self.nhcube
|
|
1402
|
-
if self.beta
|
|
1394
|
+
if self.beta >= 0 and self.nhcube > 1 and not self.adapt_to_errors and len(self.sigf) != nsigf:
|
|
1403
1395
|
# set up sigf
|
|
1404
1396
|
self._clear_sigf_h5()
|
|
1405
1397
|
if not self.minimize_mem:
|
|
1406
|
-
self.sigf = numpy.ones(nsigf,
|
|
1398
|
+
self.sigf = numpy.ones(nsigf, float)
|
|
1407
1399
|
else:
|
|
1408
1400
|
try:
|
|
1409
1401
|
import h5py
|
|
@@ -1415,14 +1407,14 @@ cdef class Integrator(object):
|
|
|
1415
1407
|
self.sum_sigf = nsigf
|
|
1416
1408
|
self.neval_hcube = numpy.empty(self.min_neval_batch // 2 + 1, dtype=numpy.intp)
|
|
1417
1409
|
self.neval_hcube[:] = avg_neval_hcube
|
|
1418
|
-
self.y = numpy.empty((self.min_neval_batch, self.dim),
|
|
1419
|
-
self.x = numpy.empty((self.min_neval_batch, self.dim),
|
|
1420
|
-
self.jac = numpy.empty(self.min_neval_batch,
|
|
1421
|
-
self.fdv2 = numpy.empty(self.min_neval_batch,
|
|
1410
|
+
self.y = numpy.empty((self.min_neval_batch, self.dim), float)
|
|
1411
|
+
self.x = numpy.empty((self.min_neval_batch, self.dim), float)
|
|
1412
|
+
self.jac = numpy.empty(self.min_neval_batch, float)
|
|
1413
|
+
self.fdv2 = numpy.empty(self.min_neval_batch, float)
|
|
1422
1414
|
return old_val
|
|
1423
1415
|
|
|
1424
1416
|
def settings(Integrator self not None, ngrid=0):
|
|
1425
|
-
""" Assemble summary of integrator settings into string.
|
|
1417
|
+
r""" Assemble summary of integrator settings into string.
|
|
1426
1418
|
|
|
1427
1419
|
Args:
|
|
1428
1420
|
ngrid (int): Number of grid nodes in each direction
|
|
@@ -1431,7 +1423,7 @@ cdef class Integrator(object):
|
|
|
1431
1423
|
Returns:
|
|
1432
1424
|
String containing the settings.
|
|
1433
1425
|
"""
|
|
1434
|
-
cdef
|
|
1426
|
+
cdef Py_ssize_t d
|
|
1435
1427
|
nhcube = numpy.prod(self.nstrat)
|
|
1436
1428
|
neval = nhcube * self.min_neval_hcube if self.beta <= 0 else self.neval
|
|
1437
1429
|
ans = "Integrator Settings:\n"
|
|
@@ -1576,7 +1568,7 @@ cdef class Integrator(object):
|
|
|
1576
1568
|
bint yield_y=False,
|
|
1577
1569
|
# fcn = None,
|
|
1578
1570
|
):
|
|
1579
|
-
""" Low-level batch iterator over integration points and weights.
|
|
1571
|
+
r""" Low-level batch iterator over integration points and weights.
|
|
1580
1572
|
|
|
1581
1573
|
This method creates an iterator that returns integration
|
|
1582
1574
|
points from |vegas|, and their corresponding weights in an
|
|
@@ -1602,24 +1594,41 @@ cdef class Integrator(object):
|
|
|
1602
1594
|
corresponds to a single iteration. The number in a batch
|
|
1603
1595
|
is controlled by parameter ``nhcube_batch``.
|
|
1604
1596
|
"""
|
|
1605
|
-
|
|
1597
|
+
for t in self._random_batch(yield_hcube, yield_y):
|
|
1598
|
+
yield tuple(numpy.array(ti) for ti in t)
|
|
1599
|
+
|
|
1600
|
+
def _random_batch(
|
|
1601
|
+
Integrator self not None,
|
|
1602
|
+
bint yield_hcube=False,
|
|
1603
|
+
bint yield_y=False,
|
|
1604
|
+
# fcn = None,
|
|
1605
|
+
):
|
|
1606
|
+
r""" Underlying implementation of generator :meth:`Integrator.random_batch`.
|
|
1607
|
+
|
|
1608
|
+
Only difference from ``random_batch()`` is that the values for
|
|
1609
|
+
``x``, ``y``, etc. are returned here as memoryviews into internal buffers
|
|
1610
|
+
that are overwritten by subsequent iterations. ``random_batch()`` returns
|
|
1611
|
+
copies of the views that are not overwritten. ``_random_batch()`` is used
|
|
1612
|
+
internally to minimize memory and memory churn.
|
|
1613
|
+
"""
|
|
1614
|
+
cdef Py_ssize_t nhcube = numpy.prod(self.nstrat)
|
|
1606
1615
|
cdef double dv_y = 1. / nhcube
|
|
1607
|
-
# cdef
|
|
1608
|
-
cdef
|
|
1609
|
-
cdef
|
|
1610
|
-
cdef
|
|
1611
|
-
cdef
|
|
1616
|
+
# cdef Py_ssize_t min_neval_batch #= min(self.min_neval_batch, nhcube)
|
|
1617
|
+
cdef Py_ssize_t neval_batch # self.neval_batch
|
|
1618
|
+
cdef Py_ssize_t hcube_base
|
|
1619
|
+
cdef Py_ssize_t i_start, ihcube, i, d, tmp_hcube, hcube
|
|
1620
|
+
cdef Py_ssize_t[::1] hcube_array
|
|
1612
1621
|
cdef double neval_sigf = (
|
|
1613
1622
|
self.neval_frac * self.neval / self.sum_sigf
|
|
1614
1623
|
if self.beta > 0 and self.sum_sigf > 0 and not self.adapt_to_errors
|
|
1615
1624
|
else 0.0 # use min_neval_hcube (should not happen ever)
|
|
1616
1625
|
)
|
|
1617
|
-
cdef
|
|
1618
|
-
cdef
|
|
1619
|
-
cdef
|
|
1620
|
-
cdef
|
|
1621
|
-
cdef
|
|
1622
|
-
cdef
|
|
1626
|
+
cdef Py_ssize_t avg_neval_hcube = int(self.neval / self.nhcube)
|
|
1627
|
+
cdef Py_ssize_t min_neval_batch = self.min_neval_batch # min_neval_batch * avg_neval_hcube ####
|
|
1628
|
+
cdef Py_ssize_t max_nhcube_batch = min_neval_batch // 2 + 1 ####
|
|
1629
|
+
cdef Py_ssize_t[::1] neval_hcube = self.neval_hcube
|
|
1630
|
+
cdef Py_ssize_t[::1] y0 = numpy.empty(self.dim, numpy.intp)
|
|
1631
|
+
cdef Py_ssize_t max_neval_hcube = max(
|
|
1623
1632
|
self.max_neval_hcube, self.min_neval_hcube
|
|
1624
1633
|
)
|
|
1625
1634
|
cdef double[::1] sigf
|
|
@@ -1637,12 +1646,10 @@ cdef class Integrator(object):
|
|
|
1637
1646
|
self.neval_hcube_range = numpy.zeros(2, numpy.intp) + self.min_neval_hcube
|
|
1638
1647
|
if yield_hcube:
|
|
1639
1648
|
hcube_array = numpy.empty(self.y.shape[0], numpy.intp)
|
|
1640
|
-
if adaptive_strat and self.minimize_mem and not self.adapt:
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
#
|
|
1644
|
-
# if (hcube_base + min_neval_batch) > nhcube:
|
|
1645
|
-
# min_neval_batch = nhcube - hcube_base
|
|
1649
|
+
# if adaptive_strat and self.minimize_mem and not self.adapt:
|
|
1650
|
+
##### believe this was wrong idea; want to preserve adaptive strat if it exists
|
|
1651
|
+
# # can't minimize_mem without also adapting, so force beta=0
|
|
1652
|
+
# neval_sigf = 0.0
|
|
1646
1653
|
neval_batch = 0
|
|
1647
1654
|
hcube_base = 0
|
|
1648
1655
|
sigf = self.sigf[hcube_base:hcube_base + max_nhcube_batch]
|
|
@@ -1674,10 +1681,10 @@ cdef class Integrator(object):
|
|
|
1674
1681
|
|
|
1675
1682
|
# 1) resize work arrays if needed (to double what is needed)
|
|
1676
1683
|
if neval_batch > self.y.shape[0]:
|
|
1677
|
-
self.y = numpy.empty((2 * neval_batch, self.dim),
|
|
1678
|
-
self.x = numpy.empty((2 * neval_batch, self.dim),
|
|
1679
|
-
self.jac = numpy.empty(2 * neval_batch,
|
|
1680
|
-
self.fdv2 = numpy.empty(2 * neval_batch,
|
|
1684
|
+
self.y = numpy.empty((2 * neval_batch, self.dim), float)
|
|
1685
|
+
self.x = numpy.empty((2 * neval_batch, self.dim), float)
|
|
1686
|
+
self.jac = numpy.empty(2 * neval_batch, float)
|
|
1687
|
+
self.fdv2 = numpy.empty(2 * neval_batch, float)
|
|
1681
1688
|
y = self.y
|
|
1682
1689
|
x = self.x
|
|
1683
1690
|
jac = self.jac
|
|
@@ -1706,12 +1713,12 @@ cdef class Integrator(object):
|
|
|
1706
1713
|
if yield_hcube:
|
|
1707
1714
|
hcube_array[i] = hcube_base + ihcube
|
|
1708
1715
|
i_start += neval_hcube[ihcube]
|
|
1709
|
-
answer = (
|
|
1716
|
+
answer = (x[:neval_batch, :],)
|
|
1710
1717
|
if yield_y:
|
|
1711
|
-
answer += (
|
|
1712
|
-
answer += (
|
|
1718
|
+
answer += (y[:neval_batch, :],)
|
|
1719
|
+
answer += (jac[:neval_batch],)
|
|
1713
1720
|
if yield_hcube:
|
|
1714
|
-
answer += (
|
|
1721
|
+
answer += (hcube_array[:neval_batch],)
|
|
1715
1722
|
yield answer
|
|
1716
1723
|
|
|
1717
1724
|
# reset parameters for main loop
|
|
@@ -1726,7 +1733,7 @@ cdef class Integrator(object):
|
|
|
1726
1733
|
def random(
|
|
1727
1734
|
Integrator self not None, bint yield_hcube=False, bint yield_y=False
|
|
1728
1735
|
):
|
|
1729
|
-
""" Low-level iterator over integration points and weights.
|
|
1736
|
+
r""" Low-level iterator over integration points and weights.
|
|
1730
1737
|
|
|
1731
1738
|
This method creates an iterator that returns integration
|
|
1732
1739
|
points from |vegas|, and their corresponding weights in an
|
|
@@ -1749,9 +1756,9 @@ cdef class Integrator(object):
|
|
|
1749
1756
|
"""
|
|
1750
1757
|
cdef double[:, ::1] x
|
|
1751
1758
|
cdef double[::1] wgt
|
|
1752
|
-
cdef
|
|
1759
|
+
cdef Py_ssize_t[::1] hcube
|
|
1753
1760
|
cdef double[:, ::1] y
|
|
1754
|
-
cdef
|
|
1761
|
+
cdef Py_ssize_t i
|
|
1755
1762
|
if yield_hcube and yield_y:
|
|
1756
1763
|
for x, y, wgt, hcube in self.random_batch(yield_hcube=True, yield_y=True):
|
|
1757
1764
|
for i in range(x.shape[0]):
|
|
@@ -1770,7 +1777,7 @@ cdef class Integrator(object):
|
|
|
1770
1777
|
yield (x[i], wgt[i])
|
|
1771
1778
|
|
|
1772
1779
|
def sample(self, nbatch=None, mode='rbatch'):
|
|
1773
|
-
""" Generate random sample of integration weights and points.
|
|
1780
|
+
r""" Generate random sample of integration weights and points.
|
|
1774
1781
|
|
|
1775
1782
|
Given a :class:`vegas.Integrator` called ``integ``, the code ::
|
|
1776
1783
|
|
|
@@ -1841,7 +1848,7 @@ cdef class Integrator(object):
|
|
|
1841
1848
|
gvar.ranseed(seed)
|
|
1842
1849
|
|
|
1843
1850
|
def _make_std_integrand(self, fcn, xsample=None):
|
|
1844
|
-
""" Convert integrand ``fcn`` into an lbatch integrand.
|
|
1851
|
+
r""" Convert integrand ``fcn`` into an lbatch integrand.
|
|
1845
1852
|
|
|
1846
1853
|
Returns an object ``vi`` of type :class:`VegasIntegrand`.
|
|
1847
1854
|
This object converts an arbitrary integrand ``fcn`` (``lbatch`, `rbatch`,
|
|
@@ -1866,7 +1873,7 @@ cdef class Integrator(object):
|
|
|
1866
1873
|
)
|
|
1867
1874
|
|
|
1868
1875
|
def __call__(Integrator self not None, fcn, save=None, saveall=None, **kargs):
|
|
1869
|
-
""" Integrate integrand ``fcn``.
|
|
1876
|
+
r""" Integrate integrand ``fcn``.
|
|
1870
1877
|
|
|
1871
1878
|
A typical integrand has the form, for example::
|
|
1872
1879
|
|
|
@@ -1974,10 +1981,11 @@ cdef class Integrator(object):
|
|
|
1974
1981
|
an object of type :class:`vegas.RAvg`,
|
|
1975
1982
|
:class:`vegas.RAvgArray`, or :class:`vegas.RAvgDict`.
|
|
1976
1983
|
"""
|
|
1977
|
-
cdef
|
|
1978
|
-
cdef
|
|
1979
|
-
cdef
|
|
1980
|
-
cdef
|
|
1984
|
+
cdef double[:, ::1] x
|
|
1985
|
+
# cdef double[:, ::1] jac
|
|
1986
|
+
cdef double[::1] wgt
|
|
1987
|
+
cdef Py_ssize_t[::1] hcube
|
|
1988
|
+
|
|
1981
1989
|
cdef double[::1] sigf
|
|
1982
1990
|
cdef double[:, ::1] y
|
|
1983
1991
|
cdef double[::1] fdv2
|
|
@@ -1986,9 +1994,9 @@ cdef class Integrator(object):
|
|
|
1986
1994
|
cdef double[::1] sum_wf
|
|
1987
1995
|
cdef double[::1] sum_dwf
|
|
1988
1996
|
cdef double[:, ::1] sum_dwf2
|
|
1989
|
-
cdef double[::1] mean = numpy.empty(1,
|
|
1990
|
-
cdef double[:, ::1] var = numpy.empty((1, 1),
|
|
1991
|
-
cdef
|
|
1997
|
+
cdef double[::1] mean = numpy.empty(1, float)
|
|
1998
|
+
cdef double[:, ::1] var = numpy.empty((1, 1), float)
|
|
1999
|
+
cdef Py_ssize_t itn, i, j, jtmp, s, t, neval, fcn_size, len_hcube
|
|
1992
2000
|
cdef bint adaptive_strat
|
|
1993
2001
|
cdef double sum_sigf, sigf2
|
|
1994
2002
|
cdef bint firsteval = True
|
|
@@ -2018,12 +2026,12 @@ cdef class Integrator(object):
|
|
|
2018
2026
|
fcn_size = fcn.size
|
|
2019
2027
|
|
|
2020
2028
|
# allocate work arrays
|
|
2021
|
-
dwf = numpy.empty(fcn_size,
|
|
2022
|
-
sum_wf = numpy.empty(fcn_size,
|
|
2023
|
-
sum_dwf = numpy.empty(fcn_size,
|
|
2024
|
-
sum_dwf2 = numpy.empty((fcn_size, fcn_size),
|
|
2025
|
-
mean = numpy.empty(fcn_size,
|
|
2026
|
-
var = numpy.empty((fcn_size, fcn_size),
|
|
2029
|
+
dwf = numpy.empty(fcn_size, float)
|
|
2030
|
+
sum_wf = numpy.empty(fcn_size, float)
|
|
2031
|
+
sum_dwf = numpy.empty(fcn_size, float)
|
|
2032
|
+
sum_dwf2 = numpy.empty((fcn_size, fcn_size), float)
|
|
2033
|
+
mean = numpy.empty(fcn_size, float)
|
|
2034
|
+
var = numpy.empty((fcn_size, fcn_size), float)
|
|
2027
2035
|
mean[:] = 0.0
|
|
2028
2036
|
var[:, :] = 0.0
|
|
2029
2037
|
result = VegasResult(fcn, weighted=self.adapt)
|
|
@@ -2038,33 +2046,34 @@ cdef class Integrator(object):
|
|
|
2038
2046
|
sum_sigf = 0.0
|
|
2039
2047
|
|
|
2040
2048
|
# iterate batch-slices of integration points
|
|
2041
|
-
for x, y, wgt, hcube in self.
|
|
2049
|
+
for x, y, wgt, hcube in self._random_batch(
|
|
2042
2050
|
yield_hcube=True, yield_y=True, #fcn=fcn
|
|
2043
2051
|
):
|
|
2044
2052
|
fdv2 = self.fdv2 # must be inside loop
|
|
2045
2053
|
len_hcube = len(hcube)
|
|
2046
2054
|
|
|
2047
2055
|
# evaluate integrand at all points in x
|
|
2056
|
+
xa = numpy.asarray(x)
|
|
2048
2057
|
if self.nproc > 1:
|
|
2049
2058
|
nx = x.shape[0] // self.nproc + 1
|
|
2050
2059
|
if self.uses_jac:
|
|
2051
|
-
|
|
2060
|
+
jac1d = self.map.jac1d(y)
|
|
2052
2061
|
results = self.pool.starmap(
|
|
2053
2062
|
fcn.eval,
|
|
2054
|
-
[(
|
|
2063
|
+
[(xa[i*nx : (i+1)*nx], jac1d[i*nx : (i+1)*nx]) for i in range(self.nproc) if i*nx < xa.shape[0]],
|
|
2055
2064
|
1,
|
|
2056
2065
|
)
|
|
2057
2066
|
else:
|
|
2058
2067
|
results = self.pool.starmap(
|
|
2059
2068
|
fcn.eval,
|
|
2060
|
-
[(
|
|
2069
|
+
[(xa[i*nx : (i+1)*nx], None) for i in range(self.nproc) if i*nx < xa.shape[0]],
|
|
2061
2070
|
1,
|
|
2062
2071
|
)
|
|
2063
2072
|
fx = numpy.concatenate(results, axis=0, dtype=float)
|
|
2064
2073
|
else:
|
|
2065
2074
|
# fx = fcn.eval(x, jac=self.map.jac1d(y) if self.uses_jac else None)
|
|
2066
2075
|
fx = numpy.asarray(
|
|
2067
|
-
fcn.eval(
|
|
2076
|
+
fcn.eval(xa, jac=self.map.jac1d(y) if self.uses_jac else None),
|
|
2068
2077
|
dtype=float
|
|
2069
2078
|
)
|
|
2070
2079
|
# sanity check
|
|
@@ -2155,7 +2164,7 @@ cdef class Integrator(object):
|
|
|
2155
2164
|
return result.result
|
|
2156
2165
|
|
|
2157
2166
|
class reporter:
|
|
2158
|
-
""" Analyzer class that prints out a report, iteration
|
|
2167
|
+
r""" Analyzer class that prints out a report, iteration
|
|
2159
2168
|
by interation, on how vegas is doing. Parameter ngrid
|
|
2160
2169
|
specifies how many x[i]'s to print out from the maps
|
|
2161
2170
|
for each axis.
|
|
@@ -2199,7 +2208,7 @@ class reporter:
|
|
|
2199
2208
|
# average of the results of all iterations (unless parameter weigthed=False,
|
|
2200
2209
|
# in which case the average is unweighted).
|
|
2201
2210
|
class RAvg(gvar.GVar):
|
|
2202
|
-
""" Running average of scalar-valued Monte Carlo estimates.
|
|
2211
|
+
r""" Running average of scalar-valued Monte Carlo estimates.
|
|
2203
2212
|
|
|
2204
2213
|
This class accumulates independent Monte Carlo
|
|
2205
2214
|
estimates (e.g., of an integral) and combines
|
|
@@ -2237,7 +2246,7 @@ class RAvg(gvar.GVar):
|
|
|
2237
2246
|
self.sum_neval = sum_neval
|
|
2238
2247
|
|
|
2239
2248
|
def extend(self, ravg):
|
|
2240
|
-
""" Merge results from :class:`RAvg` object ``ravg`` after results currently in ``self``. """
|
|
2249
|
+
r""" Merge results from :class:`RAvg` object ``ravg`` after results currently in ``self``. """
|
|
2241
2250
|
for r in ravg.itn_results:
|
|
2242
2251
|
self.add(r)
|
|
2243
2252
|
self.sum_neval += ravg.sum_neval
|
|
@@ -2315,7 +2324,7 @@ class RAvg(gvar.GVar):
|
|
|
2315
2324
|
return self.sdev < atol + rtol * abs(self.mean)
|
|
2316
2325
|
|
|
2317
2326
|
def add(self, g):
|
|
2318
|
-
""" Add estimate ``g`` to the running average. """
|
|
2327
|
+
r""" Add estimate ``g`` to the running average. """
|
|
2319
2328
|
self.itn_results.append(g)
|
|
2320
2329
|
if isinstance(g, gvar.GVarRef):
|
|
2321
2330
|
return
|
|
@@ -2335,7 +2344,7 @@ class RAvg(gvar.GVar):
|
|
|
2335
2344
|
super(RAvg, self).__init__(*gvar.gvar(mean, numpy.sqrt(var)).internaldata)
|
|
2336
2345
|
|
|
2337
2346
|
def summary(self, extended=False, weighted=None):
|
|
2338
|
-
""" Assemble summary of results, iteration-by-iteration, into a string.
|
|
2347
|
+
r""" Assemble summary of results, iteration-by-iteration, into a string.
|
|
2339
2348
|
|
|
2340
2349
|
Args:
|
|
2341
2350
|
weighted (bool): Display weighted averages of results from different
|
|
@@ -2376,7 +2385,7 @@ class RAvg(gvar.GVar):
|
|
|
2376
2385
|
return ans
|
|
2377
2386
|
|
|
2378
2387
|
class RAvgDict(gvar.BufferDict):
|
|
2379
|
-
""" Running average of dictionary-valued Monte Carlo estimates.
|
|
2388
|
+
r""" Running average of dictionary-valued Monte Carlo estimates.
|
|
2380
2389
|
|
|
2381
2390
|
This class accumulates independent dictionaries of Monte Carlo
|
|
2382
2391
|
estimates (e.g., of an integral) and combines
|
|
@@ -2404,7 +2413,7 @@ class RAvgDict(gvar.BufferDict):
|
|
|
2404
2413
|
self.sum_neval = sum_neval
|
|
2405
2414
|
|
|
2406
2415
|
def extend(self, ravg):
|
|
2407
|
-
""" Merge results from :class:`RAvgDict` object ``ravg`` after results currently in ``self``. """
|
|
2416
|
+
r""" Merge results from :class:`RAvgDict` object ``ravg`` after results currently in ``self``. """
|
|
2408
2417
|
for r in ravg.itn_results:
|
|
2409
2418
|
self.add(r)
|
|
2410
2419
|
self.sum_neval += ravg.sum_neval
|
|
@@ -2453,7 +2462,7 @@ class RAvgDict(gvar.BufferDict):
|
|
|
2453
2462
|
self.rarray.add(newg.buf)
|
|
2454
2463
|
|
|
2455
2464
|
def summary(self, extended=False, weighted=None, rescale=None):
|
|
2456
|
-
""" Assemble summary of results, iteration-by-iteration, into a string.
|
|
2465
|
+
r""" Assemble summary of results, iteration-by-iteration, into a string.
|
|
2457
2466
|
|
|
2458
2467
|
Args:
|
|
2459
2468
|
extended (bool): Include a table of final averages for every
|
|
@@ -2502,7 +2511,7 @@ class RAvgDict(gvar.BufferDict):
|
|
|
2502
2511
|
rescale = property(_get_rescale, None, None, "Integrals divided by ``rescale`` before doing weighted averages.")
|
|
2503
2512
|
|
|
2504
2513
|
class RAvgArray(numpy.ndarray):
|
|
2505
|
-
""" Running average of array-valued Monte Carlo estimates.
|
|
2514
|
+
r""" Running average of array-valued Monte Carlo estimates.
|
|
2506
2515
|
|
|
2507
2516
|
This class accumulates independent arrays of Monte Carlo
|
|
2508
2517
|
estimates (e.g., of an integral) and combines
|
|
@@ -2632,7 +2641,7 @@ class RAvgArray(numpy.ndarray):
|
|
|
2632
2641
|
self.add(r)
|
|
2633
2642
|
|
|
2634
2643
|
def extend(self, ravg):
|
|
2635
|
-
""" Merge results from :class:`RAvgArray` object ``ravg`` after results currently in ``self``. """
|
|
2644
|
+
r""" Merge results from :class:`RAvgArray` object ``ravg`` after results currently in ``self``. """
|
|
2636
2645
|
for r in ravg.itn_results:
|
|
2637
2646
|
self.add(r)
|
|
2638
2647
|
self.sum_neval += ravg.sum_neval
|
|
@@ -2707,7 +2716,7 @@ class RAvgArray(numpy.ndarray):
|
|
|
2707
2716
|
avg_neval = property(_avg_neval, None, None, "Average number of integrand evaluations per iteration.")
|
|
2708
2717
|
|
|
2709
2718
|
def add(self, g):
|
|
2710
|
-
""" Add estimate ``g`` to the running average. """
|
|
2719
|
+
r""" Add estimate ``g`` to the running average. """
|
|
2711
2720
|
g = numpy.asarray(g)
|
|
2712
2721
|
self.itn_results.append(g)
|
|
2713
2722
|
if g.size > 1 and isinstance(g.flat[0], gvar.GVarRef):
|
|
@@ -2756,7 +2765,7 @@ class RAvgArray(numpy.ndarray):
|
|
|
2756
2765
|
self[:] = gvar.gvar(mean, cov).reshape(self.shape)
|
|
2757
2766
|
|
|
2758
2767
|
def summary(self, extended=False, weighted=None, rescale=None):
|
|
2759
|
-
""" Assemble summary of results, iteration-by-iteration, into a string.
|
|
2768
|
+
r""" Assemble summary of results, iteration-by-iteration, into a string.
|
|
2760
2769
|
|
|
2761
2770
|
Args:
|
|
2762
2771
|
extended (bool): Include a table of final averages for every
|
|
@@ -2874,7 +2883,7 @@ cdef class VegasResult:
|
|
|
2874
2883
|
self.result.sum_neval = self.sum_neval
|
|
2875
2884
|
|
|
2876
2885
|
def update_analyzer(self, analyzer):
|
|
2877
|
-
""" Update analyzer at end of an iteration. """
|
|
2886
|
+
r""" Update analyzer at end of an iteration. """
|
|
2878
2887
|
analyzer.end(self.result.itn_results[-1], self.result)
|
|
2879
2888
|
|
|
2880
2889
|
def converged(self, rtol, atol):
|
|
@@ -2884,7 +2893,7 @@ cdef class VegasResult:
|
|
|
2884
2893
|
cdef class VegasIntegrand:
|
|
2885
2894
|
cdef public object shape
|
|
2886
2895
|
cdef public object fcntype
|
|
2887
|
-
cdef public
|
|
2896
|
+
cdef public Py_ssize_t size
|
|
2888
2897
|
cdef public object eval
|
|
2889
2898
|
cdef public object bdict
|
|
2890
2899
|
cdef public int mpi_nproc # number of MPI processors
|
|
@@ -3016,14 +3025,14 @@ cdef class VegasIntegrand:
|
|
|
3016
3025
|
nx = x.shape[0] // self.mpi_nproc + 1
|
|
3017
3026
|
i0 = self.rank * nx
|
|
3018
3027
|
i1 = min(i0 + nx, x.shape[0])
|
|
3019
|
-
f = numpy.empty((nx, self.size),
|
|
3028
|
+
f = numpy.empty((nx, self.size), float)
|
|
3020
3029
|
if i1 > i0:
|
|
3021
3030
|
# fill f so long as haven't gone off end
|
|
3022
3031
|
if jac is None:
|
|
3023
3032
|
f[:(i1-i0)] = _eval(x[i0:i1], jac=None)
|
|
3024
3033
|
else:
|
|
3025
3034
|
f[:(i1-i0)] = _eval(x[i0:i1], jac=jac[i0:i1])
|
|
3026
|
-
results = numpy.empty((self.mpi_nproc * nx, self.size),
|
|
3035
|
+
results = numpy.empty((self.mpi_nproc * nx, self.size), float)
|
|
3027
3036
|
self.comm.Allgather(f, results)
|
|
3028
3037
|
return results[:x.shape[0]]
|
|
3029
3038
|
self.eval = _mpi_eval
|
|
@@ -3039,7 +3048,7 @@ cdef class VegasIntegrand:
|
|
|
3039
3048
|
self.eval = gvar.distribute_gvars(self.eval, gvlist)
|
|
3040
3049
|
|
|
3041
3050
|
def __call__(self, x, jac=None):
|
|
3042
|
-
""" Non-batch version of fcn """
|
|
3051
|
+
r""" Non-batch version of fcn """
|
|
3043
3052
|
# repack x as lbatch array and evaluate function via eval
|
|
3044
3053
|
if hasattr(x, 'keys'):
|
|
3045
3054
|
x = gvar.asbufferdict(x)
|
|
@@ -3050,7 +3059,7 @@ cdef class VegasIntegrand:
|
|
|
3050
3059
|
return self.format_result(fx)
|
|
3051
3060
|
|
|
3052
3061
|
def format_result(self, mean, var=None):
|
|
3053
|
-
""" Reformat output from integrator to correspond to original output format """
|
|
3062
|
+
r""" Reformat output from integrator to correspond to original output format """
|
|
3054
3063
|
if var is None:
|
|
3055
3064
|
# mean is an ndarray
|
|
3056
3065
|
if self.shape is None:
|
|
@@ -3069,7 +3078,7 @@ cdef class VegasIntegrand:
|
|
|
3069
3078
|
return gvar.gvar(mean, var).reshape(self.shape)
|
|
3070
3079
|
|
|
3071
3080
|
def format_evalx(self, evalx):
|
|
3072
|
-
""" Reformat output from eval(x).
|
|
3081
|
+
r""" Reformat output from eval(x).
|
|
3073
3082
|
|
|
3074
3083
|
``self.eval(x)`` returns an array ``evalx[i,d]`` where ``i`` is the batch index and ``d``
|
|
3075
3084
|
labels different components of the ``self.fcn`` output. ``self.format_evalx(evalx)``
|
|
@@ -3082,8 +3091,8 @@ cdef class VegasIntegrand:
|
|
|
3082
3091
|
return evalx.reshape(evalx.shape[:1] + self.shape)
|
|
3083
3092
|
|
|
3084
3093
|
def training(self, x, jac):
|
|
3085
|
-
""" Calculate first element of integrand at point ``x``. """
|
|
3086
|
-
|
|
3094
|
+
r""" Calculate first element of integrand at point ``x``. """
|
|
3095
|
+
fx =self.eval(x, jac=jac)
|
|
3087
3096
|
if fx.ndim == 1:
|
|
3088
3097
|
return fx
|
|
3089
3098
|
else:
|
|
@@ -3119,8 +3128,9 @@ cdef class _BatchIntegrand_from_Base(object):
|
|
|
3119
3128
|
def _distribute_gvars(self, gvlist):
|
|
3120
3129
|
self.fcn = gvar.distribute_gvars(self.fcn, gvlist)
|
|
3121
3130
|
|
|
3122
|
-
def non_std_arg_fcn(self,
|
|
3131
|
+
def non_std_arg_fcn(self, x, jac=None):
|
|
3123
3132
|
" fcn(x) for non-standard non-batch functions "
|
|
3133
|
+
x = numpy.asarray(x)
|
|
3124
3134
|
if self.dict_arg:
|
|
3125
3135
|
xd = gvar.BufferDict(self.xsample, buf=x)
|
|
3126
3136
|
if jac is not None:
|
|
@@ -3133,8 +3143,9 @@ cdef class _BatchIntegrand_from_Base(object):
|
|
|
3133
3143
|
else:
|
|
3134
3144
|
return self.fcn(x.reshape(self.xsample.shape))
|
|
3135
3145
|
|
|
3136
|
-
def non_std_arg_batch_fcn(self,
|
|
3146
|
+
def non_std_arg_batch_fcn(self, x, jac=None):
|
|
3137
3147
|
" fcn(x) for non-standard batch functions "
|
|
3148
|
+
x = numpy.asarray(x)
|
|
3138
3149
|
if self.dict_arg:
|
|
3139
3150
|
if self.rbatch:
|
|
3140
3151
|
xd = gvar.BufferDict(self.xsample, rbatch_buf=x.T)
|
|
@@ -3154,7 +3165,7 @@ cdef class _BatchIntegrand_from_Base(object):
|
|
|
3154
3165
|
return self.fcn(x.reshape(sh)) if jac is None else self.fcn(x.reshape(sh), jac=jac.reshape(sh))
|
|
3155
3166
|
|
|
3156
3167
|
cdef class _BatchIntegrand_from_NonBatch(_BatchIntegrand_from_Base):
|
|
3157
|
-
cdef readonly
|
|
3168
|
+
cdef readonly Py_ssize_t size
|
|
3158
3169
|
cdef readonly object shape
|
|
3159
3170
|
""" Batch integrand from non-batch integrand. """
|
|
3160
3171
|
|
|
@@ -3163,43 +3174,50 @@ cdef class _BatchIntegrand_from_NonBatch(_BatchIntegrand_from_Base):
|
|
|
3163
3174
|
self.shape = shape
|
|
3164
3175
|
super(_BatchIntegrand_from_NonBatch, self).__init__(fcn, xsample)
|
|
3165
3176
|
|
|
3166
|
-
def __call__(self,
|
|
3167
|
-
cdef
|
|
3168
|
-
cdef
|
|
3169
|
-
|
|
3177
|
+
def __call__(self, double[:, :] x, jac=None):
|
|
3178
|
+
cdef Py_ssize_t i, j
|
|
3179
|
+
cdef double[:, ::1] f
|
|
3180
|
+
cdef const double[:] fx
|
|
3181
|
+
_f = numpy.empty(
|
|
3182
|
+
(x.shape[0], self.size), float
|
|
3170
3183
|
)
|
|
3184
|
+
f = _f
|
|
3171
3185
|
if self.shape == ():
|
|
3172
3186
|
# very common special case
|
|
3173
3187
|
for i in range(x.shape[0]):
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3188
|
+
if self.std_arg:
|
|
3189
|
+
f[i, 0] = self.fcn(x[i]) if jac is None else self.fcn(x[i], jac=jac[i])
|
|
3190
|
+
else:
|
|
3191
|
+
f[i, 0] = self.non_std_arg_fcn(x[i], None if jac is None else jac[i])
|
|
3178
3192
|
else:
|
|
3179
3193
|
for i in range(x.shape[0]):
|
|
3180
3194
|
if self.std_arg:
|
|
3181
|
-
|
|
3195
|
+
fx = numpy.asarray(
|
|
3182
3196
|
self.fcn(x[i]) if jac is None else self.fcn(x[i], jac=jac[i])
|
|
3183
3197
|
).reshape((-1,))
|
|
3184
3198
|
else:
|
|
3185
|
-
|
|
3199
|
+
fx = numpy.asarray(
|
|
3186
3200
|
self.non_std_arg_fcn(x[i], None if jac is None else jac[i])
|
|
3187
3201
|
).reshape((-1,))
|
|
3188
|
-
|
|
3202
|
+
for j in range(len(fx)):
|
|
3203
|
+
f[i, j] = fx[j]
|
|
3204
|
+
return _f
|
|
3189
3205
|
|
|
3190
3206
|
cdef class _BatchIntegrand_from_NonBatchDict(_BatchIntegrand_from_Base):
|
|
3191
|
-
cdef readonly
|
|
3207
|
+
cdef readonly Py_ssize_t size
|
|
3192
3208
|
""" Batch integrand from non-batch dict-integrand. """
|
|
3193
3209
|
|
|
3194
3210
|
def __init__(self, fcn, size, xsample=None):
|
|
3195
3211
|
self.size = size
|
|
3196
3212
|
super(_BatchIntegrand_from_NonBatchDict, self).__init__(fcn, xsample)
|
|
3197
3213
|
|
|
3198
|
-
def __call__(self,
|
|
3199
|
-
cdef
|
|
3200
|
-
cdef
|
|
3214
|
+
def __call__(self, double[:, :] x, jac=None):
|
|
3215
|
+
cdef Py_ssize_t i, j
|
|
3216
|
+
cdef double[:, ::1] f
|
|
3217
|
+
_f = numpy.empty(
|
|
3201
3218
|
(x.shape[0], self.size), float
|
|
3202
3219
|
)
|
|
3220
|
+
f = _f
|
|
3203
3221
|
for i in range(x.shape[0]):
|
|
3204
3222
|
if self.std_arg:
|
|
3205
3223
|
fx = self.fcn(x[i]) if jac is None else self.fcn(x[i], jac=jac[i])
|
|
@@ -3207,8 +3225,9 @@ cdef class _BatchIntegrand_from_NonBatchDict(_BatchIntegrand_from_Base):
|
|
|
3207
3225
|
fx = self.non_std_arg_fcn(x[i], None if jac is None else jac[i])
|
|
3208
3226
|
if not isinstance(fx, gvar.BufferDict):
|
|
3209
3227
|
fx = gvar.BufferDict(fx)
|
|
3210
|
-
f[
|
|
3211
|
-
|
|
3228
|
+
for j in range(f.shape[1]):
|
|
3229
|
+
f[i, j] = fx.buf[j]
|
|
3230
|
+
return _f
|
|
3212
3231
|
|
|
3213
3232
|
cdef class _BatchIntegrand_from_Batch(_BatchIntegrand_from_Base):
|
|
3214
3233
|
cdef readonly object shape
|
|
@@ -3219,7 +3238,7 @@ cdef class _BatchIntegrand_from_Batch(_BatchIntegrand_from_Base):
|
|
|
3219
3238
|
self.rbatch = rbatch
|
|
3220
3239
|
super(_BatchIntegrand_from_Batch, self).__init__(fcn, xsample)
|
|
3221
3240
|
|
|
3222
|
-
def __call__(self,
|
|
3241
|
+
def __call__(self, x, jac=None):
|
|
3223
3242
|
# call fcn(x)
|
|
3224
3243
|
if self.std_arg:
|
|
3225
3244
|
if self.rbatch:
|
|
@@ -3244,7 +3263,7 @@ cdef class _BatchIntegrand_from_Batch(_BatchIntegrand_from_Base):
|
|
|
3244
3263
|
|
|
3245
3264
|
|
|
3246
3265
|
cdef class _BatchIntegrand_from_BatchDict(_BatchIntegrand_from_Base):
|
|
3247
|
-
cdef readonly
|
|
3266
|
+
cdef readonly Py_ssize_t size
|
|
3248
3267
|
cdef readonly object slice
|
|
3249
3268
|
cdef readonly object shape
|
|
3250
3269
|
cdef readonly bint rbatch
|
|
@@ -3259,11 +3278,13 @@ cdef class _BatchIntegrand_from_BatchDict(_BatchIntegrand_from_Base):
|
|
|
3259
3278
|
self.slice[k], self.shape[k] = bdict.slice_shape(k)
|
|
3260
3279
|
super(_BatchIntegrand_from_BatchDict, self).__init__(fcn, xsample)
|
|
3261
3280
|
|
|
3262
|
-
def __call__(self,
|
|
3263
|
-
cdef
|
|
3264
|
-
cdef
|
|
3281
|
+
def __call__(self, x, jac=None):
|
|
3282
|
+
cdef Py_ssize_t i
|
|
3283
|
+
# cdef double[:, ::1] buf
|
|
3284
|
+
buf = numpy.empty(
|
|
3265
3285
|
(x.shape[0], self.size), float
|
|
3266
3286
|
)
|
|
3287
|
+
# buf = _buf
|
|
3267
3288
|
# call fcn(x)
|
|
3268
3289
|
if self.std_arg:
|
|
3269
3290
|
if self.rbatch:
|
|
@@ -3294,7 +3315,7 @@ cdef class _BatchIntegrand_from_BatchDict(_BatchIntegrand_from_Base):
|
|
|
3294
3315
|
|
|
3295
3316
|
# LBatchIntegrand and RBatchIntegrand are container classes for batch integrands.
|
|
3296
3317
|
cdef class LBatchIntegrand(object):
|
|
3297
|
-
""" Wrapper for lbatch integrands.
|
|
3318
|
+
r""" Wrapper for lbatch integrands.
|
|
3298
3319
|
|
|
3299
3320
|
Used by :func:`vegas.lbatchintegrand`.
|
|
3300
3321
|
|
|
@@ -3316,7 +3337,7 @@ cdef class LBatchIntegrand(object):
|
|
|
3316
3337
|
return getattr(self.fcn, attr)
|
|
3317
3338
|
|
|
3318
3339
|
def lbatchintegrand(f):
|
|
3319
|
-
""" Decorator for batch integrand functions.
|
|
3340
|
+
r""" Decorator for batch integrand functions.
|
|
3320
3341
|
|
|
3321
3342
|
Applying :func:`vegas.lbatchintegrand` to a function ``fcn`` repackages
|
|
3322
3343
|
the function in a format that |vegas| can understand. Appropriate
|
|
@@ -3348,7 +3369,7 @@ def lbatchintegrand(f):
|
|
|
3348
3369
|
return LBatchIntegrand(f)
|
|
3349
3370
|
|
|
3350
3371
|
cdef class RBatchIntegrand(object):
|
|
3351
|
-
""" Same as :class:`vegas.LBatchIntegrand` but with batch indices on the right (not left). """
|
|
3372
|
+
r""" Same as :class:`vegas.LBatchIntegrand` but with batch indices on the right (not left). """
|
|
3352
3373
|
# cdef public object fcn
|
|
3353
3374
|
def __init__(self, fcn=None):
|
|
3354
3375
|
self.fcn = self if fcn is None else fcn
|
|
@@ -3365,7 +3386,7 @@ cdef class RBatchIntegrand(object):
|
|
|
3365
3386
|
|
|
3366
3387
|
|
|
3367
3388
|
def rbatchintegrand(f):
|
|
3368
|
-
""" Same as :func:`vegas.lbatchintegrand` but with batch indices on the right (not left). """
|
|
3389
|
+
r""" Same as :func:`vegas.lbatchintegrand` but with batch indices on the right (not left). """
|
|
3369
3390
|
try:
|
|
3370
3391
|
f.fcntype = 'rbatch'
|
|
3371
3392
|
return f
|