Skip to content

Commit

Permalink
Merge pull request #17 from keurfonluu/devel
Browse files Browse the repository at this point in the history
Add factory module for extra misfit terms
  • Loading branch information
keurfonluu committed Aug 16, 2023
2 parents 727e511 + e490fe2 commit 6af0a26
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 23 deletions.
Binary file modified .github/sample.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions .github/sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
model.configure(
optimizer="cpso",
misfit="rmse",
density=lambda vp: 2.0,
density=density,
optimizer_args={
"popsize": 10,
"maxiter": 100,
Expand All @@ -56,7 +56,7 @@
# Run inversion
# See stochopy's documentation for optimizer options <https://keurfonluu.github.io/stochopy/>
res = model.invert(curves)
res = res.threshold(0.1)
res = res.threshold(0.02)

# Plot results
fig, ax = plt.subplots(1, 3, figsize=(15, 6))
Expand Down
12 changes: 6 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,20 @@ Expected output:
.. code-block::
--------------------------------------------------------------------------------
Best model out of 1000 models (1 run)
Best model out of 501 models (1 run)
Velocity model Model parameters
---------------------------------------- ------------------------------
d vp vs rho d vs nu
[km] [km/s] [km/s] [g/cm3] [km] [km/s] [-]
---------------------------------------- ------------------------------
0.0296 0.5033 0.2055 2.0000 0.0296 0.2055 0.4000
1.0000 1.8191 1.0080 2.0000 - 1.0080 0.2785
0.0298 0.5033 0.2055 2.0000 0.0298 0.2055 0.4000
1.0000 2.0586 0.9935 2.0000 - 0.9935 0.3482
---------------------------------------- ------------------------------
Number of layers: 2
Number of parameters: 5
Best model misfit: 0.0153
Best model misfit: 0.0038
--------------------------------------------------------------------------------
Contributing
Expand Down
2 changes: 1 addition & 1 deletion evodcinv/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.1.2
2.2.0
2 changes: 2 additions & 0 deletions evodcinv/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from . import factory
from .__about__ import __version__
from ._curve import Curve
from ._io import read
Expand All @@ -10,6 +11,7 @@
"EarthModel",
"Layer",
"InversionResult",
"factory",
"read",
"__version__",
]
8 changes: 7 additions & 1 deletion evodcinv/_curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def __init__(
weight : scalar, optional, default 1.0
Overall weight applied to the misfit error associated to this data set.
uncertainties : scalar, array_like or None, optional, default None
Uncertainties associated to data points. If None, error will be normalized by `data`.
Uncertainties associated to data points.
"""
if len(period) != len(data):
Expand All @@ -44,6 +44,12 @@ def __init__(
raise ValueError()
if not is_sorted(period):
raise ValueError()
if (
uncertainties is not None
and np.ndim(uncertainties) == 1
and len(uncertainties) != len(data)
):
raise ValueError()

self._period = np.asarray(period)
self._data = np.asarray(data)
Expand Down
17 changes: 7 additions & 10 deletions evodcinv/_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from disba._common import ifunc
from stochopy.optimize import minimize

from . import factory
from ._common import itype
from ._curve import Curve
from ._helpers import nafe_drake
Expand Down Expand Up @@ -284,12 +285,7 @@ def invert(self, curves, maxrun=1, split_results=False):
f"Option `increasing_velocity` is not compatible yet with optimizer `{method}`."
)

def constraint(x):
vs = x[self.n_layers - 1 : 2 * self.n_layers - 1]

return 0.0 if (vs[1:] >= vs[:-1]).all() else np.Inf

self._configuration["extra_terms"].append(constraint)
self._configuration["extra_terms"].append(factory.increasing_velocity)

# Run maxrun inversion
results = []
Expand Down Expand Up @@ -337,7 +333,9 @@ def constraint(x):
with ProgressBar(prefix, max=maxiter) as bar:

def callback(X, res):
bar.misfit = res.fun
bar.misfit = (
f"{res.fun:.4f}" if res.fun >= 1.0e-4 else f"{res.fun:.4e}"
)
bar.next()

x = minimize(
Expand Down Expand Up @@ -452,10 +450,9 @@ def _misfit_function(self, x, curves):
n = len(dcalc)
if n > 0:
sigma = (
curve.data[:n]
if curve.uncertainties is None
else curve.uncertainties[:n]
curve.uncertainties if curve.uncertainties is not None else 1.0
)
sigma = sigma[:n] if np.ndim(sigma) == 1 else sigma
error += curve.weight * misfit((dcalc - curve.data[:n]) / sigma)
weights_sum += curve.weight

Expand Down
2 changes: 1 addition & 1 deletion evodcinv/_progress.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def __init__(self, *args, **kwargs):

self.width = 20
self.suffix = (
"%(percent)3d%% [%(elapsed_td)s / %(eta_td)s] - Misfit: %(misfit).4f"
"%(percent)3d%% [%(elapsed_td)s / %(eta_td)s] - Misfit: %(misfit)s"
)
self.check_tty = False
self.misfit = np.Inf
Expand Down
3 changes: 2 additions & 1 deletion evodcinv/_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ def __repr__(self):
out += [f"{40 * '-'}{'':10}{30 * '-'}\n"]

# Misc
misfit = f"{self.misfit:.4f}" if self.misfit >= 1.0e-4 else f"{self.misfit:.4e}"
out += [f"Number of layers: {n_layers}"]
out += [f"Number of parameters: {n_layers * 3 - 1}"]
out += [f"Best model misfit: {self.misfit:>.4f}"]
out += [f"Best model misfit: {misfit}"]

out += [f"{80 * '-'}"]

Expand Down
7 changes: 7 additions & 0 deletions evodcinv/factory/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from ._extra_terms import increasing_velocity, prior, smooth

__all__ = [
"increasing_velocity",
"prior",
"smooth",
]
82 changes: 82 additions & 0 deletions evodcinv/factory/_extra_terms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import numpy as np


def increasing_velocity(x, penalty=np.inf):
"""
Strictly increasing velocity models.
Parameters
----------
x : array_like
Model parameter vector.
penalty : scalar, optional, default Inf
Penalty applied to misfit of models with velocities that are not strictly increasing.
Returns
-------
scalar
Misfit value.
"""
n_layers = (len(x) + 1) // 3
vs = x[n_layers - 1 : 2 * n_layers - 1]

return 0.0 if (vs[1:] >= vs[:-1]).all() else penalty


def prior(x, depth, velocity_s, uncertainties=None, alpha=1.0e-3):
"""
Prior S-wave velocity model.
Parameters
----------
x : array_like
Model parameter vector.
depth : array_like
Prior model's depths (in km).
velocity_s : array_like.
Prior model's S-wave velocities (in km/s).
uncertainties : scalar, array_like or None, optional, default None
Uncertainties associated to prior model S-wave velocities (in km/s).
alpha : scalar, optional, default 1.0e-3
Regularization factor.
Returns
-------
scalar
Misfit value.
"""
n_layers = (len(x) + 1) // 3
d = x[: n_layers - 1]
z = np.insert(d.cumsum(), 0, 0.0)
vs = x[n_layers - 1 : 2 * n_layers - 1]
vprior = np.interp(z, depth, velocity_s)

sigma = uncertainties if uncertainties is not None else 1.0
sigma = np.interp(z, depth, uncertainties) if np.ndim(sigma) == 1 else sigma

return alpha * np.square((vs - vprior) / sigma).sum()


def smooth(x, alpha=1.0e-3):
"""
Smooth velocity models.
Parameters
----------
x : array_like
Model parameter vector.
alpha : scalar, optional, default 1.0e-3
Regularization factor.
Returns
-------
scalar
Misfit value.
"""
n_layers = (len(x) + 1) // 3
vs = x[n_layers - 1 : 2 * n_layers - 1]

return alpha * n_layers * np.square(vs[:-2] - 2.0 * vs[1:-1] + vs[2:]).sum()
2 changes: 1 addition & 1 deletion tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


@pytest.mark.parametrize(
"xref, increasing_velocity", [(8.90561595, False), (8.88578982, True)]
"xref, increasing_velocity", [(8.90561595, False), (9.13114157, True)]
)
def test_invert(xref, increasing_velocity):
model = copy.deepcopy(helpers.model)
Expand Down

0 comments on commit 6af0a26

Please sign in to comment.