Skip to content

Commit 9c106a8

Browse files
committed
Fix pylint errors, move .py example, fix failing test
1 parent cb7896e commit 9c106a8

File tree

3 files changed

+22
-73
lines changed

3 files changed

+22
-73
lines changed

docs/source/notebooks/MLDA_multilevel_groundwater_flow.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"\n",
1919
"This is the case e.g. in subsurface flow models where a partial differential equation (PDE) with highly varying coefficients needs to be solved numerically on a fine spatial grid to perform each MCMC likelihood computation. If we have access to versions of the same model on coarser grids, we can apply a multilevel approach; in simple terms, we can use multiple chains on different coarseness levels and coarser chains' samples are used as proposals for the finer chains. This has been shown to improve the effective sample size of the finest chain and this allows us to reduce the number of expensive fine-chain likelihood evaluations.\n",
2020
"\n",
21-
"For more details about the MLDA sampler and the way it should be used and parameterised, the user can refer to the code below, as well as the docstrings within the python code (the implementation is under `pymc3/pymc3/step_methods/metropolis.py`).\n",
21+
"For more details about the MLDA sampler and the way it should be used and parameterised, the user can refer to the code below, as well as the docstrings within the python code (the implementation is under `pymc3/pymc3/step_methods/metropolis.py`). A version of this code in .py form can be found under `./mlda`.\n",
2222
"\n",
2323
"Please note that the MLDA sampler is new in pymc3. The user should be extra critical about the results and report any problems as issues in the pymc3's github repository.\n",
2424
"\n",

pymc3/examples/MLDA_multilevel_groundwater_flow.py renamed to docs/source/notebooks/mlda/MLDA_multilevel_groundwater_flow.py

Lines changed: 20 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
#
33
# NOTE: This script has been converted from the python notebook in
44
# pymc3/docs/source/notebooks/MLDA_multilevel_groundwater_flow.ipynb.
5-
# Supporting code is located in pymc3/docs/source/notebooks/mlda.
5+
# Supporting utility code for the forward model is located in pymc3/docs/source/notebooks/mlda.
66
#
77
#
8-
# ### The MLDA sampler
8+
# The MLDA sampler
99
# This notebook (along with the utility code within the `./mlda` folder) is designed to
1010
# demonstrate the Multi-Level Delayed Acceptance MCMC algorithm (MLDA) proposed in [1], as implemented within pymc3.
1111
#
@@ -27,7 +27,7 @@
2727
# Please note that the MLDA sampler is new in pymc3. The user should be extra critical about the results and report
2828
# any problems as issues in the pymc3's github repository.
2929
#
30-
# ### The model
30+
# The model
3131
# Within this notebook, a simple MLDA sampler is compared to pymc3's Metropolis MCMC sampler. The
3232
# target posterior is defined within the context of a Bayesian inverse problem for groundwater flow modeling,
3333
# where we solve a PDE in each likelihood evaluation and we are able to do this in different coarseness levels.
@@ -38,7 +38,7 @@
3838
# since the ones used here are moderate to avoid long runtimes. Note that the likelihood in this example cannot be
3939
# automatically differentiated therefore NUTS cannot be used.
4040
#
41-
# ### PDE solver details
41+
# PDE solver details
4242
# The code within the `./mlda` folder solves the steady state groundwater flow problem for a
4343
# random hydraulic conductivity field [2]. This solution acts as the forward model in the context of a Bayesian
4444
# Inverse problem. In conjunction with MCMC, this setup allows for sampling from the posterior distribution of model
@@ -68,12 +68,12 @@
6868
# user can then extract hydraulic heads at datapoints using the get_data-method.
6969
#
7070
#
71-
# ### Dependencies
71+
# Dependencies
7272
# The code has been developed and tested with Python 3.6. You will need to have pymc3 installed and
7373
# also install [FEniCS](https://fenicsproject.org/) for your system.
7474
#
7575
#
76-
# ### References
76+
# References
7777
# [1] Dodwell, Tim & Ketelsen, Chris & Scheichl, Robert & Teckentrup, Aretha. (2019). Multilevel
7878
# Markov Chain Monte Carlo. SIAM Review. 61. 509-545. https://doi.org/10.1137/19M126966X
7979
#
@@ -85,33 +85,21 @@
8585
# C. Richardson, J. Ring, M. E. Rognes and G. N. Wells, Archive of Numerical Software, vol. 3, 2015
8686
#
8787

88-
# ### Import modules
89-
90-
# In[1]:
91-
88+
# Import modules
9289

9390
# Import groundwater flow model utils
94-
import sys
95-
sys.path.insert(1, '../../docs/source/notebooks/mlda/')
96-
97-
98-
# In[2]:
99-
100-
10191
import os
10292
import numpy as np
10393
import time
10494
import pymc3 as pm
10595
import theano.tensor as tt
106-
from Model import Model, model_wrapper, project_eigenpairs
10796
from itertools import product
10897
import matplotlib.pyplot as plt
98+
from Model import Model, model_wrapper, project_eigenpairs
10999
os.environ['OPENBLAS_NUM_THREADS'] = '1' # Set environmental variable
110100

111-
# ### Set parameters
112-
113-
# In[ ]:
114101

102+
# Set parameters
115103

116104
# Set the resolution of the multi-level models (from coarsest to finest)
117105
# This is a list of different model resolutions. Each
@@ -165,13 +153,9 @@
165153
points_list = [0.1, 0.3, 0.5, 0.7, 0.9]
166154

167155

168-
# ### Define the likelihood
169-
170-
# In[4]:
171-
156+
# Define the likelihood
172157

173158
# Use a Theano Op along with the code within ./mlda to construct the likelihood
174-
175159
def my_loglik(my_model, theta, datapoints, data, sigma):
176160
"""
177161
This returns the log-likelihood of my_model given theta,
@@ -181,6 +165,7 @@ def my_loglik(my_model, theta, datapoints, data, sigma):
181165
output = model_wrapper(my_model, theta, datapoints)
182166
return - (0.5 / sigma ** 2) * np.sum((output - data) ** 2)
183167

168+
184169
class LogLike(tt.Op):
185170
"""
186171
Theano Op that wraps the log-likelihood computation, necessary to
@@ -238,10 +223,7 @@ def perform(self, node, inputs, outputs):
238223
outputs[0][0] = np.array(logl) # output the log-likelihood
239224

240225

241-
# ### Instantiate Model objects and data
242-
243-
# In[5]:
244-
226+
# Instantiate Model objects and data
245227

246228
# Note this can take several minutes for large resolutions
247229
my_models = []
@@ -252,10 +234,6 @@ def perform(self, node, inputs, outputs):
252234
for i in range(len(my_models[:-1])):
253235
project_eigenpairs(my_models[-1], my_models[i])
254236

255-
256-
# In[6]:
257-
258-
259237
# Solve finest model as a test and plot transmissivity field and solution
260238
np.random.seed(data_seed)
261239
my_models[-1].solve()
@@ -264,10 +242,6 @@ def perform(self, node, inputs, outputs):
264242
# Save true parameters of finest model
265243
true_parameters = my_models[-1].random_process.parameters
266244

267-
268-
# In[7]:
269-
270-
271245
# Define the sampling points.
272246
x_data = y_data = np.array(points_list)
273247
datapoints = np.array(list(product(x_data, y_data)))
@@ -278,22 +252,14 @@ def perform(self, node, inputs, outputs):
278252
# Generate data from the finest model for use in pymc3 inference - these data are used in all levels
279253
data = model_wrapper(my_models[-1], true_parameters, datapoints) + noise
280254

281-
282-
# ### Instantiate LogLik objects
283-
284-
# In[8]:
285-
255+
# Instantiate LogLik objects
286256

287257
# create Theano Ops to wrap likelihoods of all model levels and store them in list
288258
logl = []
289259
for m in my_models:
290260
logl.append(LogLike(m, my_loglik, data, datapoints, sigma))
291261

292-
293-
# ### Construct pymc3 model objects for coarse models
294-
295-
# In[9]:
296-
262+
# Construct pymc3 model objects for coarse models
297263

298264
# Set up models in pymc3 for each level - excluding finest model level
299265
coarse_models = []
@@ -308,16 +274,12 @@ def perform(self, node, inputs, outputs):
308274
theta = tt.as_tensor_variable(parameters)
309275

310276
# use a DensityDist (use a lamdba function to "call" the Op)
311-
ll = logl[j]
312-
pm.DensityDist('likelihood', lambda v: ll(v), observed={'v': theta})
277+
temp = logl[j]
278+
pm.DensityDist('likelihood', lambda v, ll=temp: ll(v), observed={'v': theta})
313279

314280
coarse_models.append(model)
315281

316-
317-
# ### Perform inference using MLDA and Metropolis
318-
319-
# In[10]:
320-
282+
# Perform inference using MLDA and Metropolis
321283

322284
# Set up finest model and perform inference with PyMC3, using the MLDA algorithm
323285
# and passing the coarse_models list created above.
@@ -367,12 +329,7 @@ def perform(self, node, inputs, outputs):
367329
random_seed=sampling_seed))
368330
runtimes.append(time.time() - t_start)
369331

370-
371-
# ### Print performance metrics
372-
373-
# In[11]:
374-
375-
332+
# Print performance metrics
376333
for i, trace in enumerate(traces):
377334
acc.append(trace.get_sampler_stats('accepted').mean())
378335
ess.append(np.array(pm.ess(trace).to_array()))
@@ -388,22 +345,14 @@ def perform(self, node, inputs, outputs):
388345

389346
print(f"\nMLDA vs. Metropolis performance speedup in all dimensions (performance measured by ES/sec):\n{np.array(performances[1]) / np.array(performances[0])}")
390347

391-
392-
# ### Show stats summary
393-
394-
# In[22]:
395-
348+
# Show stats summary
396349

397350
# Print true theta values and pymc3 sampling summary
398351
print(f"\nDetailed summaries and plots:\nTrue parameters: {true_parameters}")
399352
for i, trace in enumerate(traces):
400353
print(f"\nSampler {method_names[i]}:\n", pm.stats.summary(trace))
401354

402-
403-
# ### Show traceplots
404-
405-
# In[ ]:
406-
355+
# Show traceplots
407356

408357
# Print true theta values and pymc3 sampling summary
409358
for i, trace in enumerate(traces):

pymc3/tests/test_step.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ def test_step_continuous(self):
555555
HamiltonianMC(scaling=C, is_cov=True, blocked=False),
556556
]
557557
),
558-
MLDA(coarse_models=[model_coarse], S=C, base_proposal_dist=MultivariateNormalProposal)
558+
MLDA(coarse_models=[model_coarse], base_S=C, base_proposal_dist=MultivariateNormalProposal)
559559
)
560560
for step in steps:
561561
trace = sample(

0 commit comments

Comments
 (0)