from typing import Callable def split(a:float=0, b: float=8, iteration=8): x = [a, b] parts = 1 dx = (b - a) for n in range(1, iteration + 1): print(n, end=" → ") parts = 2 * parts dx = dx / 2 for i in range(1, parts, 2): print(i, end=" ") x.insert(i, a + i * dx) print("\n ", x) pass def numint_epsilon(f: Callable[[float], float], a: float, b: float, epsilon: float = 1e-3): """ a not very stupid implementation of Riemann sum for a function, left sum and right sum are calculated as long as their difference less than the given epsilon. :param f: :param a: :param b: :param epsilon: :return: """ dx = b - a x = [a, b] # debug only y = [f(a), f(b)] s_left = dx * y[0] s_right = dx * y[1] (n, parts) = (0, 1) while abs(s_right - s_left) > epsilon: parts = 2 * parts dx = dx / 2 n += 1 for i in range(1, parts, 2): x.insert(i, a + i * dx) y.insert(i, f(a + i * dx)) s_left = sum(y[0:-1]) * dx s_right = sum(y[1:]) * dx return x, y, s_left, s_right, n def numint_section(f: Callable[[float], float], a: float, b: float, section_count: int = 8): """ a stupid implementation of Riemann sum for a function with a fixed number of sections in interval [a, b] :param f: :param a: :param b: :param section_count: :return: """ dx = b - a x = [a, b] y = [f(a), f(b)] (n, parts) = (0, 1) s_left = dx * y[0] s_right = dx * y[1] while parts < section_count: parts = 2 * parts dx = dx / 2 n += 1 for i in range(1, parts, 2): x.insert(i, a + i * dx) y.insert(i, f(a + i * dx)) s_left = sum(y[0:-1]) * dx s_right = sum(y[1:]) * dx pass return x, y, s_left, s_right, n def numint_compact(f: Callable[[float], float], a: float, b: float, epsilon=1e-3): dx = b - a y_l = f(a) y_r = f(b) s_left = dx * y_l s_right = dx * y_r (n, parts) = (1, 1) while abs(s_right - s_left) > epsilon: parts = 2 * parts dx = dx / 2 n += 1 for i in range(1, parts, 2): y = f(a + i*dx) y_l += y y_r += y s_left = y_l * dx s_right = y_r * dx return s_left, s_right