CUQIpy 1.1.1.post0.dev15__tar.gz → 1.1.1.post0.dev38__tar.gz
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 CUQIpy might be problematic. Click here for more details.
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/CUQIpy.egg-info/PKG-INFO +2 -1
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/CUQIpy.egg-info/requires.txt +1 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/PKG-INFO +2 -1
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/_version.py +3 -3
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/problem/_problem.py +283 -115
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/requirements.txt +1 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_bayesian_inversion.py +14 -7
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/CUQIpy.egg-info/SOURCES.txt +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/CUQIpy.egg-info/dependency_links.txt +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/CUQIpy.egg-info/top_level.txt +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/LICENSE +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/README.md +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/_messages.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/array/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/array/_array.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/config.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/data/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/data/_data.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/data/astronaut.npz +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/data/camera.npz +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/data/cat.npz +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/data/cookie.png +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/data/satellite.mat +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/density/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/density/_density.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/diagnostics.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_beta.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_cauchy.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_cmrf.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_custom.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_distribution.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_gamma.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_gaussian.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_gmrf.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_inverse_gamma.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_joint_distribution.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_laplace.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_lmrf.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_lognormal.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_modifiedhalfnormal.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_normal.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_posterior.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_smoothed_laplace.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_uniform.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_conjugate.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_conjugate_approx.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_cwmh.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_direct.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_gibbs.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_hmc.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_langevin_algorithm.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_laplace_approximation.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_mh.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_pcn.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_rto.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_sampler.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_utilities.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/geometry/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/geometry/_geometry.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/implicitprior/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/implicitprior/_regularizedGMRF.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/implicitprior/_regularizedGaussian.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/implicitprior/_regularizedUnboundedUniform.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/likelihood/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/likelihood/_likelihood.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/model/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/model/_model.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/operator/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/operator/_operator.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/pde/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/pde/_pde.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/problem/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/sampler/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/sampler/_conjugate.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/sampler/_conjugate_approx.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/sampler/_cwmh.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/sampler/_gibbs.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/sampler/_hmc.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/sampler/_langevin_algorithm.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/sampler/_laplace_approximation.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/sampler/_mh.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/sampler/_pcn.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/sampler/_rto.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/sampler/_sampler.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/samples/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/samples/_samples.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/solver/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/solver/_solver.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/testproblem/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/testproblem/_testproblem.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/utilities/__init__.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/utilities/_get_python_variable_name.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/utilities/_utilities.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/pyproject.toml +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/setup.cfg +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/setup.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_MRFs.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_abstract_distribution_density.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_density.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_distribution.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_distributions_shape.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_geometry.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_implicit_priors.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_joint_distribution.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_likelihood.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_model.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_pde.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_posterior.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_problem.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_sampler.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_samples.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_solver.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_testproblem.py +0 -0
- {cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_utilities.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: CUQIpy
|
|
3
|
-
Version: 1.1.1.post0.
|
|
3
|
+
Version: 1.1.1.post0.dev38
|
|
4
4
|
Summary: Computational Uncertainty Quantification for Inverse problems in Python
|
|
5
5
|
Maintainer-email: "Nicolai A. B. Riis" <nabr@dtu.dk>, "Jakob S. Jørgensen" <jakj@dtu.dk>, "Amal M. Alghamdi" <amaal@dtu.dk>, Chao Zhang <chaz@dtu.dk>
|
|
6
6
|
License: Apache License
|
|
@@ -204,6 +204,7 @@ Requires-Dist: matplotlib
|
|
|
204
204
|
Requires-Dist: numpy>=1.17.0
|
|
205
205
|
Requires-Dist: scipy<1.13
|
|
206
206
|
Requires-Dist: arviz
|
|
207
|
+
Requires-Dist: tqdm
|
|
207
208
|
|
|
208
209
|
<div align="center">
|
|
209
210
|
<img src="https://cuqi-dtu.github.io/CUQIpy/_static/logo.png" alt="CUQIpy logo" width="250"/>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: CUQIpy
|
|
3
|
-
Version: 1.1.1.post0.
|
|
3
|
+
Version: 1.1.1.post0.dev38
|
|
4
4
|
Summary: Computational Uncertainty Quantification for Inverse problems in Python
|
|
5
5
|
Maintainer-email: "Nicolai A. B. Riis" <nabr@dtu.dk>, "Jakob S. Jørgensen" <jakj@dtu.dk>, "Amal M. Alghamdi" <amaal@dtu.dk>, Chao Zhang <chaz@dtu.dk>
|
|
6
6
|
License: Apache License
|
|
@@ -204,6 +204,7 @@ Requires-Dist: matplotlib
|
|
|
204
204
|
Requires-Dist: numpy>=1.17.0
|
|
205
205
|
Requires-Dist: scipy<1.13
|
|
206
206
|
Requires-Dist: arviz
|
|
207
|
+
Requires-Dist: tqdm
|
|
207
208
|
|
|
208
209
|
<div align="center">
|
|
209
210
|
<img src="https://cuqi-dtu.github.io/CUQIpy/_static/logo.png" alt="CUQIpy logo" width="250"/>
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2024-09-
|
|
11
|
+
"date": "2024-09-09T21:48:47+0200",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "1.1.1.post0.
|
|
14
|
+
"full-revisionid": "98a74d508a1aa4659a6176a0126a90371a6be581",
|
|
15
|
+
"version": "1.1.1.post0.dev38"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -218,10 +218,10 @@ class BayesianProblem(object):
|
|
|
218
218
|
"""
|
|
219
219
|
if disp:
|
|
220
220
|
# Print warning to user about the automatic solver selection
|
|
221
|
-
print("
|
|
222
|
-
print("!!! Automatic solver selection is
|
|
223
|
-
print("!!!
|
|
224
|
-
print("
|
|
221
|
+
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
|
222
|
+
print("!!! Automatic solver selection is a work-in-progress !!!")
|
|
223
|
+
print("!!! Always validate the computed results. !!!")
|
|
224
|
+
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
|
225
225
|
print("")
|
|
226
226
|
|
|
227
227
|
x_ML, solver_info = self._solve_max_point(self.likelihood, disp=disp, x0=x0)
|
|
@@ -254,10 +254,10 @@ class BayesianProblem(object):
|
|
|
254
254
|
|
|
255
255
|
if disp:
|
|
256
256
|
# Print warning to user about the automatic solver selection
|
|
257
|
-
print("
|
|
258
|
-
print("!!! Automatic solver selection is
|
|
259
|
-
print("!!!
|
|
260
|
-
print("
|
|
257
|
+
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
|
258
|
+
print("!!! Automatic solver selection is a work-in-progress !!!")
|
|
259
|
+
print("!!! Always validate the computed results. !!!")
|
|
260
|
+
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
|
261
261
|
print("")
|
|
262
262
|
|
|
263
263
|
if self._check_posterior(self, Gaussian, Gaussian, LinearModel, max_dim=config.MAX_DIM_INV):
|
|
@@ -288,7 +288,7 @@ class BayesianProblem(object):
|
|
|
288
288
|
x_MAP.info = solver_info
|
|
289
289
|
return x_MAP
|
|
290
290
|
|
|
291
|
-
def sample_posterior(self, Ns, Nb=None, callback=None) -> cuqi.samples.Samples:
|
|
291
|
+
def sample_posterior(self, Ns, Nb=None, callback=None, experimental=False) -> cuqi.samples.Samples:
|
|
292
292
|
"""Sample the posterior. Sampler choice and tuning is handled automatically.
|
|
293
293
|
|
|
294
294
|
Parameters
|
|
@@ -305,6 +305,9 @@ class BayesianProblem(object):
|
|
|
305
305
|
where `sample` is the current sample and `sample_index` is the index of the sample.
|
|
306
306
|
An example is shown in demos/demo31_callback.py.
|
|
307
307
|
|
|
308
|
+
experimental : bool, *Optional*
|
|
309
|
+
If set to True, the sampler selection will use the samplers from the :mod:`cuqi.experimental.mcmc` module.
|
|
310
|
+
|
|
308
311
|
Returns
|
|
309
312
|
-------
|
|
310
313
|
samples : cuqi.samples.Samples
|
|
@@ -313,12 +316,18 @@ class BayesianProblem(object):
|
|
|
313
316
|
"""
|
|
314
317
|
|
|
315
318
|
# Print warning to user about the automatic sampler selection
|
|
316
|
-
print("
|
|
317
|
-
print("!!! Automatic sampler selection is
|
|
318
|
-
print("!!!
|
|
319
|
-
print("
|
|
319
|
+
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
|
320
|
+
print("!!! Automatic sampler selection is a work-in-progress. !!!")
|
|
321
|
+
print("!!! Always validate the computed results. !!!")
|
|
322
|
+
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
|
320
323
|
print("")
|
|
321
324
|
|
|
325
|
+
if experimental:
|
|
326
|
+
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
|
327
|
+
print("!!! Using samplers from cuqi.experimental.mcmc !!!")
|
|
328
|
+
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
|
329
|
+
print("")
|
|
330
|
+
|
|
322
331
|
# Set up burn-in if not provided
|
|
323
332
|
if Nb is None:
|
|
324
333
|
Nb = int(0.2*Ns)
|
|
@@ -326,7 +335,7 @@ class BayesianProblem(object):
|
|
|
326
335
|
# If target is a joint distribution, try Gibbs sampling
|
|
327
336
|
# This is still very experimental!
|
|
328
337
|
if isinstance(self._target, JointDistribution):
|
|
329
|
-
return self._sampleGibbs(Ns, Nb, callback=callback)
|
|
338
|
+
return self._sampleGibbs(Ns, Nb, callback=callback, experimental=experimental)
|
|
330
339
|
|
|
331
340
|
# For Gaussian small-scale we can use direct sampling
|
|
332
341
|
if self._check_posterior(self, Gaussian, Gaussian, LinearModel, config.MAX_DIM_INV) and not self._check_posterior(self, GMRF):
|
|
@@ -334,24 +343,24 @@ class BayesianProblem(object):
|
|
|
334
343
|
|
|
335
344
|
# For larger-scale Gaussian we use Linear RTO. TODO: Improve checking once we have a common Gaussian class.
|
|
336
345
|
elif hasattr(self.prior,"sqrtprecTimesMean") and hasattr(self.likelihood.distribution,"sqrtprec") and isinstance(self.model,LinearModel):
|
|
337
|
-
return self._sampleLinearRTO(Ns, Nb, callback)
|
|
346
|
+
return self._sampleLinearRTO(Ns, Nb, callback, experimental=experimental)
|
|
338
347
|
|
|
339
348
|
# For LMRF we use our awesome unadjusted Laplace approximation!
|
|
340
349
|
elif self._check_posterior(self, LMRF, Gaussian):
|
|
341
|
-
return self._sampleUGLA(Ns, Nb, callback)
|
|
350
|
+
return self._sampleUGLA(Ns, Nb, callback, experimental=experimental)
|
|
342
351
|
|
|
343
352
|
# If we have gradients, use NUTS!
|
|
344
353
|
# TODO: Fix cases where we have gradients but NUTS fails (see checks)
|
|
345
354
|
elif self._check_posterior(self, must_have_gradient=True) and not self._check_posterior(self, (Beta, InverseGamma, Lognormal)):
|
|
346
|
-
return self._sampleNUTS(Ns, Nb, callback)
|
|
355
|
+
return self._sampleNUTS(Ns, Nb, callback, experimental=experimental)
|
|
347
356
|
|
|
348
357
|
# For Gaussians with non-linear model we use pCN
|
|
349
358
|
elif self._check_posterior(self, (Gaussian, GMRF), Gaussian):
|
|
350
|
-
return self._samplepCN(Ns, Nb, callback)
|
|
359
|
+
return self._samplepCN(Ns, Nb, callback, experimental=experimental)
|
|
351
360
|
|
|
352
361
|
# For Regularized Gaussians with linear models we use RegularizedLinearRTO
|
|
353
362
|
elif self._check_posterior(self, (RegularizedGaussian, RegularizedGMRF), Gaussian, LinearModel):
|
|
354
|
-
return self._sampleRegularizedLinearRTO(Ns, Nb, callback)
|
|
363
|
+
return self._sampleRegularizedLinearRTO(Ns, Nb, callback, experimental=experimental)
|
|
355
364
|
|
|
356
365
|
else:
|
|
357
366
|
raise NotImplementedError(f"Automatic sampler choice is not implemented for model: {type(self.model)}, likelihood: {type(self.likelihood.distribution)} and prior: {type(self.prior)} and dim {self.prior.dim}. Manual sampler choice can be done via the 'sampler' module. Posterior distribution can be extracted via '.posterior' of any testproblem (BayesianProblem).")
|
|
@@ -384,7 +393,7 @@ class BayesianProblem(object):
|
|
|
384
393
|
# Now sample prior problem
|
|
385
394
|
return prior_problem.sample_posterior(Ns, Nb, callback)
|
|
386
395
|
|
|
387
|
-
def UQ(self, Ns=1000, Nb=None, percent=95, exact=None) -> cuqi.samples.Samples:
|
|
396
|
+
def UQ(self, Ns=1000, Nb=None, percent=95, exact=None, experimental=False) -> cuqi.samples.Samples:
|
|
388
397
|
""" Run an Uncertainty Quantification (UQ) analysis on the Bayesian problem and provide a summary of the results.
|
|
389
398
|
|
|
390
399
|
Parameters
|
|
@@ -402,13 +411,16 @@ class BayesianProblem(object):
|
|
|
402
411
|
percent : float, *Optional*
|
|
403
412
|
The credible interval to plot. Defaults to 95%.
|
|
404
413
|
|
|
414
|
+
experimental : bool, *Optional*
|
|
415
|
+
If set to True, the sampler selection will use the samplers from the :mod:`cuqi.experimental.mcmc` module.
|
|
416
|
+
|
|
405
417
|
Returns
|
|
406
418
|
-------
|
|
407
419
|
samples : cuqi.samples.Samples
|
|
408
420
|
Samples from the posterior. The samples can be used to compute further statistics and plots.
|
|
409
421
|
"""
|
|
410
422
|
print(f"Computing {Ns} samples")
|
|
411
|
-
samples = self.sample_posterior(Ns, Nb)
|
|
423
|
+
samples = self.sample_posterior(Ns, Nb, experimental=experimental)
|
|
412
424
|
|
|
413
425
|
print("Plotting results")
|
|
414
426
|
# Gibbs case
|
|
@@ -475,19 +487,37 @@ class BayesianProblem(object):
|
|
|
475
487
|
samples.funvals.vector.plot_variance()
|
|
476
488
|
plt.title("Sample variance of function representation")
|
|
477
489
|
|
|
478
|
-
def _sampleLinearRTO(self, Ns, Nb, callback=None):
|
|
479
|
-
print("Using LinearRTO sampler.")
|
|
480
|
-
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
490
|
+
def _sampleLinearRTO(self, Ns, Nb, callback=None, experimental=False):
|
|
481
491
|
|
|
482
|
-
|
|
483
|
-
ti = time.time()
|
|
492
|
+
if experimental:
|
|
484
493
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
samples = sampler.sample(Ns, Nb)
|
|
494
|
+
print("Using cuqi.experimental.mcmc LinearRTO sampler.")
|
|
495
|
+
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
488
496
|
|
|
489
|
-
|
|
490
|
-
|
|
497
|
+
sampler = cuqi.experimental.mcmc.LinearRTO(self.posterior, callback=callback)
|
|
498
|
+
|
|
499
|
+
ti = time.time()
|
|
500
|
+
|
|
501
|
+
sampler.warmup(Nb)
|
|
502
|
+
sampler.sample(Ns)
|
|
503
|
+
samples = sampler.get_samples().burnthin(Nb)
|
|
504
|
+
|
|
505
|
+
print('Elapsed time:', time.time() - ti)
|
|
506
|
+
|
|
507
|
+
else:
|
|
508
|
+
|
|
509
|
+
print("Using cuqi.sampler LinearRTO sampler.")
|
|
510
|
+
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
511
|
+
|
|
512
|
+
# Start timing
|
|
513
|
+
ti = time.time()
|
|
514
|
+
|
|
515
|
+
# Sample
|
|
516
|
+
sampler = cuqi.sampler.LinearRTO(self.posterior, callback=callback)
|
|
517
|
+
samples = sampler.sample(Ns, Nb)
|
|
518
|
+
|
|
519
|
+
# Print timing
|
|
520
|
+
print('Elapsed time:', time.time() - ti)
|
|
491
521
|
|
|
492
522
|
return samples
|
|
493
523
|
|
|
@@ -532,90 +562,180 @@ class BayesianProblem(object):
|
|
|
532
562
|
|
|
533
563
|
return cuqi.samples.Samples(x_s,self.model.domain_geometry)
|
|
534
564
|
|
|
535
|
-
def _sampleCWMH(self, Ns, Nb, callback=None):
|
|
536
|
-
print("Using Component-wise Metropolis-Hastings (CWMH) sampler (sample_adapt)")
|
|
537
|
-
print(f"burn-in: {Nb/Ns*100:g}%, scale: 0.05, x0: 0.5 (vector)")
|
|
565
|
+
def _sampleCWMH(self, Ns, Nb, callback=None, experimental=False):
|
|
538
566
|
|
|
539
|
-
|
|
540
|
-
n = self.prior.dim
|
|
541
|
-
|
|
542
|
-
# Set up target and proposal
|
|
543
|
-
def proposal(x_t, sigma): return np.random.normal(x_t, sigma)
|
|
567
|
+
if experimental:
|
|
544
568
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
569
|
+
print("Using cuqi.experimental.mcmc Component-wise Metropolis-Hastings (CWMH) sampler.")
|
|
570
|
+
print(f"burn-in: {Nb/Ns*100:g}%, scale: 0.05, x0: 0.5 (vector)")
|
|
571
|
+
|
|
572
|
+
scale = 0.05*np.ones(self.prior.dim)
|
|
573
|
+
x0 = 0.5*np.ones(self.prior.dim)
|
|
574
|
+
|
|
575
|
+
sampler = cuqi.experimental.mcmc.CWMH(self.posterior, scale, x0, callback=callback)
|
|
576
|
+
|
|
577
|
+
ti = time.time()
|
|
578
|
+
|
|
579
|
+
sampler.warmup(Nb)
|
|
580
|
+
sampler.sample(Ns)
|
|
581
|
+
x_s = sampler.get_samples().burnthin(Nb)
|
|
582
|
+
|
|
583
|
+
print('Elapsed time:', time.time() - ti)
|
|
584
|
+
|
|
585
|
+
else:
|
|
586
|
+
|
|
587
|
+
print("Using cuqi.sampler Component-wise Metropolis-Hastings (CWMH) sampler (sample_adapt)")
|
|
588
|
+
print(f"burn-in: {Nb/Ns*100:g}%, scale: 0.05, x0: 0.5 (vector)")
|
|
589
|
+
|
|
590
|
+
# Dimension
|
|
591
|
+
n = self.prior.dim
|
|
592
|
+
|
|
593
|
+
# Set up target and proposal
|
|
594
|
+
def proposal(x_t, sigma): return np.random.normal(x_t, sigma)
|
|
595
|
+
|
|
596
|
+
# Set up sampler
|
|
597
|
+
scale = 0.05*np.ones(n)
|
|
598
|
+
x0 = 0.5*np.ones(n)
|
|
599
|
+
MCMC = cuqi.sampler.CWMH(self.posterior, proposal, scale, x0, callback=callback)
|
|
600
|
+
|
|
601
|
+
# Run sampler
|
|
602
|
+
ti = time.time()
|
|
603
|
+
x_s = MCMC.sample_adapt(Ns,Nb); #ToDo: Make results class
|
|
604
|
+
print('Elapsed time:', time.time() - ti)
|
|
554
605
|
|
|
555
606
|
return x_s
|
|
556
607
|
|
|
557
|
-
def _samplepCN(self, Ns, Nb, callback=None):
|
|
558
|
-
print("Using preconditioned Crank-Nicolson (pCN) sampler (sample_adapt)")
|
|
559
|
-
print(f"burn-in: {Nb/Ns*100:g}%, scale: 0.02")
|
|
608
|
+
def _samplepCN(self, Ns, Nb, callback=None, experimental=False):
|
|
560
609
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
610
|
+
if experimental:
|
|
611
|
+
|
|
612
|
+
print("Using cuqi.experimental.mcmc preconditioned Crank-Nicolson (pCN) sampler.")
|
|
613
|
+
print(f"burn-in: {Nb/Ns*100:g}%, scale: 0.02")
|
|
614
|
+
|
|
615
|
+
scale = 0.02
|
|
616
|
+
|
|
617
|
+
sampler = cuqi.experimental.mcmc.pCN(self.posterior, scale, callback=callback)
|
|
618
|
+
|
|
619
|
+
ti = time.time()
|
|
620
|
+
|
|
621
|
+
sampler.warmup(Nb)
|
|
622
|
+
sampler.sample(Ns)
|
|
623
|
+
x_s = sampler.get_samples().burnthin(Nb)
|
|
624
|
+
|
|
625
|
+
print('Elapsed time:', time.time() - ti)
|
|
626
|
+
|
|
627
|
+
else:
|
|
628
|
+
|
|
629
|
+
print("Using cuqi.sampler preconditioned Crank-Nicolson (pCN) sampler (sample_adapt)")
|
|
630
|
+
print(f"burn-in: {Nb/Ns*100:g}%, scale: 0.02")
|
|
631
|
+
|
|
632
|
+
scale = 0.02
|
|
633
|
+
|
|
634
|
+
MCMC = cuqi.sampler.pCN(self.posterior, scale, callback=callback)
|
|
635
|
+
|
|
636
|
+
#Run sampler
|
|
637
|
+
ti = time.time()
|
|
638
|
+
x_s = MCMC.sample_adapt(Ns, Nb)
|
|
639
|
+
print('Elapsed time:', time.time() - ti)
|
|
570
640
|
|
|
571
641
|
return x_s
|
|
572
642
|
|
|
573
|
-
def _sampleNUTS(self, Ns, Nb, callback=None):
|
|
574
|
-
print("Using No-U-Turn (NUTS) sampler")
|
|
575
|
-
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
643
|
+
def _sampleNUTS(self, Ns, Nb, callback=None, experimental=False):
|
|
576
644
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
645
|
+
if experimental:
|
|
646
|
+
|
|
647
|
+
print("Using cuqi.experimental.mcmc No-U-Turn (NUTS) sampler.")
|
|
648
|
+
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
649
|
+
|
|
650
|
+
sampler = cuqi.experimental.mcmc.NUTS(self.posterior, callback=callback)
|
|
651
|
+
|
|
652
|
+
ti = time.time()
|
|
653
|
+
|
|
654
|
+
sampler.warmup(Nb)
|
|
655
|
+
sampler.sample(Ns)
|
|
656
|
+
x_s = sampler.get_samples().burnthin(Nb)
|
|
657
|
+
|
|
658
|
+
print('Elapsed time:', time.time() - ti)
|
|
659
|
+
|
|
660
|
+
else:
|
|
661
|
+
|
|
662
|
+
print("Using cuqi.sampler No-U-Turn (NUTS) sampler")
|
|
663
|
+
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
664
|
+
|
|
665
|
+
MCMC = cuqi.sampler.NUTS(self.posterior, callback=callback)
|
|
666
|
+
|
|
667
|
+
# Run sampler
|
|
668
|
+
ti = time.time()
|
|
669
|
+
x_s = MCMC.sample_adapt(Ns,Nb)
|
|
670
|
+
print('Elapsed time:', time.time() - ti)
|
|
587
671
|
|
|
588
672
|
return x_s
|
|
589
673
|
|
|
590
|
-
def _sampleUGLA(self, Ns, Nb, callback=None):
|
|
591
|
-
print("Using UGLA sampler")
|
|
592
|
-
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
674
|
+
def _sampleUGLA(self, Ns, Nb, callback=None, experimental=False):
|
|
593
675
|
|
|
594
|
-
|
|
595
|
-
ti = time.time()
|
|
676
|
+
if experimental:
|
|
596
677
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
samples = sampler.sample(Ns, Nb)
|
|
678
|
+
print("Using cuqi.experimental.mcmc Unadjusted Gaussian Laplace Approximation (UGLA) sampler.")
|
|
679
|
+
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
600
680
|
|
|
601
|
-
|
|
602
|
-
|
|
681
|
+
sampler = cuqi.experimental.mcmc.UGLA(self.posterior, callback=callback)
|
|
682
|
+
|
|
683
|
+
ti = time.time()
|
|
684
|
+
|
|
685
|
+
sampler.warmup(Nb)
|
|
686
|
+
sampler.sample(Ns)
|
|
687
|
+
samples = sampler.get_samples().burnthin(Nb)
|
|
688
|
+
|
|
689
|
+
print('Elapsed time:', time.time() - ti)
|
|
690
|
+
|
|
691
|
+
else:
|
|
692
|
+
|
|
693
|
+
print("Using cuqi.sampler UGLA sampler")
|
|
694
|
+
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
695
|
+
|
|
696
|
+
# Start timing
|
|
697
|
+
ti = time.time()
|
|
698
|
+
|
|
699
|
+
# Sample
|
|
700
|
+
sampler = cuqi.sampler.UGLA(self.posterior, callback=callback)
|
|
701
|
+
samples = sampler.sample(Ns, Nb)
|
|
702
|
+
|
|
703
|
+
# Print timing
|
|
704
|
+
print('Elapsed time:', time.time() - ti)
|
|
603
705
|
|
|
604
706
|
return samples
|
|
605
707
|
|
|
606
|
-
def _sampleRegularizedLinearRTO(self, Ns, Nb, callback=None):
|
|
607
|
-
print("Using Regularized LinearRTO sampler.")
|
|
608
|
-
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
708
|
+
def _sampleRegularizedLinearRTO(self, Ns, Nb, callback=None, experimental=False):
|
|
609
709
|
|
|
610
|
-
|
|
611
|
-
ti = time.time()
|
|
710
|
+
if experimental:
|
|
612
711
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
samples = sampler.sample(Ns, Nb)
|
|
712
|
+
print("Using cuqi.experimental.mcmc Regularized LinearRTO sampler.")
|
|
713
|
+
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
616
714
|
|
|
617
|
-
|
|
618
|
-
|
|
715
|
+
sampler = cuqi.experimental.mcmc.RegularizedLinearRTO(self.posterior, maxit=100, stepsize = "automatic", abstol=1e-10, callback=callback)
|
|
716
|
+
|
|
717
|
+
ti = time.time()
|
|
718
|
+
|
|
719
|
+
sampler.warmup(Nb)
|
|
720
|
+
sampler.sample(Ns)
|
|
721
|
+
samples = sampler.get_samples().burnthin(Nb)
|
|
722
|
+
|
|
723
|
+
print('Elapsed time:', time.time() - ti)
|
|
724
|
+
|
|
725
|
+
else:
|
|
726
|
+
|
|
727
|
+
print("Using cuqi.sampler Regularized LinearRTO sampler.")
|
|
728
|
+
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
729
|
+
|
|
730
|
+
# Start timing
|
|
731
|
+
ti = time.time()
|
|
732
|
+
|
|
733
|
+
# Sample
|
|
734
|
+
sampler = cuqi.sampler.RegularizedLinearRTO(self.posterior, maxit=100, stepsize = "automatic", abstol=1e-10, callback=callback)
|
|
735
|
+
samples = sampler.sample(Ns, Nb)
|
|
736
|
+
|
|
737
|
+
# Print timing
|
|
738
|
+
print('Elapsed time:', time.time() - ti)
|
|
619
739
|
|
|
620
740
|
return samples
|
|
621
741
|
|
|
@@ -719,31 +839,61 @@ class BayesianProblem(object):
|
|
|
719
839
|
|
|
720
840
|
return L and P and M and D and G
|
|
721
841
|
|
|
722
|
-
def _sampleGibbs(self, Ns, Nb, callback=None):
|
|
842
|
+
def _sampleGibbs(self, Ns, Nb, callback=None, experimental=False):
|
|
723
843
|
""" This is a helper function for sampling from the posterior using Gibbs sampler. """
|
|
724
844
|
|
|
725
|
-
|
|
726
|
-
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
727
|
-
print("")
|
|
845
|
+
if experimental:
|
|
728
846
|
|
|
729
|
-
|
|
730
|
-
|
|
847
|
+
print("Using cuqi.experimental.mcmc HybridGibbs sampler")
|
|
848
|
+
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
849
|
+
print("")
|
|
731
850
|
|
|
732
|
-
|
|
733
|
-
|
|
851
|
+
if callback is not None:
|
|
852
|
+
raise NotImplementedError("Callback not implemented for Gibbs sampler")
|
|
734
853
|
|
|
735
|
-
|
|
736
|
-
|
|
854
|
+
# Start timing
|
|
855
|
+
ti = time.time()
|
|
737
856
|
|
|
738
|
-
|
|
739
|
-
|
|
857
|
+
# Sampling strategy
|
|
858
|
+
sampling_strategy = self._determine_sampling_strategy(experimental=True)
|
|
740
859
|
|
|
741
|
-
|
|
742
|
-
|
|
860
|
+
sampler = cuqi.experimental.mcmc.HybridGibbs(self._target, sampling_strategy)
|
|
861
|
+
sampler.warmup(Nb)
|
|
862
|
+
sampler.sample(Ns)
|
|
863
|
+
samples = sampler.get_samples()
|
|
864
|
+
# Dict with Samples objects for each parameter
|
|
865
|
+
# Now apply burnthin to each value in dict
|
|
866
|
+
for key, value in samples.items():
|
|
867
|
+
samples[key] = value.burnthin(Nb)
|
|
868
|
+
|
|
869
|
+
# Print timing
|
|
870
|
+
print('Elapsed time:', time.time() - ti)
|
|
871
|
+
|
|
872
|
+
else:
|
|
873
|
+
|
|
874
|
+
print("Using Gibbs sampler")
|
|
875
|
+
print(f"burn-in: {Nb/Ns*100:g}%")
|
|
876
|
+
print("")
|
|
877
|
+
|
|
878
|
+
if callback is not None:
|
|
879
|
+
raise NotImplementedError("Callback not implemented for Gibbs sampler")
|
|
880
|
+
|
|
881
|
+
# Start timing
|
|
882
|
+
ti = time.time()
|
|
883
|
+
|
|
884
|
+
# Sampling strategy
|
|
885
|
+
sampling_strategy = self._determine_sampling_strategy()
|
|
886
|
+
|
|
887
|
+
sampler = cuqi.sampler.Gibbs(self._target, sampling_strategy)
|
|
888
|
+
samples = sampler.sample(Ns, Nb)
|
|
889
|
+
|
|
890
|
+
# Print timing
|
|
891
|
+
print('Elapsed time:', time.time() - ti)
|
|
743
892
|
|
|
744
893
|
return samples
|
|
745
894
|
|
|
746
|
-
|
|
895
|
+
|
|
896
|
+
def _determine_sampling_strategy(self, experimental=False):
|
|
747
897
|
""" This is a helper function for determining the sampling strategy for Gibbs sampler.
|
|
748
898
|
|
|
749
899
|
It is still very experimental and not very robust.
|
|
@@ -774,31 +924,49 @@ class BayesianProblem(object):
|
|
|
774
924
|
raise NotImplementedError(f"Unable to determine sampling strategy for {par_name} with target {cond_target}")
|
|
775
925
|
|
|
776
926
|
# Gamma prior, Gaussian likelihood -> Conjugate
|
|
777
|
-
if self._check_posterior(cond_target, Gamma, (Gaussian, GMRF, RegularizedGaussian, RegularizedGMRF)):
|
|
778
|
-
|
|
927
|
+
if self._check_posterior(cond_target, Gamma, (Gaussian, GMRF, RegularizedGaussian, RegularizedGMRF)):
|
|
928
|
+
if experimental:
|
|
929
|
+
sampling_strategy[par_name] = cuqi.experimental.mcmc.Conjugate()
|
|
930
|
+
else:
|
|
931
|
+
sampling_strategy[par_name] = cuqi.sampler.Conjugate
|
|
779
932
|
|
|
780
933
|
# Gamma prior, LMRF likelihood -> ConjugateApprox
|
|
781
934
|
elif self._check_posterior(cond_target, Gamma, LMRF):
|
|
782
|
-
|
|
935
|
+
if experimental:
|
|
936
|
+
sampling_strategy[par_name] = cuqi.experimental.mcmc.ConjugateApprox()
|
|
937
|
+
else:
|
|
938
|
+
sampling_strategy[par_name] = cuqi.sampler.ConjugateApprox
|
|
783
939
|
|
|
784
940
|
# Gaussian prior, Gaussian likelihood, Linear model -> LinearRTO
|
|
785
941
|
elif self._check_posterior(cond_target, (Gaussian, GMRF), Gaussian, LinearModel):
|
|
786
|
-
|
|
942
|
+
if experimental:
|
|
943
|
+
sampling_strategy[par_name] = cuqi.experimental.mcmc.LinearRTO()
|
|
944
|
+
else:
|
|
945
|
+
sampling_strategy[par_name] = cuqi.sampler.LinearRTO
|
|
787
946
|
|
|
788
947
|
# Implicit Regularized Gaussian prior, Gaussian likelihood, linear model -> RegularizedLinearRTO
|
|
789
948
|
elif self._check_posterior(cond_target, (RegularizedGaussian, RegularizedGMRF), Gaussian, LinearModel):
|
|
790
|
-
|
|
949
|
+
if experimental:
|
|
950
|
+
sampling_strategy[par_name] = cuqi.experimental.mcmc.RegularizedLinearRTO()
|
|
951
|
+
else:
|
|
952
|
+
sampling_strategy[par_name] = cuqi.sampler.RegularizedLinearRTO
|
|
791
953
|
|
|
792
954
|
# LMRF prior, Gaussian likelihood, Linear model -> UGLA
|
|
793
955
|
elif self._check_posterior(cond_target, LMRF, Gaussian, LinearModel):
|
|
794
|
-
|
|
956
|
+
if experimental:
|
|
957
|
+
sampling_strategy[par_name] = cuqi.experimental.mcmc.UGLA()
|
|
958
|
+
else:
|
|
959
|
+
sampling_strategy[par_name] = cuqi.sampler.UGLA
|
|
795
960
|
|
|
796
961
|
else:
|
|
797
962
|
raise NotImplementedError(f"Unable to determine sampling strategy for {par_name} with target {cond_target}")
|
|
798
963
|
|
|
799
964
|
print("Automatically determined sampling strategy:")
|
|
800
965
|
for dist_name, strategy in sampling_strategy.items():
|
|
801
|
-
|
|
966
|
+
if experimental:
|
|
967
|
+
print(f"\t{dist_name}: {strategy.__class__.__name__} (mcmc.experimental)")
|
|
968
|
+
else:
|
|
969
|
+
print(f"\t{dist_name}: {strategy.__name__}")
|
|
802
970
|
print("")
|
|
803
971
|
|
|
804
972
|
return sampling_strategy
|
|
@@ -20,7 +20,8 @@ from cuqi.density import Density
|
|
|
20
20
|
(Deconvolution1D, "square", RegularizedGaussian(np.zeros(128), 0.1, constraint="nonnegativity"), 100, False),
|
|
21
21
|
(Deconvolution1D, "square", RegularizedGMRF(np.zeros(128), 50, constraint="nonnegativity"), 100, False),
|
|
22
22
|
])
|
|
23
|
-
|
|
23
|
+
@pytest.mark.parametrize("experimental", [False, True])
|
|
24
|
+
def test_TP_BayesianProblem_sample(copy_reference, TP_type, phantom, prior, Ns, use_legacy, experimental):
|
|
24
25
|
# SKIP NUTS test if not windows (for now)
|
|
25
26
|
if isinstance(prior, CMRF) and not sys.platform.startswith('win'):
|
|
26
27
|
pytest.skip("NUTS(CMRF) regression test is not implemented for this platform")
|
|
@@ -35,7 +36,7 @@ def test_TP_BayesianProblem_sample(copy_reference, TP_type, phantom, prior, Ns,
|
|
|
35
36
|
TP.prior = prior
|
|
36
37
|
|
|
37
38
|
# Sample posterior
|
|
38
|
-
samples = TP.sample_posterior(Ns=Ns)
|
|
39
|
+
samples = TP.sample_posterior(Ns=Ns, experimental=experimental)
|
|
39
40
|
|
|
40
41
|
# Extract samples and compute properties
|
|
41
42
|
res = samples.samples
|
|
@@ -44,9 +45,14 @@ def test_TP_BayesianProblem_sample(copy_reference, TP_type, phantom, prior, Ns,
|
|
|
44
45
|
lo95, up95 = np.percentile(res, [2.5, 97.5], axis=1)
|
|
45
46
|
|
|
46
47
|
# Load reference file into temp folder and load
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
if experimental:
|
|
49
|
+
ref_fname = f"{TP_type.__name__}_{phantom}_{prior.__class__.__name__}_{Ns}_experimental"
|
|
50
|
+
else:
|
|
51
|
+
ref_fname = f"{TP_type.__name__}_{phantom}_{prior.__class__.__name__}_{Ns}"
|
|
52
|
+
|
|
53
|
+
#if isinstance(prior, RegularizedGMRF): #Put the case you want to update for here.
|
|
49
54
|
# np.savez(ref_fname, median=med_xpos, sigma=sigma_xpos, lo95=lo95, up95=up95) #uncomment to update
|
|
55
|
+
|
|
50
56
|
ref_file = copy_reference(f"data/{ref_fname}.npz")
|
|
51
57
|
ref = np.load(ref_file)
|
|
52
58
|
|
|
@@ -56,6 +62,7 @@ def test_TP_BayesianProblem_sample(copy_reference, TP_type, phantom, prior, Ns,
|
|
|
56
62
|
assert lo95 == pytest.approx(ref["lo95"], rel=1e-3, abs=1e-6)
|
|
57
63
|
assert up95 == pytest.approx(ref["up95"], rel=1e-3, abs=1e-6)
|
|
58
64
|
|
|
65
|
+
@pytest.mark.parametrize("experimental", [False, True])
|
|
59
66
|
@pytest.mark.parametrize("TP_type, phantom, priors, Ns",
|
|
60
67
|
[
|
|
61
68
|
# Case: Gaussian prior (no hyperparameters)
|
|
@@ -123,7 +130,7 @@ def test_TP_BayesianProblem_sample(copy_reference, TP_type, phantom, prior, Ns,
|
|
|
123
130
|
),
|
|
124
131
|
]
|
|
125
132
|
)
|
|
126
|
-
def test_Bayesian_inversion_hierarchical(TP_type: BayesianProblem, phantom: str, priors: Dict[str, Density], Ns: int):
|
|
133
|
+
def test_Bayesian_inversion_hierarchical(TP_type: BayesianProblem, phantom: str, priors: Dict[str, Density], Ns: int, experimental: bool):
|
|
127
134
|
""" This tests Bayesian inversion for Bayesian Problem using a hierarchical model.
|
|
128
135
|
|
|
129
136
|
It is an end-to-end test that checks that the posterior samples are consistent with the expected shape.
|
|
@@ -144,9 +151,9 @@ def test_Bayesian_inversion_hierarchical(TP_type: BayesianProblem, phantom: str,
|
|
|
144
151
|
|
|
145
152
|
# Sample posterior using UQ method
|
|
146
153
|
if len(priors) == 1: # No hyperparameters
|
|
147
|
-
samples = BP.UQ(Ns=Ns, exact=probInfo.exactSolution)
|
|
154
|
+
samples = BP.UQ(Ns=Ns, exact=probInfo.exactSolution, experimental=experimental)
|
|
148
155
|
else:
|
|
149
|
-
samples = BP.UQ(Ns=Ns, exact={priors[0].name: probInfo.exactSolution})
|
|
156
|
+
samples = BP.UQ(Ns=Ns, exact={priors[0].name: probInfo.exactSolution}, experimental=experimental)
|
|
150
157
|
|
|
151
158
|
# No regression test yet, just check that the samples are the right shape
|
|
152
159
|
if isinstance(samples, dict): # Gibbs case
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_joint_distribution.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_modifiedhalfnormal.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/distribution/_smoothed_laplace.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_conjugate_approx.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/experimental/mcmc/_langevin_algorithm.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/implicitprior/_regularizedGMRF.py
RENAMED
|
File without changes
|
{cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/implicitprior/_regularizedGaussian.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/sampler/_laplace_approximation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/cuqi/utilities/_get_python_variable_name.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.1.1.post0.dev15 → cuqipy-1.1.1.post0.dev38}/tests/test_abstract_distribution_density.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|