def __init__(self, function: Callable, r: np.ndarray, max_interval, cutoff: float = None, cache_size: int = 4096, cache_key_decimals: int = 2, tolerance: float = 1e-6): self._function = function self._r = r if cutoff is None: self._cutoff = r[-1] else: self._cutoff = cutoff self._cache = Cache(cache_size) self._cache_key_decimals = cache_key_decimals self._tolerance = tolerance def f(z): return self._function( np.sqrt(self.r[0]**2 + (z * max_interval / 2 + max_interval / 2)**2)) value, error_estimate, step_size, order = integrate( f, -1, 1, self._tolerance) self._xk, self._wk = tanh_sinh_nodes_and_weights(step_size, order)
def cached_integrate(self, a, b): zm = (b - a) / 2. zp = (a + b) / 2. f = lambda z: self._function(np.sqrt(self.r[0]**2 + (z * zm + zp)**2)) value, error_estimate, step_size, order = integrate( f, -1, 1, self._tolerance) xk, wk = tanh_sinh_nodes_and_weights(step_size, order) f = lambda z: self._function( np.sqrt(self.r[:, None]**2 + (z * zm + zp)**2)) values = np.sum(f(xk[None]) * wk[None], axis=1) * zm derivatives = np.diff(values) / np.diff(self.r) return values, derivatives