CUQIpy 1.3.0.post0.dev70__tar.gz → 1.3.0.post0.dev104__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.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/CUQIpy.egg-info/PKG-INFO +3 -2
- cuqipy-1.3.0.post0.dev104/CUQIpy.egg-info/requires.txt +10 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/PKG-INFO +3 -2
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/_version.py +3 -3
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_truncated_normal.py +1 -1
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_uniform.py +1 -1
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/_rto.py +23 -15
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/implicitprior/_regularizedGaussian.py +8 -2
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/solver/_solver.py +6 -2
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/utilities/_utilities.py +1 -1
- cuqipy-1.3.0.post0.dev104/requirements.txt +6 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_bayesian_inversion.py +10 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_implicit_priors.py +3 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_model.py +1 -1
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_solver.py +12 -4
- cuqipy-1.3.0.post0.dev70/CUQIpy.egg-info/requires.txt +0 -5
- cuqipy-1.3.0.post0.dev70/requirements.txt +0 -5
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/CUQIpy.egg-info/SOURCES.txt +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/CUQIpy.egg-info/dependency_links.txt +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/CUQIpy.egg-info/top_level.txt +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/LICENSE +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/README.md +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/_messages.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/array/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/array/_array.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/config.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/data/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/data/_data.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/data/astronaut.npz +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/data/camera.npz +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/data/cat.npz +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/data/cookie.png +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/data/satellite.mat +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/density/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/density/_density.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/diagnostics.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_beta.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_cauchy.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_cmrf.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_custom.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_distribution.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_gamma.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_gaussian.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_gmrf.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_inverse_gamma.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_joint_distribution.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_laplace.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_lmrf.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_lognormal.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_modifiedhalfnormal.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_normal.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_posterior.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_smoothed_laplace.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/algebra/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/algebra/_ast.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/algebra/_orderedset.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/algebra/_randomvariable.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/geometry/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/geometry/_productgeometry.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/_conjugate.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/_conjugate_approx.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/_cwmh.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/_direct.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/_gibbs.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/_hmc.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/_langevin_algorithm.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/_laplace_approximation.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/_mh.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/_pcn.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/_sampler.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/_utilities.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/geometry/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/geometry/_geometry.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/implicitprior/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/implicitprior/_regularizedGMRF.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/implicitprior/_regularizedUnboundedUniform.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/implicitprior/_restorator.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/likelihood/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/likelihood/_likelihood.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/model/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/model/_model.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/operator/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/operator/_operator.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/pde/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/pde/_pde.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/problem/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/problem/_problem.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/sampler/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/sampler/_conjugate.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/sampler/_conjugate_approx.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/sampler/_cwmh.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/sampler/_gibbs.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/sampler/_hmc.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/sampler/_langevin_algorithm.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/sampler/_laplace_approximation.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/sampler/_mh.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/sampler/_pcn.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/sampler/_rto.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/sampler/_sampler.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/samples/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/samples/_samples.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/solver/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/testproblem/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/testproblem/_testproblem.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/utilities/__init__.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/utilities/_get_python_variable_name.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/pyproject.toml +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/setup.cfg +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/setup.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_MRFs.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_abstract_distribution_density.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_density.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_distribution.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_distributions_shape.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_geometry.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_joint_distribution.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_likelihood.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_pde.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_posterior.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_problem.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_sampler.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_samples.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_testproblem.py +0 -0
- {cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/tests/test_utilities.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: CUQIpy
|
|
3
|
-
Version: 1.3.0.post0.
|
|
3
|
+
Version: 1.3.0.post0.dev104
|
|
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
|
|
@@ -202,7 +202,8 @@ Description-Content-Type: text/markdown
|
|
|
202
202
|
License-File: LICENSE
|
|
203
203
|
Requires-Dist: matplotlib
|
|
204
204
|
Requires-Dist: numpy>=1.17.0
|
|
205
|
-
Requires-Dist: scipy
|
|
205
|
+
Requires-Dist: scipy==1.12.0; python_version <= "3.9"
|
|
206
|
+
Requires-Dist: scipy; python_version > "3.9"
|
|
206
207
|
Requires-Dist: arviz
|
|
207
208
|
Requires-Dist: tqdm
|
|
208
209
|
Dynamic: license-file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: CUQIpy
|
|
3
|
-
Version: 1.3.0.post0.
|
|
3
|
+
Version: 1.3.0.post0.dev104
|
|
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
|
|
@@ -202,7 +202,8 @@ Description-Content-Type: text/markdown
|
|
|
202
202
|
License-File: LICENSE
|
|
203
203
|
Requires-Dist: matplotlib
|
|
204
204
|
Requires-Dist: numpy>=1.17.0
|
|
205
|
-
Requires-Dist: scipy
|
|
205
|
+
Requires-Dist: scipy==1.12.0; python_version <= "3.9"
|
|
206
|
+
Requires-Dist: scipy; python_version > "3.9"
|
|
206
207
|
Requires-Dist: arviz
|
|
207
208
|
Requires-Dist: tqdm
|
|
208
209
|
Dynamic: license-file
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2025-04-
|
|
11
|
+
"date": "2025-04-28T12:59:25+0200",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "1.3.0.post0.
|
|
14
|
+
"full-revisionid": "c62aed4105837bc321e7e325f1b1a2286c659b2f",
|
|
15
|
+
"version": "1.3.0.post0.dev104"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
{cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_truncated_normal.py
RENAMED
|
@@ -107,7 +107,7 @@ class TruncatedNormal(Distribution):
|
|
|
107
107
|
"""
|
|
108
108
|
# check if x falls in the range between np.array a and b
|
|
109
109
|
if np.any(x < self.low) or np.any(x > self.high):
|
|
110
|
-
return np.
|
|
110
|
+
return np.nan*np.ones_like(x)
|
|
111
111
|
else:
|
|
112
112
|
return self._normal.gradient(x, *args, **kwargs)
|
|
113
113
|
|
|
@@ -3,7 +3,7 @@ from scipy.linalg.interpolative import estimate_spectral_norm
|
|
|
3
3
|
from scipy.sparse.linalg import LinearOperator as scipyLinearOperator
|
|
4
4
|
import numpy as np
|
|
5
5
|
import cuqi
|
|
6
|
-
from cuqi.solver import CGLS, FISTA, ADMM, ScipyLinearLSQ
|
|
6
|
+
from cuqi.solver import CGLS, FISTA, ADMM, ScipyLinearLSQ, ScipyMinimizer
|
|
7
7
|
from cuqi.experimental.mcmc import Sampler
|
|
8
8
|
|
|
9
9
|
|
|
@@ -167,6 +167,7 @@ class RegularizedLinearRTO(LinearRTO):
|
|
|
167
167
|
ADMM: [2] Boyd et al. "Distributed optimization and statistical learning via the alternating direction method of multipliers."Foundations and Trends® in Machine learning, 2011.
|
|
168
168
|
Used when prior.proximal is a list of penalty terms.
|
|
169
169
|
ScipyLinearLSQ: Wrapper for Scipy's lsq_linear for the Trust Region Reflective algorithm. Optionally used when the constraint is either "nonnegativity" or "box".
|
|
170
|
+
ScipyMinimizer: Wrapper for Scipy's minimize. Optionally used when the constraint is either "nonnegativity" or "box".
|
|
170
171
|
|
|
171
172
|
Parameters
|
|
172
173
|
------------
|
|
@@ -177,7 +178,7 @@ class RegularizedLinearRTO(LinearRTO):
|
|
|
177
178
|
Initial point for the sampler. *Optional*.
|
|
178
179
|
|
|
179
180
|
maxit : int
|
|
180
|
-
Maximum number of iterations of the FISTA/ADMM/ScipyLinearLSQ solver. *Optional*.
|
|
181
|
+
Maximum number of iterations of the FISTA/ADMM/ScipyLinearLSQ/ScipyMinimizer solver. *Optional*.
|
|
181
182
|
|
|
182
183
|
inner_max_it : int
|
|
183
184
|
Maximum number of iterations of the CGLS solver used within the ADMM solver. *Optional*.
|
|
@@ -191,7 +192,7 @@ class RegularizedLinearRTO(LinearRTO):
|
|
|
191
192
|
See [2] or `cuqi.solver.ADMM`
|
|
192
193
|
|
|
193
194
|
abstol : float
|
|
194
|
-
Absolute tolerance of the FISTA/ScipyLinearLSQ solver. *Optional*.
|
|
195
|
+
Absolute tolerance of the FISTA/ScipyLinearLSQ/ScipyMinimizer solver. *Optional*.
|
|
195
196
|
|
|
196
197
|
inner_abstol : float
|
|
197
198
|
Tolerance parameter for ScipyLinearLSQ's inner solve of the unbounded least-squares problem. *Optional*.
|
|
@@ -200,7 +201,7 @@ class RegularizedLinearRTO(LinearRTO):
|
|
|
200
201
|
If True, FISTA is used as solver, otherwise ISTA is used. *Optional*.
|
|
201
202
|
|
|
202
203
|
solver : string
|
|
203
|
-
|
|
204
|
+
Options are "FISTA" (default for a single constraint or regularization), "ADMM" (default and the only option for multiple constraints or regularizations), "ScipyLinearLSQ" and "ScipyMinimizer". Note "ScipyLinearLSQ" and "ScipyMinimizer" can only be used with `RegularizedGaussian` of a single `box` or `nonnegativity` constraint. *Optional*.
|
|
204
205
|
|
|
205
206
|
callback : callable, optional
|
|
206
207
|
A function that will be called after each sampling step. It can be useful for monitoring the sampler during sampling.
|
|
@@ -234,11 +235,11 @@ class RegularizedLinearRTO(LinearRTO):
|
|
|
234
235
|
|
|
235
236
|
@solver.setter
|
|
236
237
|
def solver(self, value):
|
|
237
|
-
if value == "ScipyLinearLSQ":
|
|
238
|
+
if value == "ScipyLinearLSQ" or value == "ScipyMinimizer":
|
|
238
239
|
if (self.target.prior.preset["constraint"] == "nonnegativity" or self.target.prior.preset["constraint"] == "box"):
|
|
239
240
|
self._solver = value
|
|
240
241
|
else:
|
|
241
|
-
raise ValueError("ScipyLinearLSQ only
|
|
242
|
+
raise ValueError("ScipyLinearLSQ and ScipyMinimizer only support RegularizedGaussian with box or nonnegativity constraint.")
|
|
242
243
|
else:
|
|
243
244
|
self._solver = value
|
|
244
245
|
|
|
@@ -281,15 +282,22 @@ class RegularizedLinearRTO(LinearRTO):
|
|
|
281
282
|
sim = ADMM(self.M, y, self.proximal,
|
|
282
283
|
self.current_point, self.penalty_parameter, maxit = self.maxit, inner_max_it = self.inner_max_it, adaptive = self.adaptive)
|
|
283
284
|
elif self.solver == "ScipyLinearLSQ":
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
285
|
+
A_op = sp.sparse.linalg.LinearOperator((sum([llh.distribution.dim for llh in self.likelihoods])+self.target.prior.dim, self.target.prior.dim),
|
|
286
|
+
matvec=lambda x: self.M(x, 1),
|
|
287
|
+
rmatvec=lambda x: self.M(x, 2)
|
|
288
|
+
)
|
|
289
|
+
sim = ScipyLinearLSQ(A_op, y, self.target.prior._box_bounds,
|
|
290
|
+
max_iter = self.maxit,
|
|
291
|
+
lsmr_maxiter = self.inner_max_it,
|
|
292
|
+
tol = self.abstol,
|
|
293
|
+
lsmr_tol = self.inner_abstol)
|
|
294
|
+
elif self.solver == "ScipyMinimizer":
|
|
295
|
+
# Adapt bounds format, as scipy.minimize requires a bounds format
|
|
296
|
+
# different than that in scipy.lsq_linear.
|
|
297
|
+
bounds = [(self.target.prior._box_bounds[0][i], self.target.prior._box_bounds[1][i]) for i in range(self.target.prior.dim)]
|
|
298
|
+
# Note that the objective function is defined as 0.5*||Mx-y||^2,
|
|
299
|
+
# and the corresponding gradient (gradfunc) is given by M^T(Mx-y).
|
|
300
|
+
sim = ScipyMinimizer(lambda x: 0.5*np.sum((self.M(x, 1)-y)**2), self.current_point, gradfunc=lambda x: self.M(self.M(x, 1) - y, 2), bounds=bounds, tol=self.abstol, options={"maxiter": self.maxit})
|
|
293
301
|
else:
|
|
294
302
|
raise ValueError("Choice of solver not supported.")
|
|
295
303
|
|
{cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/implicitprior/_regularizedGaussian.py
RENAMED
|
@@ -189,12 +189,18 @@ class RegularizedGaussian(Distribution):
|
|
|
189
189
|
elif c_lower == "increasing":
|
|
190
190
|
if not isinstance(self.geometry, Continuous1D):
|
|
191
191
|
raise ValueError("Geometry not supported for " + c_lower)
|
|
192
|
-
|
|
192
|
+
if hasattr(spoptimize, 'isotonic_regression'):
|
|
193
|
+
self._constraint_prox = lambda z, _: spoptimize.isotonic_regression(z, increasing=True).x
|
|
194
|
+
else:
|
|
195
|
+
raise AttributeError(f"The function 'isotonic_regression' does not exist in scipy.optimize. Installed scipy version: {spoptimize.__version__}. You need to install a scipy >= 1.12.0")
|
|
193
196
|
self._preset["constraint"] = "increasing"
|
|
194
197
|
elif c_lower == "decreasing":
|
|
195
198
|
if not isinstance(self.geometry, Continuous1D):
|
|
196
199
|
raise ValueError("Geometry not supported for " + c_lower)
|
|
197
|
-
|
|
200
|
+
if hasattr(spoptimize, 'isotonic_regression'):
|
|
201
|
+
self._constraint_prox = lambda z, _: spoptimize.isotonic_regression(z, increasing=False).x
|
|
202
|
+
else:
|
|
203
|
+
raise AttributeError(f"The function 'isotonic_regression' does not exist in scipy.optimize. Installed scipy version: {spoptimize.__version__}. You need to install a scipy >= 1.12.0")
|
|
198
204
|
self._preset["constraint"] = "decreasing"
|
|
199
205
|
elif c_lower == "convex":
|
|
200
206
|
if not isinstance(self.geometry, Continuous1D):
|
|
@@ -196,8 +196,11 @@ class ScipyLSQ(object):
|
|
|
196
196
|
'trf', Trust Region Reflective algorithm: for large sparse problems with bounds.
|
|
197
197
|
'dogbox', dogleg algorithm with rectangular trust regions, for small problems with bounds.
|
|
198
198
|
'lm', Levenberg-Marquardt algorithm as implemented in MINPACK. Doesn't handle bounds and sparse Jacobians.
|
|
199
|
+
tol : The numerical tolerance for convergence checks.
|
|
200
|
+
maxit : The maximum number of iterations.
|
|
201
|
+
kwargs : Additional keyword arguments passed to scipy's least_squares. Empty by default. See documentation for scipy.optimize.least_squares
|
|
199
202
|
"""
|
|
200
|
-
def __init__(self, func, x0, jacfun='2-point', method='trf', loss='linear', tol=1e-6, maxit=1e4):
|
|
203
|
+
def __init__(self, func, x0, jacfun='2-point', method='trf', loss='linear', tol=1e-6, maxit=1e4, **kwargs):
|
|
201
204
|
self.func = func
|
|
202
205
|
self.x0 = x0
|
|
203
206
|
self.jacfun = jacfun
|
|
@@ -205,6 +208,7 @@ class ScipyLSQ(object):
|
|
|
205
208
|
self.loss = loss
|
|
206
209
|
self.tol = tol
|
|
207
210
|
self.maxit = int(maxit)
|
|
211
|
+
self.kwargs = kwargs
|
|
208
212
|
|
|
209
213
|
def solve(self):
|
|
210
214
|
"""Runs optimization algorithm and returns solution and info.
|
|
@@ -215,7 +219,7 @@ class ScipyLSQ(object):
|
|
|
215
219
|
Solution found (array_like) and optimization information (dictionary).
|
|
216
220
|
"""
|
|
217
221
|
solution = least_squares(self.func, self.x0, jac=self.jacfun, \
|
|
218
|
-
method=self.method, loss=self.loss, xtol=self.tol, max_nfev=self.maxit)
|
|
222
|
+
method=self.method, loss=self.loss, xtol=self.tol, max_nfev=self.maxit, **self.kwargs)
|
|
219
223
|
info = {"success": solution['success'],
|
|
220
224
|
"message": solution['message'],
|
|
221
225
|
"func": solution['fun'],
|
|
@@ -188,7 +188,7 @@ def approx_derivative(func, wrt, direction=None, epsilon=np.sqrt(np.finfo(float)
|
|
|
188
188
|
# We compute the Jacobian matrix of func using forward differences.
|
|
189
189
|
# If the function is scalar-valued, we compute the gradient instead.
|
|
190
190
|
# If the direction is provided, we compute the direction-Jacobian product.
|
|
191
|
-
wrt = np.
|
|
191
|
+
wrt = np.asarray(wrt)
|
|
192
192
|
f0 = func(wrt)
|
|
193
193
|
Matr = np.zeros([infer_len(wrt), infer_len(f0)])
|
|
194
194
|
dx = np.zeros(len(wrt))
|
|
@@ -2,7 +2,9 @@ from typing import Dict
|
|
|
2
2
|
|
|
3
3
|
import pytest
|
|
4
4
|
import numpy as np
|
|
5
|
+
import scipy
|
|
5
6
|
import sys
|
|
7
|
+
from packaging import version
|
|
6
8
|
|
|
7
9
|
from cuqi.testproblem import Deconvolution1D
|
|
8
10
|
from cuqi.distribution import Gaussian, GMRF, CMRF, LMRF, Gamma
|
|
@@ -25,6 +27,14 @@ def test_TP_BayesianProblem_sample(copy_reference, TP_type, phantom, prior, Ns,
|
|
|
25
27
|
# SKIP NUTS test if not windows (for now)
|
|
26
28
|
if isinstance(prior, CMRF) and not sys.platform.startswith('win'):
|
|
27
29
|
pytest.skip("NUTS(CMRF) regression test is not implemented for this platform")
|
|
30
|
+
elif (
|
|
31
|
+
isinstance(prior, RegularizedGaussian)
|
|
32
|
+
or isinstance(prior, RegularizedGMRF)
|
|
33
|
+
) and version.parse(scipy.__version__) >= version.parse('1.13.0'):
|
|
34
|
+
pytest.skip(
|
|
35
|
+
"Saved reference data is not consistent with scipy>=1.13.0 "
|
|
36
|
+
"(due to different default behaviour of scipy.optimize)"
|
|
37
|
+
)
|
|
28
38
|
|
|
29
39
|
np.random.seed(19937)
|
|
30
40
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import cuqi
|
|
2
2
|
import numpy as np
|
|
3
|
+
import scipy
|
|
3
4
|
import pytest
|
|
5
|
+
from packaging import version
|
|
4
6
|
|
|
5
7
|
def test_RegularizedGaussian_default_init():
|
|
6
8
|
""" Test that the implicit regularized Gaussian requires at least 1 regularization argument """
|
|
@@ -186,6 +188,7 @@ def test_RegularizedGaussian_double_preset():
|
|
|
186
188
|
assert len(x.proximal[0]) == 2
|
|
187
189
|
assert len(x.proximal[1]) == 2
|
|
188
190
|
|
|
191
|
+
@pytest.mark.skipif(version.parse(scipy.__version__) < version.parse('1.12.0'), reason="isotonic_regression in not available in scipy < 1.12.0")
|
|
189
192
|
def test_regression_increasing():
|
|
190
193
|
""" Regression test for the increasing constraints in RegularizedGaussian"""
|
|
191
194
|
|
|
@@ -19,7 +19,7 @@ def test_LinearModel_getMatrix(seed):
|
|
|
19
19
|
mat1 = model1.get_matrix() #Normal matrix
|
|
20
20
|
mat2 = model2.get_matrix() #Sparse matrix (generated from functions)
|
|
21
21
|
|
|
22
|
-
assert np.allclose(mat1,mat2.
|
|
22
|
+
assert np.allclose(mat1,mat2.toarray())
|
|
23
23
|
|
|
24
24
|
def test_initialize_model_dim():
|
|
25
25
|
model1 = cuqi.model.Model(lambda x:x, range_geometry=4, domain_geometry=4)
|
|
@@ -100,19 +100,27 @@ def test_ScipyLinearLSQ_with_LinearOperator():
|
|
|
100
100
|
sol, _ = ScipyLinearLSQ(A_op, b).solve()
|
|
101
101
|
assert np.allclose(sol, ref_sol, rtol=1e-10)
|
|
102
102
|
|
|
103
|
-
def
|
|
103
|
+
def test_ScipyLinearLSQ_against_ScipyMinimizer_and_against_FISTA():
|
|
104
104
|
A = np.array([[73,71,52],[87,74,46],[72,2,7],[80,89,71]])
|
|
105
105
|
b = np.array([49,67,68,20])
|
|
106
|
+
|
|
107
|
+
# solve with ScipyMinimizer
|
|
108
|
+
def fun(x):
|
|
109
|
+
return 0.5*np.linalg.norm(A@x-b)**2
|
|
110
|
+
def jac(x):
|
|
111
|
+
return A.T@(A@x-b)
|
|
112
|
+
sol_min, _ = ScipyMinimizer(fun, np.zeros(3), gradfunc=jac, tol=1e-10, bounds=[(0,np.inf),(0,np.inf),(0,np.inf)]).solve()
|
|
113
|
+
|
|
106
114
|
# solve with ScipyLinearLSQ
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
sol_lsq, _ = ScipyLinearLSQ(A, b, (lb,ub)).solve()
|
|
115
|
+
sol_lsq, _ = ScipyLinearLSQ(A, b, ([0,0,0],[np.inf,np.inf,np.inf]), tol=1e-10).solve()
|
|
116
|
+
|
|
110
117
|
# solve with FISTA
|
|
111
118
|
rng = np.random.default_rng(seed = 1219)
|
|
112
119
|
x0 = rng.standard_normal(3)
|
|
113
120
|
sol_fista, _ = FISTA(A, b, lambda x, _: ProjectNonnegative(x), x0, stepsize=1e-7, maxit=100000, abstol=1e-16, adaptive=True).solve()
|
|
114
121
|
|
|
115
122
|
assert np.allclose(sol_lsq, sol_fista, rtol=1e-8)
|
|
123
|
+
assert np.allclose(sol_min, sol_lsq, rtol=1e-8)
|
|
116
124
|
|
|
117
125
|
def test_LM():
|
|
118
126
|
# compare to MATLAB's original code solution
|
|
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.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_joint_distribution.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_modifiedhalfnormal.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/distribution/_smoothed_laplace.py
RENAMED
|
File without changes
|
|
File without changes
|
{cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/algebra/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/algebra/_orderedset.py
RENAMED
|
File without changes
|
{cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/algebra/_randomvariable.py
RENAMED
|
File without changes
|
{cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/geometry/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/experimental/mcmc/_conjugate_approx.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/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
|
{cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/implicitprior/_regularizedGMRF.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
|
{cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/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
|
{cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/cuqi/utilities/_get_python_variable_name.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuqipy-1.3.0.post0.dev70 → cuqipy-1.3.0.post0.dev104}/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
|