eryn 1.2.3__py3-none-any.whl → 1.2.4__py3-none-any.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.
- eryn/backends/backend.py +5 -2
- eryn/ensemble.py +9 -2
- eryn/moves/gaussian.py +6 -1
- eryn/utils/utility.py +4 -3
- {eryn-1.2.3.dist-info → eryn-1.2.4.dist-info}/METADATA +1 -1
- {eryn-1.2.3.dist-info → eryn-1.2.4.dist-info}/RECORD +7 -9
- {eryn-1.2.3.dist-info → eryn-1.2.4.dist-info}/WHEEL +1 -1
- eryn/tests/__init__.py +0 -0
- eryn/tests/test_eryn.py +0 -1246
eryn/backends/backend.py
CHANGED
|
@@ -703,8 +703,11 @@ class Backend(object):
|
|
|
703
703
|
"thermo",
|
|
704
704
|
"ti",
|
|
705
705
|
]:
|
|
706
|
-
logls =
|
|
707
|
-
|
|
706
|
+
logls = logls_all.copy()
|
|
707
|
+
logls[~np.isfinite(logls)] = np.nan
|
|
708
|
+
meanlogls = np.nanmean(logls, axis=(0, -1))
|
|
709
|
+
logZ, dlogZ = thermodynamic_integration_log_evidence(betas, meanlogls)
|
|
710
|
+
|
|
708
711
|
elif method.lower() in [
|
|
709
712
|
"stepping stone",
|
|
710
713
|
"ss",
|
eryn/ensemble.py
CHANGED
|
@@ -1208,6 +1208,9 @@ class EnsembleSampler(object):
|
|
|
1208
1208
|
# vectorized because everything is rectangular (no groups to indicate model difference)
|
|
1209
1209
|
prior_out += prior_out_temp.sum(axis=-1)
|
|
1210
1210
|
|
|
1211
|
+
if np.any(np.isnan(prior_out)):
|
|
1212
|
+
raise ValueError("The prior function is returning Nan.")
|
|
1213
|
+
|
|
1211
1214
|
return prior_out
|
|
1212
1215
|
|
|
1213
1216
|
def compute_log_like(
|
|
@@ -1493,8 +1496,9 @@ class EnsembleSampler(object):
|
|
|
1493
1496
|
ll[inds_fix_zeros] = self.fill_zero_leaves_val
|
|
1494
1497
|
|
|
1495
1498
|
# deal with blobs
|
|
1496
|
-
|
|
1497
|
-
|
|
1499
|
+
_blobs_out = np.zeros((nwalkers_all, results.shape[1] - 1))
|
|
1500
|
+
_blobs_out[unique_groups] = results[:, 1:]
|
|
1501
|
+
blobs_out = _blobs_out.reshape(ntemps, nwalkers)
|
|
1498
1502
|
|
|
1499
1503
|
elif results.dtype == "object":
|
|
1500
1504
|
# TODO: check blobs and add this capability
|
|
@@ -1531,6 +1535,9 @@ class EnsembleSampler(object):
|
|
|
1531
1535
|
for key in branch_supps_in_2[name_i]
|
|
1532
1536
|
}
|
|
1533
1537
|
|
|
1538
|
+
if np.any(np.isnan(ll)):
|
|
1539
|
+
raise ValueError("The likelihood function is returning Nan.")
|
|
1540
|
+
|
|
1534
1541
|
# return Likelihood and blobs
|
|
1535
1542
|
return ll.reshape(ntemps, nwalkers), blobs_out
|
|
1536
1543
|
|
eryn/moves/gaussian.py
CHANGED
|
@@ -137,7 +137,12 @@ class _isotropic_proposal(object):
|
|
|
137
137
|
def __init__(self, scale, factor, mode):
|
|
138
138
|
self.index = 0
|
|
139
139
|
self.scale = scale
|
|
140
|
-
|
|
140
|
+
|
|
141
|
+
if isinstance(scale, float):
|
|
142
|
+
self.invscale = 1. / scale
|
|
143
|
+
else:
|
|
144
|
+
self.invscale = np.linalg.inv(np.linalg.cholesky(scale))
|
|
145
|
+
|
|
141
146
|
if factor is None:
|
|
142
147
|
self._log_factor = None
|
|
143
148
|
else:
|
eryn/utils/utility.py
CHANGED
|
@@ -237,11 +237,12 @@ def stepping_stone_log_evidence(betas, logls, block_len=50, repeats=100):
|
|
|
237
237
|
|
|
238
238
|
def calculate_stepping_stone(betas, logls):
|
|
239
239
|
n = logls.shape[0]
|
|
240
|
-
delta_betas = betas[1:] - betas[:-1]
|
|
241
240
|
n_T = betas.shape[0]
|
|
242
|
-
|
|
241
|
+
delta_betas = betas[1:] - betas[:-1]
|
|
242
|
+
throwaways = np.any(~np.isfinite(logls), axis=1) # a safeguard against non-finite entries
|
|
243
|
+
log_ratio = logsumexp(delta_betas * logls[~throwaways, :-1], axis=0) - (n_T - 1.0)*np.log(n - np.sum(throwaways))
|
|
243
244
|
return np.sum(log_ratio), log_ratio
|
|
244
|
-
|
|
245
|
+
|
|
245
246
|
# make sure they are the same length
|
|
246
247
|
if len(betas) != logls.shape[1]:
|
|
247
248
|
raise ValueError(
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
eryn/CMakeLists.txt,sha256=rs-_qMYpJryM_FyvERto4RgQQ_NV4lkYvFzCNU7vvFc,1736
|
|
2
2
|
eryn/__init__.py,sha256=eMxCEUQyqtaUM8zTr6kDCxeuFWpxZsfY41TefWUNHXI,821
|
|
3
3
|
eryn/backends/__init__.py,sha256=yRQszA4WSofDDsSpTsA1V9eNw-pLVO_qalP5wpKjyZQ,380
|
|
4
|
-
eryn/backends/backend.py,sha256=
|
|
4
|
+
eryn/backends/backend.py,sha256=VitOOK3vkzVlpzYj-y-_N0Q5GA6DBdm9ZwIMKvQjBOE,47011
|
|
5
5
|
eryn/backends/hdfbackend.py,sha256=njW1KA2Anw9zxpLTYLkpNErNRBgNMA4VKidZXidkh-A,29414
|
|
6
|
-
eryn/ensemble.py,sha256=
|
|
6
|
+
eryn/ensemble.py,sha256=TqpTLun3iydLOycEi2Gtlg0enLEL2raVrPyVMIQgn-o,71998
|
|
7
7
|
eryn/git_version.py.in,sha256=dZ5WklaoF4dDsCVqhgw5jwr3kJCc8zjRX_LR90byZOw,139
|
|
8
8
|
eryn/model.py,sha256=5TeWTI6V-Xcuy5C2LI6AmtZZU-EkRSSuA7VojXNALk8,284
|
|
9
9
|
eryn/moves/__init__.py,sha256=9pWsSZSKLt05Ihd46vPASHwotTOHOPk_zEsCm8jWiw8,1081
|
|
@@ -11,7 +11,7 @@ eryn/moves/combine.py,sha256=YfIiRqObi11qBbTgqRQ3nMBr6a-ugGGBd1VgPSEosx4,4545
|
|
|
11
11
|
eryn/moves/delayedrejection.py,sha256=deaPPwNG2nKz-FAvi5NVTsrcoKONhy-LD15FLN0iLpY,7645
|
|
12
12
|
eryn/moves/distgen.py,sha256=jNTxL23KSradICJydeTsUcnE7BqMDTPmzuGh4ydQGkQ,3935
|
|
13
13
|
eryn/moves/distgenrj.py,sha256=szTgY1VYriJ1YYDJEOYT_kkjewk42BoXgQeZc41CO_c,9133
|
|
14
|
-
eryn/moves/gaussian.py,sha256=
|
|
14
|
+
eryn/moves/gaussian.py,sha256=Uj1O14ONPReku8SoYLZ00_MIPjbHrxL9LM05bLqHdCk,6957
|
|
15
15
|
eryn/moves/group.py,sha256=sm1iUvHJwuk_dvtmBTbmhZBbB_Esxl_4f2h0Ofx5p7s,10100
|
|
16
16
|
eryn/moves/groupstretch.py,sha256=tMXeCauYy_AyAhWM5kpgOcoQRdKLJYx2h85Tdfq6WLk,3920
|
|
17
17
|
eryn/moves/mh.py,sha256=63xvBRk6iNLn6EZmGb1W_buLmNw3WS7ch4kSK7yGfeE,6517
|
|
@@ -26,14 +26,12 @@ eryn/moves/tempering.py,sha256=e2doT8jVWSuaPpVUKIkWQjRe20T0i98w70wi-dz7buo,23977
|
|
|
26
26
|
eryn/pbar.py,sha256=uDDn8dMVHLD6EqZyk6vGhkOQwxgFm21Us9dz-nZE4oI,1330
|
|
27
27
|
eryn/prior.py,sha256=x4E5NS4v7Odag7a30OXQ-kJuoU3a6M6JnJuKlWGO6F4,14393
|
|
28
28
|
eryn/state.py,sha256=x4HZNrGhxnR6Ia2JrVskJGDS1Uk3AgQHgxJ4384Hpzs,31456
|
|
29
|
-
eryn/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
|
-
eryn/tests/test_eryn.py,sha256=JTac0NdiBfTa2-l8z0Q6S5oxr-C-UzH0uNTOE61jVFY,39792
|
|
31
29
|
eryn/utils/__init__.py,sha256=HzlQs1wg3J1xdrZjIMO34QHd0ZT58SQFCKEdclj7vpM,250
|
|
32
30
|
eryn/utils/periodic.py,sha256=Q07HKMNeUN8V_rauUjT7fKRwlYOd2AFsa9DekuRYUbk,4135
|
|
33
31
|
eryn/utils/stopping.py,sha256=fX1np10U3B-fpI3dGqEPZfqeYt8dc0x3PQGwrvYbbFU,5095
|
|
34
32
|
eryn/utils/transform.py,sha256=wzOYow7xHjqVOi8ZQDXBeoFj9y53cCtIeLggrQuo_sc,8895
|
|
35
33
|
eryn/utils/updates.py,sha256=U3T9UxPLabJzJuuB9s2OuX3vMD_2P7486SkgaFEkbLw,2137
|
|
36
|
-
eryn/utils/utility.py,sha256=
|
|
37
|
-
eryn-1.2.
|
|
38
|
-
eryn-1.2.
|
|
39
|
-
eryn-1.2.
|
|
34
|
+
eryn/utils/utility.py,sha256=mgmfoL0BFFb3hho7OAQSJLO7T_erx6f6t38V-5yKSA4,11296
|
|
35
|
+
eryn-1.2.4.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
|
|
36
|
+
eryn-1.2.4.dist-info/METADATA,sha256=IBGDzBc3Esx7RPZ_RKSFQewgaitRnFyVEaacPn3-9MA,6240
|
|
37
|
+
eryn-1.2.4.dist-info/RECORD,,
|
eryn/tests/__init__.py
DELETED
|
File without changes
|
eryn/tests/test_eryn.py
DELETED
|
@@ -1,1246 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
# coding: utf-8
|
|
3
|
-
|
|
4
|
-
# In[14]:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
from eryn.ensemble import EnsembleSampler
|
|
8
|
-
from eryn.state import State
|
|
9
|
-
from eryn.prior import ProbDistContainer, uniform_dist
|
|
10
|
-
from eryn.utils import TransformContainer
|
|
11
|
-
from eryn.moves import (
|
|
12
|
-
GaussianMove,
|
|
13
|
-
StretchMove,
|
|
14
|
-
CombineMove,
|
|
15
|
-
DistributionGenerateRJ,
|
|
16
|
-
GroupStretchMove,
|
|
17
|
-
)
|
|
18
|
-
from eryn.utils.utility import groups_from_inds
|
|
19
|
-
from eryn.backends import HDFBackend
|
|
20
|
-
|
|
21
|
-
import os
|
|
22
|
-
import unittest
|
|
23
|
-
import matplotlib.pyplot as plt
|
|
24
|
-
import numpy as np
|
|
25
|
-
|
|
26
|
-
# set random seed
|
|
27
|
-
np.random.seed(42)
|
|
28
|
-
|
|
29
|
-
import corner
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
# Gaussian likelihood
|
|
33
|
-
def log_like_fn(x, mu, invcov):
|
|
34
|
-
diff = x - mu
|
|
35
|
-
return -0.5 * (diff * np.dot(invcov, diff.T).T).sum()
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def gaussian_pulse(x, a, b, c):
|
|
39
|
-
f_x = a * np.exp(-((x - b) ** 2) / (2 * c**2))
|
|
40
|
-
return f_x
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def combine_gaussians(t, params):
|
|
44
|
-
template = np.zeros_like(t)
|
|
45
|
-
for param in params:
|
|
46
|
-
template += gaussian_pulse(t, *param) # *params -> a, b, c
|
|
47
|
-
return template
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def log_like_fn_gauss_pulse(params, t, data, sigma):
|
|
51
|
-
template = combine_gaussians(t, params)
|
|
52
|
-
|
|
53
|
-
ll = -0.5 * np.sum(((template - data) / sigma) ** 2, axis=-1)
|
|
54
|
-
return ll
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def gaussian_pulse(x, a, b, c):
|
|
58
|
-
f_x = a * np.exp(-((x - b) ** 2) / (2 * c**2))
|
|
59
|
-
return f_x
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def combine_gaussians(t, params):
|
|
63
|
-
template = np.zeros_like(t)
|
|
64
|
-
for param in params:
|
|
65
|
-
template += gaussian_pulse(t, *param) # *params -> a, b, c
|
|
66
|
-
return template
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def sine(x, a, b, c):
|
|
70
|
-
f_x = a * np.sin(2 * np.pi * b * x + c)
|
|
71
|
-
return f_x
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def combine_sine(t, params):
|
|
75
|
-
template = np.zeros_like(t)
|
|
76
|
-
for param in params:
|
|
77
|
-
template += sine(t, *param) # *params -> a, b, c
|
|
78
|
-
return template
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def log_like_fn_gauss_and_sine(params_both, t, data, sigma):
|
|
82
|
-
params_gauss, params_sine = params_both
|
|
83
|
-
template = np.zeros_like(t)
|
|
84
|
-
|
|
85
|
-
if params_gauss is not None:
|
|
86
|
-
template += combine_gaussians(t, params_gauss)
|
|
87
|
-
|
|
88
|
-
if params_sine is not None:
|
|
89
|
-
template += combine_sine(t, params_sine)
|
|
90
|
-
|
|
91
|
-
ll = -0.5 * np.sum(((template - data) / sigma) ** 2, axis=-1)
|
|
92
|
-
return ll
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
class ErynTest(unittest.TestCase):
|
|
96
|
-
def test_base(self):
|
|
97
|
-
ndim = 5
|
|
98
|
-
nwalkers = 99
|
|
99
|
-
|
|
100
|
-
means = np.zeros(ndim) # np.random.rand(ndim)
|
|
101
|
-
|
|
102
|
-
# define covariance matrix
|
|
103
|
-
cov = np.diag(np.ones(ndim))
|
|
104
|
-
invcov = np.linalg.inv(cov)
|
|
105
|
-
|
|
106
|
-
lims = 5.0
|
|
107
|
-
priors_in = {
|
|
108
|
-
i: uniform_dist(-lims + means[i], lims + means[i]) for i in range(ndim)
|
|
109
|
-
}
|
|
110
|
-
priors = ProbDistContainer(priors_in)
|
|
111
|
-
|
|
112
|
-
ensemble = EnsembleSampler(
|
|
113
|
-
nwalkers,
|
|
114
|
-
ndim,
|
|
115
|
-
log_like_fn,
|
|
116
|
-
priors,
|
|
117
|
-
args=[means, invcov],
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
coords = priors.rvs(size=(nwalkers,))
|
|
121
|
-
|
|
122
|
-
# check log_like
|
|
123
|
-
log_like = np.asarray(
|
|
124
|
-
[log_like_fn(coords[i], means, invcov) for i in range(nwalkers)]
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
# check log_prior
|
|
128
|
-
log_prior = np.asarray([priors.logpdf(coords[i]) for i in range(nwalkers)])
|
|
129
|
-
|
|
130
|
-
nsteps = 50
|
|
131
|
-
# burn for 1000 steps
|
|
132
|
-
burn = 10
|
|
133
|
-
# thin by 5
|
|
134
|
-
thin_by = 1
|
|
135
|
-
out = ensemble.run_mcmc(
|
|
136
|
-
coords, nsteps, burn=burn, progress=False, thin_by=thin_by
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
samples = ensemble.get_chain()["model_0"].reshape(-1, ndim)
|
|
140
|
-
|
|
141
|
-
ll = ensemble.backend.get_log_like()
|
|
142
|
-
lp = ensemble.backend.get_log_prior()
|
|
143
|
-
|
|
144
|
-
samples = ensemble.get_chain()
|
|
145
|
-
|
|
146
|
-
ensemble.backend.shape
|
|
147
|
-
|
|
148
|
-
last_state = ensemble.backend.get_last_sample()
|
|
149
|
-
|
|
150
|
-
last_state.branches
|
|
151
|
-
|
|
152
|
-
last_state.branches["model_0"].coords
|
|
153
|
-
|
|
154
|
-
def test_pt(self):
|
|
155
|
-
# set up problem
|
|
156
|
-
ndim = 5
|
|
157
|
-
nwalkers = 100
|
|
158
|
-
ntemps = 10
|
|
159
|
-
|
|
160
|
-
means = np.zeros(ndim) # np.random.rand(ndim)
|
|
161
|
-
|
|
162
|
-
# define covariance matrix
|
|
163
|
-
cov = np.diag(np.ones(ndim))
|
|
164
|
-
invcov = np.linalg.inv(cov)
|
|
165
|
-
|
|
166
|
-
lims = 5.0
|
|
167
|
-
priors_in = {
|
|
168
|
-
i: uniform_dist(-lims + means[i], lims + means[i]) for i in range(ndim)
|
|
169
|
-
}
|
|
170
|
-
priors = ProbDistContainer(priors_in)
|
|
171
|
-
|
|
172
|
-
# fill kwargs dictionary
|
|
173
|
-
tempering_kwargs = dict(ntemps=ntemps)
|
|
174
|
-
|
|
175
|
-
# randomize throughout prior
|
|
176
|
-
coords = priors.rvs(
|
|
177
|
-
size=(
|
|
178
|
-
ntemps,
|
|
179
|
-
nwalkers,
|
|
180
|
-
)
|
|
181
|
-
)
|
|
182
|
-
|
|
183
|
-
backend_test_file = "_hdf_backend_test_file.h5"
|
|
184
|
-
# initialize sampler
|
|
185
|
-
ensemble_pt = EnsembleSampler(
|
|
186
|
-
nwalkers,
|
|
187
|
-
ndim,
|
|
188
|
-
log_like_fn,
|
|
189
|
-
priors,
|
|
190
|
-
args=[means, cov],
|
|
191
|
-
backend=backend_test_file,
|
|
192
|
-
tempering_kwargs=tempering_kwargs,
|
|
193
|
-
)
|
|
194
|
-
|
|
195
|
-
nsteps = 50
|
|
196
|
-
# burn for 1000 steps
|
|
197
|
-
burn = 10
|
|
198
|
-
# thin by 5
|
|
199
|
-
thin_by = 1
|
|
200
|
-
ensemble_pt.run_mcmc(coords, nsteps, burn=burn, progress=False, thin_by=thin_by)
|
|
201
|
-
|
|
202
|
-
for temp in range(ntemps):
|
|
203
|
-
samples = ensemble_pt.get_chain()["model_0"][:, temp].reshape(-1, ndim)
|
|
204
|
-
|
|
205
|
-
ll = ensemble_pt.backend.get_log_like()
|
|
206
|
-
|
|
207
|
-
# check temperature index and branch_names
|
|
208
|
-
cold_chain = ensemble_pt.backend.get_chain(discard=10, thin=2, temp_index=0, branch_names=["model_0"])
|
|
209
|
-
os.remove(backend_test_file)
|
|
210
|
-
|
|
211
|
-
def test_rj(self):
|
|
212
|
-
nwalkers = 20
|
|
213
|
-
ntemps = 8
|
|
214
|
-
ndim = 3
|
|
215
|
-
nleaves_max = {"gauss": 1}
|
|
216
|
-
nleaves_min = {"gauss": 0}
|
|
217
|
-
|
|
218
|
-
branch_names = ["gauss"]
|
|
219
|
-
|
|
220
|
-
# define time stream
|
|
221
|
-
num = 500
|
|
222
|
-
t = np.linspace(-1, 1, num)
|
|
223
|
-
|
|
224
|
-
gauss_inj_params = [
|
|
225
|
-
# [3.3, -0.2, 0.1],
|
|
226
|
-
# [2.6, -0.1, 0.1],
|
|
227
|
-
# [3.4, 0.0, 0.1],
|
|
228
|
-
# [2.9, 0.3, 0.1],
|
|
229
|
-
]
|
|
230
|
-
|
|
231
|
-
# combine gaussians
|
|
232
|
-
injection = combine_gaussians(t, np.asarray(gauss_inj_params))
|
|
233
|
-
|
|
234
|
-
# set noise level
|
|
235
|
-
sigma = 0.00001
|
|
236
|
-
|
|
237
|
-
# produce full data
|
|
238
|
-
y = injection + sigma * np.random.randn(len(injection))
|
|
239
|
-
|
|
240
|
-
coords = {"gauss": np.zeros((ntemps, nwalkers, nleaves_max["gauss"], ndim))}
|
|
241
|
-
|
|
242
|
-
# this is the sigma for the multivariate Gaussian that sets starting points
|
|
243
|
-
# We need it to be very small to assume we are passed the search phase
|
|
244
|
-
# we will verify this is with likelihood calculations
|
|
245
|
-
sig1 = 0.0001
|
|
246
|
-
|
|
247
|
-
# setup initial walkers to be the correct count (it will spread out)
|
|
248
|
-
# for nn in range(nleaves_max["gauss"]):
|
|
249
|
-
# if nn >= len(gauss_inj_params):
|
|
250
|
-
# # not going to add parameters for these unused leaves
|
|
251
|
-
# continue
|
|
252
|
-
|
|
253
|
-
# coords["gauss"][:, :, nn] = np.random.multivariate_normal(
|
|
254
|
-
# gauss_inj_params[nn],
|
|
255
|
-
# np.diag(np.ones(3) * sig1),
|
|
256
|
-
# size=(ntemps, nwalkers),
|
|
257
|
-
# )
|
|
258
|
-
|
|
259
|
-
# make sure to start near the proper setup
|
|
260
|
-
inds = {"gauss": np.zeros((ntemps, nwalkers, nleaves_max["gauss"]), dtype=bool)}
|
|
261
|
-
|
|
262
|
-
# turn False -> True for any binary in the sampler
|
|
263
|
-
# inds["gauss"][:, :, : len(gauss_inj_params)] = True
|
|
264
|
-
|
|
265
|
-
# describes priors for all leaves independently
|
|
266
|
-
priors = {
|
|
267
|
-
"gauss": {
|
|
268
|
-
0: uniform_dist(2.5, 3.5), # amplitude
|
|
269
|
-
1: uniform_dist(t.min(), t.max()), # mean
|
|
270
|
-
2: uniform_dist(0.01, 0.21), # sigma
|
|
271
|
-
},
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
# for the Gaussian Move, will be explained later
|
|
275
|
-
factor = 0.00001
|
|
276
|
-
cov = {"gauss": np.diag(np.ones(ndim)) * factor}
|
|
277
|
-
|
|
278
|
-
priors_gen = {"gauss": ProbDistContainer(priors["gauss"])}
|
|
279
|
-
moves = GaussianMove(cov)
|
|
280
|
-
rj_moves = [
|
|
281
|
-
DistributionGenerateRJ(
|
|
282
|
-
priors_gen, nleaves_min=nleaves_min, nleaves_max=nleaves_max
|
|
283
|
-
),
|
|
284
|
-
DistributionGenerateRJ(
|
|
285
|
-
priors_gen, nleaves_min=nleaves_min, nleaves_max=nleaves_max
|
|
286
|
-
),
|
|
287
|
-
]
|
|
288
|
-
|
|
289
|
-
base_like = log_like_fn_gauss_pulse(np.asarray([]), t, y, sigma)
|
|
290
|
-
|
|
291
|
-
ensemble = EnsembleSampler(
|
|
292
|
-
nwalkers,
|
|
293
|
-
ndim,
|
|
294
|
-
log_like_fn_gauss_pulse,
|
|
295
|
-
priors,
|
|
296
|
-
args=[t, y, sigma],
|
|
297
|
-
tempering_kwargs=dict(ntemps=ntemps),
|
|
298
|
-
nbranches=len(branch_names),
|
|
299
|
-
branch_names=branch_names,
|
|
300
|
-
nleaves_max=nleaves_max,
|
|
301
|
-
nleaves_min=nleaves_min,
|
|
302
|
-
moves=moves,
|
|
303
|
-
fill_zero_leaves_val=base_like,
|
|
304
|
-
rj_moves=rj_moves, # basic generation of new leaves from the prior
|
|
305
|
-
)
|
|
306
|
-
|
|
307
|
-
log_prior = ensemble.compute_log_prior(coords, inds=inds)
|
|
308
|
-
log_like = ensemble.compute_log_like(coords, inds=inds, logp=log_prior)[0]
|
|
309
|
-
|
|
310
|
-
# setup starting state
|
|
311
|
-
state = State(coords, log_like=log_like, log_prior=log_prior, inds=inds)
|
|
312
|
-
|
|
313
|
-
nsteps = 1000
|
|
314
|
-
last_sample = ensemble.run_mcmc(
|
|
315
|
-
state, nsteps, burn=1000, progress=True, thin_by=1
|
|
316
|
-
)
|
|
317
|
-
|
|
318
|
-
last_sample.branches["gauss"].nleaves
|
|
319
|
-
|
|
320
|
-
nleaves = ensemble.get_nleaves()["gauss"]
|
|
321
|
-
bns = (
|
|
322
|
-
np.arange(1, nleaves_max["gauss"] + 2) - 0.5
|
|
323
|
-
) # Just to make it pretty and center the bins
|
|
324
|
-
|
|
325
|
-
samples = ensemble.get_chain()["gauss"][:, 0].reshape(-1, ndim)
|
|
326
|
-
|
|
327
|
-
# same as ensemble.get_chain()['gauss'][ensemble.get_inds()['gauss']]
|
|
328
|
-
samples = samples[~np.isnan(samples[:, 0])]
|
|
329
|
-
|
|
330
|
-
# check temperature index and branch_names
|
|
331
|
-
cold_chain = ensemble.backend.get_chain(discard=10, thin=2, temp_index=1, branch_names=["gauss"])
|
|
332
|
-
|
|
333
|
-
#means = np.asarray(gauss_inj_params)[:, 1]
|
|
334
|
-
# fig, (ax1, ax2) = plt.subplots(1, 2)
|
|
335
|
-
# ax1.hist(nleaves[:, 0].flatten(), np.arange(0, 3) - 0.5)
|
|
336
|
-
# ax2.plot(t, y)
|
|
337
|
-
# ax2.plot(t, injection)
|
|
338
|
-
# plt.show()
|
|
339
|
-
# breakpoint()
|
|
340
|
-
|
|
341
|
-
def test_rj_multiple_branches(self):
|
|
342
|
-
nwalkers = 20
|
|
343
|
-
ntemps = 8
|
|
344
|
-
ndims = {"gauss": 3, "sine": 3}
|
|
345
|
-
nleaves_max = {"gauss": 8, "sine": 4}
|
|
346
|
-
nleaves_min = {"gauss": 0, "sine": 0}
|
|
347
|
-
|
|
348
|
-
branch_names = ["gauss", "sine"]
|
|
349
|
-
|
|
350
|
-
# define time stream
|
|
351
|
-
num = 500
|
|
352
|
-
t = np.linspace(-1, 1, num)
|
|
353
|
-
|
|
354
|
-
gauss_inj_params = [
|
|
355
|
-
[3.3, -0.2, 0.1],
|
|
356
|
-
[2.6, -0.1, 0.1],
|
|
357
|
-
[3.4, 0.0, 0.1],
|
|
358
|
-
[2.9, 0.3, 0.1],
|
|
359
|
-
]
|
|
360
|
-
|
|
361
|
-
sine_inj_params = [
|
|
362
|
-
[1.3, 10.1, 1.0],
|
|
363
|
-
[0.8, 4.6, 1.2],
|
|
364
|
-
]
|
|
365
|
-
|
|
366
|
-
# combine gaussians
|
|
367
|
-
injection = combine_gaussians(t, np.asarray(gauss_inj_params))
|
|
368
|
-
injection += combine_sine(t, np.asarray(sine_inj_params))
|
|
369
|
-
|
|
370
|
-
# set noise level
|
|
371
|
-
sigma = 200.0
|
|
372
|
-
|
|
373
|
-
# produce full data
|
|
374
|
-
y = injection + sigma * np.random.randn(len(injection))
|
|
375
|
-
|
|
376
|
-
coords = {
|
|
377
|
-
"gauss": np.zeros((ntemps, nwalkers, nleaves_max["gauss"], ndims["gauss"])),
|
|
378
|
-
"sine": np.zeros((ntemps, nwalkers, nleaves_max["sine"], ndims["sine"])),
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
# make sure to start near the proper setup
|
|
382
|
-
inds = {
|
|
383
|
-
"gauss": np.zeros((ntemps, nwalkers, nleaves_max["gauss"]), dtype=bool),
|
|
384
|
-
"sine": np.zeros((ntemps, nwalkers, nleaves_max["sine"]), dtype=bool),
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
# this is the sigma for the multivariate Gaussian that sets starting points
|
|
388
|
-
# We need it to be very small to assume we are passed the search phase
|
|
389
|
-
# we will verify this is with likelihood calculations
|
|
390
|
-
sig1 = 0.0001
|
|
391
|
-
|
|
392
|
-
# setup initial walkers to be the correct count (it will spread out)
|
|
393
|
-
# start with gaussians
|
|
394
|
-
for nn in range(nleaves_max["gauss"]):
|
|
395
|
-
if nn >= len(gauss_inj_params):
|
|
396
|
-
# not going to add parameters for these unused leaves
|
|
397
|
-
continue
|
|
398
|
-
coords["gauss"][:, :, nn] = np.random.multivariate_normal(
|
|
399
|
-
gauss_inj_params[nn],
|
|
400
|
-
np.diag(np.ones(3) * sig1),
|
|
401
|
-
size=(ntemps, nwalkers),
|
|
402
|
-
)
|
|
403
|
-
inds["gauss"][:, :, nn] = True
|
|
404
|
-
|
|
405
|
-
# next do sine waves
|
|
406
|
-
for nn in range(nleaves_max["sine"]):
|
|
407
|
-
if nn >= len(sine_inj_params):
|
|
408
|
-
# not going to add parameters for these unused leaves
|
|
409
|
-
continue
|
|
410
|
-
coords["sine"][:, :, nn] = np.random.multivariate_normal(
|
|
411
|
-
sine_inj_params[nn], np.diag(np.ones(3) * sig1), size=(ntemps, nwalkers)
|
|
412
|
-
)
|
|
413
|
-
inds["sine"][:, :, nn] = True
|
|
414
|
-
|
|
415
|
-
# describes priors for all leaves independently
|
|
416
|
-
priors = {
|
|
417
|
-
"gauss": {
|
|
418
|
-
0: uniform_dist(2.5, 3.5), # amplitude
|
|
419
|
-
1: uniform_dist(t.min(), t.max()), # mean
|
|
420
|
-
2: uniform_dist(0.01, 0.21), # sigma
|
|
421
|
-
},
|
|
422
|
-
"sine": {
|
|
423
|
-
0: uniform_dist(0.5, 1.5), # amplitude
|
|
424
|
-
1: uniform_dist(1.0, 20.0), # mean
|
|
425
|
-
2: uniform_dist(0.0, 2 * np.pi), # sigma
|
|
426
|
-
},
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
# for the Gaussian Move, will be explained later
|
|
430
|
-
factor = 0.00001
|
|
431
|
-
cov = {
|
|
432
|
-
"gauss": np.diag(np.ones(ndims["gauss"])) * factor,
|
|
433
|
-
"sine": np.diag(np.ones(ndims["sine"])) * factor,
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
moves = GaussianMove(cov)
|
|
437
|
-
|
|
438
|
-
fp = "_test_backend.h5"
|
|
439
|
-
|
|
440
|
-
# just to test iterate_branches
|
|
441
|
-
tmp = EnsembleSampler(
|
|
442
|
-
nwalkers,
|
|
443
|
-
ndims,
|
|
444
|
-
log_like_fn_gauss_and_sine,
|
|
445
|
-
priors,
|
|
446
|
-
args=[t, y, sigma],
|
|
447
|
-
tempering_kwargs=dict(ntemps=ntemps),
|
|
448
|
-
nbranches=len(branch_names),
|
|
449
|
-
branch_names=branch_names,
|
|
450
|
-
nleaves_max=nleaves_max,
|
|
451
|
-
nleaves_min=nleaves_min,
|
|
452
|
-
moves=moves,
|
|
453
|
-
rj_moves="iterate_branches", # basic generation of new leaves from the prior
|
|
454
|
-
backend=None,
|
|
455
|
-
)
|
|
456
|
-
del tmp
|
|
457
|
-
|
|
458
|
-
ensemble = EnsembleSampler(
|
|
459
|
-
nwalkers,
|
|
460
|
-
ndims,
|
|
461
|
-
log_like_fn_gauss_and_sine,
|
|
462
|
-
priors,
|
|
463
|
-
args=[t, y, sigma],
|
|
464
|
-
tempering_kwargs=dict(ntemps=ntemps),
|
|
465
|
-
nbranches=len(branch_names),
|
|
466
|
-
branch_names=branch_names,
|
|
467
|
-
nleaves_max=nleaves_max,
|
|
468
|
-
nleaves_min=nleaves_min,
|
|
469
|
-
moves=moves,
|
|
470
|
-
rj_moves="separate_branches", # basic generation of new leaves from the prior
|
|
471
|
-
backend=fp,
|
|
472
|
-
)
|
|
473
|
-
|
|
474
|
-
log_prior = ensemble.compute_log_prior(coords, inds=inds)
|
|
475
|
-
log_like = ensemble.compute_log_like(coords, inds=inds, logp=log_prior)[0]
|
|
476
|
-
|
|
477
|
-
# make sure it is reasonably close to the maximum which this is
|
|
478
|
-
# will not be zero due to noise
|
|
479
|
-
|
|
480
|
-
# setup starting state
|
|
481
|
-
state = State(coords, log_like=log_like, log_prior=log_prior, inds=inds)
|
|
482
|
-
|
|
483
|
-
state.branches
|
|
484
|
-
|
|
485
|
-
nsteps = 50
|
|
486
|
-
last_sample = ensemble.run_mcmc(
|
|
487
|
-
state, nsteps, burn=10, progress=False, thin_by=1
|
|
488
|
-
)
|
|
489
|
-
|
|
490
|
-
np.array(
|
|
491
|
-
[
|
|
492
|
-
last_sample.branches["gauss"].nleaves[0],
|
|
493
|
-
last_sample.branches["sine"].nleaves[0],
|
|
494
|
-
]
|
|
495
|
-
).T
|
|
496
|
-
|
|
497
|
-
nleaves_gauss = ensemble.get_nleaves()["gauss"]
|
|
498
|
-
nleaves_sine = ensemble.get_nleaves()["sine"]
|
|
499
|
-
|
|
500
|
-
samples = ensemble.get_chain()["gauss"][:, 0].reshape(-1, ndims["gauss"])
|
|
501
|
-
|
|
502
|
-
# same as ensemble.get_chain()['gauss'][ensemble.get_inds()['gauss']]
|
|
503
|
-
samples = samples[~np.isnan(samples[:, 0])]
|
|
504
|
-
|
|
505
|
-
means = np.asarray(gauss_inj_params)[:, 1]
|
|
506
|
-
|
|
507
|
-
os.remove(fp)
|
|
508
|
-
|
|
509
|
-
def test_gibbs_sampling(self):
|
|
510
|
-
nwalkers = 20
|
|
511
|
-
ntemps = 8
|
|
512
|
-
ndims = {"gauss": 3, "sine": 3}
|
|
513
|
-
nleaves_max = {"gauss": 8, "sine": 2} # same min and max means no changing
|
|
514
|
-
nleaves_min = {"gauss": 0, "sine": 2}
|
|
515
|
-
|
|
516
|
-
branch_names = ["gauss", "sine"]
|
|
517
|
-
|
|
518
|
-
# define time stream
|
|
519
|
-
num = 500
|
|
520
|
-
t = np.linspace(-1, 1, num)
|
|
521
|
-
|
|
522
|
-
gauss_inj_params = [
|
|
523
|
-
[3.3, -0.2, 0.1],
|
|
524
|
-
[2.6, -0.1, 0.1],
|
|
525
|
-
[3.4, 0.0, 0.1],
|
|
526
|
-
[2.9, 0.3, 0.1],
|
|
527
|
-
]
|
|
528
|
-
|
|
529
|
-
sine_inj_params = [
|
|
530
|
-
[1.3, 10.1, 1.0],
|
|
531
|
-
[0.8, 4.6, 1.2],
|
|
532
|
-
]
|
|
533
|
-
|
|
534
|
-
# combine gaussians
|
|
535
|
-
injection = combine_gaussians(t, np.asarray(gauss_inj_params))
|
|
536
|
-
injection += combine_sine(t, np.asarray(sine_inj_params))
|
|
537
|
-
|
|
538
|
-
# set noise level
|
|
539
|
-
sigma = 2.0
|
|
540
|
-
|
|
541
|
-
# produce full data
|
|
542
|
-
y = injection + sigma * np.random.randn(len(injection))
|
|
543
|
-
|
|
544
|
-
coords = {
|
|
545
|
-
"gauss": np.zeros((ntemps, nwalkers, nleaves_max["gauss"], ndims["gauss"])),
|
|
546
|
-
"sine": np.zeros((ntemps, nwalkers, nleaves_max["sine"], ndims["sine"])),
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
# make sure to start near the proper setup
|
|
550
|
-
inds = {
|
|
551
|
-
"gauss": np.zeros((ntemps, nwalkers, nleaves_max["gauss"]), dtype=bool),
|
|
552
|
-
"sine": np.ones((ntemps, nwalkers, nleaves_max["sine"]), dtype=bool),
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
# this is the sigma for the multivariate Gaussian that sets starting points
|
|
556
|
-
# We need it to be very small to assume we are passed the search phase
|
|
557
|
-
# we will verify this is with likelihood calculations
|
|
558
|
-
sig1 = 0.0001
|
|
559
|
-
|
|
560
|
-
# setup initial walkers to be the correct count (it will spread out)
|
|
561
|
-
# start with gaussians
|
|
562
|
-
for nn in range(nleaves_max["gauss"]):
|
|
563
|
-
if nn >= len(gauss_inj_params):
|
|
564
|
-
# not going to add parameters for these unused leaves
|
|
565
|
-
continue
|
|
566
|
-
coords["gauss"][:, :, nn] = np.random.multivariate_normal(
|
|
567
|
-
gauss_inj_params[nn],
|
|
568
|
-
np.diag(np.ones(3) * sig1),
|
|
569
|
-
size=(ntemps, nwalkers),
|
|
570
|
-
)
|
|
571
|
-
inds["gauss"][:, :, nn] = True
|
|
572
|
-
|
|
573
|
-
# next do sine waves
|
|
574
|
-
for nn in range(nleaves_max["sine"]):
|
|
575
|
-
if nn >= len(sine_inj_params):
|
|
576
|
-
# not going to add parameters for these unused leaves
|
|
577
|
-
continue
|
|
578
|
-
coords["sine"][:, :, nn] = np.random.multivariate_normal(
|
|
579
|
-
sine_inj_params[nn], np.diag(np.ones(3) * sig1), size=(ntemps, nwalkers)
|
|
580
|
-
)
|
|
581
|
-
# inds["sine"][:, :, nn] = True # already True
|
|
582
|
-
|
|
583
|
-
# describes priors for all leaves independently
|
|
584
|
-
priors = {
|
|
585
|
-
"gauss": {
|
|
586
|
-
0: uniform_dist(2.5, 3.5), # amplitude
|
|
587
|
-
1: uniform_dist(t.min(), t.max()), # mean
|
|
588
|
-
2: uniform_dist(0.01, 0.21), # sigma
|
|
589
|
-
},
|
|
590
|
-
"sine": {
|
|
591
|
-
0: uniform_dist(0.5, 1.5), # amplitude
|
|
592
|
-
1: uniform_dist(1.0, 20.0), # mean
|
|
593
|
-
2: uniform_dist(0.0, 2 * np.pi), # sigma
|
|
594
|
-
},
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
# for the Gaussian Move
|
|
598
|
-
factor = 0.00001
|
|
599
|
-
cov = {
|
|
600
|
-
"gauss": np.diag(np.ones(ndims["gauss"])) * factor,
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
# pass boolean array of shape (nleaves_max["gauss"], ndims["gauss"])
|
|
604
|
-
gibbs_sampling_gauss = [
|
|
605
|
-
("gauss", np.zeros((nleaves_max["gauss"], ndims["gauss"]), dtype=bool))
|
|
606
|
-
for _ in range(nleaves_max["gauss"])
|
|
607
|
-
]
|
|
608
|
-
|
|
609
|
-
for i in range(nleaves_max["gauss"]):
|
|
610
|
-
gibbs_sampling_gauss[i][-1][i] = True
|
|
611
|
-
|
|
612
|
-
gauss_move = GaussianMove(cov, gibbs_sampling_setup=gibbs_sampling_gauss)
|
|
613
|
-
|
|
614
|
-
gibbs_sampling_sine = [
|
|
615
|
-
("sine", np.zeros((nleaves_max["sine"], ndims["sine"]), dtype=bool))
|
|
616
|
-
for _ in range(2 * nleaves_max["sine"])
|
|
617
|
-
]
|
|
618
|
-
for i in range(nleaves_max["sine"]):
|
|
619
|
-
for j in range(2):
|
|
620
|
-
if j == 0:
|
|
621
|
-
gibbs_sampling_sine[2 * i + j][-1][i, :2] = True
|
|
622
|
-
else:
|
|
623
|
-
gibbs_sampling_sine[2 * i + j][-1][i, 2:] = True
|
|
624
|
-
|
|
625
|
-
sine_move = StretchMove(
|
|
626
|
-
live_dangerously=True, gibbs_sampling_setup=gibbs_sampling_sine
|
|
627
|
-
)
|
|
628
|
-
|
|
629
|
-
move = CombineMove([gauss_move, sine_move])
|
|
630
|
-
|
|
631
|
-
ensemble = EnsembleSampler(
|
|
632
|
-
nwalkers,
|
|
633
|
-
ndims,
|
|
634
|
-
log_like_fn_gauss_and_sine,
|
|
635
|
-
priors,
|
|
636
|
-
args=[t, y, sigma],
|
|
637
|
-
tempering_kwargs=dict(ntemps=ntemps),
|
|
638
|
-
nbranches=len(branch_names),
|
|
639
|
-
branch_names=branch_names,
|
|
640
|
-
nleaves_max=nleaves_max,
|
|
641
|
-
nleaves_min=nleaves_min,
|
|
642
|
-
moves=move,
|
|
643
|
-
rj_moves=True, # basic generation of new leaves from the prior
|
|
644
|
-
)
|
|
645
|
-
|
|
646
|
-
log_prior = ensemble.compute_log_prior(coords, inds=inds)
|
|
647
|
-
log_like = ensemble.compute_log_like(coords, inds=inds, logp=log_prior)[0]
|
|
648
|
-
|
|
649
|
-
# make sure it is reasonably close to the maximum which this is
|
|
650
|
-
# will not be zero due to noise
|
|
651
|
-
|
|
652
|
-
# setup starting state
|
|
653
|
-
state = State(coords, log_like=log_like, log_prior=log_prior, inds=inds)
|
|
654
|
-
|
|
655
|
-
nsteps = 50
|
|
656
|
-
last_sample = ensemble.run_mcmc(
|
|
657
|
-
state, nsteps, burn=10, progress=False, thin_by=1
|
|
658
|
-
)
|
|
659
|
-
|
|
660
|
-
def test_utilities(self):
|
|
661
|
-
def transform1(x, y):
|
|
662
|
-
return x * y, y / x
|
|
663
|
-
|
|
664
|
-
# this will do transform lambda x, y: (x**2, y**2) before transform1
|
|
665
|
-
parameter_transforms = {
|
|
666
|
-
0: lambda x: np.log(x),
|
|
667
|
-
(1, 2): lambda x, y: (x**2, y**2),
|
|
668
|
-
(0, 2): transform1,
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
fill_dict = {
|
|
672
|
-
"ndim_full": 6, # full dimensionality after values are added
|
|
673
|
-
"fill_inds": np.array([2, 3, 5]), # indexes for fill values in final array
|
|
674
|
-
"fill_values": np.array([0.0, 1.0, -1.0]), # associated values for filling
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
tc = TransformContainer(
|
|
678
|
-
parameter_transforms=parameter_transforms, fill_dict=fill_dict
|
|
679
|
-
)
|
|
680
|
-
|
|
681
|
-
x = np.random.uniform(0.1, 4.0, size=(40, 3))
|
|
682
|
-
|
|
683
|
-
# can copy and transpose values if needed
|
|
684
|
-
out = tc.transform_base_parameters(x, copy=True, return_transpose=False)
|
|
685
|
-
|
|
686
|
-
def lnprob(x1, group1, x2, group2, transform_containers):
|
|
687
|
-
x = [x1, x2]
|
|
688
|
-
for i, (x_i, transform) in enumerate(zip([x1, x2], transform_containers)):
|
|
689
|
-
temp = transform.transform_base_parameters(
|
|
690
|
-
x_i, copy=True, return_transpose=False
|
|
691
|
-
)
|
|
692
|
-
x[i] = transform.fill_values(temp)
|
|
693
|
-
|
|
694
|
-
## do more in the likelihood here with transformed information
|
|
695
|
-
|
|
696
|
-
# setup transforms for x1
|
|
697
|
-
parameter_transforms1 = {0: lambda x: np.log(x)}
|
|
698
|
-
|
|
699
|
-
# setup transforms for x2
|
|
700
|
-
parameter_transforms2 = {(1, 2): lambda x, y: (x**2, y**2)}
|
|
701
|
-
|
|
702
|
-
# fill dict for x1
|
|
703
|
-
fill_dict1 = {
|
|
704
|
-
"ndim_full": 6, # full dimensionality after values are added
|
|
705
|
-
"fill_inds": np.array([2, 3, 5]), # indexes for fill values in final array
|
|
706
|
-
"fill_values": np.array([0.0, 1.0, -1.0]), # associated values for filling
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
# fill dict for x2
|
|
710
|
-
fill_dict2 = {
|
|
711
|
-
"ndim_full": 5, # full dimensionality after values are added
|
|
712
|
-
"fill_inds": np.array([1]), # indexes for fill values in final array
|
|
713
|
-
"fill_values": np.array([-1.0]), # associated values for filling
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
tcs = [
|
|
717
|
-
TransformContainer(
|
|
718
|
-
parameter_transforms=parameter_transforms1, fill_dict=fill_dict1
|
|
719
|
-
),
|
|
720
|
-
TransformContainer(
|
|
721
|
-
parameter_transforms=parameter_transforms2, fill_dict=fill_dict2
|
|
722
|
-
),
|
|
723
|
-
]
|
|
724
|
-
|
|
725
|
-
num = 40
|
|
726
|
-
x1 = np.random.uniform(0.1, 4.0, size=(num, 3))
|
|
727
|
-
x2 = np.random.uniform(0.1, 4.0, size=(num, 4))
|
|
728
|
-
|
|
729
|
-
group1 = np.arange(num)
|
|
730
|
-
group2 = np.arange(num)
|
|
731
|
-
|
|
732
|
-
# it can be added via args or kwargs in the ensemble sampler
|
|
733
|
-
lnprob(x1, group1, x2, group2, tcs)
|
|
734
|
-
|
|
735
|
-
# ### Periodic Container
|
|
736
|
-
|
|
737
|
-
from eryn.utils import PeriodicContainer
|
|
738
|
-
|
|
739
|
-
periodic = PeriodicContainer({"sine": {2: 2 * np.pi}})
|
|
740
|
-
ntemps, nwalkers, nleaves_max, ndim = (10, 100, 2, 3)
|
|
741
|
-
|
|
742
|
-
params_before_1 = {
|
|
743
|
-
"sine": np.random.uniform(
|
|
744
|
-
0, 7.0, size=(ntemps * nwalkers, nleaves_max, ndim)
|
|
745
|
-
)
|
|
746
|
-
}
|
|
747
|
-
params_before_2 = {
|
|
748
|
-
"sine": np.random.uniform(
|
|
749
|
-
0, 7.0, size=(ntemps * nwalkers, nleaves_max, ndim)
|
|
750
|
-
)
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
distance = periodic.distance(params_before_1, params_before_2)
|
|
754
|
-
|
|
755
|
-
# the max distance should be near half the period
|
|
756
|
-
|
|
757
|
-
params_after_1 = periodic.wrap(params_before_1)
|
|
758
|
-
|
|
759
|
-
# max after wrapping should be near the period
|
|
760
|
-
|
|
761
|
-
# ### Stopping & Update Functions
|
|
762
|
-
from eryn.utils import SearchConvergeStopping
|
|
763
|
-
|
|
764
|
-
ndim = 5
|
|
765
|
-
nwalkers = 100
|
|
766
|
-
|
|
767
|
-
# mean
|
|
768
|
-
means = np.zeros(ndim) # np.random.rand(ndim)
|
|
769
|
-
|
|
770
|
-
# define covariance matrix
|
|
771
|
-
cov = np.diag(np.ones(ndim))
|
|
772
|
-
invcov = np.linalg.inv(cov)
|
|
773
|
-
|
|
774
|
-
# set prior limits
|
|
775
|
-
lims = 50.0
|
|
776
|
-
priors_in = {
|
|
777
|
-
i: uniform_dist(-lims + means[i], lims + means[i]) for i in range(ndim)
|
|
778
|
-
}
|
|
779
|
-
priors = ProbDistContainer(priors_in)
|
|
780
|
-
|
|
781
|
-
stop = SearchConvergeStopping(n_iters=5, diff=0.01, verbose=False)
|
|
782
|
-
|
|
783
|
-
ensemble = EnsembleSampler(
|
|
784
|
-
nwalkers,
|
|
785
|
-
ndim,
|
|
786
|
-
log_like_fn,
|
|
787
|
-
priors,
|
|
788
|
-
args=[means, invcov],
|
|
789
|
-
stopping_fn=stop,
|
|
790
|
-
stopping_iterations=5,
|
|
791
|
-
)
|
|
792
|
-
|
|
793
|
-
# starting positions
|
|
794
|
-
# randomize throughout prior
|
|
795
|
-
coords = priors.rvs(size=(nwalkers,))
|
|
796
|
-
|
|
797
|
-
# check log_like
|
|
798
|
-
log_like = np.asarray(
|
|
799
|
-
[log_like_fn(coords[i], means, invcov) for i in range(nwalkers)]
|
|
800
|
-
)
|
|
801
|
-
|
|
802
|
-
# check log_prior
|
|
803
|
-
log_prior = np.asarray([priors.logpdf(coords[i]) for i in range(nwalkers)])
|
|
804
|
-
|
|
805
|
-
nsteps = 50
|
|
806
|
-
# burn for 1000 steps
|
|
807
|
-
burn = 10
|
|
808
|
-
# thin by 5
|
|
809
|
-
thin_by = 1
|
|
810
|
-
out = ensemble.run_mcmc(
|
|
811
|
-
coords, nsteps, burn=burn, progress=False, thin_by=thin_by
|
|
812
|
-
)
|
|
813
|
-
|
|
814
|
-
def test_group_stretch(self):
|
|
815
|
-
|
|
816
|
-
from eryn.moves import GroupStretchMove
|
|
817
|
-
|
|
818
|
-
class MeanGaussianGroupMove(GroupStretchMove):
|
|
819
|
-
def __init__(self, **kwargs):
|
|
820
|
-
# make sure kwargs get sent into group stretch parent class
|
|
821
|
-
GroupStretchMove.__init__(self, **kwargs)
|
|
822
|
-
|
|
823
|
-
def setup_friends(self, branches):
|
|
824
|
-
|
|
825
|
-
# store cold-chain information
|
|
826
|
-
friends = branches["gauss"].coords[0, branches["gauss"].inds[0]]
|
|
827
|
-
means = friends[:, 1].copy() # need the copy
|
|
828
|
-
|
|
829
|
-
# take unique to avoid errors at the start of sampling
|
|
830
|
-
self.means, uni_inds = np.unique(means, return_index=True)
|
|
831
|
-
self.friends = friends[uni_inds]
|
|
832
|
-
|
|
833
|
-
# sort
|
|
834
|
-
inds_sort = np.argsort(self.means)
|
|
835
|
-
self.friends[:] = self.friends[inds_sort]
|
|
836
|
-
self.means[:] = self.means[inds_sort]
|
|
837
|
-
|
|
838
|
-
# get all current means from all temperatures
|
|
839
|
-
current_means = branches["gauss"].coords[branches["gauss"].inds, 1]
|
|
840
|
-
|
|
841
|
-
# calculate their distances to each stored friend
|
|
842
|
-
dist = np.abs(current_means[:, None] - self.means[None, :])
|
|
843
|
-
|
|
844
|
-
# get closest friends
|
|
845
|
-
inds_closest = np.argsort(dist, axis=1)[:, : self.nfriends]
|
|
846
|
-
|
|
847
|
-
# store in branch supplemental
|
|
848
|
-
branches["gauss"].branch_supplemental[branches["gauss"].inds] = {
|
|
849
|
-
"inds_closest": inds_closest
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
# make sure to "turn off" leaves that are deactivated by setting their
|
|
853
|
-
# index to -1.
|
|
854
|
-
branches["gauss"].branch_supplemental[~branches["gauss"].inds] = {
|
|
855
|
-
"inds_closest": -np.ones(
|
|
856
|
-
(ntemps, nwalkers, nleaves_max, self.nfriends), dtype=int
|
|
857
|
-
)[~branches["gauss"].inds]
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
def fix_friends(self, branches):
|
|
861
|
-
# when RJMCMC activates a new leaf, when it gets to this proposal, its inds_closest
|
|
862
|
-
# will need to be updated
|
|
863
|
-
|
|
864
|
-
# activated & does not have an assigned index
|
|
865
|
-
fix = branches["gauss"].inds & (
|
|
866
|
-
np.all(
|
|
867
|
-
branches["gauss"].branch_supplemental[:]["inds_closest"] == -1,
|
|
868
|
-
axis=-1,
|
|
869
|
-
)
|
|
870
|
-
)
|
|
871
|
-
|
|
872
|
-
if not np.any(fix):
|
|
873
|
-
return
|
|
874
|
-
|
|
875
|
-
# same process as above, only for fix
|
|
876
|
-
current_means = branches["gauss"].coords[fix, 1]
|
|
877
|
-
|
|
878
|
-
dist = np.abs(current_means[:, None] - self.means[None, :])
|
|
879
|
-
inds_closest = np.argsort(dist, axis=1)[:, : self.nfriends]
|
|
880
|
-
|
|
881
|
-
branches["gauss"].branch_supplemental[fix] = {
|
|
882
|
-
"inds_closest": inds_closest
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
# verify everything worked
|
|
886
|
-
fix_check = branches["gauss"].inds & (
|
|
887
|
-
np.all(
|
|
888
|
-
branches["gauss"].branch_supplemental[:]["inds_closest"] == -1,
|
|
889
|
-
axis=-1,
|
|
890
|
-
)
|
|
891
|
-
)
|
|
892
|
-
assert not np.any(fix_check)
|
|
893
|
-
|
|
894
|
-
def find_friends(self, name, s, s_inds=None, branch_supps=None):
|
|
895
|
-
|
|
896
|
-
# prepare buffer array
|
|
897
|
-
friends = np.zeros_like(s)
|
|
898
|
-
|
|
899
|
-
# determine the closest friends for s_inds == True
|
|
900
|
-
inds_closest_here = branch_supps[name][s_inds]["inds_closest"]
|
|
901
|
-
|
|
902
|
-
# take one at random
|
|
903
|
-
random_inds = inds_closest_here[
|
|
904
|
-
np.arange(inds_closest_here.shape[0]),
|
|
905
|
-
np.random.randint(
|
|
906
|
-
self.nfriends, size=(inds_closest_here.shape[0],)
|
|
907
|
-
),
|
|
908
|
-
]
|
|
909
|
-
|
|
910
|
-
# store in buffer array
|
|
911
|
-
friends[s_inds] = self.friends[random_inds]
|
|
912
|
-
return friends
|
|
913
|
-
|
|
914
|
-
# set random seed
|
|
915
|
-
np.random.seed(42)
|
|
916
|
-
|
|
917
|
-
def gaussian_pulse(x, a, b, c):
|
|
918
|
-
f_x = a * np.exp(-((x - b) ** 2) / (2 * c**2))
|
|
919
|
-
return f_x
|
|
920
|
-
|
|
921
|
-
def combine_gaussians(t, params):
|
|
922
|
-
template = np.zeros_like(t)
|
|
923
|
-
for param in params:
|
|
924
|
-
template += gaussian_pulse(t, *param) # *params -> a, b, c
|
|
925
|
-
return template
|
|
926
|
-
|
|
927
|
-
def log_like_fn_gauss_pulse(params, t, data, sigma):
|
|
928
|
-
template = combine_gaussians(t, params)
|
|
929
|
-
|
|
930
|
-
ll = -0.5 * np.sum(((template - data) / sigma) ** 2, axis=-1)
|
|
931
|
-
return ll
|
|
932
|
-
|
|
933
|
-
nwalkers = 20
|
|
934
|
-
ntemps = 8
|
|
935
|
-
ndim = 3
|
|
936
|
-
nleaves_max = 8
|
|
937
|
-
nleaves_min = 0
|
|
938
|
-
|
|
939
|
-
branch_names = ["gauss"]
|
|
940
|
-
|
|
941
|
-
# define time stream
|
|
942
|
-
num = 500
|
|
943
|
-
t = np.linspace(-1, 1, num)
|
|
944
|
-
|
|
945
|
-
gauss_inj_params = [
|
|
946
|
-
[3.3, -0.2, 0.1],
|
|
947
|
-
[2.6, -0.1, 0.1],
|
|
948
|
-
[3.4, 0.0, 0.1],
|
|
949
|
-
[2.9, 0.3, 0.1],
|
|
950
|
-
]
|
|
951
|
-
|
|
952
|
-
# combine gaussians
|
|
953
|
-
injection = combine_gaussians(t, np.asarray(gauss_inj_params))
|
|
954
|
-
|
|
955
|
-
# set noise level
|
|
956
|
-
sigma = 2.0
|
|
957
|
-
|
|
958
|
-
# produce full data
|
|
959
|
-
y = injection + sigma * np.random.randn(len(injection))
|
|
960
|
-
|
|
961
|
-
coords = {"gauss": np.zeros((ntemps, nwalkers, nleaves_max, ndim))}
|
|
962
|
-
|
|
963
|
-
# this is the sigma for the multivariate Gaussian that sets starting points
|
|
964
|
-
# We need it to be very small to assume we are passed the search phase
|
|
965
|
-
# we will verify this is with likelihood calculations
|
|
966
|
-
sig1 = 0.0001
|
|
967
|
-
|
|
968
|
-
# setup initial walkers to be the correct count (it will spread out)
|
|
969
|
-
for nn in range(nleaves_max):
|
|
970
|
-
if nn >= len(gauss_inj_params):
|
|
971
|
-
# not going to add parameters for these unused leaves
|
|
972
|
-
continue
|
|
973
|
-
|
|
974
|
-
coords["gauss"][:, :, nn] = np.random.multivariate_normal(
|
|
975
|
-
gauss_inj_params[nn],
|
|
976
|
-
np.diag(np.ones(3) * sig1),
|
|
977
|
-
size=(ntemps, nwalkers),
|
|
978
|
-
)
|
|
979
|
-
|
|
980
|
-
# make sure to start near the proper setup
|
|
981
|
-
inds = {"gauss": np.zeros((ntemps, nwalkers, nleaves_max), dtype=bool)}
|
|
982
|
-
|
|
983
|
-
# turn False -> True for any binary in the sampler
|
|
984
|
-
inds["gauss"][:, :, : len(gauss_inj_params)] = True
|
|
985
|
-
|
|
986
|
-
# describes priors for all leaves independently
|
|
987
|
-
priors = {
|
|
988
|
-
"gauss": {
|
|
989
|
-
0: uniform_dist(2.5, 3.5), # amplitude
|
|
990
|
-
1: uniform_dist(t.min(), t.max()), # mean
|
|
991
|
-
2: uniform_dist(0.01, 0.21), # sigma
|
|
992
|
-
},
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
# for the Gaussian Move, will be explained later
|
|
996
|
-
# factor = 0.00001
|
|
997
|
-
# cov = {"gauss": np.diag(np.ones(ndim)) * factor}
|
|
998
|
-
|
|
999
|
-
# moves = GaussianMove(cov)
|
|
1000
|
-
nfriends = nwalkers
|
|
1001
|
-
moves = MeanGaussianGroupMove(nfriends=nfriends)
|
|
1002
|
-
|
|
1003
|
-
ensemble = EnsembleSampler(
|
|
1004
|
-
nwalkers,
|
|
1005
|
-
ndim,
|
|
1006
|
-
log_like_fn_gauss_pulse,
|
|
1007
|
-
priors,
|
|
1008
|
-
args=[t, y, sigma],
|
|
1009
|
-
tempering_kwargs=dict(ntemps=ntemps),
|
|
1010
|
-
nbranches=len(branch_names),
|
|
1011
|
-
branch_names=branch_names,
|
|
1012
|
-
nleaves_max=nleaves_max,
|
|
1013
|
-
nleaves_min=nleaves_min,
|
|
1014
|
-
moves=moves,
|
|
1015
|
-
rj_moves=True, # basic generation of new leaves from the prior
|
|
1016
|
-
)
|
|
1017
|
-
|
|
1018
|
-
log_prior = ensemble.compute_log_prior(coords, inds=inds)
|
|
1019
|
-
log_like = ensemble.compute_log_like(coords, inds=inds, logp=log_prior)[0]
|
|
1020
|
-
|
|
1021
|
-
# make sure it is reasonably close to the maximum which this is
|
|
1022
|
-
# will not be zero due to noise
|
|
1023
|
-
|
|
1024
|
-
# setup starting state
|
|
1025
|
-
from eryn.state import BranchSupplemental
|
|
1026
|
-
|
|
1027
|
-
branch_supps = {
|
|
1028
|
-
"gauss": BranchSupplemental(
|
|
1029
|
-
{
|
|
1030
|
-
"inds_closest": np.zeros(
|
|
1031
|
-
inds["gauss"].shape + (nfriends,), dtype=int
|
|
1032
|
-
)
|
|
1033
|
-
},
|
|
1034
|
-
base_shape=(ntemps, nwalkers, nleaves_max),
|
|
1035
|
-
)
|
|
1036
|
-
}
|
|
1037
|
-
state = State(
|
|
1038
|
-
coords,
|
|
1039
|
-
log_like=log_like,
|
|
1040
|
-
log_prior=log_prior,
|
|
1041
|
-
inds=inds,
|
|
1042
|
-
branch_supplemental=branch_supps,
|
|
1043
|
-
)
|
|
1044
|
-
|
|
1045
|
-
nsteps = 2000
|
|
1046
|
-
last_sample = ensemble.run_mcmc(
|
|
1047
|
-
state, nsteps, burn=10, progress=False, thin_by=1
|
|
1048
|
-
)
|
|
1049
|
-
|
|
1050
|
-
nleaves = ensemble.get_nleaves()["gauss"][:, 0].flatten()
|
|
1051
|
-
|
|
1052
|
-
def test_mt(self):
|
|
1053
|
-
# Gaussian likelihood
|
|
1054
|
-
def log_like_fn(x, mu, invcov):
|
|
1055
|
-
diff = x - mu
|
|
1056
|
-
return -0.5 * (diff * np.dot(invcov, diff.T).T).sum()
|
|
1057
|
-
|
|
1058
|
-
ndim = 5
|
|
1059
|
-
nwalkers = 100
|
|
1060
|
-
|
|
1061
|
-
# mean
|
|
1062
|
-
means = np.zeros(ndim) # np.random.rand(ndim)
|
|
1063
|
-
|
|
1064
|
-
# define covariance matrix
|
|
1065
|
-
cov = np.diag(np.ones(ndim))
|
|
1066
|
-
invcov = np.linalg.inv(cov)
|
|
1067
|
-
|
|
1068
|
-
# set prior limits
|
|
1069
|
-
lims = 5.0
|
|
1070
|
-
priors_in = {
|
|
1071
|
-
i: uniform_dist(-lims + means[i], lims + means[i]) for i in range(ndim)
|
|
1072
|
-
}
|
|
1073
|
-
priors = ProbDistContainer(priors_in)
|
|
1074
|
-
|
|
1075
|
-
nwalkers = 20
|
|
1076
|
-
ntemps = 10
|
|
1077
|
-
nleaves_max = 1
|
|
1078
|
-
|
|
1079
|
-
from eryn.moves import MTDistGenMove
|
|
1080
|
-
|
|
1081
|
-
mt_prior = MTDistGenMove(priors, num_try=25, independent=True)
|
|
1082
|
-
|
|
1083
|
-
ensemble = EnsembleSampler(
|
|
1084
|
-
nwalkers,
|
|
1085
|
-
ndim,
|
|
1086
|
-
log_like_fn,
|
|
1087
|
-
priors,
|
|
1088
|
-
args=[means, invcov],
|
|
1089
|
-
moves=mt_prior,
|
|
1090
|
-
tempering_kwargs={"ntemps": ntemps},
|
|
1091
|
-
)
|
|
1092
|
-
|
|
1093
|
-
# starting positions
|
|
1094
|
-
# randomize throughout prior
|
|
1095
|
-
coords = priors.rvs(size=(ntemps, nwalkers, 1))
|
|
1096
|
-
|
|
1097
|
-
nsteps = 50
|
|
1098
|
-
# burn for 1000 steps
|
|
1099
|
-
burn = 10
|
|
1100
|
-
# thin by 5
|
|
1101
|
-
thin_by = 1
|
|
1102
|
-
|
|
1103
|
-
out = ensemble.run_mcmc(
|
|
1104
|
-
coords, nsteps, burn=burn, progress=False, thin_by=thin_by
|
|
1105
|
-
)
|
|
1106
|
-
|
|
1107
|
-
samples_out = ensemble.get_chain()["model_0"][:, 0].reshape(-1, ndim)
|
|
1108
|
-
|
|
1109
|
-
def test_mt_rj(self):
|
|
1110
|
-
def gaussian_pulse(x, a, b, c):
|
|
1111
|
-
f_x = a * np.exp(-((x - b) ** 2) / (2 * c**2))
|
|
1112
|
-
return f_x
|
|
1113
|
-
|
|
1114
|
-
def combine_gaussians(t, params):
|
|
1115
|
-
template = np.zeros_like(t)
|
|
1116
|
-
for param in params:
|
|
1117
|
-
template += gaussian_pulse(t, *param) # *params -> a, b, c
|
|
1118
|
-
return template
|
|
1119
|
-
|
|
1120
|
-
def log_like_fn_gauss_pulse(params, t, data, sigma):
|
|
1121
|
-
template = combine_gaussians(t, params)
|
|
1122
|
-
|
|
1123
|
-
ll = -0.5 * np.sum(((template - data) / sigma) ** 2, axis=-1)
|
|
1124
|
-
return ll
|
|
1125
|
-
|
|
1126
|
-
nwalkers = 20
|
|
1127
|
-
ntemps = 8
|
|
1128
|
-
ndim = 3
|
|
1129
|
-
nleaves_max = 8
|
|
1130
|
-
nleaves_min = 0
|
|
1131
|
-
|
|
1132
|
-
branch_names = ["gauss"]
|
|
1133
|
-
|
|
1134
|
-
# define time stream
|
|
1135
|
-
num = 500
|
|
1136
|
-
t = np.linspace(-1, 1, num)
|
|
1137
|
-
|
|
1138
|
-
gauss_inj_params = [
|
|
1139
|
-
[3.3, -0.2, 0.1],
|
|
1140
|
-
[2.6, -0.1, 0.1],
|
|
1141
|
-
[3.4, 0.0, 0.1],
|
|
1142
|
-
[2.9, 0.3, 0.1],
|
|
1143
|
-
]
|
|
1144
|
-
|
|
1145
|
-
# combine gaussians
|
|
1146
|
-
injection = combine_gaussians(t, np.asarray(gauss_inj_params))
|
|
1147
|
-
|
|
1148
|
-
# set noise level
|
|
1149
|
-
sigma = 2.0
|
|
1150
|
-
|
|
1151
|
-
# produce full data
|
|
1152
|
-
y = injection + sigma * np.random.randn(len(injection))
|
|
1153
|
-
|
|
1154
|
-
coords = {"gauss": np.zeros((ntemps, nwalkers, nleaves_max, ndim))}
|
|
1155
|
-
|
|
1156
|
-
# this is the sigma for the multivariate Gaussian that sets starting points
|
|
1157
|
-
# We need it to be very small to assume we are passed the search phase
|
|
1158
|
-
# we will verify this is with likelihood calculations
|
|
1159
|
-
sig1 = 0.0001
|
|
1160
|
-
|
|
1161
|
-
# setup initial walkers to be the correct count (it will spread out)
|
|
1162
|
-
for nn in range(nleaves_max):
|
|
1163
|
-
if nn >= len(gauss_inj_params):
|
|
1164
|
-
# not going to add parameters for these unused leaves
|
|
1165
|
-
continue
|
|
1166
|
-
|
|
1167
|
-
coords["gauss"][:, :, nn] = np.random.multivariate_normal(
|
|
1168
|
-
gauss_inj_params[nn],
|
|
1169
|
-
np.diag(np.ones(3) * sig1),
|
|
1170
|
-
size=(ntemps, nwalkers),
|
|
1171
|
-
)
|
|
1172
|
-
|
|
1173
|
-
# make sure to start near the proper setup
|
|
1174
|
-
inds = {"gauss": np.zeros((ntemps, nwalkers, nleaves_max), dtype=bool)}
|
|
1175
|
-
|
|
1176
|
-
# turn False -> True for any binary in the sampler
|
|
1177
|
-
inds["gauss"][:, :, : len(gauss_inj_params)] = True
|
|
1178
|
-
|
|
1179
|
-
# describes priors for all leaves independently
|
|
1180
|
-
priors = {
|
|
1181
|
-
"gauss": ProbDistContainer(
|
|
1182
|
-
{
|
|
1183
|
-
0: uniform_dist(2.5, 3.5), # amplitude
|
|
1184
|
-
1: uniform_dist(t.min(), t.max()), # mean
|
|
1185
|
-
2: uniform_dist(0.01, 0.21), # sigma
|
|
1186
|
-
}
|
|
1187
|
-
)
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
# for the Gaussian Move, will be explained later
|
|
1191
|
-
factor = 0.00001
|
|
1192
|
-
cov = {"gauss": np.diag(np.ones(ndim)) * factor}
|
|
1193
|
-
|
|
1194
|
-
moves = GaussianMove(cov)
|
|
1195
|
-
|
|
1196
|
-
from eryn.moves import MTDistGenMoveRJ
|
|
1197
|
-
|
|
1198
|
-
mt_rj_prior = MTDistGenMoveRJ(
|
|
1199
|
-
priors,
|
|
1200
|
-
nleaves_max={"gauss": nleaves_max},
|
|
1201
|
-
nleaves_min={"gauss": nleaves_min},
|
|
1202
|
-
num_try=25,
|
|
1203
|
-
rj=True,
|
|
1204
|
-
)
|
|
1205
|
-
|
|
1206
|
-
ensemble = EnsembleSampler(
|
|
1207
|
-
nwalkers,
|
|
1208
|
-
ndim,
|
|
1209
|
-
log_like_fn_gauss_pulse,
|
|
1210
|
-
priors,
|
|
1211
|
-
args=[t, y, sigma],
|
|
1212
|
-
tempering_kwargs=dict(ntemps=ntemps),
|
|
1213
|
-
nbranches=len(branch_names),
|
|
1214
|
-
branch_names=branch_names,
|
|
1215
|
-
nleaves_max=nleaves_max,
|
|
1216
|
-
nleaves_min=nleaves_min,
|
|
1217
|
-
moves=moves,
|
|
1218
|
-
rj_moves=mt_rj_prior, # basic generation of new leaves from the prior
|
|
1219
|
-
)
|
|
1220
|
-
|
|
1221
|
-
log_prior = ensemble.compute_log_prior(coords, inds=inds)
|
|
1222
|
-
log_like = ensemble.compute_log_like(coords, inds=inds, logp=log_prior)[0]
|
|
1223
|
-
|
|
1224
|
-
# make sure it is reasonably close to the maximum which this is
|
|
1225
|
-
# will not be zero due to noise
|
|
1226
|
-
|
|
1227
|
-
# setup starting state
|
|
1228
|
-
state = State(coords, log_like=log_like, log_prior=log_prior, inds=inds)
|
|
1229
|
-
|
|
1230
|
-
nsteps = 20
|
|
1231
|
-
last_sample = ensemble.run_mcmc(
|
|
1232
|
-
state, nsteps, burn=10, progress=False, thin_by=1
|
|
1233
|
-
)
|
|
1234
|
-
|
|
1235
|
-
nleaves = ensemble.get_nleaves()["gauss"]
|
|
1236
|
-
bns = (
|
|
1237
|
-
np.arange(1, nleaves_max + 2) - 0.5
|
|
1238
|
-
) # Just to make it pretty and center the bins
|
|
1239
|
-
|
|
1240
|
-
def test_2d_prior(self):
|
|
1241
|
-
cov = np.array([[0.8, -0.2], [-0.2, 0.4]])
|
|
1242
|
-
from scipy.stats import multivariate_normal
|
|
1243
|
-
|
|
1244
|
-
priors_in = {(0, 1): multivariate_normal(cov=cov)}
|
|
1245
|
-
priors = ProbDistContainer(priors_in)
|
|
1246
|
-
prior_vals = priors.rvs(size=12)
|