Hong-Phuc Bui
2024-09-27 45c96fe258657363ef4ad1a2ae93513ca4139e26
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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