-
Notifications
You must be signed in to change notification settings - Fork 44
/
utils.py
70 lines (49 loc) · 1.57 KB
/
utils.py
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
import numpy as np
import math
def psi(theta: float, k: int = 1, gamma: float = 0.):
r"""
Rotation matrix corresponding to the angle :math:`k \theta + \gamma`.
"""
x = k * theta + gamma
c, s = np.cos(x), np.sin(x)
return np.array(([
[c, -s],
[s, c],
]))
def chi(s: int):
#
r"""
The orthonormal matrix associated to the reflection along the :math:`y` axis if ``s=1``, the identity otherwise.
"""
assert s in [0, 1]
s = (-1 if s else 1)
# assert s in [-1, 1]
return np.array(([
[1, 0],
[0, s],
]))
def psichi(theta: float, s: int, k: int = 1, gamma: float = 0.):
r"""
Rotation matrix corresponding to the angle :math:`k \theta + \gamma` if `s=0`.
Otherwise, it corresponds to the reflection along the axis defined by that angle.
It is equal to::
psi(theta, k, gamma) @ chi(s)
"""
assert s in [0, 1]
s = (-1 if s else 1)
# assert s in [-1, 1]
x = k * theta + gamma
return np.array(([
[np.cos(x), -s*np.sin(x)],
[np.sin(x), s*np.cos(x)],
]))
def cycle_isclose(a, b, S, rtol=1e-9, atol=1e-11):
r"""
Cyclic "isclose" check.
Checks if the numbers ``a`` and ``b`` are close to each other in a cycle of length ``S``,
i.e. if ``a - b`` is close to a multiple of ``S``.
"""
d = (a - b) % S
close_0 = math.isclose(d, 0., rel_tol=rtol, abs_tol=atol) and d >= 0.
close_S = math.isclose(d, S, rel_tol=rtol, abs_tol=atol) and d <= S
return close_0 or close_S