CUQIpy 1.0.0.post0.dev180__tar.gz → 1.0.0.post0.dev200__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 (110) hide show
  1. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/CUQIpy.egg-info/PKG-INFO +1 -1
  2. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/CUQIpy.egg-info/SOURCES.txt +1 -0
  3. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/PKG-INFO +1 -1
  4. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/_version.py +3 -3
  5. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/experimental/mcmc/__init__.py +1 -0
  6. cuqipy-1.0.0.post0.dev200/cuqi/experimental/mcmc/_laplace_approximation.py +159 -0
  7. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/CUQIpy.egg-info/dependency_links.txt +0 -0
  8. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/CUQIpy.egg-info/requires.txt +0 -0
  9. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/CUQIpy.egg-info/top_level.txt +0 -0
  10. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/LICENSE +0 -0
  11. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/README.md +0 -0
  12. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/__init__.py +0 -0
  13. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/_messages.py +0 -0
  14. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/array/__init__.py +0 -0
  15. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/array/_array.py +0 -0
  16. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/config.py +0 -0
  17. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/data/__init__.py +0 -0
  18. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/data/_data.py +0 -0
  19. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/data/astronaut.npz +0 -0
  20. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/data/camera.npz +0 -0
  21. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/data/cat.npz +0 -0
  22. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/data/cookie.png +0 -0
  23. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/data/satellite.mat +0 -0
  24. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/density/__init__.py +0 -0
  25. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/density/_density.py +0 -0
  26. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/diagnostics.py +0 -0
  27. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/__init__.py +0 -0
  28. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_beta.py +0 -0
  29. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_cauchy.py +0 -0
  30. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_cmrf.py +0 -0
  31. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_custom.py +0 -0
  32. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_distribution.py +0 -0
  33. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_gamma.py +0 -0
  34. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_gaussian.py +0 -0
  35. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_gmrf.py +0 -0
  36. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_inverse_gamma.py +0 -0
  37. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_joint_distribution.py +0 -0
  38. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_laplace.py +0 -0
  39. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_lmrf.py +0 -0
  40. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_lognormal.py +0 -0
  41. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_normal.py +0 -0
  42. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_posterior.py +0 -0
  43. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/distribution/_uniform.py +0 -0
  44. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/experimental/__init__.py +0 -0
  45. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/experimental/mcmc/_cwmh.py +0 -0
  46. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/experimental/mcmc/_hmc.py +0 -0
  47. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/experimental/mcmc/_langevin_algorithm.py +0 -0
  48. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/experimental/mcmc/_mh.py +0 -0
  49. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/experimental/mcmc/_pcn.py +0 -0
  50. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/experimental/mcmc/_rto.py +0 -0
  51. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/experimental/mcmc/_sampler.py +0 -0
  52. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/geometry/__init__.py +0 -0
  53. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/geometry/_geometry.py +0 -0
  54. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/implicitprior/__init__.py +0 -0
  55. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/implicitprior/_regularizedGMRF.py +0 -0
  56. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/implicitprior/_regularizedGaussian.py +0 -0
  57. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/likelihood/__init__.py +0 -0
  58. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/likelihood/_likelihood.py +0 -0
  59. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/model/__init__.py +0 -0
  60. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/model/_model.py +0 -0
  61. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/operator/__init__.py +0 -0
  62. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/operator/_operator.py +0 -0
  63. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/pde/__init__.py +0 -0
  64. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/pde/_pde.py +0 -0
  65. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/problem/__init__.py +0 -0
  66. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/problem/_problem.py +0 -0
  67. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/sampler/__init__.py +0 -0
  68. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/sampler/_conjugate.py +0 -0
  69. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/sampler/_conjugate_approx.py +0 -0
  70. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/sampler/_cwmh.py +0 -0
  71. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/sampler/_gibbs.py +0 -0
  72. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/sampler/_hmc.py +0 -0
  73. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/sampler/_langevin_algorithm.py +0 -0
  74. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/sampler/_laplace_approximation.py +0 -0
  75. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/sampler/_mh.py +0 -0
  76. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/sampler/_pcn.py +0 -0
  77. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/sampler/_rto.py +0 -0
  78. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/sampler/_sampler.py +0 -0
  79. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/samples/__init__.py +0 -0
  80. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/samples/_samples.py +0 -0
  81. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/solver/__init__.py +0 -0
  82. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/solver/_solver.py +0 -0
  83. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/testproblem/__init__.py +0 -0
  84. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/testproblem/_testproblem.py +0 -0
  85. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/utilities/__init__.py +0 -0
  86. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/utilities/_get_python_variable_name.py +0 -0
  87. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/cuqi/utilities/_utilities.py +0 -0
  88. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/pyproject.toml +0 -0
  89. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/requirements.txt +0 -0
  90. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/setup.cfg +0 -0
  91. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/setup.py +0 -0
  92. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_MRFs.py +0 -0
  93. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_abstract_distribution_density.py +0 -0
  94. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_bayesian_inversion.py +0 -0
  95. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_density.py +0 -0
  96. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_distribution.py +0 -0
  97. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_distributions_shape.py +0 -0
  98. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_geometry.py +0 -0
  99. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_implicit_priors.py +0 -0
  100. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_joint_distribution.py +0 -0
  101. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_likelihood.py +0 -0
  102. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_model.py +0 -0
  103. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_pde.py +0 -0
  104. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_posterior.py +0 -0
  105. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_problem.py +0 -0
  106. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_sampler.py +0 -0
  107. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_samples.py +0 -0
  108. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_solver.py +0 -0
  109. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/tests/test_testproblem.py +0 -0
  110. {cuqipy-1.0.0.post0.dev180 → cuqipy-1.0.0.post0.dev200}/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.dev180
3
+ Version: 1.0.0.post0.dev200
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
@@ -46,6 +46,7 @@ cuqi/experimental/mcmc/__init__.py
46
46
  cuqi/experimental/mcmc/_cwmh.py
47
47
  cuqi/experimental/mcmc/_hmc.py
48
48
  cuqi/experimental/mcmc/_langevin_algorithm.py
49
+ cuqi/experimental/mcmc/_laplace_approximation.py
49
50
  cuqi/experimental/mcmc/_mh.py
50
51
  cuqi/experimental/mcmc/_pcn.py
51
52
  cuqi/experimental/mcmc/_rto.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: CUQIpy
3
- Version: 1.0.0.post0.dev180
3
+ Version: 1.0.0.post0.dev200
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-04-22T18:01:04+0200",
11
+ "date": "2024-04-26T10:35:11+0200",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "be4b485322b1be52f78dfe6d03694d6ba2000b11",
15
- "version": "1.0.0.post0.dev180"
14
+ "full-revisionid": "f8f57f6a84e3242f71819fd301d3892fc8fb87c9",
15
+ "version": "1.0.0.post0.dev200"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -6,4 +6,5 @@ from ._mh import MHNew
6
6
  from ._pcn import pCNNew
7
7
  from ._rto import LinearRTONew, RegularizedLinearRTONew
8
8
  from ._cwmh import CWMHNew
9
+ from ._laplace_approximation import UGLANew
9
10
  from ._hmc import NUTSNew
@@ -0,0 +1,159 @@
1
+ import scipy as sp
2
+ import numpy as np
3
+ import cuqi
4
+ from cuqi.solver import CGLS
5
+ from cuqi.experimental.mcmc import SamplerNew
6
+
7
+ class UGLANew(SamplerNew):
8
+ """ Unadjusted (Gaussian) Laplace Approximation sampler
9
+
10
+ Samples an approximate posterior where the prior is approximated
11
+ by a Gaussian distribution. The likelihood must be Gaussian.
12
+
13
+ Currently only works for LMRF priors.
14
+
15
+ The inner solver is Conjugate Gradient Least Squares (CGLS) solver.
16
+
17
+ For more details see: Uribe, Felipe, et al. A hybrid Gibbs sampler for edge-preserving
18
+ tomographic reconstruction with uncertain view angles. SIAM/ASA Journal on UQ,
19
+ https://doi.org/10.1137/21M1412268 (2022).
20
+
21
+ Parameters
22
+ ----------
23
+ target : `cuqi.distribution.Posterior`
24
+ The target posterior distribution to sample.
25
+
26
+ initial_point : ndarray, *Optional*
27
+ Initial parameters.
28
+ If not provided, it defaults to zeros.
29
+
30
+ maxit : int
31
+ Maximum number of inner iterations for solver when generating one sample.
32
+ If not provided, it defaults to 50.
33
+
34
+ tol : float
35
+ Tolerance for inner solver.
36
+ The inner solvers will stop before maxit if convergence check reaches tol.
37
+ If not provided, it defaults to 1e-4.
38
+
39
+ beta : float
40
+ Smoothing parameter for the Gaussian approximation of the Laplace distribution.
41
+ A small value in the range of 1e-7 to 1e-3 is recommended, though values out of this
42
+ range might give better results in some cases. Generally, a larger beta value makes
43
+ sampling easier but results in a worse approximation. See details in Section 3.3 of the paper.
44
+ If not provided, it defaults to 1e-5.
45
+
46
+ callback : callable, *Optional*
47
+ If set, this function will be called after every sample.
48
+ The signature of the callback function is `callback(sample, sample_index)`,
49
+ where `sample` is the current sample and `sample_index` is the index of the sample.
50
+ An example is shown in demos/demo31_callback.py.
51
+ """
52
+ def __init__(self, target, initial_point=None, maxit=50, tol=1e-4, beta=1e-5, **kwargs):
53
+
54
+ super().__init__(target=target, initial_point=initial_point, **kwargs)
55
+
56
+ if initial_point is None: #TODO: Replace later with a getter
57
+ self.initial_point = np.zeros(self.dim)
58
+ self._samples = [self.initial_point]
59
+
60
+ self.current_point = self.initial_point
61
+ self._acc = [1] # TODO. Check if we need this
62
+
63
+ # Parameters
64
+ self.maxit = maxit
65
+ self.tol = tol
66
+ self.beta = beta
67
+
68
+ @property
69
+ def prior(self):
70
+ return self.target.prior
71
+
72
+ @property
73
+ def likelihood(self):
74
+ return self.target.likelihood
75
+
76
+ @property
77
+ def model(self):
78
+ return self.target.model
79
+
80
+ @property
81
+ def data(self):
82
+ return self.target.data
83
+
84
+ def _pre_warmup(self):
85
+ super()._pre_warmup()
86
+ D = self.prior._diff_op
87
+ n = D.shape[0]
88
+
89
+ # Gaussian approximation of LMRF prior as function of x_k
90
+ def Lk_fun(x_k):
91
+ dd = 1/np.sqrt((D @ x_k)**2 + self.beta*np.ones(n))
92
+ W = sp.sparse.diags(dd)
93
+ return W.sqrt() @ D
94
+ self.Lk_fun = Lk_fun
95
+
96
+ self._m = len(self.data)
97
+ self._L1 = self.likelihood.distribution.sqrtprec
98
+
99
+ # If prior location is scalar, repeat it to match dimensions
100
+ if len(self.prior.location) == 1:
101
+ self._priorloc = np.repeat(self.prior.location, self.dim)
102
+ else:
103
+ self._priorloc = self.prior.location
104
+
105
+ # Initial Laplace approx
106
+ self._L2 = Lk_fun(self.initial_point)
107
+ self._L2mu = self._L2@self._priorloc
108
+ self._b_tild = np.hstack([self._L1@self.data, self._L2mu])
109
+
110
+ # Least squares form
111
+ def M(x, flag):
112
+ if flag == 1:
113
+ out1 = self._L1 @ self.model.forward(x)
114
+ out2 = np.sqrt(1/self.prior.scale)*(self._L2 @ x)
115
+ out = np.hstack([out1, out2])
116
+ elif flag == 2:
117
+ idx = int(self._m)
118
+ out1 = self.model.adjoint(self._L1.T@x[:idx])
119
+ out2 = np.sqrt(1/self.prior.scale)*(self._L2.T @ x[idx:])
120
+ out = out1 + out2
121
+ return out
122
+ self.M = M
123
+
124
+ def _pre_sample(self):
125
+ self._pre_warmup()
126
+
127
+ def step(self):
128
+ # Update Laplace approximation
129
+ self._L2 = self.Lk_fun(self.current_point)
130
+ self._L2mu = self._L2@self._priorloc
131
+ self._b_tild = np.hstack([self._L1@self.data, self._L2mu])
132
+
133
+ # Sample from approximate posterior
134
+ e = np.random.randn(len(self._b_tild))
135
+ y = self._b_tild + e # Perturb data
136
+ sim = CGLS(self.M, y, self.current_point, self.maxit, self.tol)
137
+ self.current_point, _ = sim.solve()
138
+ acc = 1
139
+ return acc
140
+
141
+ def tune(self, skip_len, update_count):
142
+ pass
143
+
144
+ def validate_target(self):
145
+ # Check target type
146
+ if not isinstance(self.target, cuqi.distribution.Posterior):
147
+ raise ValueError(f"To initialize an object of type {self.__class__}, 'target' need to be of type 'cuqi.distribution.Posterior'.")
148
+
149
+ # Check Linear model
150
+ if not isinstance(self.likelihood.model, cuqi.model.LinearModel):
151
+ raise TypeError("Model needs to be linear")
152
+
153
+ # Check Gaussian likelihood
154
+ if not hasattr(self.likelihood.distribution, "sqrtprec"):
155
+ raise TypeError("Distribution in Likelihood must contain a sqrtprec attribute")
156
+
157
+ # Check that prior is LMRF
158
+ if not isinstance(self.prior, cuqi.distribution.LMRF):
159
+ raise ValueError('Unadjusted Gaussian Laplace approximation (UGLA) requires LMRF prior')