# AUTOGENERATED FILE! PLEASE DON'T EDIT
"""Higher order functions"""
__all__ = ["Func", "polyfit", "derivative", "optimize", "inverse", "integrate"]
from typing import Callable, List
import k1lib, numpy as np
Func = Callable[[float], float]
[docs]def polyfit(x:List[float], y:List[float], deg:int=6) -> Func:
"""Returns a function that approximate :math:`f(x) = y`.
:param deg: degree of the polynomial of the returned function
"""
params = np.polyfit(x, y, deg)
def _inner(_x):
answer = np.zeros_like(_x, dtype=np.float)
for expo, param in enumerate(params):
answer += param * _x**(len(params)-expo-1)
return answer
return _inner
[docs]def derivative(f:Func, delta:float=1e-6) -> Func:
"""Returns the derivative of a function.
Example::
f = lambda x: x**2
df = k1lib.derivative(f)
df(3) # returns roughly 6 """
return lambda x: (f(x + delta) - f(x)) / delta
[docs]def optimize(f:Func, v:float=1, threshold:float=1e-6) -> float:
r"""Given :math:`f(x) = 0`, solves for x using Newton's method with initial value
`v`. Example::
f = lambda x: x**2-2
# returns 1.4142 (root 2)
k1lib.optimize(f)
# returns -1.4142 (negative root 2)
k1lib.optimize(f, -1)
Interestingly, for some reason, result of this is more accurate than :meth:`derivative`.
"""
fD = derivative(f)
while abs(f(v)) > threshold: v = v - f(v)/fD(v)
return v
[docs]def inverse(f:Func) -> Func:
"""Returns the inverse of a function.
Example::
f = lambda x: x**2
fInv = k1lib.inverse(f)
# returns roughly 3
fInv(9)
.. warning::
The inverse function takes a long time to run, so don't use this
where you need lots of speed. Also, as you might imagine, the
inverse function isn't really airtight. Should work well with
monotonic functions, but all bets are off with other functions."""
return lambda y: optimize(lambda x: f(x) - y)
[docs]def integrate(f:Func, _range:k1lib.Range) -> float:
"""Integrates a function over a range.
Example::
f = lambda x: x**2
# returns roughly 9
k1lib.integrate(f, [0, 3])"""
_range = k1lib.Range(_range)
n = 1000; xs = np.linspace(*_range, n)
return sum([f(x)*_range.delta/n for x in xs])