Skip to article frontmatterSkip to article content

3. Numerical integration

Authors
Affiliations
TNO
TNO
TNO

Numerical integration is straightforward to implement; however, “the curse of dimensionality” exists. This can be expressed mathematically as:

npointsj=1dngrids=ngridsdn_{\text{points}} \sim \prod_{j=1}^{d} n_{\text{grids}} = n_{\text{grids}}^{d}

where:

  • npoints n_{\text{points}} : Represents the number of points.

  • j=1dngrids \prod_{j=1}^{d} n_{\text{grids}} : Indicates the product of ngrids n_{\text{grids}} from j=1 j=1 to d d .

  • ngridsd n_{\text{grids}}^{d} : Shows that the number of grids is raised to the power of d d .

numerical integration example

“A Conceptual Introduction to Markov Chain Monte Carlo Methods”, Joshua Speagle (2019)

Imports

import matplotlib.pyplot as plt
import numpy as np
from scipy import stats

Problem setup

# Fixed parameters
I = 1e9  # mm^4
L = 10_000  # mm
Q = 100  # kN

# Measurements
d_meas = 50  # mm
sigma_meas =  10  # mm

# Prior
E_mean = 60  # GPa
E_std = 20  # GPa

Forward model

def midspan_deflection(E):
    return Q * L ** 3 / (48 * E * I)

Bayesian functions

## Write your code where the three dots are

def likelihood(E):
    return ...


def prior(E):
    return ...

Perform numerical integration

## Write your code where the three dots are

E_values = np.linspace(-20, 140, 1000)

# Calculate prior and likelihood values
prior_values = ...
likelihood_values = ...

evidence = ... # use the trapezoidal rule to integrate
posterior_values = ... 

Posterior summary

## Write your code where the three dots are

 # Mean
mean = ... # use the trapezoidal rule to integrate
print(f'Mean: {mean:.2f} GPa')

# Median
cdf = np.cumsum(posterior_values) * np.diff(E_values, prepend=0)
median = E_values[np.argmin(np.abs(cdf - 0.5))]
print(f'Median: {median:.2f} GPa')

# Standard deviation
std = ...  # use the trapezoidal rule to integrate
print(f'Standard deviation: {std:.2f} GPa')

# 5th and 95th percentiles
percentiles = np.interp([0.05, 0.95], cdf, E_values)
print(f'5th percentile: {percentiles[0]:.2f} GPa')
print(f'95th percentile: {percentiles[1]:.2f} GPa')

Plot

plt.plot(E_values, prior_values, label='Prior')
plt.plot(E_values, likelihood_values, label='Likelihood')
plt.plot(E_values, posterior_values, label='Posterior')
plt.xlabel('E (GPa)')
plt.ylabel('Density')
plt.ylim([0, 0.045])
plt.legend()
plt.show()