CUQIpy 1.0.0.post0.dev371__tar.gz → 1.0.0.post0.dev387__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.

Files changed (118) hide show
  1. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/CUQIpy.egg-info/PKG-INFO +1 -1
  2. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/CUQIpy.egg-info/SOURCES.txt +1 -0
  3. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/PKG-INFO +1 -1
  4. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/_version.py +3 -3
  5. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/__init__.py +1 -0
  6. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_custom.py +2 -2
  7. cuqipy-1.0.0.post0.dev387/cuqi/distribution/_smoothed_laplace.py +95 -0
  8. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/problem/_problem.py +1 -2
  9. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_distribution.py +27 -1
  10. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/CUQIpy.egg-info/dependency_links.txt +0 -0
  11. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/CUQIpy.egg-info/requires.txt +0 -0
  12. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/CUQIpy.egg-info/top_level.txt +0 -0
  13. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/LICENSE +0 -0
  14. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/README.md +0 -0
  15. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/__init__.py +0 -0
  16. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/_messages.py +0 -0
  17. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/array/__init__.py +0 -0
  18. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/array/_array.py +0 -0
  19. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/config.py +0 -0
  20. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/data/__init__.py +0 -0
  21. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/data/_data.py +0 -0
  22. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/data/astronaut.npz +0 -0
  23. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/data/camera.npz +0 -0
  24. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/data/cat.npz +0 -0
  25. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/data/cookie.png +0 -0
  26. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/data/satellite.mat +0 -0
  27. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/density/__init__.py +0 -0
  28. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/density/_density.py +0 -0
  29. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/diagnostics.py +0 -0
  30. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_beta.py +0 -0
  31. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_cauchy.py +0 -0
  32. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_cmrf.py +0 -0
  33. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_distribution.py +0 -0
  34. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_gamma.py +0 -0
  35. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_gaussian.py +0 -0
  36. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_gmrf.py +0 -0
  37. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_inverse_gamma.py +0 -0
  38. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_joint_distribution.py +0 -0
  39. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_laplace.py +0 -0
  40. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_lmrf.py +0 -0
  41. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_lognormal.py +0 -0
  42. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_modifiedhalfnormal.py +0 -0
  43. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_normal.py +0 -0
  44. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_posterior.py +0 -0
  45. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/distribution/_uniform.py +0 -0
  46. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/__init__.py +0 -0
  47. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/mcmc/__init__.py +0 -0
  48. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/mcmc/_conjugate.py +0 -0
  49. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/mcmc/_conjugate_approx.py +0 -0
  50. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/mcmc/_cwmh.py +0 -0
  51. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/mcmc/_direct.py +0 -0
  52. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/mcmc/_gibbs.py +0 -0
  53. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/mcmc/_hmc.py +0 -0
  54. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/mcmc/_langevin_algorithm.py +0 -0
  55. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/mcmc/_laplace_approximation.py +0 -0
  56. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/mcmc/_mh.py +0 -0
  57. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/mcmc/_pcn.py +0 -0
  58. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/mcmc/_rto.py +0 -0
  59. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/mcmc/_sampler.py +0 -0
  60. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/experimental/mcmc/_utilities.py +0 -0
  61. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/geometry/__init__.py +0 -0
  62. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/geometry/_geometry.py +0 -0
  63. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/implicitprior/__init__.py +0 -0
  64. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/implicitprior/_regularizedGMRF.py +0 -0
  65. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/implicitprior/_regularizedGaussian.py +0 -0
  66. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/implicitprior/_regularizedUnboundedUniform.py +0 -0
  67. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/likelihood/__init__.py +0 -0
  68. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/likelihood/_likelihood.py +0 -0
  69. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/model/__init__.py +0 -0
  70. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/model/_model.py +0 -0
  71. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/operator/__init__.py +0 -0
  72. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/operator/_operator.py +0 -0
  73. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/pde/__init__.py +0 -0
  74. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/pde/_pde.py +0 -0
  75. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/problem/__init__.py +0 -0
  76. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/sampler/__init__.py +0 -0
  77. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/sampler/_conjugate.py +0 -0
  78. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/sampler/_conjugate_approx.py +0 -0
  79. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/sampler/_cwmh.py +0 -0
  80. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/sampler/_gibbs.py +0 -0
  81. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/sampler/_hmc.py +0 -0
  82. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/sampler/_langevin_algorithm.py +0 -0
  83. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/sampler/_laplace_approximation.py +0 -0
  84. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/sampler/_mh.py +0 -0
  85. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/sampler/_pcn.py +0 -0
  86. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/sampler/_rto.py +0 -0
  87. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/sampler/_sampler.py +0 -0
  88. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/samples/__init__.py +0 -0
  89. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/samples/_samples.py +0 -0
  90. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/solver/__init__.py +0 -0
  91. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/solver/_solver.py +0 -0
  92. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/testproblem/__init__.py +0 -0
  93. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/testproblem/_testproblem.py +0 -0
  94. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/utilities/__init__.py +0 -0
  95. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/utilities/_get_python_variable_name.py +0 -0
  96. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/cuqi/utilities/_utilities.py +0 -0
  97. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/pyproject.toml +0 -0
  98. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/requirements.txt +0 -0
  99. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/setup.cfg +0 -0
  100. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/setup.py +0 -0
  101. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_MRFs.py +0 -0
  102. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_abstract_distribution_density.py +0 -0
  103. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_bayesian_inversion.py +0 -0
  104. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_density.py +0 -0
  105. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_distributions_shape.py +0 -0
  106. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_geometry.py +0 -0
  107. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_implicit_priors.py +0 -0
  108. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_joint_distribution.py +0 -0
  109. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_likelihood.py +0 -0
  110. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_model.py +0 -0
  111. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_pde.py +0 -0
  112. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_posterior.py +0 -0
  113. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_problem.py +0 -0
  114. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_sampler.py +0 -0
  115. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_samples.py +0 -0
  116. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_solver.py +0 -0
  117. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_testproblem.py +0 -0
  118. {cuqipy-1.0.0.post0.dev371 → cuqipy-1.0.0.post0.dev387}/tests/test_utilities.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: CUQIpy
3
- Version: 1.0.0.post0.dev371
3
+ Version: 1.0.0.post0.dev387
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
@@ -41,6 +41,7 @@ cuqi/distribution/_lognormal.py
41
41
  cuqi/distribution/_modifiedhalfnormal.py
42
42
  cuqi/distribution/_normal.py
43
43
  cuqi/distribution/_posterior.py
44
+ cuqi/distribution/_smoothed_laplace.py
44
45
  cuqi/distribution/_uniform.py
45
46
  cuqi/experimental/__init__.py
46
47
  cuqi/experimental/mcmc/__init__.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: CUQIpy
3
- Version: 1.0.0.post0.dev371
3
+ Version: 1.0.0.post0.dev387
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-07-05T10:04:17+0300",
11
+ "date": "2024-07-05T10:30:02+0300",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "62f642d707e561a7c9deb0006625b11866043b81",
15
- "version": "1.0.0.post0.dev371"
14
+ "full-revisionid": "192b464555ba1f70ce8b0041ecd49ff4978d5689",
15
+ "version": "1.0.0.post0.dev387"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -9,6 +9,7 @@ from ._gmrf import GMRF
9
9
  from ._inverse_gamma import InverseGamma
10
10
  from ._lmrf import LMRF
11
11
  from ._laplace import Laplace
12
+ from ._smoothed_laplace import SmoothedLaplace
12
13
  from ._lognormal import Lognormal
13
14
  from ._normal import Normal
14
15
  from ._posterior import Posterior
@@ -50,13 +50,13 @@ class UserDefinedDistribution(Distribution):
50
50
  if self.logpdf_func is not None:
51
51
  return self.logpdf_func(x)
52
52
  else:
53
- raise Exception("logpdf_func is not defined.")
53
+ raise NotImplementedError("logpdf_func is not defined.")
54
54
 
55
55
  def _gradient(self, x):
56
56
  if self.gradient_func is not None:
57
57
  return self.gradient_func(x)
58
58
  else:
59
- raise Exception("gradient_func is not defined.")
59
+ raise NotImplementedError("gradient_func is not defined.")
60
60
 
61
61
  def _sample(self, N=1, rng=None):
62
62
  #TODO(nabr) allow sampling more than 1 sample and potentially rng?
@@ -0,0 +1,95 @@
1
+ import numpy as np
2
+ from cuqi.utilities import force_ndarray
3
+ from cuqi.distribution import Distribution
4
+
5
+ class SmoothedLaplace(Distribution):
6
+ """ Smoothed Laplace distribution.
7
+
8
+ Defines a smoothed Laplace distribution given a location, a scale and a smoothing parameter
9
+ beta. The smoothed Laplace distribution is defined as
10
+
11
+ .. math::
12
+
13
+ p(x) = \\frac{1}{2b} \exp\left(-\\frac{\sqrt{(x-\mu)^2 + \beta}}{b}\\right),
14
+
15
+ where :math:`\mu` is the location (mean), :math:`b` is the scale (decay) parameter and
16
+ :math:`\beta` is the smoothing parameter.
17
+
18
+ The rate parameter is defined as :math:`\lambda = \\frac{1}{b}`.
19
+
20
+ The variables of this Laplace distribution are independent identically distributed (i.i.d.).
21
+
22
+ Parameters
23
+ ----------
24
+ location : scalar, list, tuple, or ndarray
25
+ The location parameter of the distribution.
26
+
27
+ scale : scalar, list, tuple, or ndarray
28
+ The scale parameter of the distribution.
29
+
30
+ beta : scalar
31
+ The smoothing parameter of the distribution.
32
+
33
+ """
34
+
35
+ def __init__(self, location=None, scale=None, beta=1e-3, **kwargs):
36
+ super().__init__(**kwargs)
37
+
38
+ self.location = location
39
+ self.scale = scale
40
+ self.beta = beta
41
+
42
+ @property
43
+ def location(self):
44
+ """ Location parameter """
45
+ return self._location
46
+
47
+ @location.setter
48
+ def location(self, value):
49
+ self._location = force_ndarray(value, flatten=True)
50
+
51
+ @property
52
+ def scale(self):
53
+ """ Scale parameter """
54
+ return self._scale
55
+
56
+ @scale.setter
57
+ def scale(self, value):
58
+ self._scale = force_ndarray(value, flatten=True)
59
+
60
+ @property
61
+ def beta(self):
62
+ """ Beta parameter """
63
+ return self._beta
64
+
65
+ @beta.setter
66
+ def beta(self, value):
67
+ self._beta = value
68
+
69
+ def logpdf(self, x):
70
+ """
71
+ Computes the logarithm of the probability density function at the given values of x.
72
+ """
73
+ # x accepts scalar, list, tuple, or ndarray
74
+ if isinstance(x, (float, int)):
75
+ x = np.array([x])
76
+ elif isinstance(x, (list, tuple)):
77
+ x = np.array(x)
78
+ return np.sum(np.log(0.5 / self.scale)) - np.sum(np.sqrt((x - self.location) ** 2 + self.beta) / self.scale)
79
+
80
+ def gradient(self, x):
81
+ """
82
+ Computes the gradient of logpdf at the given values of x.
83
+ """
84
+ # x accepts scalar, list, tuple, or ndarray
85
+ if isinstance(x, (float, int)):
86
+ x = np.array([x])
87
+ elif isinstance(x, (list, tuple)):
88
+ x = np.array(x)
89
+ return -np.array((x - self.location) / self.scale / np.sqrt((x - self.location) ** 2 + self.beta))
90
+
91
+ def _sample(self, N=1, rng=None):
92
+ """
93
+ Generates random samples from the distribution.
94
+ """
95
+ raise NotImplementedError(f"sample is not implemented for {self.__class__.__name__}.")
@@ -710,8 +710,7 @@ class BayesianProblem(object):
710
710
  # Require gradient?
711
711
  if must_have_gradient:
712
712
  try:
713
- posterior.prior.gradient(np.zeros(posterior.prior.dim))
714
- posterior.likelihood.gradient(np.zeros(posterior.likelihood.dim))
713
+ posterior.posterior.gradient(np.zeros(posterior.posterior.dim))
715
714
  G = True
716
715
  except (NotImplementedError, AttributeError):
717
716
  G = False
@@ -779,4 +779,30 @@ def test_MHN_regression(alpha, beta, gamma, expected_logpdf, expected_gradient):
779
779
  logpdf = dist.logpdf(np.array([1.0, 2.0, 3.0, 4.0, 5.0]))
780
780
  gradient = dist._gradient(np.array([1.0, 2.0, 3.0, 4.0, 5.0]))
781
781
  assert np.allclose( logpdf, np.array(expected_logpdf))
782
- assert np.allclose( gradient, np.array(expected_gradient))
782
+ assert np.allclose( gradient, np.array(expected_gradient))
783
+
784
+ def test_Smoothed_Laplace():
785
+ """ Test Smoothed Laplace distribution logpdf and gradient """
786
+
787
+ location = np.array([1, 2])
788
+ scale = np.array([1, 2])
789
+ scalar_laplace_0 = cuqi.distribution.Laplace(location[0], scale[0])
790
+
791
+ scalar_smoothed_laplace_0 = cuqi.distribution.SmoothedLaplace(location[0], scale[0], 1e-8)
792
+ scalar_smoothed_laplace_1 = cuqi.distribution.SmoothedLaplace(location[1], scale[1], 1e-8)
793
+ vector_smoothed_laplace = cuqi.distribution.SmoothedLaplace(location, scale, 1e-8)
794
+
795
+ x = np.array([3, 4])
796
+
797
+ # logpdf (scalar Laplace vs scalar Smoothed Laplace)
798
+ assert np.allclose(scalar_laplace_0.logpdf([x[0]]), scalar_smoothed_laplace_0.logpdf(x[0]))
799
+
800
+ # logpdf (scalar Smoothed Laplace * scalar Smoothed Laplace vs vector Smoothed Laplace)
801
+ assert np.allclose(scalar_smoothed_laplace_0.logpdf(x[0])+scalar_smoothed_laplace_1.logpdf(x[1]),
802
+ vector_smoothed_laplace.logpdf(x))
803
+
804
+ # gradient (scalar Smoothed Laplace vs analytical)
805
+ assert np.allclose(scalar_smoothed_laplace_0.gradient(x[0]), -1/scale[0])
806
+
807
+ # gradient (vector Smoothed Laplace vs analytical)
808
+ assert np.allclose(vector_smoothed_laplace.gradient(x), -1/scale)