CUQIpy 0.8.0.post0.dev82__py3-none-any.whl → 0.8.0.post0.dev92__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: CUQIpy
3
- Version: 0.8.0.post0.dev82
3
+ Version: 0.8.0.post0.dev92
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
  cuqi/__init__.py,sha256=XX1aQmtltqgf2qhIc2ISxvBcQJ_oLnMwaYByBzsBkNs,461
2
2
  cuqi/_messages.py,sha256=fzEBrZT2kbmfecBBPm7spVu7yHdxGARQB4QzXhJbCJ0,415
3
- cuqi/_version.py,sha256=0vzNVkotpZiMe5YA4qiuns7UnkYRCushk3VHVvMY3y0,509
3
+ cuqi/_version.py,sha256=QE1vOtj6T-IolXKLjvnTzaqtnoVhUuHMh2Fnly-qYqE,509
4
4
  cuqi/config.py,sha256=wcYvz19wkeKW2EKCGIKJiTpWt5kdaxyt4imyRkvtTRA,526
5
5
  cuqi/diagnostics.py,sha256=5OrbJeqpynqRXOe5MtOKKhe7EAVdOEpHIqHnlMW9G_c,3029
6
6
  cuqi/array/__init__.py,sha256=-EeiaiWGNsE3twRS4dD814BIlfxEsNkTCZUc5gjOXb0,30
@@ -15,12 +15,12 @@ cuqi/data/satellite.mat,sha256=a0Nz_Ak-Y0m360dH74pa_rpk-MhaQ91ftGTKhQX7I8g,16373
15
15
  cuqi/density/__init__.py,sha256=0zfVcPgqdqiPkss5n_WP_PUt-G3ovHXjokhqEKIlLwA,48
16
16
  cuqi/density/_density.py,sha256=BG7gtP0cbFYLVgjYQGkNAhM95PR5ocBVLKRlOVX2PyM,7253
17
17
  cuqi/distribution/__init__.py,sha256=f85DzOHPvGec9nr_AIfp_THSuC4WN8ZUJMSLZrKClG8,615
18
- cuqi/distribution/_beta.py,sha256=xQ6nURJqB20j1A8YNnpKO9BUcb-kKUdq8QCmljlm9l4,2980
18
+ cuqi/distribution/_beta.py,sha256=hdAc6Tbuz9Yqf76NSHxpaUgN7s6Z2lNV7YSRD3JhyCU,2997
19
19
  cuqi/distribution/_cauchy.py,sha256=UsVXYz8HhagXN5fIWSAIyELqhsJAX_-wk9kkRGgRmA8,3296
20
20
  cuqi/distribution/_cmrf.py,sha256=tCbEulM_O7FB3C_W-3IqZp9zGHkTofCdFF0ybHc9UZI,3745
21
21
  cuqi/distribution/_custom.py,sha256=uUJwGlGjcMY89mIyu9nFI3OafLOMgn8uAEMfCbTDzi0,10661
22
22
  cuqi/distribution/_distribution.py,sha256=Qh8Yq-rtKh9xgog-2bo7d4-o0vaW_aAt5LaGbXlgX0U,17951
23
- cuqi/distribution/_gamma.py,sha256=GGsbIeHQhzUb1eTNeARcLXjJqcZ5iZWvaDaNsfJv9N0,1303
23
+ cuqi/distribution/_gamma.py,sha256=9vljt5iaBDCHRhrVCMLc2RWDuBchZRQcv9buJMDYPlM,3434
24
24
  cuqi/distribution/_gaussian.py,sha256=Ymllxg7ZQE24ss0oVgtPII4Hx4-xy3x1tAb01_-4i_U,33026
25
25
  cuqi/distribution/_gmrf.py,sha256=OwId8qQWEtmC2fxVhL4iBHZnc8ZCrZzfV6yGXDE3k30,9522
26
26
  cuqi/distribution/_inverse_gamma.py,sha256=XRcNGW_jzORL08V7VvtsuMUoQioBAGbN12qe8hCXJvg,3309
@@ -47,7 +47,7 @@ cuqi/pde/_pde.py,sha256=WRkOYyIdT_T3aZepRh0aS9C5nBbUZUcHaA80iSRvgoo,12572
47
47
  cuqi/problem/__init__.py,sha256=JxJty4JqHTOqSG6NeTGiXRQ7OLxiRK9jvVq3lXLeIRw,38
48
48
  cuqi/problem/_problem.py,sha256=Irk4OlTAhZAX81excesi8ANokz2GSAS3z_mcvx8Wqdc,32018
49
49
  cuqi/sampler/__init__.py,sha256=D-dYa0gFgIwQukP8_VKhPGmlGKXbvVo7YqaET4SdAeQ,382
50
- cuqi/sampler/_conjugate.py,sha256=DlzNFluR51ohfYXzsD5HD7Qt50Mm_LZUL5nkoNTMgzo,2626
50
+ cuqi/sampler/_conjugate.py,sha256=ztmUR3V3qZk9zelKx48ULnmMs_zKTDUfohc256VOIe8,2753
51
51
  cuqi/sampler/_conjugate_approx.py,sha256=xX-X71EgxGnZooOY6CIBhuJTs3dhcKfoLnoFxX3CO2g,1938
52
52
  cuqi/sampler/_cwmh.py,sha256=VlAVT1SXQU0yD5ZeR-_ckWvX-ifJrMweFFdFbxdfB_k,7775
53
53
  cuqi/sampler/_gibbs.py,sha256=N7qcePwMkRtxINN5JF0FaMIdDCXZGqsfKjfha_KHCck,8627
@@ -67,8 +67,8 @@ cuqi/testproblem/_testproblem.py,sha256=x769LwwRdJdzIiZkcQUGb_5-vynNTNALXWKato7s
67
67
  cuqi/utilities/__init__.py,sha256=EfxHLdsyDNugbmbzs43nV_AeKcycM9sVBjG9WZydagA,351
68
68
  cuqi/utilities/_get_python_variable_name.py,sha256=QwlBVj2koJRA8s8pWd554p7-ElcI7HUwY32HknaR92E,1827
69
69
  cuqi/utilities/_utilities.py,sha256=At3DOXRdF3GwLkVcM2FXooGyjAGfPkIM0bRzhTfLmWk,8046
70
- CUQIpy-0.8.0.post0.dev82.dist-info/LICENSE,sha256=kJWRPrtRoQoZGXyyvu50Uc91X6_0XRaVfT0YZssicys,10799
71
- CUQIpy-0.8.0.post0.dev82.dist-info/METADATA,sha256=_z7DAYrSpHj443n4zWkAPIVlpWdLUbhyhzWz4EaP5R4,18386
72
- CUQIpy-0.8.0.post0.dev82.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
73
- CUQIpy-0.8.0.post0.dev82.dist-info/top_level.txt,sha256=AgmgMc6TKfPPqbjV0kvAoCBN334i_Lwwojc7HE3ZwD0,5
74
- CUQIpy-0.8.0.post0.dev82.dist-info/RECORD,,
70
+ CUQIpy-0.8.0.post0.dev92.dist-info/LICENSE,sha256=kJWRPrtRoQoZGXyyvu50Uc91X6_0XRaVfT0YZssicys,10799
71
+ CUQIpy-0.8.0.post0.dev92.dist-info/METADATA,sha256=9krqvItPH0RrEJpVaYemnNMjcJw3svPm6syoEK2gCy8,18386
72
+ CUQIpy-0.8.0.post0.dev92.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
73
+ CUQIpy-0.8.0.post0.dev92.dist-info/top_level.txt,sha256=AgmgMc6TKfPPqbjV0kvAoCBN334i_Lwwojc7HE3ZwD0,5
74
+ CUQIpy-0.8.0.post0.dev92.dist-info/RECORD,,
cuqi/_version.py CHANGED
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-01-22T07:47:25+0100",
11
+ "date": "2024-02-19T05:04:22+0100",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "26e399cc13e1d7bf982d16d1d345b6d6616dac92",
15
- "version": "0.8.0.post0.dev82"
14
+ "full-revisionid": "f274c4a7b3044d1ba3e9567bb167a1cdbea05283",
15
+ "version": "0.8.0.post0.dev92"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -69,7 +69,7 @@ class Beta(Distribution):
69
69
  def _sample(self, N=1, rng=None):
70
70
  return sps.beta.rvs(a=self.alpha, b=self.beta, size=(N,self.dim), random_state=rng).T
71
71
 
72
- def _gradient(self, x):
72
+ def _gradient(self, x, *args, **kwargs):
73
73
  #Avoid complicated geometries that change the gradient.
74
74
  if not type(self.geometry) in _get_identity_geometries():
75
75
  raise NotImplementedError("Gradient not implemented for distribution {} with geometry {}".format(self,self.geometry))
@@ -1,37 +1,105 @@
1
1
  import numpy as np
2
- from scipy.special import loggamma, gammainc
2
+ import scipy.stats as sps
3
3
  from cuqi.distribution import Distribution
4
+ from cuqi.utilities import force_ndarray
4
5
 
5
6
  class Gamma(Distribution):
7
+ """
8
+ Represents a multivariate Gamma distribution characterized by shape and rate parameters of independent random variables x_i. Each is distributed according to the PDF function
9
+
10
+ f(x_i; shape, rate) = rate^shape * x_i^(shape-1) * exp(-rate * x_i) / Gamma(shape)
6
11
 
12
+ where `shape` and `rate` are the parameters of the distribution, and Gamma is the Gamma function.
13
+
14
+ In case shape and/or rate are arrays, the pdf looks like
15
+
16
+ f(x_i; shape_i, rate_i) = rate_i^shape_i * x_i^(shape_i-1) * exp(-rate_i * x_i) / Gamma(shape_i)
17
+
18
+ Parameters
19
+ ----------
20
+ shape : float or array_like, optional
21
+ The shape parameter of the Gamma distribution. Must be positive.
22
+
23
+ rate : float or array_like, optional
24
+ The rate parameter of the Gamma distribution. Must be positive.
25
+
26
+ Examples
27
+ --------
28
+ .. code-block:: python
29
+
30
+ import numpy as np
31
+ import cuqi
32
+ import matplotlib.pyplot as plt
33
+
34
+ # Create a multivariate Gamma distribution with the same shape and rate parameters
35
+ shape = 1
36
+ rate = 1e-4
37
+ gamma_dist = cuqi.distribution.Gamma(shape=shape, rate=rate, geometry=10)
38
+
39
+ # Generate samples
40
+ samples = gamma_dist.sample(10000)
41
+
42
+ # Plot histogram of samples for index 0
43
+ samples.hist_chain(0, bins=70)
44
+
45
+
46
+ .. code-block:: python
47
+
48
+ import numpy as np
49
+ import cuqi
50
+ import matplotlib.pyplot as plt
51
+
52
+ # Create a multivariate Gamma distribution with different shape and rate parameters
53
+ shape = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
54
+ rate = [1e-4, 1e-3, 1e-2, 1e-1, 1, 1e1, 1e2, 1e3, 1e4, 1e5]
55
+ gamma_dist = cuqi.distribution.Gamma(shape=shape, rate=rate)
56
+
57
+ # Generate samples
58
+ samples = gamma_dist.sample(10000)
59
+
60
+ # Plot histogram of samples for index 0
61
+ samples.hist_chain(0, bins=70)
62
+
63
+ """
7
64
  def __init__(self, shape=None, rate=None, is_symmetric=False, **kwargs):
8
65
  # Init from abstract distribution class
9
66
  super().__init__(is_symmetric=is_symmetric,**kwargs)
10
67
 
11
- # Init specific to this distribution
12
68
  self.shape = shape
13
- self.rate = rate
69
+ self.rate = rate
70
+
71
+ @property
72
+ def shape(self):
73
+ """ Shape parameter of the Gamma distribution. Must be positive. """
74
+ return self._shape
75
+
76
+ @shape.setter
77
+ def shape(self, value):
78
+ self._shape = force_ndarray(value, flatten=True)
79
+
80
+ @property
81
+ def rate(self):
82
+ """ Rate parameter of the Gamma distribution. Must be positive. """
83
+ return self._rate
84
+
85
+ @rate.setter
86
+ def rate(self, value):
87
+ self._rate = force_ndarray(value, flatten=True)
14
88
 
15
89
  @property
16
90
  def scale(self):
91
+ """ Scale parameter of the Gamma distribution. Must be positive. This is the inverse of the rate parameter. """
17
92
  return 1/self.rate
18
93
 
19
- def pdf(self, x):
20
- # sps.gamma.pdf(x, a=self.shape, loc=0, scale=self.scale)
21
- # (self.rate**self.shape)/(gamma(self.shape)) * (x**(self.shape-1)*np.exp(-self.rate*x))
22
- return np.exp(self.logpdf(x))
23
-
24
94
  def logpdf(self, x):
25
- # sps.gamma.logpdf(x, a=self.shape, loc=0, scale=self.scale)
26
- return (self.shape*np.log(self.rate)-loggamma(self.shape)) + ((self.shape-1)*np.log(x) - self.rate*x)
95
+ return np.sum(sps.gamma.logpdf(x, a=self.shape, loc=0, scale=self.scale))
27
96
 
28
97
  def cdf(self, x):
29
- # sps.gamma.cdf(x, a=self.shape, loc=0, scale=self.scale)
30
- return gammainc(self.shape, self.rate*x)
98
+ return np.prod(sps.gamma.cdf(x, a=self.shape, loc=0, scale=self.scale))
31
99
 
32
100
  def _sample(self, N, rng=None):
33
101
  if rng is not None:
34
- return rng.gamma(shape=self.shape, scale=self.scale, size=(N))
102
+ return rng.gamma(shape=self.shape, scale=self.scale, size=(N, self.dim)).T
35
103
  else:
36
- return np.random.gamma(shape=self.shape, scale=self.scale, size=(N))
104
+ return np.random.gamma(shape=self.shape, scale=self.scale, size=(N, self.dim)).T
37
105
 
@@ -25,6 +25,8 @@ class Conjugate: # TODO: Subclass from Sampler once updated
25
25
  raise ValueError("Conjugate sampler only works with a Gaussian-type likelihood function")
26
26
  if not isinstance(target.prior, Gamma):
27
27
  raise ValueError("Conjugate sampler only works with Gamma prior")
28
+ if not target.prior.dim == 1:
29
+ raise ValueError("Conjugate sampler only works with univariate Gamma prior")
28
30
 
29
31
  if isinstance(target.likelihood.distribution, (RegularizedGaussian, RegularizedGMRF)) and target.likelihood.distribution.preset not in ["nonnegativity"]:
30
32
  raise ValueError("Conjugate sampler only works implicit regularized Gaussian likelihood with nonnegativity constraints")