Skip to content

Commit fb01354

Browse files
authored
Merge pull request #76 from DanielVandH/bivariate
Bivariate profiles
2 parents 0a3e517 + ac78230 commit fb01354

40 files changed

+4514
-331
lines changed

Project.toml

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
name = "ProfileLikelihood"
22
uuid = "3fca794e-44fa-49a6-b6a0-8cd45572ba0a"
3-
authors = ["DanielVandH <[email protected]>"]
4-
version = "0.1.3"
3+
authors = ["Daniel VandenHeuvel <[email protected]>"]
4+
version = "0.2.0"
55

66
[deps]
77
ChunkSplitters = "ae650224-84b6-46f8-82ea-d812ca08434e"
8+
Contour = "d38c429a-6771-53c6-b99e-75d170b6e991"
89
FunctionWrappers = "069b7b12-0de2-55c6-9aab-29f3d0a68a2e"
910
Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
1011
InvertedIndices = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
12+
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
13+
PolygonInbounds = "e4521ec6-8c1d-418e-9da2-b3bc4ae105d6"
1114
PreallocationTools = "d236fae5-4411-538c-8e31-a6e3d9e00b46"
1215
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
1316
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
@@ -16,9 +19,12 @@ SimpleNonlinearSolve = "727e6d20-b764-4bd8-a329-72de5adea6c7"
1619
StatsFuns = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
1720

1821
[compat]
22+
Contour = "0.6"
1923
FunctionWrappers = "1.1"
2024
Interpolations = "0.14"
2125
InvertedIndices = "1.2"
26+
OffsetArrays = "1.12"
27+
PolygonInbounds = "0.2"
2228
PreallocationTools = "0.4"
2329
Requires = "1.3"
2430
SciMLBase = "1.77"

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
[![](https://img.shields.io/badge/docs-dev-blue.svg)](https://DanielVandH.github.io/ProfileLikelihood.jl/dev)
66
[![](https://img.shields.io/badge/docs-stable-blue.svg)](https://DanielVandH.github.io/ProfileLikelihood.jl/stable)
77

8-
This package defines the routines required for computing maximum likelihood estimates and profile likelihoods. The optimisation routines are built around the [Optimization.jl](https://github.com/SciML/Optimization.jl) interface, allowing us to e.g. easily switch between algorithms, between finite differences and automatic differentiation, and it allows for constraints to be defined with ease. Below we list the definitions we are using for likelihoods and profile likelihoods. This code only works for scalar parameters of interest (i.e. out of a vector $\boldsymbol \theta$, you can profile a single scalar parameter $\theta_i \in \boldsymbol\theta$) for now.
8+
This package defines the routines required for computing maximum likelihood estimates and profile likelihoods. The optimisation routines are built around the [Optimization.jl](https://github.com/SciML/Optimization.jl) interface, allowing us to e.g. easily switch between algorithms, between finite differences and automatic differentiation, and it allows for constraints to be defined with ease. Below we list the definitions we are using for likelihoods and profile likelihoods. This code works for univariate and bivariate profiles.
99

1010
**Definition: Likelihood function** (see Casella & Berger, 2002): Let $f(\boldsymbol x \mid \boldsymbol \theta)$ denote the joint probability density function (PDF) of the sample $\boldsymbol X = (X_1,\ldots,X_n)^{\mathsf T}$, where $\boldsymbol \theta \in \Theta$ is some set of parameters and $\Theta$ is the parameter space. We define the _likelihood function_ $\mathcal L \colon \Theta \to [0, \infty)$ by $\mathcal L(\boldsymbol \theta \mid \boldsymbol x) = f(\boldsymbol x \mid \boldsymbol \theta)$ for some realisation $\boldsymbol x = (x_1,\ldots,x_n)^{\mathsf T}$ of $\boldsymbol X$. The _log-likelihood function_ $\ell\colon\Theta\to\mathbb R$ is defined by $\ell(\boldsymbol \theta \mid \boldsymbol x) = \log\mathcal L(\boldsymbol\theta \mid \boldsymbol x)$.The _maximum likelihood estimate_ (MLE) $\hat{\boldsymbol\theta}$ is the parameter $\boldsymbol\theta$ that maximises the likelihood function, $\hat{\boldsymbol{\theta}} = argmax_{\boldsymbol{\theta} \in \Theta} \mathcal{L}(\boldsymbol{\theta} \mid \boldsymbol x) = argmax_{\boldsymbol\theta \in \Theta} \ell(\boldsymbol\theta \mid \boldsymbol x)$.
1111

1212
**Definition: Profile likelihood function** (see Pawitan, 2001): Suppose we have some parameters of interest, $\boldsymbol \theta \in \Theta$, and some nuisance parameters, $\boldsymbol \phi \in \Phi$, and some data $\boldsymbol x = (x_1,\ldots,x_n)^{\mathsf T}$, giving some joint likelihood $\mathcal L \colon \Theta \cup \Phi \to [0, \infty)$ defined by $\mathcal L(\boldsymbol\theta, \boldsymbol\phi \mid \boldsymbol x)$. We define the _profile likelihood_ $\mathcal L_p \colon \Theta \to [0, \infty)$ of $\boldsymbol\theta$ by $\mathcal L_p(\boldsymbol\theta \mid \boldsymbol x) = \sup_{\boldsymbol \phi \in \Phi \mid \boldsymbol \theta} \mathcal L(\boldsymbol \theta, \boldsymbol \phi \mid \boldsymbol x)$. The _profile log-likelihood_ $\ell_p \colon \Theta \to \mathbb R$ of $\boldsymbol\theta$ is defined by $\ell_p(\boldsymbol \theta \mid \boldsymbol x) = \log \mathcal L_p(\boldsymbol\theta \mid \boldsymbol x)$. The _normalised profile likelihood_ is defined by $\hat{\mathcal L}_p(\boldsymbol\theta \mid \boldsymbol x) = \mathcal L_p(\boldsymbol \theta \mid \boldsymbol x) - \mathcal L_p(\hat{\boldsymbol\theta} \mid \boldsymbol x)$, where $\hat{\boldsymbol\theta}$ is the MLE of $\boldsymbol\theta$, and similarly for the normalised profile log-likelihood.
1313

1414
From Wilk's theorem, we know that $2\hat{\ell}\_p(\boldsymbol\theta \mid \boldsymbol x) \geq -\chi_{p, 1-\alpha}^2$ is an approximate $100(1-\alpha)\%$ confidence region for $\boldsymbol \theta$, and this enables us to obtain confidence intervals for parameters by considering only their profile likelihood, where $\chi_{p,1-\alpha}^2$ is the $1-\alpha$ quantile of the $\chi_p^2$ distribution and $p$ is the length of $\boldsymbol\theta$. For the case of a scalar parameter of interest, $-\chi_{1, 0.95}^2 \approx -1.92$.
1515

16-
We compute the profile log-likelihood in this package by starting at the MLE, and stepping left/right until we reach a given threshold. The code is iterative to not waste time in so much of the parameter space.
16+
We compute the profile log-likelihood in this package by starting at the MLE, and stepping left/right until we reach a given threshold. The code is iterative to not waste time in so much of the parameter space. In the bivariate case, we start at the MLE and expand outwards in layers. This implementation is described in the documentation.
1717

1818
More detail about the methods we use in this package are given in the documentation, along with several examples.

docs/make.jl

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pages = [
1111
"Example II: Logistic ordinary differential equation" => "logistic.md"
1212
"Example III: Linear exponential ODE and grid searching" => "exponential.md"
1313
"Example IV: Diffusion equation on a square plate" => "heat.md"
14+
"Example V: Lotka-Volterra ODE, GeneralLazyBufferCache, and computing bivarate profile likelihoods" => "lotka.md"
1415
"Mathematical and Implementation Details" => "math.md"
1516
])
1617

docs/src/docstrings.md

+11-2
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,22 @@ ProfileLikelihood.ProfileLikelihoodSolution
2424
ProfileLikelihood.ConfidenceInterval
2525
profile
2626
replace_profile!
27-
ProfileLikelihood.set_next_initial_estimate!
27+
ProfileLikelihood.set_next_initial_estimate!(::Any, ::Any, ::Any, ::Any, ::Any)
28+
```
29+
30+
## BivariateProfileLikelihoodSolution
31+
32+
```@docs
33+
ProfileLikelihood.BivariateProfileLikelihoodSolution
34+
ProfileLikelihood.ConfidenceRegion
35+
bivariate_profile
36+
ProfileLikelihood.set_next_initial_estimate!(::Any, ::Any, ::CartesianIndex, ::Any, ::Any, ::Any, ::Any, ::Val{M}) where M
2837
```
2938

3039
## Prediction intervals
3140

3241
```@docs
3342
get_prediction_intervals
34-
eval_prediction_function
3543
```
3644

3745
## Plotting
@@ -47,6 +55,7 @@ plot_profiles
4755
```@docs
4856
ProfileLikelihood.AbstractGrid
4957
ProfileLikelihood.RegularGrid
58+
ProfileLikelihood.FusedRegularGrid
5059
ProfileLikelihood.IrregularGrid
5160
```
5261

docs/src/heat.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ x = getx.(xy)
5757
y = gety.(xy)
5858
r = 0.022
5959
GMSH_PATH = "./gmsh-4.9.4-Windows64/gmsh.exe"
60-
T, adj, adj2v, DG, points, BN = generate_mesh(x, y, r; gmsh_path=GMSH_PATH)
60+
(T, adj, adj2v, DG, points), BN = generate_mesh(x, y, r; gmsh_path=GMSH_PATH)
6161
mesh = FVMGeometry(T, adj, adj2v, DG, points, BN)
6262
bc = ((x, y, t, u::T, p) where {T}) -> zero(T)
6363
type = :D
@@ -458,7 +458,7 @@ t_many_pts = LinRange(prob.initial_time, prob.final_time, 250)
458458
jac = FiniteVolumeMethod.jacobian_sparsity(prob)
459459
prediction_data = (c=c, prob=prob, t=t_many_pts, alg=alg, jac=jac)
460460
parameter_wise, union_intervals, all_curves, param_range =
461-
get_prediction_intervals(compute_mass_function, prof, prediction_data; q_type=Vector{Float64})
461+
get_prediction_intervals(compute_mass_function, prof, prediction_data; parallel=true)
462462
```
463463

464464
Now we can visualise the curves. We will also show the mass curve from the exact parameter values, as well as from the MLE.
@@ -472,7 +472,7 @@ latex_names = [L"k", L"u_0"]
472472
for i in 1:2
473473
ax = Axis(fig[1, i], title=L"(%$(alp[i])): Profile-wise PI for %$(latex_names[i])",
474474
titlealign=:left, width=600, height=300)
475-
[lines!(ax, t_many_pts, all_curves[i][j], color=:grey) for j in eachindex(param_range[1])]
475+
[lines!(ax, t_many_pts, all_curves[i][:, j], color=:grey) for j in eachindex(param_range[1])]
476476
lines!(ax, t_many_pts, exact_soln, color=:red)
477477
lines!(ax, t_many_pts, mle_soln, color=:blue, linestyle=:dash)
478478
lines!(ax, t_many_pts, getindex.(parameter_wise[i], 1), color=:black)

docs/src/index.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
[![DOI](https://zenodo.org/badge/508701126.svg)](https://zenodo.org/badge/latestdoi/508701126)
44

5-
This package defines the routines required for computing maximum likelihood estimates and profile likelihoods. The optimisation routines are built around the [Optimization.jl](https://github.com/SciML/Optimization.jl) interface, allowing us to e.g. easily switch between algorithms, between finite differences and automatic differentiation, and it allows for constraints to be defined with ease. Below we list the definitions we are using for likelihoods and profile likelihoods. This code only works for scalar parameters of interest (i.e. out of a vector $\boldsymbol \theta$, you can profile a single scalar parameter $\theta_i \in \boldsymbol\theta$) for now. We use the following definitions:
5+
This package defines the routines required for computing maximum likelihood estimates and profile likelihoods. The optimisation routines are built around the [Optimization.jl](https://github.com/SciML/Optimization.jl) interface, allowing us to e.g. easily switch between algorithms, between finite differences and automatic differentiation, and it allows for constraints to be defined with ease. Below we list the definitions we are using for likelihoods and profile likelihoods. This code only works for scalar or bivariate parameters of interest (i.e. out of a vector $\boldsymbol \theta$, you can profile a single scalar parameter $\theta_i \in \boldsymbol\theta$ or a pair $(\theta_i,\theta_j) \in \boldsymbol\theta$) for now. We use the following definitions:
66

77
**Definition: Likelihood function** (see Casella & Berger, 2002): Let $f(\boldsymbol x \mid \boldsymbol \theta)$ denote the joint probability density function (PDF) of the sample $\boldsymbol X = (X_1,\ldots,X_n)^{\mathsf T}$, where $\boldsymbol \theta \in \Theta$ is some set of parameters and $\Theta$ is the parameter space. We define the _likelihood function_ $\mathcal L \colon \Theta \to [0, \infty)$ by $\mathcal L(\boldsymbol \theta \mid \boldsymbol x) = f(\boldsymbol x \mid \boldsymbol \theta)$ for some realisation $\boldsymbol x = (x_1,\ldots,x_n)^{\mathsf T}$ of $\boldsymbol X$. The _log-likelihood function_ $\ell\colon\Theta\to\mathbb R$ is defined by $\ell(\boldsymbol \theta \mid \boldsymbol x) = \log\mathcal L(\boldsymbol\theta \mid \boldsymbol x)$.The _maximum likelihood estimate_ (MLE) $\hat{\boldsymbol\theta}$ is the parameter $\boldsymbol\theta$ that maximises the likelihood function, $\hat{\boldsymbol{\theta}} = argmax_{\boldsymbol{\theta} \in \Theta} \mathcal{L}(\boldsymbol{\theta} \mid \boldsymbol x) = argmax_{\boldsymbol\theta \in \Theta} \ell(\boldsymbol\theta \mid \boldsymbol x)$.
88

99
**Definition: Profile likelihood function** (see Pawitan, 2001): Suppose we have some parameters of interest, $\boldsymbol \theta \in \Theta$, and some nuisance parameters, $\boldsymbol \phi \in \Phi$, and some data $\boldsymbol x = (x_1,\ldots,x_n)^{\mathsf T}$, giving some joint likelihood $\mathcal L \colon \Theta \cup \Phi \to [0, \infty)$ defined by $\mathcal L(\boldsymbol\theta, \boldsymbol\phi \mid \boldsymbol x)$. We define the _profile likelihood_ $\mathcal L_p \colon \Theta \to [0, \infty)$ of $\boldsymbol\theta$ by $\mathcal L_p(\boldsymbol\theta \mid \boldsymbol x) = \sup_{\boldsymbol \phi \in \Phi \mid \boldsymbol \theta} \mathcal L(\boldsymbol \theta, \boldsymbol \phi \mid \boldsymbol x)$. The _profile log-likelihood_ $\ell_p \colon \Theta \to \mathbb R$ of $\boldsymbol\theta$ is defined by $\ell_p(\boldsymbol \theta \mid \boldsymbol x) = \log \mathcal L_p(\boldsymbol\theta \mid \boldsymbol x)$. The _normalised profile likelihood_ is defined by $\hat{\mathcal L}_p(\boldsymbol\theta \mid \boldsymbol x) = \mathcal L_p(\boldsymbol \theta \mid \boldsymbol x) - \mathcal L_p(\hat{\boldsymbol\theta} \mid \boldsymbol x)$, where $\hat{\boldsymbol\theta}$ is the MLE of $\boldsymbol\theta$, and similarly for the normalised profile log-likelihood.
1010

11-
From Wilk's theorem, we know that $2\hat{\ell}\_p(\boldsymbol\theta \mid \boldsymbol x) \geq -\chi_{p, 1-\alpha}^2$ is an approximate $100(1-\alpha)\%$ confidence region for $\boldsymbol \theta$, and this enables us to obtain confidence intervals for parameters by considering only their profile likelihood, where $\chi_{p,1-\alpha}^2$ is the $1-\alpha$ quantile of the $\chi_p^2$ distribution and $p$ is the length of $\boldsymbol\theta$. For the case of a scalar parameter of interest, $-\chi_{1, 0.95}^2 \approx -1.92$.
11+
From Wilk's theorem, we know that $2\hat{\ell}\_p(\boldsymbol\theta \mid \boldsymbol x) \geq -\chi_{p, 1-\alpha}^2$ is an approximate $100(1-\alpha)\%$ confidence region for $\boldsymbol \theta$, and this enables us to obtain confidence intervals for parameters by considering only their profile likelihood, where $\chi_{p,1-\alpha}^2$ is the $1-\alpha$ quantile of the $\chi_p^2$ distribution and $p$ is the length of $\boldsymbol\theta$. For the case of a scalar parameter of interest, $-\chi_{1, 0.95}^2/2 \approx -1.92$, and for a bivariate parameter of interest we have $-\chi_{2,0.95}^2/2 \approx -3$.
1212

13-
We compute the profile log-likelihood in this package by starting at the MLE, and stepping left/right until we reach a given threshold. The code is iterative to not waste time in so much of the parameter space.
13+
We compute the profile log-likelihood in this package by starting at the MLE, and stepping left/right until we reach a given threshold. The code is iterative to not waste time in so much of the parameter space. In the bivariate case, we start at the MLE and expand outwards in layers. This implementation is described in the documentation.
1414

15-
More detail about the methods we use in this package is given in the following sections, with extra detail in the tests.
15+
More detail about the methods we use in this package is given in the sections in the sidebar, with extra detail in the tests.

0 commit comments

Comments
 (0)