Skip to content

Commit 2166f30

Browse files
authored
Merge pull request #9 from numericalEFT/dev
Vegas update
2 parents 0c83ced + e4b16f7 commit 2166f30

File tree

6 files changed

+765
-305
lines changed

6 files changed

+765
-305
lines changed

examples/benchmark_vegas.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import vegas
2+
import numpy as np
3+
import gvar
4+
import torch
5+
6+
dim = 4
7+
nitn = 10
8+
ninc = 1000
9+
10+
11+
@vegas.lbatchintegrand
12+
def f_batch(x):
13+
dx2 = 0.0
14+
for d in range(dim):
15+
dx2 += (x[:, d] - 0.5) ** 2
16+
return np.exp(-200 * dx2)
17+
# ans = np.empty((x.shape[0], 3), float)
18+
# dx2 = 0.0
19+
# for d in range(dim):
20+
# dx2 += (x[:, d] - 0.5) ** 2
21+
# ans[:, 0] = np.exp(-200 * dx2)
22+
# ans[:, 1] = x[:, 0] * ans[:, 0]
23+
# ans[:, 2] = x[:, 0] ** 2 * ans[:, 0]
24+
# return ans
25+
26+
27+
def smc(f, map, neval, dim):
28+
"integrates f(y) over dim-dimensional unit hypercube"
29+
y = np.random.uniform(0, 1, (neval, dim))
30+
jac = np.empty(y.shape[0], float)
31+
x = np.empty(y.shape, float)
32+
map.map(y, x, jac)
33+
fy = jac * f(x)
34+
return (np.average(fy), np.std(fy) / neval**0.5)
35+
36+
37+
def mc(f, neval, dim):
38+
"integrates f(y) over dim-dimensional unit hypercube"
39+
y = np.random.uniform(0, 1, (neval, dim))
40+
fy = f(y)
41+
return (np.average(fy), np.std(fy) / neval**0.5)
42+
43+
44+
m = vegas.AdaptiveMap(dim * [[0, 1]], ninc=ninc)
45+
ny = 20000
46+
# torch.manual_seed(0)
47+
# y = torch.rand((ny, dim), dtype=torch.float64).numpy()
48+
y = np.random.uniform(0.0, 1.0, (ny, dim)) # 1000 random y's
49+
50+
x = np.empty(y.shape, float) # work space
51+
jac = np.empty(y.shape[0], float)
52+
f2 = np.empty(y.shape[0], float)
53+
54+
for itn in range(10): # 5 iterations to adapt
55+
m.map(y, x, jac) # compute x's and jac
56+
57+
f2 = (jac * f_batch(x)) ** 2
58+
m.add_training_data(y, f2) # adapt
59+
# if itn == 0:
60+
# print(np.array(memoryview(m.sum_f)))
61+
# print(np.array(memoryview(m.n_f)))
62+
m.adapt(alpha=0.5)
63+
64+
65+
# with map
66+
r = smc(f_batch, m, 50_000, dim)
67+
print(" SMC + map:", f"{r[0]} +- {r[1]}")
68+
69+
# without map
70+
r = mc(f_batch, 50_000, dim)
71+
print("SMC (no map):", f"{r[0]} +- {r[1]}")
72+
73+
74+
# vegas with adaptive stratified sampling
75+
print("VEGAS using adaptive stratified sampling")
76+
integ = vegas.Integrator(dim * [[0, 1]])
77+
training = integ(f_batch, nitn=10, neval=20000) # adapt grid
78+
79+
# final analysis
80+
result = integ(f_batch, nitn=1, neval=50_000, adapt=False)
81+
print(result)
82+
result = integ(f_batch, nitn=5, neval=10_000, adapt=False)
83+
print(result)
84+
result = integ(f_batch, nitn=5, neval=10_000)
85+
print(result)
86+
# print("I[0] =", result[0], " I[1] =", result[1], " I[2] =", result[2])
87+
# print("Q = %.2f\n" % result.Q)
88+
# print("<x> =", result[1] / result[0])
89+
# print(
90+
# "sigma_x**2 = <x**2> - <x>**2 =",
91+
# result[2] / result[0] - (result[1] / result[0]) ** 2,
92+
# )
93+
# print("\ncorrelation matrix:\n", gv.evalcorr(result))

src/base.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import torch
2+
from torch import nn
3+
import numpy as np
4+
5+
6+
class BaseDistribution(nn.Module):
7+
"""
8+
Base distribution of a flow-based model
9+
Parameters do not depend of target variable (as is the case for a VAE encoder)
10+
"""
11+
12+
def __init__(self, bounds, device="cpu", dtype=torch.float64):
13+
super().__init__()
14+
self.dtype = dtype
15+
# self.bounds = bounds
16+
if isinstance(bounds, (list, np.ndarray)):
17+
self.bounds = torch.tensor(bounds, dtype=dtype, device=device)
18+
elif isinstance(bounds, torch.Tensor):
19+
self.bounds = bounds
20+
else:
21+
raise ValueError("Unsupported map specification")
22+
self.dim = self.bounds.shape[0]
23+
self.device = device
24+
25+
def sample(self, nsamples=1, **kwargs):
26+
"""Samples from base distribution
27+
28+
Args:
29+
num_samples: Number of samples to draw from the distriubtion
30+
31+
Returns:
32+
Samples drawn from the distribution
33+
"""
34+
raise NotImplementedError
35+
36+
37+
class Uniform(BaseDistribution):
38+
"""
39+
Multivariate uniform distribution
40+
"""
41+
42+
def __init__(self, bounds, device="cpu", dtype=torch.float64):
43+
super().__init__(bounds, device, dtype)
44+
self._rangebounds = self.bounds[:, 1] - self.bounds[:, 0]
45+
46+
def sample(self, nsamples=1, **kwargs):
47+
# torch.manual_seed(0) # test seed
48+
u = (
49+
torch.rand((nsamples, self.dim), device=self.device, dtype=self.dtype)
50+
* self._rangebounds
51+
+ self.bounds[:, 0]
52+
)
53+
log_detJ = torch.log(self._rangebounds).sum().repeat(nsamples)
54+
return u, log_detJ

0 commit comments

Comments
 (0)