MCPcopy Create free account
hub / github.com/NanoComp/meep / find_root_deriv

Function find_root_deriv

python/geom.py:1693–1766  ·  view source on GitHub ↗
(f, tol, x_min, x_max, x_guess=None)

Source from the content-addressed store, hash-verified

1691# Find a root by Newton's method with bounds and bisection,
1692# given a function f that returns a pair of (value . derivative)
1693def find_root_deriv(f, tol, x_min, x_max, x_guess=None):
1694 # Some trickiness: we only need to evaluate the function at x_min and
1695 # x_max if a Newton step fails, and even then only if we haven't already
1696 # bracketed the root, so do this via lazy evaluation.
1697 f_memo = memoize(f)
1698
1699 def lazy(x):
1700 return x if isinstance(x, Number) else x()
1701
1702 def pick_bound(which):
1703 def _pb():
1704 fmin_tup = f_memo(x_min)
1705 fmax_tup = f_memo(x_max)
1706 fmin = fmin_tup[0]
1707 fmax = fmax_tup[0]
1708
1709 if which(fmin):
1710 return x_min
1711 elif which(fmax):
1712 return x_max
1713 else:
1714 raise ValueError("failed to bracket the root in find_root_deriv")
1715
1716 return _pb
1717
1718 def in_bounds(x, f, df, a, b):
1719 return (f - (df * (x - a))) * (f - (df * (x - b))) < 0
1720
1721 def newton(x, a, b, dx):
1722 if abs(dx) < abs(tol * x):
1723 return x
1724
1725 fx_tup = f_memo(x)
1726 f = fx_tup[0]
1727 df = fx_tup[1]
1728
1729 if f == 0:
1730 return x
1731
1732 a_prime = x if f < 0 else a
1733 b_prime = x if f > 0 else b
1734
1735 if (
1736 dx != x_max - x_min
1737 and dx * (f / df) < 0
1738 and f_memo(lazy(a_prime))[0] * f_memo(lazy(b_prime))[0] > 0
1739 ):
1740 raise ValueError("failed to bracket the root in find_root_deriv")
1741
1742 if isinstance(a, Number) and isinstance(b, Number):
1743 is_in_bounds = in_bounds(x, f, df, a, b)
1744 else:
1745 is_in_bounds = in_bounds(x, f, df, x_min, x_max)
1746
1747 if is_in_bounds:
1748 return newton(x - (f / df), a_prime, b_prime, f / df)
1749
1750 av = lazy(a)

Callers

nothing calls this directly

Calls 3

memoizeFunction · 0.85
newtonFunction · 0.85
pick_boundFunction · 0.85

Tested by

no test coverage detected