metrics¶
Differentiable loss functions for parameter fitting and model comparison.
All functions in this module operate on plain jax.Array arguments and are fully differentiable through jax.grad. They are designed to be passed as (or called within) the loss_fn argument of fit_parameters.
from jbubble.metrics import mse_radius, normalised_mse_radius
from jbubble.metrics import mse_emission, normalised_mse_emission
from jbubble.metrics import peak_expansion, peak_expansion_error
mse_radius
¶
Mean squared error between simulated and target radii [m²].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r_sim
|
(Array, shape(N))
|
Simulated radius trajectory [m]. |
required |
r_target
|
(Array, shape(N))
|
Target radius trajectory [m]. |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Scalar mean squared error [m²]. |
Source code in jbubble/metrics.py
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | |
normalised_mse_radius
¶
Normalised mean squared radius error (dimensionless).
Equivalent to mse_radius(r_sim / R0, r_target / R0). The \(R_0\)
normalisation makes the loss dimensionless and of order 1 regardless of
bubble size, which improves optimiser conditioning.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r_sim
|
(Array, shape(N))
|
Simulated radius trajectory [m]. |
required |
r_target
|
(Array, shape(N))
|
Target radius trajectory [m]. |
required |
R0
|
float or Array
|
Equilibrium radius used for normalisation [m]. |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Scalar normalised mean squared error. |
Source code in jbubble/metrics.py
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | |
peak_expansion
¶
Maximum radial expansion ratio, \(R_\text{max}/R_0\).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r_sim
|
(Array, shape(N))
|
Simulated radius trajectory [m]. |
required |
R0
|
float or Array
|
Equilibrium radius [m]. |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Scalar expansion ratio (dimensionless). |
Source code in jbubble/metrics.py
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | |
peak_expansion_error
¶
Squared error in the peak expansion ratio.
Useful when only the maximum oscillation amplitude matters rather than the full waveform.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r_sim
|
(Array, shape(N))
|
Simulated radius trajectory [m]. |
required |
R0
|
float or Array
|
Equilibrium radius [m]. |
required |
target_expansion
|
float or Array
|
Target \(R_\text{max}/R_0\) value. |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Scalar squared error (dimensionless). |
Source code in jbubble/metrics.py
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | |
mse_emission
¶
Mean squared error between simulated and target emission pressure [Pa²].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
p_sim
|
(Array, shape(N))
|
Simulated radiated pressure [Pa]. |
required |
p_target
|
(Array, shape(N))
|
Target radiated pressure [Pa]. |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Scalar mean squared error [Pa²]. |
Source code in jbubble/metrics.py
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | |
normalised_mse_emission
¶
Normalised mean squared error (MSE) for emission pressure (dimensionless).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
p_sim
|
(Array, shape(N))
|
Simulated radiated pressure [Pa]. |
required |
p_target
|
(Array, shape(N))
|
Target radiated pressure [Pa]. |
required |
p_ref
|
float or Array
|
Reference pressure for normalisation [Pa]. |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Scalar normalised mean squared error. |
Source code in jbubble/metrics.py
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | |
Choosing a loss function¶
| Loss | Use when |
|---|---|
mse_radius |
Direct radius fitting; same units as data |
normalised_mse_radius |
Fitting across bubbles of different sizes; scale-invariant |
peak_expansion_error |
Only the amplitude matters, not the full waveform shape |
mse_emission |
Fitting to hydrophone measurements |
normalised_mse_emission |
Fitting to hydrophone data with a known reference level |
Normalised losses are generally preferable for gradient-based fitting because they keep the loss \(\mathcal{O}(1)\) regardless of bubble size or driving pressure, making the choice of learning rate more robust.
Custom loss functions¶
Any differentiable function of SimulationResult fields works as a loss_fn. For example, fitting to the power spectral density:
import jax.numpy as jnp
def psd_loss(result, target_psd):
fft_r = jnp.abs(jnp.fft.rfft(result.radius)) ** 2
return jnp.mean((fft_r - target_psd) ** 2)
fit_result = fit_parameters(
...,
loss_fn=lambda result: psd_loss(result, measured_psd),
)