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.
- cuqi/__init__.py +2 -0
- cuqi/_version.py +3 -3
- cuqi/algebra/__init__.py +2 -0
- cuqi/algebra/_abstract_syntax_tree.py +358 -0
- cuqi/algebra/_ordered_set.py +82 -0
- cuqi/algebra/_random_variable.py +457 -0
- cuqi/array/_array.py +4 -13
- cuqi/config.py +7 -0
- cuqi/density/_density.py +9 -1
- cuqi/distribution/__init__.py +3 -2
- cuqi/distribution/_beta.py +7 -11
- cuqi/distribution/_cauchy.py +2 -2
- cuqi/distribution/_custom.py +0 -6
- cuqi/distribution/_distribution.py +31 -45
- cuqi/distribution/_gamma.py +7 -3
- cuqi/distribution/_gaussian.py +2 -12
- cuqi/distribution/_inverse_gamma.py +4 -10
- cuqi/distribution/_joint_distribution.py +112 -15
- cuqi/distribution/_lognormal.py +0 -7
- cuqi/distribution/{_modifiedhalfnormal.py → _modified_half_normal.py} +23 -23
- cuqi/distribution/_normal.py +34 -7
- cuqi/distribution/_posterior.py +9 -0
- cuqi/distribution/_truncated_normal.py +129 -0
- cuqi/distribution/_uniform.py +47 -1
- cuqi/experimental/__init__.py +2 -2
- cuqi/experimental/_recommender.py +216 -0
- cuqi/geometry/__init__.py +2 -0
- cuqi/geometry/_geometry.py +15 -1
- cuqi/geometry/_product_geometry.py +181 -0
- cuqi/implicitprior/__init__.py +5 -3
- cuqi/implicitprior/_regularized_gaussian.py +483 -0
- cuqi/implicitprior/{_regularizedGMRF.py → _regularized_gmrf.py} +4 -2
- cuqi/implicitprior/{_regularizedUnboundedUniform.py → _regularized_unbounded_uniform.py} +3 -2
- cuqi/implicitprior/_restorator.py +269 -0
- cuqi/legacy/__init__.py +2 -0
- cuqi/{experimental/mcmc → legacy/sampler}/__init__.py +7 -11
- cuqi/legacy/sampler/_conjugate.py +55 -0
- cuqi/legacy/sampler/_conjugate_approx.py +52 -0
- cuqi/legacy/sampler/_cwmh.py +196 -0
- cuqi/legacy/sampler/_gibbs.py +231 -0
- cuqi/legacy/sampler/_hmc.py +335 -0
- cuqi/{experimental/mcmc → legacy/sampler}/_langevin_algorithm.py +82 -111
- cuqi/legacy/sampler/_laplace_approximation.py +184 -0
- cuqi/legacy/sampler/_mh.py +190 -0
- cuqi/legacy/sampler/_pcn.py +244 -0
- cuqi/{experimental/mcmc → legacy/sampler}/_rto.py +132 -90
- cuqi/legacy/sampler/_sampler.py +182 -0
- cuqi/likelihood/_likelihood.py +9 -1
- cuqi/model/__init__.py +1 -1
- cuqi/model/_model.py +1361 -359
- cuqi/pde/__init__.py +4 -0
- cuqi/pde/_observation_map.py +36 -0
- cuqi/pde/_pde.py +134 -33
- cuqi/problem/_problem.py +93 -87
- cuqi/sampler/__init__.py +120 -8
- cuqi/sampler/_conjugate.py +376 -35
- cuqi/sampler/_conjugate_approx.py +40 -16
- cuqi/sampler/_cwmh.py +132 -138
- cuqi/{experimental/mcmc → sampler}/_direct.py +1 -1
- cuqi/sampler/_gibbs.py +288 -130
- cuqi/sampler/_hmc.py +328 -201
- cuqi/sampler/_langevin_algorithm.py +284 -100
- cuqi/sampler/_laplace_approximation.py +87 -117
- cuqi/sampler/_mh.py +47 -157
- cuqi/sampler/_pcn.py +65 -213
- cuqi/sampler/_rto.py +211 -142
- cuqi/sampler/_sampler.py +553 -136
- cuqi/samples/__init__.py +1 -1
- cuqi/samples/_samples.py +24 -18
- cuqi/solver/__init__.py +6 -4
- cuqi/solver/_solver.py +230 -26
- cuqi/testproblem/_testproblem.py +2 -3
- cuqi/utilities/__init__.py +6 -1
- cuqi/utilities/_get_python_variable_name.py +2 -2
- cuqi/utilities/_utilities.py +182 -2
- {CUQIpy-1.1.1.post0.dev36.dist-info → cuqipy-1.4.1.post0.dev124.dist-info}/METADATA +10 -6
- cuqipy-1.4.1.post0.dev124.dist-info/RECORD +101 -0
- {CUQIpy-1.1.1.post0.dev36.dist-info → cuqipy-1.4.1.post0.dev124.dist-info}/WHEEL +1 -1
- CUQIpy-1.1.1.post0.dev36.dist-info/RECORD +0 -92
- cuqi/experimental/mcmc/_conjugate.py +0 -197
- cuqi/experimental/mcmc/_conjugate_approx.py +0 -81
- cuqi/experimental/mcmc/_cwmh.py +0 -191
- cuqi/experimental/mcmc/_gibbs.py +0 -268
- cuqi/experimental/mcmc/_hmc.py +0 -470
- cuqi/experimental/mcmc/_laplace_approximation.py +0 -156
- cuqi/experimental/mcmc/_mh.py +0 -78
- cuqi/experimental/mcmc/_pcn.py +0 -89
- cuqi/experimental/mcmc/_sampler.py +0 -561
- cuqi/experimental/mcmc/_utilities.py +0 -17
- cuqi/implicitprior/_regularizedGaussian.py +0 -323
- {CUQIpy-1.1.1.post0.dev36.dist-info → cuqipy-1.4.1.post0.dev124.dist-info/licenses}/LICENSE +0 -0
- {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)
|
|
File without changes
|
|
File without changes
|