CUQIpy 1.1.0.post0.dev39__tar.gz → 1.1.1.post0.dev5__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.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/CUQIpy.egg-info/PKG-INFO +1 -1
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/PKG-INFO +1 -1
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/_version.py +3 -3
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_joint_distribution.py +21 -5
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/model/_model.py +72 -34
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_joint_distribution.py +83 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/CUQIpy.egg-info/SOURCES.txt +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/CUQIpy.egg-info/dependency_links.txt +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/CUQIpy.egg-info/requires.txt +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/CUQIpy.egg-info/top_level.txt +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/LICENSE +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/README.md +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/_messages.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/array/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/array/_array.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/config.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/data/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/data/_data.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/data/astronaut.npz +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/data/camera.npz +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/data/cat.npz +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/data/cookie.png +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/data/satellite.mat +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/density/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/density/_density.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/diagnostics.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_beta.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_cauchy.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_cmrf.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_custom.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_distribution.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_gamma.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_gaussian.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_gmrf.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_inverse_gamma.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_laplace.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_lmrf.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_lognormal.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_modifiedhalfnormal.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_normal.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_posterior.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_smoothed_laplace.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_uniform.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/mcmc/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/mcmc/_conjugate.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/mcmc/_conjugate_approx.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/mcmc/_cwmh.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/mcmc/_direct.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/mcmc/_gibbs.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/mcmc/_hmc.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/mcmc/_langevin_algorithm.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/mcmc/_laplace_approximation.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/mcmc/_mh.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/mcmc/_pcn.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/mcmc/_rto.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/mcmc/_sampler.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/experimental/mcmc/_utilities.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/geometry/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/geometry/_geometry.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/implicitprior/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/implicitprior/_regularizedGMRF.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/implicitprior/_regularizedGaussian.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/implicitprior/_regularizedUnboundedUniform.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/likelihood/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/likelihood/_likelihood.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/model/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/operator/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/operator/_operator.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/pde/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/pde/_pde.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/problem/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/problem/_problem.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/sampler/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/sampler/_conjugate.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/sampler/_conjugate_approx.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/sampler/_cwmh.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/sampler/_gibbs.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/sampler/_hmc.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/sampler/_langevin_algorithm.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/sampler/_laplace_approximation.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/sampler/_mh.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/sampler/_pcn.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/sampler/_rto.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/sampler/_sampler.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/samples/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/samples/_samples.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/solver/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/solver/_solver.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/testproblem/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/testproblem/_testproblem.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/utilities/__init__.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/utilities/_get_python_variable_name.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/utilities/_utilities.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/pyproject.toml +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/requirements.txt +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/setup.cfg +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/setup.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_MRFs.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_abstract_distribution_density.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_bayesian_inversion.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_density.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_distribution.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_distributions_shape.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_geometry.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_implicit_priors.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_likelihood.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_model.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_pde.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_posterior.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_problem.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_sampler.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_samples.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_solver.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_testproblem.py +0 -0
- {cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/tests/test_utilities.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: CUQIpy
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.1.post0.dev5
|
|
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.1.
|
|
3
|
+
Version: 1.1.1.post0.dev5
|
|
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-08-
|
|
11
|
+
"date": "2024-08-31T21:02:04+0200",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "1.1.
|
|
14
|
+
"full-revisionid": "b38281138379969a9a8c4683ba3ecf8a88031939",
|
|
15
|
+
"version": "1.1.1.post0.dev5"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
{cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_joint_distribution.py
RENAMED
|
@@ -175,6 +175,10 @@ class JointDistribution:
|
|
|
175
175
|
kwargs[ordered_keys[index]] = arg
|
|
176
176
|
return kwargs
|
|
177
177
|
|
|
178
|
+
def _sum_evaluated_densities(self):
|
|
179
|
+
""" Return the sum of the evaluated densities in the joint distribution """
|
|
180
|
+
return sum([density.logd() for density in self._evaluated_densities])
|
|
181
|
+
|
|
178
182
|
def _reduce_to_single_density(self):
|
|
179
183
|
""" Reduce the joint distribution to a single density if possible.
|
|
180
184
|
|
|
@@ -183,7 +187,6 @@ class JointDistribution:
|
|
|
183
187
|
This method is a hack to allow our current samplers to work with
|
|
184
188
|
the joint distribution. It should be removed in the future.
|
|
185
189
|
"""
|
|
186
|
-
|
|
187
190
|
# Count number of distributions and likelihoods
|
|
188
191
|
n_dist = len(self._distributions)
|
|
189
192
|
n_likelihood = len(self._likelihoods)
|
|
@@ -201,16 +204,29 @@ class JointDistribution:
|
|
|
201
204
|
# Ensure parameter names match, otherwise return the joint distribution
|
|
202
205
|
if set(self._likelihoods[0].get_parameter_names()) != set(self._distributions[0].get_parameter_names()):
|
|
203
206
|
return self
|
|
204
|
-
return Posterior(self._likelihoods[0], self._distributions[0])
|
|
205
|
-
|
|
207
|
+
return self._add_constants_to_density(Posterior(self._likelihoods[0], self._distributions[0]))
|
|
208
|
+
|
|
206
209
|
# If exactly one distribution and no likelihoods its a Distribution
|
|
207
210
|
if n_dist == 1 and n_likelihood == 0:
|
|
208
|
-
return self._distributions[0]
|
|
209
|
-
|
|
211
|
+
return self._add_constants_to_density(self._distributions[0])
|
|
212
|
+
|
|
210
213
|
# If no distributions and exactly one likelihood its a Likelihood
|
|
211
214
|
if n_likelihood == 1 and n_dist == 0:
|
|
212
215
|
return self._likelihoods[0]
|
|
213
216
|
|
|
217
|
+
# If only evaluated densities left return joint to ensure logd method is available
|
|
218
|
+
if n_dist == 0 and n_likelihood == 0:
|
|
219
|
+
return self
|
|
220
|
+
|
|
221
|
+
def _add_constants_to_density(self, density: Density):
|
|
222
|
+
""" Add the constants (evaluated densities) to a single density. Used when reducing to single density. """
|
|
223
|
+
|
|
224
|
+
if isinstance(density, EvaluatedDensity):
|
|
225
|
+
raise ValueError("Cannot add the sum of all evaluated densities to an EvaluatedDensity.")
|
|
226
|
+
|
|
227
|
+
density._constant += self._sum_evaluated_densities()
|
|
228
|
+
return density
|
|
229
|
+
|
|
214
230
|
def _as_stacked(self) -> _StackedJointDistribution:
|
|
215
231
|
""" Return a stacked JointDistribution with the same densities. """
|
|
216
232
|
return _StackedJointDistribution(*self._densities)
|
|
@@ -19,10 +19,10 @@ class Model(object):
|
|
|
19
19
|
Forward operator.
|
|
20
20
|
|
|
21
21
|
range_geometry : integer or cuqi.geometry.Geometry
|
|
22
|
-
If integer is given a _DefaultGeometry is created with dimension of the integer.
|
|
22
|
+
If integer is given, a cuqi.geometry._DefaultGeometry is created with dimension of the integer.
|
|
23
23
|
|
|
24
24
|
domain_geometry : integer or cuqi.geometry.Geometry
|
|
25
|
-
If integer is given a _DefaultGeometry is created with dimension of the integer.
|
|
25
|
+
If integer is given, a cuqi.geometry._DefaultGeometry is created with dimension of the integer.
|
|
26
26
|
|
|
27
27
|
gradient : callable function, optional
|
|
28
28
|
The direction-Jacobian product of the forward operator Jacobian with
|
|
@@ -35,14 +35,20 @@ class Model(object):
|
|
|
35
35
|
The Jacobian of the forward operator with respect to the forward operator input,
|
|
36
36
|
evaluated at a point (`wrt`). The signature of the Jacobian function should be (`wrt`).
|
|
37
37
|
The Jacobian function should return a 2D ndarray of shape (range_dim, domain_dim).
|
|
38
|
-
The Jacobian function is used to specify the gradient function
|
|
38
|
+
The Jacobian function is used to specify the gradient function by computing the vector-Jacobian
|
|
39
|
+
product (VJP), here we refer to the vector in the VJP as the `direction` since it is the direction at
|
|
40
|
+
which the gradient is computed.
|
|
39
41
|
automatically and thus the gradient function should not be specified when the Jacobian
|
|
40
42
|
function is specified.
|
|
41
43
|
|
|
44
|
+
|
|
45
|
+
:ivar range_geometry: The geometry representing the range.
|
|
46
|
+
:ivar domain_geometry: The geometry representing the domain.
|
|
47
|
+
|
|
42
48
|
Example
|
|
43
49
|
-------
|
|
44
50
|
|
|
45
|
-
Consider a forward model :math:`F: \mathbb{R}^2
|
|
51
|
+
Consider a forward model :math:`F: \mathbb{R}^2 \\rightarrow \mathbb{R}` defined by the following forward operator:
|
|
46
52
|
|
|
47
53
|
.. math::
|
|
48
54
|
|
|
@@ -141,11 +147,17 @@ class Model(object):
|
|
|
141
147
|
self._non_default_args = cuqi.utilities.get_non_default_args(self._forward_func)
|
|
142
148
|
|
|
143
149
|
@property
|
|
144
|
-
def domain_dim(self):
|
|
150
|
+
def domain_dim(self):
|
|
151
|
+
"""
|
|
152
|
+
The dimension of the domain
|
|
153
|
+
"""
|
|
145
154
|
return self.domain_geometry.par_dim
|
|
146
155
|
|
|
147
156
|
@property
|
|
148
157
|
def range_dim(self):
|
|
158
|
+
"""
|
|
159
|
+
The dimension of the range
|
|
160
|
+
"""
|
|
149
161
|
return self.range_geometry.par_dim
|
|
150
162
|
|
|
151
163
|
def _2fun(self, x, geometry, is_par):
|
|
@@ -466,28 +478,61 @@ class LinearModel(Model):
|
|
|
466
478
|
forward : 2D ndarray or callable function.
|
|
467
479
|
Forward operator.
|
|
468
480
|
|
|
469
|
-
adjoint :
|
|
481
|
+
adjoint : 2D ndarray or callable function. (optional if matrix is passed as forward)
|
|
470
482
|
|
|
471
483
|
range_geometry : integer or cuqi.geometry.Geometry (optional)
|
|
472
|
-
If integer is given a _DefaultGeometry is created with dimension of the integer.
|
|
484
|
+
If integer is given, a cuqi.geometry._DefaultGeometry is created with dimension of the integer.
|
|
473
485
|
|
|
474
486
|
domain_geometry : integer or cuqi.geometry.Geometry (optional)
|
|
475
|
-
If integer is given a _DefaultGeometry is created with dimension of the integer.
|
|
487
|
+
If integer is given, a cuqi.geometry._DefaultGeometry is created with dimension of the integer.
|
|
476
488
|
|
|
477
|
-
Attributes
|
|
478
|
-
-----------
|
|
479
|
-
range_geometry : cuqi.geometry.Geometry
|
|
480
|
-
The geometry representing the range.
|
|
481
489
|
|
|
482
|
-
|
|
483
|
-
|
|
490
|
+
:ivar range_geometry: The geometry representing the range.
|
|
491
|
+
:ivar domain_geometry: The geometry representing the domain.
|
|
484
492
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
:
|
|
490
|
-
|
|
493
|
+
Example
|
|
494
|
+
-------
|
|
495
|
+
|
|
496
|
+
Consider a linear model represented by a matrix, i.e., :math:`y=Ax` where
|
|
497
|
+
:math:`A` is a matrix.
|
|
498
|
+
|
|
499
|
+
We can define such a linear model by passing the matrix :math:`A`:
|
|
500
|
+
|
|
501
|
+
.. code-block:: python
|
|
502
|
+
|
|
503
|
+
import numpy as np
|
|
504
|
+
from cuqi.model import LinearModel
|
|
505
|
+
|
|
506
|
+
A = np.random.randn(2,3)
|
|
507
|
+
|
|
508
|
+
model = LinearModel(A)
|
|
509
|
+
|
|
510
|
+
The dimension of the range and domain geometries will be automatically
|
|
511
|
+
inferred from the matrix :math:`A`.
|
|
512
|
+
|
|
513
|
+
Meanwhile, such a linear model can also be defined by a forward function
|
|
514
|
+
and an adjoint function:
|
|
515
|
+
|
|
516
|
+
.. code-block:: python
|
|
517
|
+
|
|
518
|
+
import numpy as np
|
|
519
|
+
from cuqi.model import LinearModel
|
|
520
|
+
|
|
521
|
+
A = np.random.randn(2,3)
|
|
522
|
+
|
|
523
|
+
def forward(x):
|
|
524
|
+
return A@x
|
|
525
|
+
|
|
526
|
+
def adjoint(y):
|
|
527
|
+
return A.T@y
|
|
528
|
+
|
|
529
|
+
model = LinearModel(forward,
|
|
530
|
+
adjoint=adjoint,
|
|
531
|
+
range_geometry=2,
|
|
532
|
+
domain_geometry=3)
|
|
533
|
+
|
|
534
|
+
Note that you would need to specify the range and domain geometries in this
|
|
535
|
+
case as they cannot be inferred from the forward and adjoint functions.
|
|
491
536
|
"""
|
|
492
537
|
# Linear forward model with forward and adjoint (transpose).
|
|
493
538
|
|
|
@@ -552,6 +597,9 @@ class LinearModel(Model):
|
|
|
552
597
|
|
|
553
598
|
|
|
554
599
|
def get_matrix(self):
|
|
600
|
+
"""
|
|
601
|
+
Returns an ndarray with the matrix representing the forward operator.
|
|
602
|
+
"""
|
|
555
603
|
if self._matrix is not None: #Matrix exists so return it
|
|
556
604
|
return self._matrix
|
|
557
605
|
else:
|
|
@@ -594,24 +642,14 @@ class PDEModel(Model):
|
|
|
594
642
|
Forward operator assembling, solving and observing the pde.
|
|
595
643
|
|
|
596
644
|
range_geometry : integer or cuqi.geometry.Geometry (optional)
|
|
597
|
-
If integer is given a _DefaultGeometry is created with dimension of the integer.
|
|
645
|
+
If integer is given, a cuqi.geometry._DefaultGeometry is created with dimension of the integer.
|
|
598
646
|
|
|
599
647
|
domain_geometry : integer or cuqi.geometry.Geometry (optional)
|
|
600
|
-
If integer is given a _DefaultGeometry is created with dimension of the integer.
|
|
601
|
-
|
|
602
|
-
Attributes
|
|
603
|
-
-----------
|
|
604
|
-
range_geometry : cuqi.geometry.Geometry
|
|
605
|
-
The geometry representing the range.
|
|
648
|
+
If integer is given, a cuqi.geometry._DefaultGeometry is created with dimension of the integer.
|
|
606
649
|
|
|
607
|
-
domain_geometry : cuqi.geometry.Geometry
|
|
608
|
-
The geometry representing the domain.
|
|
609
650
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
:meth:`forward` the forward operator.
|
|
613
|
-
:meth:`range_dim` the dimension of the range.
|
|
614
|
-
:meth:`domain_dim` the dimension of the domain.
|
|
651
|
+
:ivar range_geometry: The geometry representing the range.
|
|
652
|
+
:ivar domain_geometry: The geometry representing the domain.
|
|
615
653
|
"""
|
|
616
654
|
def __init__(self, PDE: cuqi.pde.PDE, range_geometry, domain_geometry):
|
|
617
655
|
|
|
@@ -310,3 +310,86 @@ def test_MultipleLikelihoodPosterior_should_raise_if_names_do_not_match():
|
|
|
310
310
|
with pytest.raises(ValueError, match=r"the same parameter name"):
|
|
311
311
|
cuqi.distribution.MultipleLikelihoodPosterior(y.to_likelihood(1), x, z)
|
|
312
312
|
|
|
313
|
+
@pytest.mark.parametrize("joint, variables", [
|
|
314
|
+
(
|
|
315
|
+
cuqi.distribution.JointDistribution(
|
|
316
|
+
cuqi.distribution.Normal(0, 1, name="x"),
|
|
317
|
+
cuqi.distribution.Normal(0, 1, name="y")
|
|
318
|
+
),
|
|
319
|
+
{
|
|
320
|
+
"x": 0,
|
|
321
|
+
"y": 0
|
|
322
|
+
}
|
|
323
|
+
),
|
|
324
|
+
(
|
|
325
|
+
cuqi.distribution.JointDistribution(
|
|
326
|
+
cuqi.distribution.Uniform(0, 10, name="d"),
|
|
327
|
+
cuqi.distribution.Uniform(0, 5, name="s"),
|
|
328
|
+
cuqi.distribution.Gaussian(np.zeros(8), lambda d: d, name="x"),
|
|
329
|
+
cuqi.distribution.Gaussian(
|
|
330
|
+
mean=cuqi.testproblem.Deconvolution1D(dim=8).model,
|
|
331
|
+
cov=lambda s: s,
|
|
332
|
+
name="y"
|
|
333
|
+
)
|
|
334
|
+
),
|
|
335
|
+
{
|
|
336
|
+
"d": 5,
|
|
337
|
+
"s": 2,
|
|
338
|
+
"x": np.zeros(8),
|
|
339
|
+
"y": cuqi.testproblem.Deconvolution1D(dim=8).data
|
|
340
|
+
}
|
|
341
|
+
),
|
|
342
|
+
(
|
|
343
|
+
cuqi.distribution.JointDistribution(
|
|
344
|
+
cuqi.distribution.Uniform(0, 10, name="d"),
|
|
345
|
+
cuqi.distribution.Uniform(0, 5, name="s"),
|
|
346
|
+
cuqi.distribution.Gaussian(np.zeros(8), lambda d: d, name="x"),
|
|
347
|
+
cuqi.distribution.Gaussian(
|
|
348
|
+
mean=cuqi.testproblem.Deconvolution1D(dim=8).model,
|
|
349
|
+
cov=lambda s: s,
|
|
350
|
+
name="y"
|
|
351
|
+
)
|
|
352
|
+
),
|
|
353
|
+
{
|
|
354
|
+
"d": 11, # Out of bounds (all should return -Inf)
|
|
355
|
+
"s": 2,
|
|
356
|
+
"x": np.zeros(8),
|
|
357
|
+
"y": cuqi.testproblem.Deconvolution1D(dim=8).data
|
|
358
|
+
}
|
|
359
|
+
)
|
|
360
|
+
]
|
|
361
|
+
)
|
|
362
|
+
def test_logd_consistency_when_conditioning(joint, variables):
|
|
363
|
+
""" Test consistency of logd value when conditioning the joint distribution.
|
|
364
|
+
|
|
365
|
+
This ensures we always return the correct value for logd even when reducing to single density.
|
|
366
|
+
|
|
367
|
+
"""
|
|
368
|
+
|
|
369
|
+
# True value of logd by fully evaluating the joint distribution
|
|
370
|
+
true_value = joint.logd(**variables)
|
|
371
|
+
|
|
372
|
+
# Loop over all variables and evaluate the logd value
|
|
373
|
+
# where all previously seen variables are conditioned
|
|
374
|
+
# and not seen variables are given to logd.
|
|
375
|
+
cond_vars = {}
|
|
376
|
+
for key, value in variables.items():
|
|
377
|
+
# Remaining variables are those that are not used for conditioning
|
|
378
|
+
remaining_vars = {k: v for k, v in variables.items() if k not in cond_vars}
|
|
379
|
+
|
|
380
|
+
# Condition the joint distribution
|
|
381
|
+
cond_joint = joint(**cond_vars)
|
|
382
|
+
|
|
383
|
+
# Evaluate the logd value of conditioned joint distribution
|
|
384
|
+
# This may be a single density or a joint distribution since
|
|
385
|
+
# joint can reduce to single density (such as Posterior)
|
|
386
|
+
logd_value = cond_joint.logd(**remaining_vars)
|
|
387
|
+
|
|
388
|
+
# Potential error message if this assert fails:
|
|
389
|
+
msg = f"Evaluated: \n {joint} \n with variables {variables}.\nFailed at {key}={value} for \n {cond_joint} \n with variables {remaining_vars}."
|
|
390
|
+
|
|
391
|
+
# Assert the logd value matches
|
|
392
|
+
assert logd_value == pytest.approx(true_value, rel=1e-6), msg
|
|
393
|
+
|
|
394
|
+
# Add current variable to the variables that need to be conditioned
|
|
395
|
+
cond_vars[key] = value
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/cuqi/distribution/_modifiedhalfnormal.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
|
{cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/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.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/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
|
|
File without changes
|
{cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/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
|
|
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.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/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
|
|
File without changes
|
{cuqipy-1.1.0.post0.dev39 → cuqipy-1.1.1.post0.dev5}/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
|