2021-09-27 15:21:55 +01:00
|
|
|
import scipy.optimize
|
|
|
|
from autograd import jacobian
|
2021-11-07 11:24:56 +00:00
|
|
|
from .obs import derived_observable, pseudo_Obs
|
2021-10-11 12:22:58 +01:00
|
|
|
|
2021-09-27 15:21:55 +01:00
|
|
|
|
|
|
|
def find_root(d, func, guess=1.0, **kwargs):
|
2021-11-09 10:19:05 +00:00
|
|
|
r'''Finds the root of the function func(x, d) where d is an `Obs`.
|
2021-09-27 15:21:55 +01:00
|
|
|
|
|
|
|
Parameters
|
|
|
|
-----------------
|
2021-11-09 10:19:05 +00:00
|
|
|
d : Obs
|
|
|
|
Obs passed to the function.
|
|
|
|
func : object
|
|
|
|
Function to be minimized. Any numpy functions have to use the autograd.numpy wrapper.
|
|
|
|
Example:
|
|
|
|
```python
|
|
|
|
import autograd.numpy as anp
|
|
|
|
def root_func(x, d):
|
|
|
|
return anp.exp(-x ** 2) - d
|
|
|
|
```
|
|
|
|
guess : float
|
|
|
|
Initial guess for the minimization.
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
Obs
|
|
|
|
`Obs` valued root of the function.
|
|
|
|
'''
|
2021-09-27 15:21:55 +01:00
|
|
|
root = scipy.optimize.fsolve(func, guess, d.value)
|
|
|
|
|
2021-09-29 12:55:19 +01:00
|
|
|
# Error propagation as detailed in arXiv:1809.01289
|
2021-09-27 15:21:55 +01:00
|
|
|
dx = jacobian(func)(root[0], d.value)
|
2021-10-11 12:22:58 +01:00
|
|
|
da = jacobian(lambda u, v: func(v, u))(d.value, root[0])
|
2021-09-27 15:21:55 +01:00
|
|
|
deriv = - da / dx
|
|
|
|
|
|
|
|
return derived_observable(lambda x, **kwargs: x[0], [pseudo_Obs(root, 0.0, d.names[0], d.shape[d.names[0]]), d], man_grad=[0, deriv])
|