pygeoinf 1.0.8__py3-none-any.whl → 1.0.9__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.
- pygeoinf/direct_sum.py +17 -15
- pygeoinf/forms.py +17 -57
- pygeoinf/symmetric_space/sphere.py +13 -0
- {pygeoinf-1.0.8.dist-info → pygeoinf-1.0.9.dist-info}/METADATA +2 -1
- {pygeoinf-1.0.8.dist-info → pygeoinf-1.0.9.dist-info}/RECORD +7 -7
- {pygeoinf-1.0.8.dist-info → pygeoinf-1.0.9.dist-info}/LICENSE +0 -0
- {pygeoinf-1.0.8.dist-info → pygeoinf-1.0.9.dist-info}/WHEEL +0 -0
pygeoinf/direct_sum.py
CHANGED
|
@@ -119,12 +119,10 @@ class HilbertSpaceDirectSum(HilbertSpace):
|
|
|
119
119
|
"""
|
|
120
120
|
if len(xps) != self.number_of_subspaces:
|
|
121
121
|
raise ValueError("Incorrect number of dual vectors provided.")
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
),
|
|
127
|
-
)
|
|
122
|
+
|
|
123
|
+
cps = [space.dual.to_components(xp) for space, xp in zip(self._spaces, xps)]
|
|
124
|
+
cp = np.concatenate(cps, 0)
|
|
125
|
+
return LinearForm(self, components=cp)
|
|
128
126
|
|
|
129
127
|
def canonical_dual_inverse_isomorphism(self, xp: LinearForm) -> List[LinearForm]:
|
|
130
128
|
"""
|
|
@@ -136,12 +134,17 @@ class HilbertSpaceDirectSum(HilbertSpace):
|
|
|
136
134
|
Args:
|
|
137
135
|
xp (LinearForm): A dual vector on the direct sum space.
|
|
138
136
|
"""
|
|
139
|
-
return [
|
|
140
|
-
LinearForm(space, mapping=lambda x, j=i: xp(self.subspace_inclusion(j)(x)))
|
|
141
|
-
for i, space in enumerate(self.subspaces)
|
|
142
|
-
]
|
|
143
137
|
|
|
144
|
-
|
|
138
|
+
cp = self.dual.to_components(xp)
|
|
139
|
+
xps = []
|
|
140
|
+
i = 0
|
|
141
|
+
for space in self._spaces:
|
|
142
|
+
j = i + space.dim
|
|
143
|
+
xp = space.dual.from_components(cp[i:j])
|
|
144
|
+
xps.append(xp)
|
|
145
|
+
i = j
|
|
146
|
+
return xps
|
|
147
|
+
|
|
145
148
|
def __to_components(self, xs: List[Any]) -> np.ndarray:
|
|
146
149
|
cs = [space.to_components(x) for space, x in zip(self._spaces, xs)]
|
|
147
150
|
return np.concatenate(cs, 0)
|
|
@@ -204,7 +207,6 @@ class BlockStructure(ABC):
|
|
|
204
207
|
An abstract base class for operators with a block structure.
|
|
205
208
|
"""
|
|
206
209
|
|
|
207
|
-
# ... (class content is the same) ...
|
|
208
210
|
def __init__(self, row_dim: int, col_dim: int) -> None:
|
|
209
211
|
self._row_dim: int = row_dim
|
|
210
212
|
self._col_dim: int = col_dim
|
|
@@ -245,7 +247,7 @@ class BlockLinearOperator(LinearOperator, BlockStructure):
|
|
|
245
247
|
"""
|
|
246
248
|
if not blocks or not blocks[0]:
|
|
247
249
|
raise ValueError("Block structure cannot be empty.")
|
|
248
|
-
|
|
250
|
+
|
|
249
251
|
domains = [operator.domain for operator in blocks[0]]
|
|
250
252
|
codomains = []
|
|
251
253
|
for row in blocks:
|
|
@@ -281,7 +283,7 @@ class BlockLinearOperator(LinearOperator, BlockStructure):
|
|
|
281
283
|
return self._blocks[i][j]
|
|
282
284
|
|
|
283
285
|
def __mapping(self, xs: List[Any]) -> List[Any]:
|
|
284
|
-
|
|
286
|
+
|
|
285
287
|
ys = []
|
|
286
288
|
for i in range(self.row_dim):
|
|
287
289
|
codomain = self._codomains[i]
|
|
@@ -293,7 +295,7 @@ class BlockLinearOperator(LinearOperator, BlockStructure):
|
|
|
293
295
|
return ys
|
|
294
296
|
|
|
295
297
|
def __adjoint_mapping(self, ys: List[Any]) -> List[Any]:
|
|
296
|
-
|
|
298
|
+
|
|
297
299
|
xs = []
|
|
298
300
|
for j in range(self.col_dim):
|
|
299
301
|
domain = self._domains[j]
|
pygeoinf/forms.py
CHANGED
|
@@ -17,6 +17,9 @@ class LinearForm:
|
|
|
17
17
|
"""
|
|
18
18
|
Represents a linear form, which is a linear functional that maps
|
|
19
19
|
vectors from a Hilbert space to a scalar value (a real number).
|
|
20
|
+
|
|
21
|
+
Internally, the form is represented by its components relative to the basis for
|
|
22
|
+
its domain, with these components stored as in a numpy vector.
|
|
20
23
|
"""
|
|
21
24
|
|
|
22
25
|
def __init__(
|
|
@@ -40,19 +43,19 @@ class LinearForm:
|
|
|
40
43
|
"""
|
|
41
44
|
|
|
42
45
|
self._domain: "HilbertSpace" = domain
|
|
43
|
-
self._components: Optional[np.ndarray] = components
|
|
44
|
-
self._mapping: Callable[[Any], float]
|
|
45
46
|
|
|
46
47
|
if components is None:
|
|
47
48
|
if mapping is None:
|
|
48
49
|
raise AssertionError("Neither mapping nor components specified.")
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
self._components = np.zeros(self.domain.dim)
|
|
51
|
+
cx = np.zeros(self.domain.dim)
|
|
52
|
+
for i in range(self.domain.dim):
|
|
53
|
+
cx[i] = 1
|
|
54
|
+
x = self.domain.from_components(cx)
|
|
55
|
+
self._components[i] = mapping(x)
|
|
56
|
+
cx[i] = 0
|
|
51
57
|
else:
|
|
52
|
-
|
|
53
|
-
self._mapping = self._mapping_from_components
|
|
54
|
-
else:
|
|
55
|
-
self._mapping = mapping
|
|
58
|
+
self._components: np.ndarray = components
|
|
56
59
|
|
|
57
60
|
@staticmethod
|
|
58
61
|
def from_linear_operator(operator: "LinearOperator") -> "LinearForm":
|
|
@@ -69,35 +72,12 @@ class LinearForm:
|
|
|
69
72
|
"""The Hilbert space on which the form is defined."""
|
|
70
73
|
return self._domain
|
|
71
74
|
|
|
72
|
-
@property
|
|
73
|
-
def components_stored(self) -> bool:
|
|
74
|
-
"""True if the form's component vector is cached."""
|
|
75
|
-
return self._components is not None
|
|
76
|
-
|
|
77
75
|
@property
|
|
78
76
|
def components(self) -> np.ndarray:
|
|
79
77
|
"""
|
|
80
78
|
The component vector of the form.
|
|
81
|
-
|
|
82
|
-
The components are computed and cached on first access if not
|
|
83
|
-
provided during initialization.
|
|
84
79
|
"""
|
|
85
|
-
|
|
86
|
-
return self._components
|
|
87
|
-
else:
|
|
88
|
-
self.store_components()
|
|
89
|
-
return self.components
|
|
90
|
-
|
|
91
|
-
def store_components(self) -> None:
|
|
92
|
-
"""Computes and caches the component vector of the form."""
|
|
93
|
-
if not self.components_stored:
|
|
94
|
-
self._components = np.zeros(self.domain.dim)
|
|
95
|
-
cx = np.zeros(self.domain.dim)
|
|
96
|
-
for i in range(self.domain.dim):
|
|
97
|
-
cx[i] = 1
|
|
98
|
-
x = self.domain.from_components(cx)
|
|
99
|
-
self._components[i] = self(x)
|
|
100
|
-
cx[i] = 0
|
|
80
|
+
return self._components
|
|
101
81
|
|
|
102
82
|
@property
|
|
103
83
|
def as_linear_operator(self) -> "LinearOperator":
|
|
@@ -117,21 +97,15 @@ class LinearForm:
|
|
|
117
97
|
|
|
118
98
|
def __call__(self, x: Any) -> float:
|
|
119
99
|
"""Applies the linear form to a vector."""
|
|
120
|
-
return self.
|
|
100
|
+
return np.dot(self._components, self.domain.to_components(x))
|
|
121
101
|
|
|
122
102
|
def __neg__(self) -> "LinearForm":
|
|
123
103
|
"""Returns the additive inverse of the form."""
|
|
124
|
-
|
|
125
|
-
return LinearForm(self.domain, components=-self._components)
|
|
126
|
-
else:
|
|
127
|
-
return LinearForm(self.domain, mapping=lambda x: -self(x))
|
|
104
|
+
return LinearForm(self.domain, components=-self._components)
|
|
128
105
|
|
|
129
106
|
def __mul__(self, a: float) -> "LinearForm":
|
|
130
107
|
"""Returns the product of the form and a scalar."""
|
|
131
|
-
|
|
132
|
-
return LinearForm(self.domain, components=a * self._components)
|
|
133
|
-
else:
|
|
134
|
-
return LinearForm(self.domain, mapping=lambda x: a * self(x))
|
|
108
|
+
return LinearForm(self.domain, components=a * self._components)
|
|
135
109
|
|
|
136
110
|
def __rmul__(self, a: float) -> "LinearForm":
|
|
137
111
|
"""Returns the product of the form and a scalar."""
|
|
@@ -143,26 +117,12 @@ class LinearForm:
|
|
|
143
117
|
|
|
144
118
|
def __add__(self, other: "LinearForm") -> "LinearForm":
|
|
145
119
|
"""Returns the sum of this form and another."""
|
|
146
|
-
|
|
147
|
-
return LinearForm(
|
|
148
|
-
self.domain, components=self.components + other.components
|
|
149
|
-
)
|
|
150
|
-
else:
|
|
151
|
-
return LinearForm(self.domain, mapping=lambda x: self(x) + other(x))
|
|
120
|
+
return LinearForm(self.domain, components=self.components + other.components)
|
|
152
121
|
|
|
153
122
|
def __sub__(self, other: "LinearForm") -> "LinearForm":
|
|
154
123
|
"""Returns the difference between this form and another."""
|
|
155
|
-
|
|
156
|
-
return LinearForm(
|
|
157
|
-
self.domain, components=self.components - other.components
|
|
158
|
-
)
|
|
159
|
-
else:
|
|
160
|
-
return LinearForm(self.domain, mapping=lambda x: self(x) - other(x))
|
|
124
|
+
return LinearForm(self.domain, components=self.components - other.components)
|
|
161
125
|
|
|
162
126
|
def __str__(self) -> str:
|
|
163
127
|
"""Returns the string representation of the form's components."""
|
|
164
128
|
return self.components.__str__()
|
|
165
|
-
|
|
166
|
-
def _mapping_from_components(self, x: Any) -> float:
|
|
167
|
-
"""Implements the action of the form using its cached components."""
|
|
168
|
-
return np.dot(self._components, self.domain.to_components(x))
|
|
@@ -221,6 +221,19 @@ class Sobolev(SymmetricSpaceSobolev):
|
|
|
221
221
|
# Public methods #
|
|
222
222
|
# ==============================================#
|
|
223
223
|
|
|
224
|
+
def project_function(self, f: Callable[[(float, float)], float]) -> np.ndarray:
|
|
225
|
+
"""
|
|
226
|
+
Returns an element of the space by projecting a given function.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
f: A function that takes a point `(lat, lon)` and returns a value.
|
|
230
|
+
"""
|
|
231
|
+
u = self.zero
|
|
232
|
+
for j, lon in enumerate(u.lons()):
|
|
233
|
+
for i, lat in enumerate(u.lats()):
|
|
234
|
+
u.data[i, j] = f((lat, lon))
|
|
235
|
+
return u
|
|
236
|
+
|
|
224
237
|
def random_point(self) -> List[float]:
|
|
225
238
|
"""Returns a random point as `[latitude, longitude]`."""
|
|
226
239
|
latitude = np.random.uniform(-90.0, 90.0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pygeoinf
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.9
|
|
4
4
|
Summary: A package for solving geophysical inference and inverse problems
|
|
5
5
|
License: BSD-3-Clause
|
|
6
6
|
Author: David Al-Attar and Dan Heathcote
|
|
@@ -16,6 +16,7 @@ Requires-Dist: numpy (>=1.26.0)
|
|
|
16
16
|
Requires-Dist: pyqt6 (>=6.0.0)
|
|
17
17
|
Requires-Dist: pyshtools (>=4.0.0)
|
|
18
18
|
Requires-Dist: scipy (>=1.0.0)
|
|
19
|
+
Requires-Dist: snakeviz (>=2.2.2,<3.0.0)
|
|
19
20
|
Description-Content-Type: text/markdown
|
|
20
21
|
|
|
21
22
|
# pygeoinf: A Python Library for Geophysical Inference
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
pygeoinf/__init__.py,sha256=PsUfD2hfc-eoIz6fHSC-Mn3MHflaU07W2mHT6fLYKr0,1076
|
|
2
|
-
pygeoinf/direct_sum.py,sha256=
|
|
3
|
-
pygeoinf/forms.py,sha256=
|
|
2
|
+
pygeoinf/direct_sum.py,sha256=jgG1BTDfoU7rg_YYBKWZU08Ugj9Vfo7PaDuF3XXIcOo,15706
|
|
3
|
+
pygeoinf/forms.py,sha256=ddgXrRmM3CCBWjSE2RQUFbIlEiBCAlnVVIRwnQ50TaA,4362
|
|
4
4
|
pygeoinf/forward_problem.py,sha256=4V40qvHN4qAu8CXsxGAuJ5F9oukqXbXbGCARFpBYaD0,9546
|
|
5
5
|
pygeoinf/gaussian_measure.py,sha256=UEFViRtLYU730U4upV33KB_ksg78tpW0dwGVFgt1hOw,21595
|
|
6
6
|
pygeoinf/hilbert_space.py,sha256=m0wbzm2XIITs8KenwrNrgvRKilsf-KrX6SR0ylKyhLg,14342
|
|
@@ -13,9 +13,9 @@ pygeoinf/random_matrix.py,sha256=d6apC9Sd5ud-QgLnvvXaURdar3LiYJPwz-CYbDojH54,754
|
|
|
13
13
|
pygeoinf/symmetric_space/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
14
|
pygeoinf/symmetric_space/circle.py,sha256=TWjQwX42EvZ4-zOIJKATo8lVg0YbXRaQgxVzj6xXYlM,12467
|
|
15
15
|
pygeoinf/symmetric_space/line.py,sha256=FoZL5qVEVWzOkWwhbmwsg3D_0ceX9Nj8L8OJXQevtr4,13203
|
|
16
|
-
pygeoinf/symmetric_space/sphere.py,sha256=
|
|
16
|
+
pygeoinf/symmetric_space/sphere.py,sha256=re-TjugmBABcBpR5LEMhSCxJn0T_h3TRm4tjyGGwTyE,24664
|
|
17
17
|
pygeoinf/symmetric_space/symmetric_space.py,sha256=E-8lXZmW5WWaHgX-YTu--NwV6dXP3M7hIP3J3H6uv3U,9067
|
|
18
|
-
pygeoinf-1.0.
|
|
19
|
-
pygeoinf-1.0.
|
|
20
|
-
pygeoinf-1.0.
|
|
21
|
-
pygeoinf-1.0.
|
|
18
|
+
pygeoinf-1.0.9.dist-info/LICENSE,sha256=GrTQnKJemVi69FSbHprq60KN0OJGsOSR-joQoTq-oD8,1501
|
|
19
|
+
pygeoinf-1.0.9.dist-info/METADATA,sha256=HkPhf8yGiBK2x6bjYgATq-6rr8Y7oVxib31fBqcz_Po,14416
|
|
20
|
+
pygeoinf-1.0.9.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
21
|
+
pygeoinf-1.0.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|