CUQIpy 1.0.0.post0.dev229__tar.gz → 1.0.0.post0.dev305__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.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/CUQIpy.egg-info/PKG-INFO +1 -1
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/PKG-INFO +1 -1
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/_version.py +3 -3
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/experimental/mcmc/_cwmh.py +29 -42
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/experimental/mcmc/_hmc.py +34 -34
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/experimental/mcmc/_langevin_algorithm.py +5 -4
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/experimental/mcmc/_laplace_approximation.py +10 -12
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/experimental/mcmc/_mh.py +8 -15
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/experimental/mcmc/_pcn.py +14 -34
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/experimental/mcmc/_rto.py +24 -51
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/experimental/mcmc/_sampler.py +172 -56
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/CUQIpy.egg-info/SOURCES.txt +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/CUQIpy.egg-info/dependency_links.txt +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/CUQIpy.egg-info/requires.txt +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/CUQIpy.egg-info/top_level.txt +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/LICENSE +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/README.md +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/_messages.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/array/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/array/_array.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/config.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/data/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/data/_data.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/data/astronaut.npz +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/data/camera.npz +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/data/cat.npz +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/data/cookie.png +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/data/satellite.mat +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/density/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/density/_density.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/diagnostics.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_beta.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_cauchy.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_cmrf.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_custom.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_distribution.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_gamma.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_gaussian.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_gmrf.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_inverse_gamma.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_joint_distribution.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_laplace.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_lmrf.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_lognormal.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_normal.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_posterior.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/distribution/_uniform.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/experimental/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/experimental/mcmc/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/geometry/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/geometry/_geometry.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/implicitprior/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/implicitprior/_regularizedGMRF.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/implicitprior/_regularizedGaussian.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/likelihood/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/likelihood/_likelihood.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/model/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/model/_model.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/operator/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/operator/_operator.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/pde/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/pde/_pde.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/problem/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/problem/_problem.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/sampler/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/sampler/_conjugate.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/sampler/_conjugate_approx.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/sampler/_cwmh.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/sampler/_gibbs.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/sampler/_hmc.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/sampler/_langevin_algorithm.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/sampler/_laplace_approximation.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/sampler/_mh.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/sampler/_pcn.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/sampler/_rto.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/sampler/_sampler.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/samples/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/samples/_samples.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/solver/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/solver/_solver.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/testproblem/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/testproblem/_testproblem.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/utilities/__init__.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/utilities/_get_python_variable_name.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/cuqi/utilities/_utilities.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/pyproject.toml +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/requirements.txt +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/setup.cfg +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/setup.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_MRFs.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_abstract_distribution_density.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_bayesian_inversion.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_density.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_distribution.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_distributions_shape.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_geometry.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_implicit_priors.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_joint_distribution.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_likelihood.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_model.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_pde.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_posterior.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_problem.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_sampler.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_samples.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_solver.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_testproblem.py +0 -0
- {cuqipy-1.0.0.post0.dev229 → cuqipy-1.0.0.post0.dev305}/tests/test_utilities.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: CUQIpy
|
|
3
|
-
Version: 1.0.0.post0.
|
|
3
|
+
Version: 1.0.0.post0.dev305
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: CUQIpy
|
|
3
|
-
Version: 1.0.0.post0.
|
|
3
|
+
Version: 1.0.0.post0.dev305
|
|
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
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2024-05-
|
|
11
|
+
"date": "2024-05-27T07:34:21+0200",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "1.0.0.post0.
|
|
14
|
+
"full-revisionid": "1274ccfff1cb9663b547dd2aeb9c86c72dccb2ae",
|
|
15
|
+
"version": "1.0.0.post0.dev305"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -67,16 +67,21 @@ class CWMHNew(ProposalBasedSamplerNew):
|
|
|
67
67
|
samples = sampler.sample(2000).get_samples()
|
|
68
68
|
|
|
69
69
|
"""
|
|
70
|
-
|
|
70
|
+
|
|
71
|
+
_STATE_KEYS = ProposalBasedSamplerNew._STATE_KEYS.union(['_scale_temp'])
|
|
72
|
+
|
|
73
|
+
def __init__(self, target:cuqi.density.Density=None, proposal=None, scale=1,
|
|
71
74
|
initial_point=None, **kwargs):
|
|
72
75
|
super().__init__(target, proposal=proposal, scale=scale,
|
|
73
76
|
initial_point=initial_point, **kwargs)
|
|
77
|
+
|
|
78
|
+
def _initialize(self):
|
|
79
|
+
if isinstance(self.scale, Number):
|
|
80
|
+
self.scale = np.ones(self.dim)*self.scale
|
|
81
|
+
self._acc = [np.ones((self.dim))] # Overwrite acc from ProposalBasedSamplerNew with list of arrays
|
|
74
82
|
|
|
75
|
-
#
|
|
76
|
-
self.
|
|
77
|
-
|
|
78
|
-
# set initial acceptance rate
|
|
79
|
-
self._acc = [np.ones((self.dim))]
|
|
83
|
+
# Handling of temporary scale parameter due to possible bug in old CWMH
|
|
84
|
+
self._scale_temp = self.scale.copy()
|
|
80
85
|
|
|
81
86
|
@property
|
|
82
87
|
def scale(self):
|
|
@@ -86,53 +91,35 @@ class CWMHNew(ProposalBasedSamplerNew):
|
|
|
86
91
|
@scale.setter
|
|
87
92
|
def scale(self, value):
|
|
88
93
|
""" Set the scale parameter. """
|
|
89
|
-
if isinstance(value, Number):
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
self._scale = value
|
|
93
|
-
self._scale_temp = self._scale.copy()
|
|
94
|
+
if self._is_initialized and isinstance(value, Number):
|
|
95
|
+
value = np.ones(self.dim)*value
|
|
96
|
+
self._scale = value
|
|
94
97
|
|
|
95
98
|
def validate_target(self):
|
|
96
99
|
if not isinstance(self.target, cuqi.density.Density):
|
|
97
100
|
raise ValueError(
|
|
98
101
|
"Target should be an instance of "+\
|
|
99
102
|
f"{cuqi.density.Density.__class__.__name__}")
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if value is None:
|
|
103
|
+
|
|
104
|
+
def validate_proposal(self):
|
|
105
|
+
if not isinstance(self.proposal, cuqi.distribution.Distribution):
|
|
106
|
+
raise ValueError("Proposal must be a cuqi.distribution.Distribution object")
|
|
107
|
+
if not self.proposal.is_symmetric:
|
|
108
|
+
raise ValueError("Proposal must be symmetric")
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def proposal(self):
|
|
112
|
+
if self._proposal is None:
|
|
112
113
|
self._proposal = cuqi.distribution.Normal(
|
|
113
114
|
mean=lambda location: location,
|
|
114
115
|
std=lambda scale: scale,
|
|
115
116
|
geometry=self.dim,
|
|
116
117
|
)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
elif isinstance(value, cuqi.distribution.Normal) and sorted(
|
|
124
|
-
value.get_conditioning_variables()
|
|
125
|
-
) == ["mean", "std"]:
|
|
126
|
-
self._proposal = value(
|
|
127
|
-
mean=lambda location: location, std=lambda scale: scale
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
elif not isinstance(value, cuqi.distribution.Distribution) and callable(
|
|
131
|
-
value):
|
|
132
|
-
self._proposal = value
|
|
133
|
-
|
|
134
|
-
else:
|
|
135
|
-
raise ValueError(fail_msg)
|
|
118
|
+
return self._proposal
|
|
119
|
+
|
|
120
|
+
@proposal.setter
|
|
121
|
+
def proposal(self, value):
|
|
122
|
+
self._proposal = value
|
|
136
123
|
|
|
137
124
|
def step(self):
|
|
138
125
|
# Initialize x_t which is used to store the current CWMH sample
|
|
@@ -95,7 +95,7 @@ class NUTSNew(SamplerNew):
|
|
|
95
95
|
'epsilon_list',
|
|
96
96
|
'epsilon_bar_list'})
|
|
97
97
|
|
|
98
|
-
def __init__(self, target, initial_point=None, max_depth=15,
|
|
98
|
+
def __init__(self, target=None, initial_point=None, max_depth=15,
|
|
99
99
|
step_size=None, opt_acc_rate=0.6, **kwargs):
|
|
100
100
|
super().__init__(target, initial_point=initial_point, **kwargs)
|
|
101
101
|
|
|
@@ -103,9 +103,6 @@ class NUTSNew(SamplerNew):
|
|
|
103
103
|
self.max_depth = max_depth
|
|
104
104
|
self.step_size = step_size
|
|
105
105
|
self.opt_acc_rate = opt_acc_rate
|
|
106
|
-
|
|
107
|
-
# Set current point
|
|
108
|
-
self.current_point = self.initial_point
|
|
109
106
|
|
|
110
107
|
# Initialize epsilon and epsilon_bar
|
|
111
108
|
# epsilon is the step size used in the current iteration
|
|
@@ -115,12 +112,37 @@ class NUTSNew(SamplerNew):
|
|
|
115
112
|
self._epsilon_bar = None
|
|
116
113
|
self._H_bar = None
|
|
117
114
|
|
|
115
|
+
# Extra parameters for tuning
|
|
116
|
+
self._n_alpha = None
|
|
117
|
+
self._alpha = None
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _initialize(self):
|
|
121
|
+
|
|
118
122
|
# Arrays to store acceptance rate
|
|
119
|
-
self._acc = [None]
|
|
123
|
+
self._acc = [None] # Overwrites acc from SamplerNew. TODO. Check if this is necessary
|
|
124
|
+
|
|
125
|
+
self._alpha = 0 # check if meaningful value
|
|
126
|
+
self._n_alpha = 0 # check if meaningful value
|
|
127
|
+
|
|
128
|
+
self.current_target_logd, self.current_target_grad = self._nuts_target(self.current_point)
|
|
129
|
+
|
|
130
|
+
# parameters dual averaging
|
|
131
|
+
if self.step_size is None:
|
|
132
|
+
self._epsilon = self._FindGoodEpsilon()
|
|
133
|
+
else:
|
|
134
|
+
self._epsilon = self.step_size
|
|
135
|
+
self._epsilon_bar = "unset"
|
|
136
|
+
|
|
137
|
+
# Parameter mu, does not change during the run
|
|
138
|
+
self._mu = np.log(10*self._epsilon)
|
|
139
|
+
|
|
140
|
+
self._H_bar = 0
|
|
120
141
|
|
|
121
142
|
# NUTS run diagnostic:
|
|
122
143
|
# number of tree nodes created each NUTS iteration
|
|
123
144
|
self._num_tree_node = 0
|
|
145
|
+
|
|
124
146
|
# Create lists to store NUTS run diagnostics
|
|
125
147
|
self._create_run_diagnostic_attributes()
|
|
126
148
|
|
|
@@ -176,9 +198,9 @@ class NUTSNew(SamplerNew):
|
|
|
176
198
|
except:
|
|
177
199
|
raise ValueError('Target must have logd and gradient methods.')
|
|
178
200
|
|
|
179
|
-
def
|
|
201
|
+
def reinitialize(self):
|
|
180
202
|
# Call the parent reset method
|
|
181
|
-
super().
|
|
203
|
+
super().reinitialize()
|
|
182
204
|
# Reset NUTS run diagnostic attributes
|
|
183
205
|
self._reset_run_diagnostic_attributes()
|
|
184
206
|
|
|
@@ -275,10 +297,6 @@ class NUTSNew(SamplerNew):
|
|
|
275
297
|
np.exp(eta*np.log(self._epsilon) +(1-eta)*np.log(self._epsilon_bar))
|
|
276
298
|
|
|
277
299
|
def _pre_warmup(self):
|
|
278
|
-
super()._pre_warmup()
|
|
279
|
-
|
|
280
|
-
self.current_target_logd, self.current_target_grad =\
|
|
281
|
-
self._nuts_target(self.current_point)
|
|
282
300
|
|
|
283
301
|
# Set up tuning parameters (only first time tuning is called)
|
|
284
302
|
# Note:
|
|
@@ -289,32 +307,14 @@ class NUTSNew(SamplerNew):
|
|
|
289
307
|
# Parameters that does not change during the run
|
|
290
308
|
# self._mu
|
|
291
309
|
|
|
292
|
-
if self.
|
|
293
|
-
# parameters dual averaging
|
|
294
|
-
self._epsilon = self._FindGoodEpsilon()
|
|
295
|
-
# Parameter mu, does not change during the run
|
|
296
|
-
self._mu = np.log(10*self._epsilon)
|
|
297
|
-
|
|
298
|
-
if self._epsilon_bar is None: # Initial value of epsilon_bar
|
|
310
|
+
if self._epsilon_bar == "unset": # Initial value of epsilon_bar for tuning
|
|
299
311
|
self._epsilon_bar = 1
|
|
300
312
|
|
|
301
|
-
if self._H_bar is None: # Initial value of H_bar
|
|
302
|
-
self._H_bar = 0
|
|
303
|
-
|
|
304
313
|
def _pre_sample(self):
|
|
305
|
-
super()._pre_sample()
|
|
306
314
|
|
|
307
|
-
|
|
308
|
-
self.
|
|
309
|
-
|
|
310
|
-
# Set up epsilon and epsilon_bar if not set
|
|
311
|
-
if self._epsilon is None:
|
|
312
|
-
if self.step_size is None:
|
|
313
|
-
step_size = self._FindGoodEpsilon()
|
|
314
|
-
else:
|
|
315
|
-
step_size = self.step_size
|
|
316
|
-
self._epsilon = step_size
|
|
317
|
-
self._epsilon_bar = step_size
|
|
315
|
+
if self._epsilon_bar == "unset": # Initial value of epsilon_bar for sampling
|
|
316
|
+
self._epsilon_bar = self._epsilon
|
|
317
|
+
|
|
318
318
|
|
|
319
319
|
#=========================================================================
|
|
320
320
|
def _nuts_target(self, x): # returns logposterior tuple evaluation-gradient
|
|
@@ -467,4 +467,4 @@ class NUTSNew(SamplerNew):
|
|
|
467
467
|
# Store the step size used in iteration k
|
|
468
468
|
self.epsilon_list.append(eps)
|
|
469
469
|
# Store the step size suggestion during adaptation in iteration k
|
|
470
|
-
self.epsilon_bar_list.append(eps_bar)
|
|
470
|
+
self.epsilon_bar_list.append(eps_bar)
|
|
@@ -63,15 +63,16 @@ class ULANew(SamplerNew): # Refactor to Proposal-based sampler?
|
|
|
63
63
|
|
|
64
64
|
_STATE_KEYS = SamplerNew._STATE_KEYS.union({'current_target_logd', 'scale', 'current_target_grad'})
|
|
65
65
|
|
|
66
|
-
def __init__(self, target, scale=1.0, **kwargs):
|
|
66
|
+
def __init__(self, target=None, scale=1.0, **kwargs):
|
|
67
67
|
|
|
68
68
|
super().__init__(target, **kwargs)
|
|
69
69
|
|
|
70
|
-
self.
|
|
71
|
-
|
|
70
|
+
self.initial_scale = scale
|
|
71
|
+
|
|
72
|
+
def _initialize(self):
|
|
73
|
+
self.scale = self.initial_scale
|
|
72
74
|
self.current_target_logd = self.target.logd(self.current_point)
|
|
73
75
|
self.current_target_grad = self.target.gradient(self.current_point)
|
|
74
|
-
self._acc = [1] # TODO. Check if we need this
|
|
75
76
|
|
|
76
77
|
def validate_target(self):
|
|
77
78
|
try:
|
|
@@ -53,17 +53,13 @@ class UGLANew(SamplerNew):
|
|
|
53
53
|
|
|
54
54
|
super().__init__(target=target, initial_point=initial_point, **kwargs)
|
|
55
55
|
|
|
56
|
-
if initial_point is None: #TODO: Replace later with a getter
|
|
57
|
-
self.initial_point = np.zeros(self.dim)
|
|
58
|
-
self._samples = [self.initial_point]
|
|
59
|
-
|
|
60
|
-
self.current_point = self.initial_point
|
|
61
|
-
self._acc = [1] # TODO. Check if we need this
|
|
62
|
-
|
|
63
56
|
# Parameters
|
|
64
57
|
self.maxit = maxit
|
|
65
58
|
self.tol = tol
|
|
66
59
|
self.beta = beta
|
|
60
|
+
|
|
61
|
+
def _initialize(self):
|
|
62
|
+
self._precompute()
|
|
67
63
|
|
|
68
64
|
@property
|
|
69
65
|
def prior(self):
|
|
@@ -81,8 +77,8 @@ class UGLANew(SamplerNew):
|
|
|
81
77
|
def data(self):
|
|
82
78
|
return self.target.data
|
|
83
79
|
|
|
84
|
-
def
|
|
85
|
-
|
|
80
|
+
def _precompute(self):
|
|
81
|
+
|
|
86
82
|
D = self.prior._diff_op
|
|
87
83
|
n = D.shape[0]
|
|
88
84
|
|
|
@@ -121,9 +117,6 @@ class UGLANew(SamplerNew):
|
|
|
121
117
|
return out
|
|
122
118
|
self.M = M
|
|
123
119
|
|
|
124
|
-
def _pre_sample(self):
|
|
125
|
-
self._pre_warmup()
|
|
126
|
-
|
|
127
120
|
def step(self):
|
|
128
121
|
# Update Laplace approximation
|
|
129
122
|
self._L2 = self.Lk_fun(self.current_point)
|
|
@@ -157,3 +150,8 @@ class UGLANew(SamplerNew):
|
|
|
157
150
|
# Check that prior is LMRF
|
|
158
151
|
if not isinstance(self.prior, cuqi.distribution.LMRF):
|
|
159
152
|
raise ValueError('Unadjusted Gaussian Laplace approximation (UGLA) requires LMRF prior')
|
|
153
|
+
|
|
154
|
+
@property
|
|
155
|
+
def _default_initial_point(self):
|
|
156
|
+
""" Get the default initial point for the sampler. Defaults to an array of zeros. """
|
|
157
|
+
return np.zeros(self.dim)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
import cuqi
|
|
3
3
|
from cuqi.experimental.mcmc import ProposalBasedSamplerNew
|
|
4
|
-
from cuqi.array import CUQIarray
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
class MHNew(ProposalBasedSamplerNew):
|
|
@@ -27,25 +26,19 @@ class MHNew(ProposalBasedSamplerNew):
|
|
|
27
26
|
|
|
28
27
|
def __init__(self, target, proposal=None, scale=1, **kwargs):
|
|
29
28
|
super().__init__(target, proposal=proposal, scale=scale, **kwargs)
|
|
29
|
+
|
|
30
|
+
def _initialize(self):
|
|
30
31
|
# Due to a bug? in old MH, we must keep track of this extra variable to match behavior.
|
|
31
|
-
self._scale_temp = self.scale
|
|
32
|
+
self._scale_temp = self.scale
|
|
32
33
|
|
|
33
34
|
def validate_target(self):
|
|
34
35
|
pass # All targets are valid
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
self._proposal = cuqi.distribution.Gaussian(np.zeros(self.dim), 1)
|
|
42
|
-
elif not isinstance(value, cuqi.distribution.Distribution) and callable(value):
|
|
43
|
-
raise NotImplementedError(fail_msg)
|
|
44
|
-
elif isinstance(value, cuqi.distribution.Distribution) and value.is_symmetric:
|
|
45
|
-
self._proposal = value
|
|
46
|
-
else:
|
|
47
|
-
raise ValueError(fail_msg)
|
|
48
|
-
self._proposal.geometry = self.target.geometry
|
|
37
|
+
def validate_proposal(self):
|
|
38
|
+
if not isinstance(self.proposal, cuqi.distribution.Distribution):
|
|
39
|
+
raise ValueError("Proposal must be a cuqi.distribution.Distribution object")
|
|
40
|
+
if not self.proposal.is_symmetric:
|
|
41
|
+
raise ValueError("Proposal must be symmetric")
|
|
49
42
|
|
|
50
43
|
def step(self):
|
|
51
44
|
# propose state
|
|
@@ -7,29 +7,25 @@ class PCNNew(SamplerNew): # Refactor to Proposal-based sampler?
|
|
|
7
7
|
|
|
8
8
|
_STATE_KEYS = SamplerNew._STATE_KEYS.union({'scale', 'current_likelihood_logd', 'lambd'})
|
|
9
9
|
|
|
10
|
-
def __init__(self, target, scale=1.0, **kwargs):
|
|
10
|
+
def __init__(self, target=None, scale=1.0, **kwargs):
|
|
11
11
|
|
|
12
12
|
super().__init__(target, **kwargs)
|
|
13
|
+
self.initial_scale = scale
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
self.
|
|
15
|
+
def _initialize(self):
|
|
16
|
+
self.scale = self.initial_scale
|
|
16
17
|
self.current_likelihood_logd = self._loglikelihood(self.current_point)
|
|
17
18
|
|
|
18
|
-
self._acc = [1] # TODO. Check if we need this
|
|
19
|
-
|
|
20
19
|
# parameters used in the Robbins-Monro recursion for tuning the scale parameter
|
|
21
20
|
# see details and reference in the tune method
|
|
22
21
|
self.lambd = self.scale
|
|
23
22
|
self.star_acc = 0.44 #TODO: 0.234 # target acceptance rate
|
|
24
23
|
|
|
25
24
|
def validate_target(self):
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
raise ValueError("The prior distribution of the target need to be Gaussian")
|
|
31
|
-
except AttributeError:
|
|
32
|
-
raise ValueError("The target need to have a prior distribution")
|
|
25
|
+
if not isinstance(self.target, cuqi.distribution.Posterior):
|
|
26
|
+
raise ValueError(f"To initialize an object of type {self.__class__}, 'target' need to be of type 'cuqi.distribution.Posterior'.")
|
|
27
|
+
if not isinstance(self.prior, (cuqi.distribution.Gaussian, cuqi.distribution.Normal)):
|
|
28
|
+
raise ValueError("The prior distribution of the target need to be Gaussian")
|
|
33
29
|
|
|
34
30
|
def step(self):
|
|
35
31
|
# propose state
|
|
@@ -55,30 +51,14 @@ class PCNNew(SamplerNew): # Refactor to Proposal-based sampler?
|
|
|
55
51
|
|
|
56
52
|
@property
|
|
57
53
|
def prior(self):
|
|
58
|
-
|
|
59
|
-
return self.target.prior
|
|
60
|
-
elif isinstance(self.target,tuple) and len(self.target)==2:
|
|
61
|
-
return self.target[1]
|
|
54
|
+
return self.target.prior
|
|
62
55
|
|
|
63
56
|
@property
|
|
64
57
|
def likelihood(self):
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
@SamplerNew.target.setter
|
|
71
|
-
def target(self, value):
|
|
72
|
-
if isinstance(value, cuqi.distribution.Posterior):
|
|
73
|
-
self._target = value
|
|
74
|
-
self._loglikelihood = lambda x : self.likelihood.logd(x)
|
|
75
|
-
elif isinstance(value,tuple) and len(value)==2 and \
|
|
76
|
-
(isinstance(value[0], cuqi.likelihood.Likelihood) or isinstance(value[0], cuqi.likelihood.UserDefinedLikelihood)) and \
|
|
77
|
-
isinstance(value[1], cuqi.distribution.Distribution):
|
|
78
|
-
self._target = value
|
|
79
|
-
self._loglikelihood = lambda x : self.likelihood.logd(x)
|
|
80
|
-
else:
|
|
81
|
-
raise ValueError(f"To initialize an object of type {self.__class__}, 'target' need to be of type 'cuqi.distribution.Posterior'.")
|
|
58
|
+
return self.target.likelihood
|
|
59
|
+
|
|
60
|
+
def _loglikelihood(self, x):
|
|
61
|
+
return self.likelihood.logd(x)
|
|
82
62
|
|
|
83
63
|
@property
|
|
84
64
|
def dim(self): # TODO. Check if we need this. Implemented in base class
|
|
@@ -106,4 +86,4 @@ class PCNNew(SamplerNew): # Refactor to Proposal-based sampler?
|
|
|
106
86
|
self.lambd = np.exp(np.log(self.lambd) + zeta*(hat_acc-self.star_acc))
|
|
107
87
|
|
|
108
88
|
# update scale parameter
|
|
109
|
-
self.scale = min(self.lambd, 1)
|
|
89
|
+
self.scale = min(self.lambd, 1)
|
|
@@ -5,7 +5,6 @@ import numpy as np
|
|
|
5
5
|
import cuqi
|
|
6
6
|
from cuqi.solver import CGLS, FISTA
|
|
7
7
|
from cuqi.experimental.mcmc import SamplerNew
|
|
8
|
-
from cuqi.array import CUQIarray
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
class LinearRTONew(SamplerNew):
|
|
@@ -44,21 +43,17 @@ class LinearRTONew(SamplerNew):
|
|
|
44
43
|
An example is shown in demos/demo31_callback.py.
|
|
45
44
|
|
|
46
45
|
"""
|
|
47
|
-
def __init__(self, target, initial_point=None, maxit=10, tol=1e-6, **kwargs):
|
|
46
|
+
def __init__(self, target=None, initial_point=None, maxit=10, tol=1e-6, **kwargs):
|
|
48
47
|
|
|
49
48
|
super().__init__(target=target, initial_point=initial_point, **kwargs)
|
|
50
49
|
|
|
51
|
-
if initial_point is None: #TODO: Replace later with a getter
|
|
52
|
-
self.initial_point = np.zeros(self.dim)
|
|
53
|
-
self._samples = [self.initial_point]
|
|
54
|
-
|
|
55
|
-
self.current_point = self.initial_point
|
|
56
|
-
self._acc = [1] # TODO. Check if we need this
|
|
57
|
-
|
|
58
50
|
# Other parameters
|
|
59
51
|
self.maxit = maxit
|
|
60
52
|
self.tol = tol
|
|
61
53
|
|
|
54
|
+
def _initialize(self):
|
|
55
|
+
self._precompute()
|
|
56
|
+
|
|
62
57
|
@property
|
|
63
58
|
def prior(self):
|
|
64
59
|
return self.target.prior
|
|
@@ -81,41 +76,7 @@ class LinearRTONew(SamplerNew):
|
|
|
81
76
|
@property
|
|
82
77
|
def data(self):
|
|
83
78
|
return self.target.data
|
|
84
|
-
|
|
85
|
-
@SamplerNew.target.setter
|
|
86
|
-
def target(self, value):
|
|
87
|
-
""" Set the target density. Runs validation of the target. """
|
|
88
|
-
# Accept tuple of inputs and construct posterior
|
|
89
|
-
if isinstance(value, tuple) and len(value) == 5:
|
|
90
|
-
# Structure (data, model, L_sqrtprec, P_mean, P_sqrtprec)
|
|
91
|
-
data = value[0]
|
|
92
|
-
model = value[1]
|
|
93
|
-
L_sqrtprec = value[2]
|
|
94
|
-
P_mean = value[3]
|
|
95
|
-
P_sqrtprec = value[4]
|
|
96
|
-
|
|
97
|
-
# If numpy matrix convert to CUQI model
|
|
98
|
-
if isinstance(model, np.ndarray) and len(model.shape) == 2:
|
|
99
|
-
model = cuqi.model.LinearModel(model)
|
|
100
|
-
|
|
101
|
-
# Check model input
|
|
102
|
-
if not isinstance(model, cuqi.model.LinearModel):
|
|
103
|
-
raise TypeError("Model needs to be cuqi.model.LinearModel or matrix")
|
|
104
|
-
|
|
105
|
-
# Likelihood
|
|
106
|
-
L = cuqi.distribution.Gaussian(model, sqrtprec=L_sqrtprec).to_likelihood(data)
|
|
107
|
-
|
|
108
|
-
# Prior TODO: allow multiple priors stacked
|
|
109
|
-
#if isinstance(P_mean, list) and isinstance(P_sqrtprec, list):
|
|
110
|
-
# P = cuqi.distribution.JointGaussianSqrtPrec(P_mean, P_sqrtprec)
|
|
111
|
-
#else:
|
|
112
|
-
P = cuqi.distribution.Gaussian(P_mean, sqrtprec=P_sqrtprec)
|
|
113
|
-
|
|
114
|
-
# Construct posterior
|
|
115
|
-
value = cuqi.distribution.Posterior(L, P)
|
|
116
|
-
super(LinearRTONew, type(self)).target.fset(self, value)
|
|
117
|
-
self._precompute()
|
|
118
|
-
|
|
79
|
+
|
|
119
80
|
def _precompute(self):
|
|
120
81
|
L1 = [likelihood.distribution.sqrtprec for likelihood in self.likelihoods]
|
|
121
82
|
L2 = self.prior.sqrtprec
|
|
@@ -188,6 +149,11 @@ class LinearRTONew(SamplerNew):
|
|
|
188
149
|
|
|
189
150
|
if not hasattr(self.prior, "sqrtprecTimesMean"):
|
|
190
151
|
raise TypeError("Prior must contain a sqrtprecTimesMean attribute")
|
|
152
|
+
|
|
153
|
+
@property
|
|
154
|
+
def _default_initial_point(self):
|
|
155
|
+
""" Get the default initial point for the sampler. Defaults to an array of zeros. """
|
|
156
|
+
return np.zeros(self.dim)
|
|
191
157
|
|
|
192
158
|
class RegularizedLinearRTONew(LinearRTONew):
|
|
193
159
|
"""
|
|
@@ -231,15 +197,22 @@ class RegularizedLinearRTONew(LinearRTONew):
|
|
|
231
197
|
self.stepsize = stepsize
|
|
232
198
|
self.abstol = abstol
|
|
233
199
|
self.adaptive = adaptive
|
|
234
|
-
self.proximal = target.prior.proximal
|
|
235
|
-
self._stepsize = self._choose_stepsize()
|
|
236
200
|
self.maxit = maxit
|
|
237
201
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
202
|
+
def _initialize(self):
|
|
203
|
+
super()._initialize()
|
|
204
|
+
self._stepsize = self._choose_stepsize()
|
|
205
|
+
|
|
206
|
+
@property
|
|
207
|
+
def proximal(self):
|
|
208
|
+
return self.target.prior.proximal
|
|
209
|
+
|
|
210
|
+
def validate_target(self):
|
|
211
|
+
super().validate_target()
|
|
212
|
+
if not isinstance(self.target.prior, (cuqi.implicitprior.RegularizedGaussian, cuqi.implicitprior.RegularizedGMRF)):
|
|
213
|
+
raise TypeError("Prior needs to be RegularizedGaussian or RegularizedGMRF")
|
|
214
|
+
if not callable(self.proximal):
|
|
215
|
+
raise TypeError("Proximal needs to be callable")
|
|
243
216
|
|
|
244
217
|
def _choose_stepsize(self):
|
|
245
218
|
if isinstance(self.stepsize, str):
|