CUQIpy 1.1.1.post0.dev36__py3-none-any.whl → 1.4.1.post0.dev124__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of CUQIpy might be problematic. Click here for more details.

Files changed (92) hide show
  1. cuqi/__init__.py +2 -0
  2. cuqi/_version.py +3 -3
  3. cuqi/algebra/__init__.py +2 -0
  4. cuqi/algebra/_abstract_syntax_tree.py +358 -0
  5. cuqi/algebra/_ordered_set.py +82 -0
  6. cuqi/algebra/_random_variable.py +457 -0
  7. cuqi/array/_array.py +4 -13
  8. cuqi/config.py +7 -0
  9. cuqi/density/_density.py +9 -1
  10. cuqi/distribution/__init__.py +3 -2
  11. cuqi/distribution/_beta.py +7 -11
  12. cuqi/distribution/_cauchy.py +2 -2
  13. cuqi/distribution/_custom.py +0 -6
  14. cuqi/distribution/_distribution.py +31 -45
  15. cuqi/distribution/_gamma.py +7 -3
  16. cuqi/distribution/_gaussian.py +2 -12
  17. cuqi/distribution/_inverse_gamma.py +4 -10
  18. cuqi/distribution/_joint_distribution.py +112 -15
  19. cuqi/distribution/_lognormal.py +0 -7
  20. cuqi/distribution/{_modifiedhalfnormal.py → _modified_half_normal.py} +23 -23
  21. cuqi/distribution/_normal.py +34 -7
  22. cuqi/distribution/_posterior.py +9 -0
  23. cuqi/distribution/_truncated_normal.py +129 -0
  24. cuqi/distribution/_uniform.py +47 -1
  25. cuqi/experimental/__init__.py +2 -2
  26. cuqi/experimental/_recommender.py +216 -0
  27. cuqi/geometry/__init__.py +2 -0
  28. cuqi/geometry/_geometry.py +15 -1
  29. cuqi/geometry/_product_geometry.py +181 -0
  30. cuqi/implicitprior/__init__.py +5 -3
  31. cuqi/implicitprior/_regularized_gaussian.py +483 -0
  32. cuqi/implicitprior/{_regularizedGMRF.py → _regularized_gmrf.py} +4 -2
  33. cuqi/implicitprior/{_regularizedUnboundedUniform.py → _regularized_unbounded_uniform.py} +3 -2
  34. cuqi/implicitprior/_restorator.py +269 -0
  35. cuqi/legacy/__init__.py +2 -0
  36. cuqi/{experimental/mcmc → legacy/sampler}/__init__.py +7 -11
  37. cuqi/legacy/sampler/_conjugate.py +55 -0
  38. cuqi/legacy/sampler/_conjugate_approx.py +52 -0
  39. cuqi/legacy/sampler/_cwmh.py +196 -0
  40. cuqi/legacy/sampler/_gibbs.py +231 -0
  41. cuqi/legacy/sampler/_hmc.py +335 -0
  42. cuqi/{experimental/mcmc → legacy/sampler}/_langevin_algorithm.py +82 -111
  43. cuqi/legacy/sampler/_laplace_approximation.py +184 -0
  44. cuqi/legacy/sampler/_mh.py +190 -0
  45. cuqi/legacy/sampler/_pcn.py +244 -0
  46. cuqi/{experimental/mcmc → legacy/sampler}/_rto.py +132 -90
  47. cuqi/legacy/sampler/_sampler.py +182 -0
  48. cuqi/likelihood/_likelihood.py +9 -1
  49. cuqi/model/__init__.py +1 -1
  50. cuqi/model/_model.py +1361 -359
  51. cuqi/pde/__init__.py +4 -0
  52. cuqi/pde/_observation_map.py +36 -0
  53. cuqi/pde/_pde.py +134 -33
  54. cuqi/problem/_problem.py +93 -87
  55. cuqi/sampler/__init__.py +120 -8
  56. cuqi/sampler/_conjugate.py +376 -35
  57. cuqi/sampler/_conjugate_approx.py +40 -16
  58. cuqi/sampler/_cwmh.py +132 -138
  59. cuqi/{experimental/mcmc → sampler}/_direct.py +1 -1
  60. cuqi/sampler/_gibbs.py +288 -130
  61. cuqi/sampler/_hmc.py +328 -201
  62. cuqi/sampler/_langevin_algorithm.py +284 -100
  63. cuqi/sampler/_laplace_approximation.py +87 -117
  64. cuqi/sampler/_mh.py +47 -157
  65. cuqi/sampler/_pcn.py +65 -213
  66. cuqi/sampler/_rto.py +211 -142
  67. cuqi/sampler/_sampler.py +553 -136
  68. cuqi/samples/__init__.py +1 -1
  69. cuqi/samples/_samples.py +24 -18
  70. cuqi/solver/__init__.py +6 -4
  71. cuqi/solver/_solver.py +230 -26
  72. cuqi/testproblem/_testproblem.py +2 -3
  73. cuqi/utilities/__init__.py +6 -1
  74. cuqi/utilities/_get_python_variable_name.py +2 -2
  75. cuqi/utilities/_utilities.py +182 -2
  76. {CUQIpy-1.1.1.post0.dev36.dist-info → cuqipy-1.4.1.post0.dev124.dist-info}/METADATA +10 -6
  77. cuqipy-1.4.1.post0.dev124.dist-info/RECORD +101 -0
  78. {CUQIpy-1.1.1.post0.dev36.dist-info → cuqipy-1.4.1.post0.dev124.dist-info}/WHEEL +1 -1
  79. CUQIpy-1.1.1.post0.dev36.dist-info/RECORD +0 -92
  80. cuqi/experimental/mcmc/_conjugate.py +0 -197
  81. cuqi/experimental/mcmc/_conjugate_approx.py +0 -81
  82. cuqi/experimental/mcmc/_cwmh.py +0 -191
  83. cuqi/experimental/mcmc/_gibbs.py +0 -268
  84. cuqi/experimental/mcmc/_hmc.py +0 -470
  85. cuqi/experimental/mcmc/_laplace_approximation.py +0 -156
  86. cuqi/experimental/mcmc/_mh.py +0 -78
  87. cuqi/experimental/mcmc/_pcn.py +0 -89
  88. cuqi/experimental/mcmc/_sampler.py +0 -561
  89. cuqi/experimental/mcmc/_utilities.py +0 -17
  90. cuqi/implicitprior/_regularizedGaussian.py +0 -323
  91. {CUQIpy-1.1.1.post0.dev36.dist-info → cuqipy-1.4.1.post0.dev124.dist-info/licenses}/LICENSE +0 -0
  92. {CUQIpy-1.1.1.post0.dev36.dist-info → cuqipy-1.4.1.post0.dev124.dist-info}/top_level.txt +0 -0
@@ -1,323 +0,0 @@
1
- from cuqi.utilities import get_non_default_args
2
- from cuqi.distribution import Distribution, Gaussian
3
- from cuqi.solver import ProjectNonnegative, ProjectBox, ProximalL1
4
-
5
- import numpy as np
6
-
7
-
8
- class RegularizedGaussian(Distribution):
9
- """ Implicit Regularized Gaussian.
10
-
11
- Defines a so-called implicit prior based on a Gaussian distribution with implicit regularization.
12
- The regularization can be defined in the form of a proximal operator or a projector.
13
- Alternatively, preset constraints and regularization can be used.
14
-
15
- Precisely one of proximal, projector, constraint or regularization needs to be provided. Otherwise, an error is raised.
16
-
17
- Can be used as a prior in a posterior which can be sampled with the RegularizedLinearRTO sampler.
18
-
19
-
20
- For more details on implicit regularized Gaussian see the following paper:
21
-
22
- [1] Everink, Jasper M., Yiqiu Dong, and Martin S. Andersen. "Sparse Bayesian inference with regularized
23
- Gaussian distributions." Inverse Problems 39.11 (2023): 115004.
24
-
25
- Parameters
26
- ----------
27
- mean
28
- See :class:`~cuqi.distribution.Gaussian` for details.
29
-
30
- cov
31
- See :class:`~cuqi.distribution.Gaussian` for details.
32
-
33
- prec
34
- See :class:`~cuqi.distribution.Gaussian` for details.
35
-
36
- sqrtcov
37
- See :class:`~cuqi.distribution.Gaussian` for details.
38
-
39
- sqrtprec
40
- See :class:`~cuqi.distribution.Gaussian` for details.
41
-
42
- proximal : callable f(x, scale) or None
43
- Euclidean proximal operator f of the regularization function g, that is, a solver for the optimization problem
44
- min_z 0.5||x-z||_2^2+scale*g(x).
45
-
46
-
47
- projector : callable f(x) or None
48
- Euclidean projection onto the constraint C, that is, a solver for the optimization problem
49
- min_(z in C) 0.5||x-z||_2^2.
50
-
51
- constraint : string or None
52
- Preset constraints. Can be set to "nonnegativity" and "box". Required for use in Gibbs.
53
- For "box", the following additional parameters can be passed:
54
- lower_bound : array_like or None
55
- Lower bound of box, defaults to zero
56
- upper_bound : array_like
57
- Upper bound of box, defaults to one
58
-
59
- regularization : string or None
60
- Preset regularization. Can be set to "l1". Required for use in Gibbs in future update.
61
- For "l1", the following additional parameters can be passed:
62
- strength : scalar
63
- Regularization parameter, i.e., strength*||x||_1 , defaults to one
64
-
65
- """
66
-
67
- def __init__(self, mean=None, cov=None, prec=None, sqrtcov=None, sqrtprec=None, proximal = None, projector = None, constraint = None, regularization = None, **kwargs):
68
-
69
- # Store regularization parameters and remove them from kwargs passed to Gaussian
70
- optional_regularization_parameters = {
71
- "lower_bound" : kwargs.pop("lower_bound", None), # Takes default of ProjectBox if None
72
- "upper_bound" : kwargs.pop("upper_bound", None), # Takes default of ProjectBox if None
73
- "strength" : kwargs.pop("strength", 1)
74
- }
75
-
76
- # We init the underlying Gaussian first for geometry and dimensionality handling
77
- self._gaussian = Gaussian(mean=mean, cov=cov, prec=prec, sqrtcov=sqrtcov, sqrtprec=sqrtprec, **kwargs)
78
-
79
- # Init from abstract distribution class
80
- super().__init__(**kwargs)
81
-
82
- self._parse_regularization_input_arguments(proximal, projector, constraint, regularization, optional_regularization_parameters)
83
-
84
- def _parse_regularization_input_arguments(self, proximal, projector, constraint, regularization, optional_regularization_parameters):
85
- """ Parse regularization input arguments with guarding statements and store internal states """
86
-
87
- # Check that only one of proximal, projector, constraint or regularization is provided
88
- if (proximal is not None) + (projector is not None) + (constraint is not None) + (regularization is not None) != 1:
89
- raise ValueError("Precisely one of proximal, projector, constraint or regularization needs to be provided.")
90
-
91
- if proximal is not None:
92
- if not callable(proximal):
93
- raise ValueError("Proximal needs to be callable.")
94
- if len(get_non_default_args(proximal)) != 2:
95
- raise ValueError("Proximal should take 2 arguments.")
96
-
97
- if projector is not None:
98
- if not callable(projector):
99
- raise ValueError("Projector needs to be callable.")
100
- if len(get_non_default_args(projector)) != 1:
101
- raise ValueError("Projector should take 1 argument.")
102
-
103
- # Preset information, for use in Gibbs
104
- self._preset = None
105
-
106
- if proximal is not None:
107
- self._proximal = proximal
108
- elif projector is not None:
109
- self._proximal = lambda z, gamma: projector(z)
110
- elif (isinstance(constraint, str) and constraint.lower() == "nonnegativity"):
111
- self._proximal = lambda z, gamma: ProjectNonnegative(z)
112
- self._preset = "nonnegativity"
113
- elif (isinstance(constraint, str) and constraint.lower() == "box"):
114
- lower = optional_regularization_parameters["lower_bound"]
115
- upper = optional_regularization_parameters["upper_bound"]
116
- self._proximal = lambda z, gamma: ProjectBox(z, lower, upper)
117
- self._preset = "box" # Not supported in Gibbs
118
- elif (isinstance(regularization, str) and regularization.lower() in ["l1"]):
119
- strength = optional_regularization_parameters["strength"]
120
- self._proximal = lambda z, gamma: ProximalL1(z, gamma*strength)
121
- self._preset = "l1"
122
- else:
123
- raise ValueError("Regularization not supported")
124
-
125
- # This is a getter only attribute for the underlying Gaussian
126
- # It also ensures that the name of the underlying Gaussian
127
- # matches the name of the implicit regularized Gaussian
128
- @property
129
- def gaussian(self):
130
- if self._name is not None:
131
- self._gaussian._name = self._name
132
- return self._gaussian
133
-
134
- @property
135
- def proximal(self):
136
- return self._proximal
137
-
138
- @property
139
- def preset(self):
140
- return self._preset
141
-
142
- def logpdf(self, x):
143
- return np.nan
144
- #raise ValueError(
145
- # f"The logpdf of a implicit regularized Gaussian is not be defined.")
146
-
147
- def _sample(self, N, rng=None):
148
- raise ValueError(
149
- "Cannot be sampled from.")
150
-
151
- @staticmethod
152
- def constraint_options():
153
- return ["nonnegativity", "box"]
154
-
155
- @staticmethod
156
- def regularization_options():
157
- return ["l1"]
158
-
159
-
160
- # --- Defer behavior of the underlying Gaussian --- #
161
- @property
162
- def geometry(self):
163
- return self.gaussian.geometry
164
-
165
- @geometry.setter
166
- def geometry(self, value):
167
- self.gaussian.geometry = value
168
-
169
- @property
170
- def mean(self):
171
- return self.gaussian.mean
172
-
173
- @mean.setter
174
- def mean(self, value):
175
- self.gaussian.mean = value
176
-
177
- @property
178
- def cov(self):
179
- return self.gaussian.cov
180
-
181
- @cov.setter
182
- def cov(self, value):
183
- self.gaussian.cov = value
184
-
185
- @property
186
- def prec(self):
187
- return self.gaussian.prec
188
-
189
- @prec.setter
190
- def prec(self, value):
191
- self.gaussian.prec = value
192
-
193
- @property
194
- def sqrtprec(self):
195
- return self.gaussian.sqrtprec
196
-
197
- @sqrtprec.setter
198
- def sqrtprec(self, value):
199
- self.gaussian.sqrtprec = value
200
-
201
- @property
202
- def sqrtcov(self):
203
- return self.gaussian.sqrtcov
204
-
205
- @sqrtcov.setter
206
- def sqrtcov(self, value):
207
- self.gaussian.sqrtcov = value
208
-
209
- def get_conditioning_variables(self):
210
- return self.gaussian.get_conditioning_variables()
211
-
212
- def get_mutable_variables(self):
213
- return self.gaussian.get_mutable_variables()
214
-
215
- # Overwrite the condition method such that the underlying Gaussian is conditioned in general, except when conditioning on self.name
216
- # which means we convert Distribution to Likelihood or EvaluatedDensity.
217
- def _condition(self, *args, **kwargs):
218
-
219
- # Handle positional arguments (similar code as in Distribution._condition)
220
- cond_vars = self.get_conditioning_variables()
221
- kwargs = self._parse_args_add_to_kwargs(cond_vars, *args, **kwargs)
222
-
223
- # When conditioning, we always do it on a copy to avoid unintentional side effects
224
- new_density = self._make_copy()
225
-
226
- # Check if self.name is in the provided keyword arguments.
227
- # If so, pop it and store its value.
228
- value = kwargs.pop(self.name, None)
229
-
230
- new_density._gaussian = self.gaussian._condition(**kwargs)
231
-
232
- # If self.name was provided, we convert to a likelihood or evaluated density
233
- if value is not None:
234
- new_density = new_density.to_likelihood(value)
235
-
236
- return new_density
237
-
238
-
239
- class ConstrainedGaussian(RegularizedGaussian):
240
- """ Implicit Constrained Gaussian.
241
-
242
- Defines a so-called implicit prior based on a Gaussian distribution with implicit constraints.
243
- The constraint can be defined as a preset or in the form of a projector.
244
-
245
- Precisely one of projector or constraint needs to be provided. Otherwise, an error is raised.
246
-
247
- Can be used as a prior in a posterior which can be sampled with the RegularizedLinearRTO sampler.
248
-
249
- Alias for :class:`~cuqi.implicitprior.RegularizedGaussian` with only constraints available.
250
-
251
- For more details on implicit regularized Gaussian see the following paper:
252
-
253
- [1] Everink, Jasper M., Yiqiu Dong, and Martin S. Andersen. "Sparse Bayesian inference with regularized
254
- Gaussian distributions." Inverse Problems 39.11 (2023): 115004.
255
-
256
- Parameters
257
- ----------
258
- mean
259
- See :class:`~cuqi.distribution.Gaussian` for details.
260
-
261
- cov
262
- See :class:`~cuqi.distribution.Gaussian` for details.
263
-
264
- prec
265
- See :class:`~cuqi.distribution.Gaussian` for details.
266
-
267
- sqrtcov
268
- See :class:`~cuqi.distribution.Gaussian` for details.
269
-
270
- sqrtprec
271
- See :class:`~cuqi.distribution.Gaussian` for details.
272
-
273
- projector : callable f(x) or None
274
- Euclidean projection onto the constraint C, that is, a solver for the optimization problem
275
- min_(z in C) 0.5||x-z||_2^2.
276
-
277
- constraint : string or None
278
- Preset constraints. Can be set to "nonnegativity" and "box". Required for use in Gibbs.
279
- For "box", the following additional parameters can be passed:
280
- lower_bound : array_like or None
281
- Lower bound of box, defaults to zero
282
- upper_bound : array_like
283
- Upper bound of box, defaults to one
284
-
285
- """
286
- def __init__(self, mean=None, cov=None, prec=None, sqrtcov=None,sqrtprec=None, projector=None, constraint=None, **kwargs):
287
- super().__init__(mean=mean, cov=cov, prec=prec, sqrtcov=sqrtcov, sqrtprec=sqrtprec, projector=projector, constraint=constraint, **kwargs)
288
-
289
-
290
- class NonnegativeGaussian(RegularizedGaussian):
291
- """ Implicit Nonnegative Gaussian.
292
-
293
- Defines a so-called implicit prior based on a Gaussian distribution with implicit nonnegativity constraints.
294
-
295
- Can be used as a prior in a posterior which can be sampled with the RegularizedLinearRTO sampler.
296
-
297
- Alias for :class:`~cuqi.implicitprior.RegularizedGaussian` with only nonnegativity constraints.
298
-
299
- For more details on implicit regularized Gaussian see the following paper:
300
-
301
- [1] Everink, Jasper M., Yiqiu Dong, and Martin S. Andersen. "Sparse Bayesian inference with regularized
302
- Gaussian distributions." Inverse Problems 39.11 (2023): 115004.
303
-
304
- Parameters
305
- ----------
306
- mean
307
- See :class:`~cuqi.distribution.Gaussian` for details.
308
-
309
- cov
310
- See :class:`~cuqi.distribution.Gaussian` for details.
311
-
312
- prec
313
- See :class:`~cuqi.distribution.Gaussian` for details.
314
-
315
- sqrtcov
316
- See :class:`~cuqi.distribution.Gaussian` for details.
317
-
318
- sqrtprec
319
- See :class:`~cuqi.distribution.Gaussian` for details.
320
-
321
- """
322
- def __init__(self, mean=None, cov=None, prec=None, sqrtcov=None,sqrtprec=None, **kwargs):
323
- super().__init__(mean=mean, cov=cov, prec=prec, sqrtcov=sqrtcov, sqrtprec=sqrtprec, constraint="nonnegativity", **kwargs)