-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added CallableNumericalModel, which is similar to CallableModel but whose dict components are python callables rather than sympy Expr. * Added a test for constraints in conjunction with CallableNumericalModel * Added Powell minimizer, and a small bugfix for this method. * __neg__ dind't negate yet, fixed. * Cleaned up inheritance structure to make the changes minimal, added docstrings. * Added tests for multiple components. * Fixed a problem with multidimensional data. Was caused by a small bug in finiti differences, which assumed 1D data. * Made the fix < py3.5 compatible * Updated tests to include a mixed model and wrong argument name * Enabled cashing on models whose components are mixed between pythonic and sympy. * Also check that 2D is the same as 1D after flattening. * Added example to the docs for CallableNumericalModel
- Loading branch information
Showing
9 changed files
with
363 additions
and
58 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Example: CallableNumericalModel | ||
=============================== | ||
|
||
Below is an example of how to use the | ||
:class:`symfit.core.fit.CallableNumericalModel`. This class allows you to | ||
provide custom callables as your model, while still allowing clean interfacing | ||
with the :mod:`symfit` API. | ||
|
||
These models also accept a mixture of symbolic and callable components, as will | ||
be demonstrated below. This allows the power-user great flexibility, since it is | ||
still easy to interface with :mod:`symfit`'s constraints, minimizers, etc. | ||
|
||
.. literalinclude:: ../../examples/callable_numerical_model.py | ||
:language: python | ||
|
||
This is the resulting fit: | ||
|
||
.. figure:: ../_static/callable_numerical_model.png | ||
:width: 500px | ||
:alt: Custom Callable Model |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
from symfit import variables, parameters, Fit, D, ODEModel, CallableNumericalModel | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
|
||
def nonanalytical_func(x, a, b): | ||
""" | ||
This can be any pythonic function which should be fitted, typically one | ||
which is not easily written or supported as an analytical expression. | ||
""" | ||
# Do your non-trivial magic here. In this case a Piecewise, although this | ||
# could also be done symbolically. | ||
y = np.zeros_like(x) | ||
y[x > b] = (a * (x - b) + b)[x > b] | ||
y[x <= b] = b | ||
return y | ||
|
||
x, y1, y2 = variables('x, y1, y2') | ||
a, b = parameters('a, b') | ||
|
||
mixed_model = CallableNumericalModel( | ||
{y1: nonanalytical_func, y2: x ** a}, | ||
independent_vars=[x], | ||
params=[a, b] | ||
) | ||
|
||
# Generate data | ||
xdata = np.linspace(0, 10) | ||
y1data, y2data = mixed_model(x=xdata, a=1.3, b=4) | ||
y1data = np.random.normal(y1data, 0.1 * y1data) | ||
y2data = np.random.normal(y2data, 0.1 * y2data) | ||
|
||
# Perform the fit | ||
b.value = 3.5 | ||
fit = Fit(mixed_model, x=xdata, y1=y1data, y2=y2data) | ||
fit_result = fit.execute() | ||
print(fit_result) | ||
|
||
# Plotting, irrelevant to the symfit part. | ||
y1_fit, y2_fit, = mixed_model(x=xdata, **fit_result.params) | ||
plt.scatter(xdata, y1data) | ||
plt.plot(xdata, y1_fit, label=r'$y_1$') | ||
plt.scatter(xdata, y2data) | ||
plt.plot(xdata, y2_fit, label=r'$y_2$') | ||
plt.legend(loc=0) | ||
plt.show() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.