Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vegas+ #64

Merged
merged 30 commits into from
Aug 27, 2021
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
4a9933a
stratified NON adaptive sampling
andrea-pasquale Feb 9, 2021
a7517fc
added adaptive-stratified sampling
andrea-pasquale Feb 9, 2021
c9ec2fc
PEP8 style corrections
andrea-pasquale Feb 13, 2021
883cd00
updated __init__.py and test_algs.py
andrea-pasquale Feb 13, 2021
befb032
added example using StratifiedFlow
andrea-pasquale Feb 13, 2021
f0fd609
fixed error in redistribute_samples
andrea-pasquale Feb 15, 2021
bf13849
first implementation of vegas+ in vegasflow
andrea-pasquale Mar 2, 2021
588d7ca
fixed problems in stratified.py and vflowplus.py
andrea-pasquale Mar 8, 2021
15aecc4
Merge branch 'master' into vegas+
andrea-pasquale Mar 8, 2021
b4bee75
first attempt at fixing retracing
andrea-pasquale Mar 12, 2021
d750c3c
suggested changes
scarlehoff Mar 15, 2021
26b5650
typo
scarlehoff Mar 15, 2021
dd7d54c
fixed self.adaptive issue
andrea-pasquale Mar 16, 2021
1426f37
Merge pull request #65 from N3PDF/vegasplus_retracing
scarrazza Mar 16, 2021
ad89727
fixed crash problem in vflowplus
andrea-pasquale Apr 14, 2021
016abe2
set adaptive off is dim > 13
andrea-pasquale Apr 14, 2021
38b87a0
typo
andrea-pasquale Apr 14, 2021
462373e
removed StratifiedFlow
andrea-pasquale Apr 22, 2021
18ca369
file update from previous commit
andrea-pasquale Apr 22, 2021
07cf119
all events in same device for vegas+
andrea-pasquale Jun 22, 2021
77674fe
merge with conflicts with master
scarlehoff Aug 16, 2021
f577231
fixed some todos
scarlehoff Aug 16, 2021
0b9ae0b
stylize
scarlehoff Aug 16, 2021
9dadcf6
bump version to 1.3.0
scarlehoff Aug 16, 2021
b3b8c36
more style
scarlehoff Aug 17, 2021
d013f4f
ups
scarlehoff Aug 17, 2021
34def6f
remove duplicated code
scarlehoff Aug 18, 2021
b1a4713
remove more duplicates
scarlehoff Aug 18, 2021
516610d
bugfix
scarlehoff Aug 25, 2021
1e1d4e3
add warning when changing event limit
scarlehoff Aug 26, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions examples/example_stratified.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""
Example: integration with stratified sampling

Basic example using the stratified_wrapper helper
"""

from vegasflow.configflow import DTYPE
import time
import numpy as np
import tensorflow as tf
from vegasflow.vflow import vegas_wrapper
from vegasflow.plain import plain_wrapper
from vegasflow.stratified import stratified_wrapper

# MC integration setup
dim = 4
ncalls = np.int32(1e5)
n_iter = 5


@tf.function
def symgauss(xarr, n_dim=None, **kwargs):
"""symgauss test function"""
if n_dim is None:
n_dim = xarr.shape[-1]
a = tf.constant(0.1, dtype=DTYPE)
n100 = tf.cast(100 * n_dim, dtype=DTYPE)
pref = tf.pow(1.0 / a / np.sqrt(np.pi), n_dim)
coef = tf.reduce_sum(tf.range(n100 + 1))
coef += tf.reduce_sum(tf.square((xarr - 1.0 / 2.0) / a), axis=1)
coef -= (n100 + 1) * n100 / 2.0
return pref * tf.exp(-coef)


if __name__ == "__main__":
"""Testing several different integrations"""
print(f"VEGAS MC, ncalls={ncalls}:")
start = time.time()
ncalls = 10*ncalls
r = stratified_wrapper(symgauss, dim, n_iter, ncalls)
end = time.time()
print(f"Vegas took: time (s): {end-start}")
43 changes: 43 additions & 0 deletions examples/retracing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""
Retracing example in VegasFlowPlus
"""

from vegasflow import VegasFlowPlus, VegasFlow, StratifiedFlow, PlainFlow
from vegasflow.configflow import DTYPE, DTYPEINT,run_eager, float_me
import time
import numpy as np
import tensorflow as tf
#import pineappl

# MC integration setup
dim = 2
ncalls = np.int32(1e3)
n_iter = 5

#@tf.function(input_signature=[
# tf.TensorSpec(shape=[None,dim], dtype=DTYPE),
# tf.TensorSpec(shape=[], dtype=DTYPE),
# tf.TensorSpec(shape=[None], dtype=DTYPE)
# ]
# )
def symgauss(xarr, n_dim=None,weight=None, **kwargs):
"""symgauss test function"""
if n_dim is None:
n_dim = xarr.shape[-1]
a = tf.constant(0.1, dtype=DTYPE)
n100 = tf.cast(100 * n_dim, dtype=DTYPE)
pref = tf.pow(1.0 / a / np.sqrt(np.pi), n_dim)
coef = tf.reduce_sum(tf.range(n100 + 1))
coef += tf.reduce_sum(tf.square((xarr - 1.0 / 2.0) / a), axis=1)
coef -= (n100 + 1) * n100 / 2.0
return pref * tf.exp(-coef)



if __name__ == "__main__":
"""Testing several different integrations"""

#run_eager()
vegas_instance = VegasFlowPlus(dim, ncalls,adaptive=True)
vegas_instance.compile(symgauss)
vegas_instance.run_integration(n_iter)
2 changes: 2 additions & 0 deletions src/vegasflow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
# Expose the main interfaces
from vegasflow.vflow import VegasFlow, vegas_wrapper
from vegasflow.plain import PlainFlow, plain_wrapper
from vegasflow.stratified import StratifiedFlow, stratified_wrapper
scarrazza marked this conversation as resolved.
Show resolved Hide resolved
from vegasflow.vflowplus import VegasFlowPlus, vegasflowplus_wrapper

__version__ = "1.2.0"
150 changes: 150 additions & 0 deletions src/vegasflow/stratified.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
"""
Implementation of the adaptive stratified sampling
"""
from itertools import product
import tensorflow as tf
import numpy as np
from vegasflow.configflow import DTYPE, fone, fzero, DTYPEINT, float_me, int_me
from vegasflow.monte_carlo import MonteCarloFlow, wrapper

BETA = 0.75


@tf.function
def generate_random_array(rnds, n_strat, n_ev, hypercubes):
"""Receives an array of random numbers 0 and 1 and
distribute them in each hypercube according to the
number of sample in each hypercube specified by n_ev

Parameters
----------
`rnds`: tensor of random number betweenn 0 and 1
`n_strat`: tensor with number of stratifications in each dimension
`n_ev`: tensor containing number of sample per each hypercube
`hypercubes`: tensor containing all different hypercube

Returns
-------
`x` : random numbers collocated in hypercubes
`w` : weight of each event
`segm` : segmentantion for later computations
"""
# stratification width
delta_y = tf.cast(1/n_strat, DTYPE)
random = rnds*delta_y
points = tf.cast(tf.repeat(hypercubes, n_ev, axis=0), DTYPE)
x = points*delta_y + random
w = tf.cast(tf.repeat(1/n_ev, n_ev), DTYPE)
segm = tf.cast(tf.repeat(tf.range(fzero,
tf.shape(hypercubes)[0]),
n_ev),
DTYPEINT)

return x, w, segm


class StratifiedFlow(MonteCarloFlow):
"""
Monte Carlo integrator with Adaptive Stratified Sampling.
"""

def __init__(self, n_dim, n_events, adaptive=True, **kwargs):
super().__init__(n_dim, n_events, **kwargs)
scarrazza marked this conversation as resolved.
Show resolved Hide resolved

self.init_calls = n_events
self.adaptive = adaptive

# Initialize stratifications
if self.adaptive:
neval_eff = int(self.n_events/2)
self.n_strat = tf.math.floor(tf.math.pow(neval_eff/2, 1/n_dim))
else:
neval_eff = self.n_events
self.n_strat = tf.math.floor(tf.math.pow(neval_eff/2, 1/n_dim))

self.n_strat = int_me(self.n_strat)

# Initialize hypercubes
hypercubes_one_dim = np.arange(0, int(self.n_strat))
hypercubes = [list(p) for p in product(hypercubes_one_dim,
repeat=int(n_dim))]
self.hypercubes = tf.convert_to_tensor(hypercubes)

if len(hypercubes) != int(tf.math.pow(self.n_strat, n_dim)):
raise ValueError("Hypercubes problem!")

# Set min evaluations per hypercube
self.min_neval_hcube = int(neval_eff // len(hypercubes))
if self.min_neval_hcube < 2:
self.min_neval_hcube = 2

# Initialize n_ev
self.n_ev = tf.fill([1, len(hypercubes)], self.min_neval_hcube)
self.n_ev = tf.reshape(self.n_ev, [-1])
self.n_events = int(tf.reduce_sum(self.n_ev))
self.xjac = float_me(1/len(hypercubes))

def redistribute_samples(self, arr_var):
"""Receives an array with the variance of the integrand in each
hypercube and recalculate the samples per hypercube according
to the VEGAS+ algorithm"""

damped_arr_sdev = tf.pow(arr_var, BETA / 2)
scarlehoff marked this conversation as resolved.
Show resolved Hide resolved
new_n_ev = tf.maximum(self.min_neval_hcube,
damped_arr_sdev
* self.init_calls / 2
/ tf.reduce_sum(damped_arr_sdev))
self.n_ev = int_me(tf.math.floor(new_n_ev))
self.n_events = int(tf.reduce_sum(self.n_ev))

andrea-pasquale marked this conversation as resolved.
Show resolved Hide resolved
def _run_event(self, integrand, ncalls=None):

if ncalls is None:
n_events = self.n_events
else:
n_events = ncalls

# Generate all random numbers
rnds = tf.random.uniform((n_events, self.n_dim), minval=0, maxval=1,
dtype=DTYPE)

# Pass random numbers in hypercubes
x, w, segm = generate_random_array(rnds,
self.n_strat,
self.n_ev,
self.hypercubes)

# compute integrand
xjac = self.xjac * w
tmp = integrand(x, n_dim=self.n_dim, weight=xjac) * xjac
tmp2 = tf.square(tmp)

# tensor containing resummed component for each hypercubes
ress = tf.math.segment_sum(tmp, segm)
ress2 = tf.math.segment_sum(tmp2, segm)

Fn_ev = tf.cast(self.n_ev, DTYPE)
arr_var = ress2 * Fn_ev - tf.square(ress)

andrea-pasquale marked this conversation as resolved.
Show resolved Hide resolved
return ress, arr_var

def _run_iteration(self):

ress, arr_var = self.run_event()

Fn_ev = tf.cast(self.n_ev, DTYPE)
sigmas2 = tf.maximum(arr_var, fzero)
res = tf.reduce_sum(ress)
sigma2 = tf.reduce_sum(sigmas2/(Fn_ev-fone))
sigma = tf.sqrt(sigma2)

# If adaptive is True redistributes samples
if self.adaptive:
self.redistribute_samples(arr_var)

return res, sigma


def stratified_wrapper(*args):
""" Wrapper around PlainFlow """
return wrapper(StratifiedFlow, *args)
24 changes: 24 additions & 0 deletions src/vegasflow/tests/test_algs.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from vegasflow.configflow import DTYPE
from vegasflow.vflow import VegasFlow
from vegasflow.plain import PlainFlow
from vegasflow.stratified import StratifiedFlow
from vegasflow.vflowplus import VegasFlowPlus

# Test setup
dim = 2
Expand Down Expand Up @@ -109,3 +111,25 @@ def test_PlainFlow():
plain_instance = instance_and_compile(PlainFlow)
result = plain_instance.run_integration(n_iter)
check_is_one(result)

def test_StratifiedFlow_ADAPTIVE_SAMPLING():
stratified_instance = instance_and_compile(StratifiedFlow)
result = stratified_instance.run_integration(n_iter)
check_is_one(result)

def test_StratifiedFlow_NOT_ADAPTIVE_SAMPLING():
stratified_instance = StratifiedFlow(dim, ncalls, adaptive=False)
stratified_instance.compile(example_integrand)
result = stratified_instance.run_integration(n_iter)
check_is_one(result)

def test_VegasFlowPlus_ADAPTIVE_SAMPLING():
vflowplus_instance = instance_and_compile(VegasFlowPlus)
result = vflowplus_instance.run_integration(n_iter)
check_is_one(result)

def test_VegasFlowPlus_NOT_ADAPTIVE_SAMPLING():
vflowplus_instance = VegasFlowPlus(dim, ncalls, adaptive=False)
vflowplus_instance.compile(example_integrand)
result = vflowplus_instance.run_integration(n_iter)
check_is_one(result)
Loading