CUQIpy 0.2.0.post0.dev116__tar.gz → 0.3.0__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 (93) hide show
  1. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/CUQIpy.egg-info/PKG-INFO +1 -1
  2. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/CUQIpy.egg-info/SOURCES.txt +2 -0
  3. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/CUQIpy.egg-info/dependency_links.txt +0 -0
  4. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/CUQIpy.egg-info/requires.txt +0 -0
  5. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/CUQIpy.egg-info/top_level.txt +0 -0
  6. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/LICENSE +0 -0
  7. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/PKG-INFO +1 -1
  8. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/README.md +0 -0
  9. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/__init__.py +1 -0
  10. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/_messages.py +0 -0
  11. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/_version.py +3 -3
  12. CUQIpy-0.3.0/cuqi/array/__init__.py +1 -0
  13. CUQIpy-0.3.0/cuqi/array/_array.py +108 -0
  14. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/config.py +0 -0
  15. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/data/__init__.py +0 -0
  16. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/data/_data.py +0 -0
  17. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/data/astronaut.npz +0 -0
  18. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/data/camera.npz +0 -0
  19. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/data/cat.npz +0 -0
  20. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/data/satellite.mat +0 -0
  21. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/density/__init__.py +0 -0
  22. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/density/_density.py +0 -0
  23. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/diagnostics.py +0 -0
  24. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/__init__.py +0 -0
  25. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_beta.py +0 -0
  26. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_cauchy_diff.py +0 -0
  27. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_custom.py +0 -0
  28. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_distribution.py +2 -1
  29. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_gamma.py +0 -0
  30. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_gaussian.py +0 -0
  31. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_gmrf.py +0 -0
  32. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_inverse_gamma.py +0 -0
  33. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_joint_distribution.py +0 -0
  34. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_laplace.py +0 -0
  35. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_laplace_diff.py +0 -0
  36. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_lmrf.py +0 -0
  37. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_lognormal.py +0 -0
  38. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_normal.py +0 -0
  39. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_posterior.py +0 -0
  40. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/distribution/_uniform.py +0 -0
  41. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/geometry/__init__.py +0 -0
  42. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/geometry/_geometry.py +0 -0
  43. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/likelihood/__init__.py +0 -0
  44. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/likelihood/_likelihood.py +1 -1
  45. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/model/__init__.py +0 -0
  46. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/model/_model.py +13 -12
  47. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/operator/__init__.py +0 -0
  48. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/operator/_operator.py +0 -0
  49. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/pde/__init__.py +0 -0
  50. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/pde/_pde.py +0 -0
  51. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/problem/__init__.py +0 -0
  52. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/problem/_problem.py +3 -3
  53. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/sampler/__init__.py +0 -0
  54. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/sampler/_conjugate.py +0 -0
  55. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/sampler/_conjugate_approx.py +0 -0
  56. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/sampler/_cwmh.py +0 -0
  57. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/sampler/_gibbs.py +0 -0
  58. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/sampler/_hmc.py +0 -0
  59. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/sampler/_langevin_algorithm.py +0 -0
  60. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/sampler/_laplace_approximation.py +0 -0
  61. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/sampler/_mh.py +0 -0
  62. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/sampler/_pcn.py +0 -0
  63. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/sampler/_rto.py +0 -0
  64. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/sampler/_sampler.py +0 -0
  65. CUQIpy-0.3.0/cuqi/samples/__init__.py +1 -0
  66. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/samples/_samples.py +1 -157
  67. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/solver/__init__.py +0 -0
  68. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/solver/_solver.py +2 -2
  69. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/testproblem/__init__.py +0 -0
  70. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/testproblem/_testproblem.py +2 -1
  71. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/utilities/__init__.py +0 -0
  72. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/utilities/_get_python_variable_name.py +0 -0
  73. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/cuqi/utilities/_utilities.py +1 -1
  74. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/pyproject.toml +0 -0
  75. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/requirements.txt +0 -0
  76. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/setup.cfg +0 -0
  77. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/setup.py +0 -0
  78. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_abstract_distribution_density.py +0 -0
  79. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_bayesian_inversion.py +0 -0
  80. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_density.py +0 -0
  81. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_distribution.py +0 -0
  82. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_geometry.py +1 -1
  83. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_joint_distribution.py +0 -0
  84. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_likelihood.py +0 -0
  85. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_model.py +9 -9
  86. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_pde.py +0 -0
  87. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_problem.py +0 -0
  88. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_sampler.py +0 -0
  89. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_samples.py +3 -3
  90. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_solver.py +0 -0
  91. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_testproblem.py +0 -0
  92. {CUQIpy-0.2.0.post0.dev116 → CUQIpy-0.3.0}/tests/test_utilities.py +0 -0
  93. CUQIpy-0.2.0.post0.dev116/cuqi/samples/__init__.py +0 -1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: CUQIpy
3
- Version: 0.2.0.post0.dev116
3
+ Version: 0.3.0
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>
6
6
  License: Apache License
@@ -13,6 +13,8 @@ cuqi/_messages.py
13
13
  cuqi/_version.py
14
14
  cuqi/config.py
15
15
  cuqi/diagnostics.py
16
+ cuqi/array/__init__.py
17
+ cuqi/array/_array.py
16
18
  cuqi/data/__init__.py
17
19
  cuqi/data/_data.py
18
20
  cuqi/data/astronaut.npz
File without changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: CUQIpy
3
- Version: 0.2.0.post0.dev116
3
+ Version: 0.3.0
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>
6
6
  License: Apache License
File without changes
@@ -9,6 +9,7 @@ from . import operator
9
9
  from . import pde
10
10
  from . import problem
11
11
  from . import sampler
12
+ from . import array
12
13
  from . import samples
13
14
  from . import solver
14
15
  from . import testproblem
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2023-02-22T10:07:14+0100",
11
+ "date": "2023-02-22T10:23:18+0100",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "336a1e76c4a7d7896ccb72c51fc5a4487c00eb1b",
15
- "version": "0.2.0.post0.dev116"
14
+ "full-revisionid": "e122312d87e155e56afba81b81b0b880b545f99f",
15
+ "version": "0.3.0"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -0,0 +1 @@
1
+ from ._array import CUQIarray
@@ -0,0 +1,108 @@
1
+ import numpy as np
2
+ from cuqi.geometry import _DefaultGeometry
3
+
4
+
5
+ class CUQIarray(np.ndarray):
6
+ """
7
+ A class to represent data arrays, subclassed from numpy array, along with geometry and plotting
8
+
9
+ Parameters
10
+ ----------
11
+ input_array : ndarray
12
+ A numpy array holding the parameter or function values.
13
+
14
+ is_par : bool, default True
15
+ Boolean flag whether input_array is to be interpreted as parameter (True) or function values (False).
16
+
17
+ geometry : cuqi.geometry.Geometry, default None
18
+ Contains the geometry related of the data
19
+
20
+ Attributes
21
+ ----------
22
+ funvals : CUQIarray
23
+ Returns itself as function values.
24
+
25
+ parameters : CUQIarray
26
+ Returns itself as parameters.
27
+
28
+ Methods
29
+ ----------
30
+ :meth:`plot`: Plots the data as function or parameters.
31
+ """
32
+
33
+ def __repr__(self) -> str:
34
+ return "CUQIarray: NumPy array wrapped with geometry.\n" + \
35
+ "---------------------------------------------\n\n" + \
36
+ "Geometry:\n {}\n\n".format(self.geometry) + \
37
+ "Parameters:\n {}\n\n".format(self.is_par) + \
38
+ "Array:\n" + \
39
+ super().__repr__()
40
+
41
+ def __new__(cls, input_array, is_par=True, geometry=None):
42
+ # Input array is an already formed ndarray instance
43
+ # We first cast to be our class type
44
+ obj = np.asarray(input_array).view(cls)
45
+ # add the new attribute to the created instance
46
+ obj.is_par = is_par
47
+ if (not is_par) and (geometry is None):
48
+ raise ValueError("geometry cannot be none when initializing a CUQIarray as function values (with is_par False).")
49
+ if is_par and (obj.ndim>1):
50
+ raise ValueError("input_array cannot be multidimensional when initializing CUQIarray as parameter (with is_par True).")
51
+ if geometry is None:
52
+ geometry = _DefaultGeometry(grid=obj.__len__())
53
+ obj.geometry = geometry
54
+ # Finally, we must return the newly created object:
55
+ return obj
56
+
57
+ def __array_finalize__(self, obj):
58
+ # see InfoArray.__array_finalize__ for comments
59
+ if obj is None: return
60
+ self.is_par = getattr(obj, 'is_par', True)
61
+ self.geometry = getattr(obj, 'geometry', None)
62
+
63
+ @property
64
+ def funvals(self):
65
+ if self.is_par is True:
66
+ vals = self.geometry.par2fun(self)
67
+ else:
68
+ vals = self
69
+
70
+ if isinstance(vals, np.ndarray):
71
+ if vals.dtype == np.dtype('O'):
72
+ # if vals is of type np.ndarray, but the data type of the array
73
+ # is object (e.g. FEniCS function), then extract the object and
74
+ # return it. reshape(1) is needed to convert the shape from
75
+ # () to (1,).
76
+ return self.reshape(1)[0]
77
+ else:
78
+ # else, cast the np.ndarray to a CUQIarray
79
+ return type(self)(vals,is_par=False,geometry=self.geometry) #vals.view(np.ndarray)
80
+ else:
81
+ return vals
82
+
83
+ @property
84
+ def parameters(self):
85
+ if self.is_par is False:
86
+ vals = self.geometry.fun2par(self)
87
+ else:
88
+ vals = self
89
+ return type(self)(vals,is_par=True,geometry=self.geometry)
90
+
91
+ def to_numpy(self):
92
+ """Return a numpy array of the CUQIarray data. If is_par is True, then
93
+ the parameters are returned as numpy.ndarray. If is_par is False, then
94
+ the function values are returned instead.
95
+ """
96
+ try:
97
+ return self.view(np.ndarray)
98
+ except:
99
+ raise ValueError(
100
+ f"Cannot convert {self.__class__.__name__} to numpy array")
101
+
102
+ def plot(self, plot_par=False, **kwargs):
103
+ if plot_par:
104
+ kwargs["is_par"]=True
105
+ return self.geometry.plot(self.parameters, plot_par=plot_par, **kwargs)
106
+ else:
107
+ kwargs["is_par"]=False
108
+ return self.geometry.plot(self.funvals, **kwargs)
@@ -5,7 +5,8 @@ from copy import copy
5
5
  from functools import partial
6
6
  from cuqi.density import Density, EvaluatedDensity
7
7
  from cuqi.likelihood import Likelihood
8
- from cuqi.samples import Samples, CUQIarray
8
+ from cuqi.samples import Samples
9
+ from cuqi.array import CUQIarray
9
10
  from cuqi.geometry import _DefaultGeometry, Geometry
10
11
  from cuqi.utilities import infer_len, get_writeable_attributes, get_writeable_properties, get_non_default_args, get_indirect_variables
11
12
  import numpy as np # To be replaced by cuqi.array_api
@@ -21,7 +21,7 @@ class Likelihood(Density):
21
21
  distribution : ~cuqi.distribution.Distribution
22
22
  | Distribution to create likelihood from.
23
23
 
24
- data : ~cuqi.samples.CUQIarray or array_like
24
+ data : ~cuqi.array.CUQIarray or array_like
25
25
  | Observation to create likelihood from.
26
26
 
27
27
  """
@@ -2,7 +2,8 @@ import numpy as np
2
2
  from scipy.sparse import csc_matrix
3
3
  from scipy.sparse import hstack
4
4
  from scipy.linalg import solve
5
- from cuqi.samples import Samples, CUQIarray
5
+ from cuqi.samples import Samples
6
+ from cuqi.array import CUQIarray
6
7
  from cuqi.geometry import Geometry, _DefaultGeometry, _get_identity_geometries
7
8
  import cuqi
8
9
  import matplotlib.pyplot as plt
@@ -93,7 +94,7 @@ class Model(object):
93
94
 
94
95
  Parameters
95
96
  ----------
96
- x : ndarray or cuqi.samples.CUQIarray
97
+ x : ndarray or cuqi.array.CUQIarray
97
98
  The input value to be converted.
98
99
 
99
100
  geometry : cuqi.geometry.Geometry
@@ -105,7 +106,7 @@ class Model(object):
105
106
 
106
107
  Returns
107
108
  -------
108
- ndarray or cuqi.samples.CUQIarray
109
+ ndarray or cuqi.array.CUQIarray
109
110
  The input value represented as a function.
110
111
  """
111
112
  if type(x) is CUQIarray and not isinstance(x.geometry, _DefaultGeometry):
@@ -120,18 +121,18 @@ class Model(object):
120
121
 
121
122
  Parameters
122
123
  ----------
123
- out : ndarray or cuqi.samples.CUQIarray
124
+ out : ndarray or cuqi.array.CUQIarray
124
125
  The output value to be converted.
125
126
 
126
127
  geometry : cuqi.geometry.Geometry
127
128
  The geometry representing the argument `out`.
128
129
 
129
130
  to_CUQIarray : bool
130
- If True, the output is wrapped as a cuqi.samples.CUQIarray.
131
+ If True, the output is wrapped as a cuqi.array.CUQIarray.
131
132
 
132
133
  Returns
133
134
  -------
134
- ndarray or cuqi.samples.CUQIarray
135
+ ndarray or cuqi.array.CUQIarray
135
136
  The output value represented as parameters.
136
137
  """
137
138
  out = geometry.fun2par(out)
@@ -156,7 +157,7 @@ class Model(object):
156
157
  func_domain_geometry : cuqi.geometry.Geometry
157
158
  The geometry representing the function `func` domain.
158
159
 
159
- x : ndarray or cuqi.samples.CUQIarray
160
+ x : ndarray or cuqi.array.CUQIarray
160
161
  The input value to the operator.
161
162
 
162
163
  is_par : bool
@@ -165,7 +166,7 @@ class Model(object):
165
166
 
166
167
  Returns
167
168
  -------
168
- ndarray or cuqi.samples.CUQIarray
169
+ ndarray or cuqi.array.CUQIarray
169
170
  The output of the function `func` converted to parameters.
170
171
  """
171
172
  # If input x is Samples we apply func for each sample
@@ -211,7 +212,7 @@ class Model(object):
211
212
 
212
213
  Parameters
213
214
  ----------
214
- *args : ndarray or cuqi.samples.CUQIarray
215
+ *args : ndarray or cuqi.array.CUQIarray
215
216
  The model input.
216
217
 
217
218
  is_par : bool
@@ -223,7 +224,7 @@ class Model(object):
223
224
 
224
225
  Returns
225
226
  -------
226
- ndarray or cuqi.samples.CUQIarray
227
+ ndarray or cuqi.array.CUQIarray
227
228
  The model output. Always returned as parameters.
228
229
  """
229
230
 
@@ -426,12 +427,12 @@ class LinearModel(Model):
426
427
 
427
428
  Parameters
428
429
  ----------
429
- y : ndarray or cuqi.samples.CUQIarray
430
+ y : ndarray or cuqi.array.CUQIarray
430
431
  The adjoint model input.
431
432
 
432
433
  Returns
433
434
  -------
434
- ndarray or cuqi.samples.CUQIarray
435
+ ndarray or cuqi.array.CUQIarray
435
436
  The adjoint model output. Always returned as parameters.
436
437
  """
437
438
  return self._apply_func(self._adjoint_func,
@@ -11,7 +11,7 @@ from cuqi.model import LinearModel, Model
11
11
  from cuqi.likelihood import Likelihood
12
12
  from cuqi.geometry import _DefaultGeometry
13
13
  from cuqi.utilities import ProblemInfo
14
- from cuqi.samples import CUQIarray
14
+ from cuqi.array import CUQIarray
15
15
 
16
16
  from copy import copy
17
17
 
@@ -228,7 +228,7 @@ class BayesianProblem(object):
228
228
  x_ML, solver_info = self._solve_max_point(self.likelihood, disp=disp, x0=x0)
229
229
 
230
230
  # Wrap the result in a CUQIarray and add solver info
231
- x_ML = cuqi.samples.CUQIarray(x_ML, geometry=self.likelihood.geometry)
231
+ x_ML = cuqi.array.CUQIarray(x_ML, geometry=self.likelihood.geometry)
232
232
  x_ML.info = solver_info
233
233
 
234
234
  return x_ML
@@ -285,7 +285,7 @@ class BayesianProblem(object):
285
285
  x_MAP, solver_info = self._solve_max_point(self.posterior, disp=disp, x0=x0)
286
286
 
287
287
  # Wrap the result in a CUQIarray and add solver info
288
- x_MAP = cuqi.samples.CUQIarray(x_MAP, geometry=self.posterior.geometry)
288
+ x_MAP = cuqi.array.CUQIarray(x_MAP, geometry=self.posterior.geometry)
289
289
  x_MAP.info = solver_info
290
290
  return x_MAP
291
291
 
@@ -0,0 +1 @@
1
+ from ._samples import Samples
@@ -1,168 +1,12 @@
1
- import warnings
2
1
  import numpy as np
3
2
  import matplotlib.pyplot as plt
4
3
  from cuqi.diagnostics import Geweke
5
4
  from cuqi.geometry import _DefaultGeometry, Continuous2D, Image2D
5
+ from cuqi.array import CUQIarray
6
6
  from copy import copy
7
7
  import arviz # Plotting tool
8
8
 
9
9
 
10
- class CUQIarray(np.ndarray):
11
- """
12
- A class to represent data arrays, subclassed from numpy array, along with geometry and plotting
13
-
14
- Parameters
15
- ----------
16
- input_array : ndarray
17
- A numpy array holding the parameter or function values.
18
-
19
- is_par : bool, default True
20
- Boolean flag whether input_array is to be interpreted as parameter (True) or function values (False).
21
-
22
- geometry : cuqi.geometry.Geometry, default None
23
- Contains the geometry related of the data
24
-
25
- Attributes
26
- ----------
27
- funvals : CUQIarray
28
- Returns itself as function values.
29
-
30
- parameters : CUQIarray
31
- Returns itself as parameters.
32
-
33
- Methods
34
- ----------
35
- :meth:`plot`: Plots the data as function or parameters.
36
- """
37
-
38
- def __repr__(self) -> str:
39
- return "CUQIarray: NumPy array wrapped with geometry.\n" + \
40
- "---------------------------------------------\n\n" + \
41
- "Geometry:\n {}\n\n".format(self.geometry) + \
42
- "Parameters:\n {}\n\n".format(self.is_par) + \
43
- "Array:\n" + \
44
- super().__repr__()
45
-
46
- def __new__(cls, input_array, is_par=True, geometry=None):
47
- # Input array is an already formed ndarray instance
48
- # We first cast to be our class type
49
- obj = np.asarray(input_array).view(cls)
50
- # add the new attribute to the created instance
51
- obj.is_par = is_par
52
- if (not is_par) and (geometry is None):
53
- raise ValueError("geometry cannot be none when initializing a CUQIarray as function values (with is_par False).")
54
- if is_par and (obj.ndim>1):
55
- raise ValueError("input_array cannot be multidimensional when initializing CUQIarray as parameter (with is_par True).")
56
- if geometry is None:
57
- geometry = _DefaultGeometry(grid=obj.__len__())
58
- obj.geometry = geometry
59
- # Finally, we must return the newly created object:
60
- return obj
61
-
62
- def __array_finalize__(self, obj):
63
- # see InfoArray.__array_finalize__ for comments
64
- if obj is None: return
65
- self.is_par = getattr(obj, 'is_par', True)
66
- self.geometry = getattr(obj, 'geometry', None)
67
-
68
- @property
69
- def funvals(self):
70
- if self.is_par is True:
71
- vals = self.geometry.par2fun(self)
72
- else:
73
- vals = self
74
-
75
- if isinstance(vals, np.ndarray):
76
- if vals.dtype == np.dtype('O'):
77
- # if vals is of type np.ndarray, but the data type of the array
78
- # is object (e.g. FEniCS function), then extract the object and
79
- # return it. reshape(1) is needed to convert the shape from
80
- # () to (1,).
81
- return self.reshape(1)[0]
82
- else:
83
- # else, cast the np.ndarray to a CUQIarray
84
- return type(self)(vals,is_par=False,geometry=self.geometry) #vals.view(np.ndarray)
85
- else:
86
- return vals
87
-
88
- @property
89
- def parameters(self):
90
- if self.is_par is False:
91
- vals = self.geometry.fun2par(self)
92
- else:
93
- vals = self
94
- return type(self)(vals,is_par=True,geometry=self.geometry)
95
-
96
- def to_numpy(self):
97
- """Return a numpy array of the CUQIarray data. If is_par is True, then
98
- the parameters are returned as numpy.ndarray. If is_par is False, then
99
- the function values are returned instead.
100
- """
101
- try:
102
- return self.view(np.ndarray)
103
- except:
104
- raise ValueError(
105
- f"Cannot convert {self.__class__.__name__} to numpy array")
106
-
107
- def plot(self, plot_par=False, **kwargs):
108
- if plot_par:
109
- kwargs["is_par"]=True
110
- return self.geometry.plot(self.parameters, plot_par=plot_par, **kwargs)
111
- else:
112
- kwargs["is_par"]=False
113
- return self.geometry.plot(self.funvals, **kwargs)
114
-
115
-
116
- class Data(object):
117
- """
118
- An container type object to represent data objects equipped with geometry.
119
- """
120
-
121
- def __init__(self, parameters=None, geometry=None, funvals=None):
122
-
123
- # Allow setting either parameter or function values, but not both.
124
- # If both provided, function values take precedence (to be confirmed).
125
- if parameters is not None and funvals is not None:
126
- parameters = None
127
-
128
- if parameters is not None:
129
- self.parameters = parameters
130
-
131
- if funvals is not None:
132
- self.funvals = funvals
133
-
134
- self.geometry = geometry
135
-
136
- def plot(self, plot_par=False, **kwargs):
137
- if plot_par:
138
- self.geometry.plot(self.parameters, plot_par=plot_par, is_par=True, **kwargs)
139
- else:
140
- self.geometry.plot(self.funvals, is_par=False, **kwargs)
141
-
142
- @property
143
- def parameters(self):
144
- return self._parameters
145
-
146
- @parameters.setter
147
- def parameters(self, value):
148
- self._parameters = value
149
- self.has_parameters = True
150
- self.has_funvals = False
151
-
152
- @property
153
- def funvals(self):
154
- if self.has_funvals:
155
- return self._funvals
156
- else:
157
- return self.geometry.par2fun(self.parameters)
158
-
159
- @funvals.setter
160
- def funvals(self, value):
161
- self.has_funvals = True
162
- self.has_parameters = False
163
- self._funvals = value
164
-
165
-
166
10
  class Samples(object):
167
11
  """
168
12
  An object used to store samples from distributions.
@@ -4,7 +4,7 @@ from scipy.optimize import fmin_l_bfgs_b, least_squares
4
4
  import scipy.optimize as opt
5
5
  import scipy.sparse as spa
6
6
 
7
- from cuqi.samples import CUQIarray
7
+ from cuqi.array import CUQIarray
8
8
  from cuqi import config
9
9
  eps = np.finfo(float).eps
10
10
 
@@ -564,4 +564,4 @@ class LM(object):
564
564
  class PDHG(object):
565
565
  """Primal-Dual Hybrid Gradient algorithm."""
566
566
  def __init__(self):
567
- raise NotImplementedError
567
+ raise NotImplementedError
@@ -10,10 +10,11 @@ from cuqi.model import LinearModel
10
10
  from cuqi.distribution import Gaussian
11
11
  from cuqi.problem import BayesianProblem
12
12
  from cuqi.geometry import Geometry, MappedGeometry, StepExpansion, KLExpansion, KLExpansion_Full, CustomKL, Continuous1D, Continuous2D, Image2D
13
- from cuqi.samples import CUQIarray
13
+ from cuqi.array import CUQIarray
14
14
  import warnings
15
15
 
16
16
 
17
+
17
18
  #=============================================================================
18
19
  class _Deblur(BayesianProblem):
19
20
  """
@@ -1,4 +1,4 @@
1
- from cuqi.samples import CUQIarray
1
+ from cuqi.array import CUQIarray
2
2
  import numpy as np
3
3
  import inspect
4
4
  from numbers import Number
File without changes
File without changes
@@ -164,7 +164,7 @@ def test_stepExpansion_fun2par(projection, func):
164
164
  SE_geom = cuqi.geometry.StepExpansion(grid, n_steps=n_steps, fun2par_projection=projection)
165
165
 
166
166
  # Create cuqi array of function values
167
- qa_f = cuqi.samples.CUQIarray(np.random.rand(len(grid)), is_par=False, geometry = SE_geom)
167
+ qa_f = cuqi.array.CUQIarray(np.random.rand(len(grid)), is_par=False, geometry = SE_geom)
168
168
 
169
169
  # Compute projection manually (function value to parameters)
170
170
  p = np.empty(n_steps)
@@ -1,4 +1,4 @@
1
- from cuqi.samples import CUQIarray
1
+ from cuqi.array import CUQIarray
2
2
  from cuqi.geometry import Continuous1D
3
3
  import numpy as np
4
4
  import scipy as sp
@@ -61,9 +61,9 @@ def test_model_allow_DefaultGeometry():
61
61
  [5, 2, 6]]).T),
62
62
  cuqi.samples.Samples),
63
63
 
64
- (cuqi.samples.CUQIarray(np.array([1, 3, 4]),
64
+ (cuqi.array.CUQIarray(np.array([1, 3, 4]),
65
65
  geometry=cuqi.geometry.Continuous1D(3)),
66
- cuqi.samples.CUQIarray)])
66
+ cuqi.array.CUQIarray)])
67
67
  def test_forward(x, expected_type):
68
68
  """For different types of input to the model forward method, assert we are obtaining the correct output type"""
69
69
  A = np.array([[1, 0, 0],[0, 3, .1]])
@@ -86,9 +86,9 @@ def test_forward(x, expected_type):
86
86
  [5, 2]])),
87
87
  cuqi.samples.Samples),
88
88
 
89
- (cuqi.samples.CUQIarray(np.array([1, 3]),
89
+ (cuqi.array.CUQIarray(np.array([1, 3]),
90
90
  geometry=cuqi.geometry.Continuous1D(2)),
91
- cuqi.samples.CUQIarray)])
91
+ cuqi.array.CUQIarray)])
92
92
  def test_adjoint(x, expected_type):
93
93
  """For different types of input to the model adjoint method, assert we are obtaining the correct output type"""
94
94
  A = np.array([[1, 0, 0],[0, 3, .1]])
@@ -109,9 +109,9 @@ def test_adjoint(x, expected_type):
109
109
  [2, 6]]).T),
110
110
  cuqi.samples.Samples),
111
111
 
112
- (cuqi.samples.CUQIarray(np.array([3, 4]),
112
+ (cuqi.array.CUQIarray(np.array([3, 4]),
113
113
  geometry=cuqi.geometry.Continuous1D(2)),
114
- cuqi.samples.CUQIarray)])
114
+ cuqi.array.CUQIarray)])
115
115
  def test_gradient(direction, expected_type):
116
116
  """For different types of input to the model gradient method, assert we are obtaining the correct output type"""
117
117
  A = np.array([[1, 0, 0],[0, 3, .1]])
@@ -246,7 +246,7 @@ def test_gradient_raised_errors(wrt, is_wrt_par, case_id):
246
246
  lambda direction, x: np.diag(
247
247
  np.cos(x))@direction,
248
248
  np.array([1, 1, 4]),
249
- cuqi.samples.CUQIarray(
249
+ cuqi.array.CUQIarray(
250
250
  np.array([1, 12**2, 8**2]), is_par=False, geometry=Continuous1D(3)), # Geometry will be updated
251
251
  cuqi.geometry.MappedGeometry(Continuous1D(
252
252
  3), map=lambda x:x**2, imap=lambda x:np.sqrt(x)),
@@ -272,7 +272,7 @@ def test_gradient_raised_errors(wrt, is_wrt_par, case_id):
272
272
  lambda x: np.sin(x),
273
273
  lambda direction, x: np.diag(
274
274
  np.cos(x))@direction,
275
- cuqi.samples.CUQIarray(
275
+ cuqi.array.CUQIarray(
276
276
  np.array([1, 1, 4]), is_par=False, geometry=Continuous1D(3)), # Geometry will be updated
277
277
  np.array([1, 12, 8]),
278
278
  cuqi.geometry.MappedGeometry(Continuous1D(
@@ -272,19 +272,19 @@ def test_parameters_property(geom, map, imap, supported):
272
272
 
273
273
  def test_cuqiarray_default_geometry():
274
274
  """ Test that CUQIarray creates a default geometry when no geometry is passed"""
275
- v = cuqi.samples.CUQIarray([0,1,2,3,4,5,6,7,8])
275
+ v = cuqi.array.CUQIarray([0,1,2,3,4,5,6,7,8])
276
276
  assert type(v.geometry) is cuqi.geometry._geometry._DefaultGeometry
277
277
 
278
278
  def test_cuqiarray_multidim():
279
279
  X = np.array([[1, 2], [3,4]])
280
280
  with pytest.raises(Exception) as e:
281
- C = cuqi.samples.CUQIarray(X)
281
+ C = cuqi.array.CUQIarray(X)
282
282
  assert "input_array cannot be multidimensional when initializing CUQIarray as parameter (with is_par True)." in str(e.value) # this message
283
283
  assert e.type == ValueError
284
284
 
285
285
  def test_cuqiarray_ispar_false_without_geometry():
286
286
  with pytest.raises(Exception) as e:
287
- X = cuqi.samples.CUQIarray([1,2,3], is_par=False)
287
+ X = cuqi.array.CUQIarray([1,2,3], is_par=False)
288
288
  assert "geometry cannot be none when initializing a CUQIarray as function values (with is_par False)." in str(e.value) # this message
289
289
  assert e.type == ValueError
290
290
 
@@ -1 +0,0 @@
1
- from ._samples import CUQIarray, Samples, Data