CUQIpy 0.4.0__py3-none-any.whl → 0.4.0.post0.dev19__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.
- {CUQIpy-0.4.0.dist-info → CUQIpy-0.4.0.post0.dev19.dist-info}/METADATA +1 -1
- {CUQIpy-0.4.0.dist-info → CUQIpy-0.4.0.post0.dev19.dist-info}/RECORD +7 -7
- cuqi/_version.py +3 -3
- cuqi/pde/_pde.py +59 -16
- {CUQIpy-0.4.0.dist-info → CUQIpy-0.4.0.post0.dev19.dist-info}/LICENSE +0 -0
- {CUQIpy-0.4.0.dist-info → CUQIpy-0.4.0.post0.dev19.dist-info}/WHEEL +0 -0
- {CUQIpy-0.4.0.dist-info → CUQIpy-0.4.0.post0.dev19.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: CUQIpy
|
|
3
|
-
Version: 0.4.0
|
|
3
|
+
Version: 0.4.0.post0.dev19
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
cuqi/__init__.py,sha256=K0ss2HNqoLUX7wGpSZdaPKxIaKdRS452fcJm4D0pcEs,433
|
|
2
2
|
cuqi/_messages.py,sha256=fzEBrZT2kbmfecBBPm7spVu7yHdxGARQB4QzXhJbCJ0,415
|
|
3
|
-
cuqi/_version.py,sha256=
|
|
3
|
+
cuqi/_version.py,sha256=JZ7qGpXX_2jvjPCycacUOXXKJPcOS4cR_KiL1scwDxg,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
|
|
@@ -39,7 +39,7 @@ cuqi/model/_model.py,sha256=Q_Mg48adoiv9WZKzzSA_kuyy8mEzXKjR9QM1QnpRTPA,24201
|
|
|
39
39
|
cuqi/operator/__init__.py,sha256=0pc9p-KPyl7KtPV0noB0ddI0CP2iYEHw5rbw49D8Njk,136
|
|
40
40
|
cuqi/operator/_operator.py,sha256=yNwPTh7jR07AiKMbMQQ5_54EgirlKFsbq9JN1EODaQI,8856
|
|
41
41
|
cuqi/pde/__init__.py,sha256=NyS_ZYruCvy-Yg24qKlwm3ZIX058kLNQX9bqs-xg4ZM,99
|
|
42
|
-
cuqi/pde/_pde.py,sha256=
|
|
42
|
+
cuqi/pde/_pde.py,sha256=WRkOYyIdT_T3aZepRh0aS9C5nBbUZUcHaA80iSRvgoo,12572
|
|
43
43
|
cuqi/problem/__init__.py,sha256=JxJty4JqHTOqSG6NeTGiXRQ7OLxiRK9jvVq3lXLeIRw,38
|
|
44
44
|
cuqi/problem/_problem.py,sha256=jQ1SXFhS9vbjPOu2EgfXfi3MnioM9r49rSPLlDuMpBY,28944
|
|
45
45
|
cuqi/sampler/__init__.py,sha256=2Rt-ISO5-bNECKOG_JbnLqtwnu9vKnYssmZV1QF-rvQ,361
|
|
@@ -63,8 +63,8 @@ cuqi/testproblem/_testproblem.py,sha256=1a52jc92NqsLRGyM5DLySNW0lVVOC6tkyKM_QV4K
|
|
|
63
63
|
cuqi/utilities/__init__.py,sha256=EfxHLdsyDNugbmbzs43nV_AeKcycM9sVBjG9WZydagA,351
|
|
64
64
|
cuqi/utilities/_get_python_variable_name.py,sha256=QwlBVj2koJRA8s8pWd554p7-ElcI7HUwY32HknaR92E,1827
|
|
65
65
|
cuqi/utilities/_utilities.py,sha256=rjycaxDWExdskIfYXV1z5ZlB0JTlqv3tCmKf08i6U5c,7973
|
|
66
|
-
CUQIpy-0.4.0.dist-info/LICENSE,sha256=kJWRPrtRoQoZGXyyvu50Uc91X6_0XRaVfT0YZssicys,10799
|
|
67
|
-
CUQIpy-0.4.0.dist-info/METADATA,sha256=
|
|
68
|
-
CUQIpy-0.4.0.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
69
|
-
CUQIpy-0.4.0.dist-info/top_level.txt,sha256=AgmgMc6TKfPPqbjV0kvAoCBN334i_Lwwojc7HE3ZwD0,5
|
|
70
|
-
CUQIpy-0.4.0.dist-info/RECORD,,
|
|
66
|
+
CUQIpy-0.4.0.post0.dev19.dist-info/LICENSE,sha256=kJWRPrtRoQoZGXyyvu50Uc91X6_0XRaVfT0YZssicys,10799
|
|
67
|
+
CUQIpy-0.4.0.post0.dev19.dist-info/METADATA,sha256=tIno8lEYjygD8oI8fQCKj3R69T1IwbERJA6fGMVVA44,16455
|
|
68
|
+
CUQIpy-0.4.0.post0.dev19.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
69
|
+
CUQIpy-0.4.0.post0.dev19.dist-info/top_level.txt,sha256=AgmgMc6TKfPPqbjV0kvAoCBN334i_Lwwojc7HE3ZwD0,5
|
|
70
|
+
CUQIpy-0.4.0.post0.dev19.dist-info/RECORD,,
|
cuqi/_version.py
CHANGED
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2023-
|
|
11
|
+
"date": "2023-06-09T10:16:49+0200",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "0.4.0"
|
|
14
|
+
"full-revisionid": "d7e4a312b9c749d530f7cf3c06068857ab6b2fe2",
|
|
15
|
+
"version": "0.4.0.post0.dev19"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
cuqi/pde/_pde.py
CHANGED
|
@@ -84,6 +84,8 @@ class PDE(ABC):
|
|
|
84
84
|
|
|
85
85
|
@grid_obs.setter
|
|
86
86
|
def grid_obs(self,value):
|
|
87
|
+
if value is None:
|
|
88
|
+
value = self.grid_sol
|
|
87
89
|
self._grids_equal = self._compare_grid(value,self.grid_sol)
|
|
88
90
|
self._grid_obs = value
|
|
89
91
|
|
|
@@ -186,7 +188,10 @@ class TimeDependentLinearPDE(LinearPDE):
|
|
|
186
188
|
Callable function with signature `PDE_form(parameter, t)` where `parameter` is the Bayesian parameter and `t` is the time at which the PDE form is evaluated. The function returns a tuple of (`differential_operator`, `source_term`, `initial_condition`) where `differential_operator` is the linear operator at time `t`, `source_term` is the source term at time `t`, and `initial_condition` is the initial condition. The types of `differential_operator` and `source_term` are determined by what the method :meth:`linalg_solve` accepts as linear operator and right-hand side, respectively. The type of `initial_condition` should be the same type as the solution returned by :meth:`linalg_solve`.
|
|
187
189
|
|
|
188
190
|
time_steps : ndarray
|
|
189
|
-
An array of the discretized times corresponding to the time steps that starts with the initial time and ends with the final time
|
|
191
|
+
An array of the discretized times corresponding to the time steps that starts with the initial time and ends with the final time
|
|
192
|
+
|
|
193
|
+
time_obs : array_like or str
|
|
194
|
+
If passed as an array_like, it is an array of the times at which the solution is observed. If passed as a string it can be set to `final` to observe at the final time step, or `all` to observe at all time steps. Default is `final`.
|
|
190
195
|
|
|
191
196
|
method: str
|
|
192
197
|
Time stepping method. Currently two options are available `forward_euler` and `backward_euler`.
|
|
@@ -199,12 +204,25 @@ class TimeDependentLinearPDE(LinearPDE):
|
|
|
199
204
|
See demos/demo34_TimeDependentLinearPDE.py for 1D heat and 1D wave equations.
|
|
200
205
|
"""
|
|
201
206
|
|
|
202
|
-
def __init__(self, PDE_form, time_steps, method='forward_euler', **kwargs):
|
|
207
|
+
def __init__(self, PDE_form, time_steps, time_obs='final', method='forward_euler', **kwargs):
|
|
203
208
|
super().__init__(PDE_form, **kwargs)
|
|
204
209
|
|
|
205
210
|
self.time_steps = time_steps
|
|
206
211
|
self.method = method
|
|
207
212
|
|
|
213
|
+
# Set time_obs
|
|
214
|
+
if time_obs is None:
|
|
215
|
+
raise ValueError("time_obs cannot be None")
|
|
216
|
+
elif isinstance(time_obs, str):
|
|
217
|
+
if time_obs.lower() == 'final':
|
|
218
|
+
time_obs = time_steps[-1:]
|
|
219
|
+
elif time_obs.lower() == 'all':
|
|
220
|
+
time_obs = time_steps
|
|
221
|
+
else:
|
|
222
|
+
raise ValueError("if time_obs is a string, it can only be set "
|
|
223
|
+
+"to `final` or `all`")
|
|
224
|
+
self._time_obs = time_obs
|
|
225
|
+
|
|
208
226
|
@property
|
|
209
227
|
def method(self):
|
|
210
228
|
return self._method
|
|
@@ -226,37 +244,62 @@ class TimeDependentLinearPDE(LinearPDE):
|
|
|
226
244
|
|
|
227
245
|
def solve(self):
|
|
228
246
|
"""Solve PDE by time-stepping"""
|
|
247
|
+
# initialize time-dependent solution
|
|
248
|
+
self.assemble_step(self.time_steps[0])
|
|
249
|
+
u = np.empty((len(self.initial_condition), len(self.time_steps)))
|
|
250
|
+
u[:, 0] = self.initial_condition
|
|
229
251
|
|
|
230
252
|
if self.method == 'forward_euler':
|
|
231
253
|
for idx, t in enumerate(self.time_steps[:-1]):
|
|
232
254
|
dt = self.time_steps[idx+1] - t
|
|
233
255
|
self.assemble_step(t)
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
u = (dt*self.diff_op + np.eye(len(u)))@u + dt*self.rhs # from u at time t, gives u at t+dt
|
|
256
|
+
u_pre = u[:, idx]
|
|
257
|
+
u[:, idx+1] = (dt*self.diff_op + np.eye(len(u_pre)))@u_pre + dt*self.rhs # from u at time t, gives u at t+dt
|
|
237
258
|
info = None
|
|
238
259
|
|
|
239
260
|
if self.method == 'backward_euler':
|
|
240
261
|
for idx, t in enumerate(self.time_steps[1:]):
|
|
241
262
|
dt = t - self.time_steps[idx]
|
|
242
263
|
self.assemble_step(t)
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
A = np.eye(len(u)) - dt*self.diff_op
|
|
264
|
+
u_pre = u[:, idx]
|
|
265
|
+
A = np.eye(len(u_pre)) - dt*self.diff_op
|
|
246
266
|
# from u at time t-dt, gives u at t
|
|
247
|
-
u, info = self._solve_linear_system(
|
|
248
|
-
A,
|
|
267
|
+
u[:, idx+1], info = self._solve_linear_system(
|
|
268
|
+
A, u_pre + dt*self.rhs, self._linalg_solve, self._linalg_solve_kwargs)
|
|
249
269
|
|
|
250
270
|
return u, info
|
|
251
271
|
|
|
252
272
|
def observe(self, solution):
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
273
|
+
|
|
274
|
+
# If observation grid is the same as solution grid and observation time
|
|
275
|
+
# is the final time step then no need to interpolate
|
|
276
|
+
if self.grids_equal and np.all(self.time_steps[-1:] == self._time_obs):
|
|
277
|
+
solution_obs = solution[..., -1]
|
|
278
|
+
|
|
279
|
+
# Interpolate solution in time and space to the observation
|
|
280
|
+
# time and space
|
|
256
281
|
else:
|
|
257
|
-
|
|
282
|
+
# Raise error if solution is 2D or 3D in space
|
|
283
|
+
if len(solution.shape) > 2:
|
|
284
|
+
raise ValueError("Interpolation of solutions of 2D and 3D "+
|
|
285
|
+
"space dimensions based on the provided "+
|
|
286
|
+
"grid_obs and time_obs are not supported. "+
|
|
287
|
+
"You can, instead, pass a custom "+
|
|
288
|
+
"observation_map and pass grid_obs and "+
|
|
289
|
+
"time_obs as None.")
|
|
290
|
+
|
|
291
|
+
# Interpolate solution in space and time to the observation
|
|
292
|
+
# time and space
|
|
293
|
+
solution_obs = scipy.interpolate.RectBivariateSpline(
|
|
294
|
+
self.grid_sol, self.time_steps, solution)(self.grid_obs,
|
|
295
|
+
self._time_obs)
|
|
258
296
|
|
|
297
|
+
# Apply observation map
|
|
259
298
|
if self.observation_map is not None:
|
|
260
299
|
solution_obs = self.observation_map(solution_obs)
|
|
261
|
-
|
|
262
|
-
|
|
300
|
+
|
|
301
|
+
# squeeze if only one time observation
|
|
302
|
+
if len(self._time_obs) == 1:
|
|
303
|
+
solution_obs = solution_obs.squeeze()
|
|
304
|
+
|
|
305
|
+
return solution_obs
|
|
File without changes
|
|
File without changes
|
|
File without changes
|