Skip to content

Commit

Permalink
fdfit: expose rootfinding
Browse files Browse the repository at this point in the history
  • Loading branch information
JoepVanlier committed Feb 24, 2024
1 parent 501160a commit 1e7ad6b
Showing 1 changed file with 50 additions and 2 deletions.
52 changes: 50 additions & 2 deletions lumicks/pylake/fitting/model.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import uuid
import inspect
import warnings
from copy import deepcopy
from collections import OrderedDict

Expand Down Expand Up @@ -241,7 +242,12 @@ def __repr__(self):
return model_info

def invert(
self, independent_min=0.0, independent_max=np.inf, interpolate=False, independent_step=1e-2
self,
independent_min=None,
independent_max=None,
interpolate=False,
method="exact",
independent_step=1e-2,
):
"""Invert this model.
Expand All @@ -264,10 +270,46 @@ def invert(
`interpolate` is set to `True`.
interpolate : bool, optional
Use interpolation method rather than numerical inversion.
method : {"exact", "interp_root", "interp_lsq"}
- "exact" : Invert each point separately (exact, but slow).
- "interp_root" : Interpolate forward model as lookup table for inversion. Appropriate range is selected by rootfinding.
- "interp_lsq" : Interpolate forward model as lookup table for inversion. Appropriate range is selected by least_squares (deprecated).
Can only be used when track is equidistantly sampled.
independent_step : float, optional
Interpolation step size. Default: 1e-2
"""
return InverseModel(self, independent_min, independent_max, interpolate, independent_step)
if method not in ("exact", "interp_root", "interp_lsq"):
raise RuntimeError("Interpolation method should either be rootfinding or least_squares")

if interpolate:
method = "exact"
warnings.warn(
RuntimeWarning("The parameter `interpolate` is deprecated. Use method parameter.")
)

if method == "exact":
return InverseModel(
self, independent_min, independent_max, False, independent_step, rootfinding=False
)
elif method == "interp_root":
return InverseModel(
self,
1e-4 if independent_min is None else independent_min,
1e5 if independent_max is None else independent_max,
True,
independent_step,
rootfinding=True,
)
elif method == "interp_lsq":
return InverseModel(
self,
0.0 if independent_min is None else independent_min,
np.inf if independent_max is None else independent_max,
True,
independent_step,
rootfinding=False,
)

def subtract_independent_offset(self):
"""
Expand Down Expand Up @@ -611,6 +653,7 @@ def __init__(
independent_max=np.inf,
interpolate=False,
independent_step=1e-2,
rootfinding=False,
):
"""
Combine two model outputs to form a new model (addition).
Expand All @@ -627,6 +670,8 @@ def __init__(
Use interpolation approximation. Default: False.
independent_step : float, optional
Interpolation step size. Default: 1e-2
rootfinding : bool
Use rootfinding rather than least squares to invert model.
Raises
------
Expand All @@ -641,6 +686,7 @@ def __init__(
self.independent_min = independent_min
self.independent_max = independent_max
self.independent_step = independent_step
self.rootfinding = rootfinding

@property
def dependent(self):
Expand Down Expand Up @@ -678,6 +724,7 @@ def _raw_call(self, independent, param_vector):
lambda f_trial: self.model._raw_call(f_trial, param_vector),
lambda f_trial: self.model.derivative(f_trial, param_vector),
dx=self.independent_step,
rootfinding=self.rootfinding,
)
else:
return invert_function(
Expand All @@ -687,6 +734,7 @@ def _raw_call(self, independent, param_vector):
self.independent_max,
lambda f_trial: self.model._raw_call(f_trial, param_vector), # Forward model
lambda f_trial: self.model.derivative(f_trial, param_vector),
rootfinding=self.rootfinding,
)

@property
Expand Down

0 comments on commit 1e7ad6b

Please sign in to comment.