Skip to content

math

Functions:

  • clamp

    Faster max(min(value, max_val), min_val) "wrapper"

  • clamp_arr

    Map an array to clamp.

  • cround

    Rounding function that accounts for float's imprecision.

  • mod2

    Force a value to be mod 2

  • mod4

    Force a value to be mod 4

  • mod8

    Force a value to be mod 8

  • mod_x

    Force a value to be divisible by x (val % x == 0).

  • ndigits
  • next_power_of_2

    Get the next power of 2 of x.

  • next_power_of_y

    Get the next power of y of x.

  • spline_coeff

    Get spline coefficient of an index and coordinates.

clamp

clamp(val: Nb, min_val: Nb, max_val: Nb) -> Nb

Faster max(min(value, max_val), min_val) "wrapper"

Source code in jetpytools/utils/math.py
20
21
22
23
def clamp[Nb: (int, float)](val: Nb, min_val: Nb, max_val: Nb) -> Nb:
    """Faster max(min(value, max_val), min_val) "wrapper" """

    return min_val if val < min_val else max_val if val > max_val else val

clamp_arr

clamp_arr(vals: Sequence[Nb], min_val: Nb, max_val: Nb) -> list[Nb]

Map an array to clamp.

Source code in jetpytools/utils/math.py
26
27
28
29
def clamp_arr[Nb: (int, float)](vals: Sequence[Nb], min_val: Nb, max_val: Nb) -> list[Nb]:
    """Map an array to clamp."""

    return [clamp(x, min_val, max_val) for x in vals]

cround

cround(x: float, *, eps: float = 1e-06) -> int

Rounding function that accounts for float's imprecision.

Source code in jetpytools/utils/math.py
32
33
34
35
def cround(x: float, *, eps: float = 1e-6) -> int:
    """Rounding function that accounts for float's imprecision."""

    return round(x + (eps if x > 0.0 else -eps))

mod2

mod2(val: int | float) -> int

Force a value to be mod 2

Source code in jetpytools/utils/math.py
47
48
49
50
def mod2(val: int | float) -> int:
    """Force a value to be mod 2"""

    return mod_x(val, x=2)

mod4

mod4(val: int | float) -> int

Force a value to be mod 4

Source code in jetpytools/utils/math.py
53
54
55
56
def mod4(val: int | float) -> int:
    """Force a value to be mod 4"""

    return mod_x(val, x=4)

mod8

mod8(val: int | float) -> int

Force a value to be mod 8

Source code in jetpytools/utils/math.py
59
60
61
62
def mod8(val: int | float) -> int:
    """Force a value to be mod 8"""

    return mod_x(val, x=8)

mod_x

mod_x(val: int | float, x: int) -> int

Force a value to be divisible by x (val % x == 0).

Source code in jetpytools/utils/math.py
38
39
40
41
42
43
44
def mod_x(val: int | float, x: int) -> int:
    """Force a value to be divisible by x (val % x == 0)."""

    if x == 0:
        return cround(val)

    return cround(val / x) * x

ndigits

ndigits(num: float) -> int
Source code in jetpytools/utils/math.py
164
165
166
167
168
169
def ndigits(num: float) -> int:
    if num == 0:
        return 1
    from math import log10

    return int(log10(abs(num))) + 1

next_power_of_2

next_power_of_2(x: float) -> int

Get the next power of 2 of x.

Source code in jetpytools/utils/math.py
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def next_power_of_2(x: float) -> int:
    """Get the next power of 2 of x."""

    x = cround(x)

    if x == 0:
        return 1

    if x & (x - 1) == 0:
        return x

    while x & (x - 1) > 0:
        x &= x - 1

    return x << 1

next_power_of_y

next_power_of_y(x: float, y: int) -> int

Get the next power of y of x.

Source code in jetpytools/utils/math.py
82
83
84
85
86
87
88
89
def next_power_of_y(x: float, y: int) -> int:
    """Get the next power of y of x."""
    from math import ceil, log

    if x == 0:
        return 1

    return int(y ** ceil(log(x, y)))

spline_coeff

spline_coeff(
    x: int,
    coordinates: list[tuple[float, float]] = [
        (0, 0),
        (0.5, 0.1),
        (1, 0.6),
        (2, 0.9),
        (2.5, 1),
        (3, 1.1),
        (3.5, 1.15),
        (4, 1.2),
        (8, 1.25),
        (255, 1.5),
    ],
) -> float

Get spline coefficient of an index and coordinates.

Source code in jetpytools/utils/math.py
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
def spline_coeff(
    x: int,
    coordinates: list[tuple[float, float]] = [
        (0, 0),
        (0.5, 0.1),
        (1, 0.6),
        (2, 0.9),
        (2.5, 1),
        (3, 1.1),
        (3.5, 1.15),
        (4, 1.2),
        (8, 1.25),
        (255, 1.5),
    ],
) -> float:
    """Get spline coefficient of an index and coordinates."""

    length = len(coordinates)

    if length < 3:
        raise ValueError("coordinates require at least three pairs")

    px, py = zip(*coordinates)

    matrix = [[1.0] + [0.0] * length]

    for i in range(1, length - 1):
        p = [0.0] * (length + 1)

        p[i - 1] = px[i] - px[i - 1]
        p[i] = 2 * (px[i + 1] - px[i - 1])
        p[i + 1] = px[i + 1] - px[i]
        p[length] = 6 * (((py[i + 1] - py[i]) / p[i + 1]) - (py[i] - py[i - 1]) / p[i - 1])

        matrix.append(p)

    matrix += [([0.0] * (length - 1) + [1.0, 0.0])]

    for i in range(length):
        num = matrix[i][i]

        for j in range(length + 1):
            matrix[i][j] /= num

        for j in range(length):
            if i != j:
                a = matrix[j][i]

                for k in range(i, length + 1):
                    matrix[j][k] -= a * matrix[i][k]

    i = 0

    for i in range(length + 1):
        if x >= px[i] and x <= px[i + 1]:
            break

    j = i + 1

    h = px[j] - px[i]

    s = matrix[j][length] * float((x - px[i]) ** 3)
    s -= matrix[i][length] * float((x - px[j]) ** 3)

    s /= 6 * h

    s += (py[j] / h - h * matrix[j][length] / 6) * (x - px[i])
    s -= (py[i] / h - h * matrix[i][length] / 6) * (x - px[j])

    return float(s)