-
-
Notifications
You must be signed in to change notification settings - Fork 263
Expand file tree
/
Copy pathtest_tools_matrix.py
More file actions
276 lines (204 loc) · 8.24 KB
/
Copy pathtest_tools_matrix.py
File metadata and controls
276 lines (204 loc) · 8.24 KB
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
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
import numpy as np
import pytest
from rocketpy import Function
from rocketpy.mathutils import Matrix, Vector
test_matrix_1 = [[-7, 2, 3], [4, 5, -6], [1, -8, 9]]
test_matrix_2 = [[np.pi, 2.5, 3.7], [4.2, np.e, -6.7], [1.1, -8.0, 0]]
test_matrix_3 = [
[0.1 + 1.0j, 3.1 + 1.2j, 2 + 0.5j],
[2.1 + 0.5j, 1.5 + 0.5j, 1 + 1.8j],
[5.2 + 1.3j, 4.2 + 7.7j, 7 + 5.3j],
]
test_matrix_4 = [[-7, 0, 0], [0, 5, 0], [0, 0, 9]]
test_matrix_5 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
test_matrices = [
test_matrix_1,
test_matrix_2,
test_matrix_3,
test_matrix_4,
test_matrix_5,
]
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_constructor(components):
matrix = Matrix(components)
assert matrix.components == components
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_getitem(components):
matrix = Matrix(components)
for i, j in [(i, j) for i in range(3) for j in range(3)]:
assert matrix[i, j] == components[i][j]
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_iter(components):
matrix = Matrix(components)
for i, j in zip(matrix, components):
assert i == j
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_call(components):
f = Function(lambda x: x**2)
matrix = Matrix(components)
callable_matrix = matrix * f
assert callable_matrix(1) == matrix
assert callable_matrix(2) == 4 * matrix
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_len(components):
matrix = Matrix(components)
assert len(matrix) == 3
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_shape(components):
matrix = Matrix(components)
assert matrix.shape == (3, 3)
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_trace(components):
matrix = Matrix(components)
assert matrix.trace == np.trace(matrix)
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_transpose(components):
matrix = Matrix(components)
assert matrix.transpose == np.transpose(matrix)
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_det(components):
matrix = Matrix(components)
assert matrix.det == pytest.approx(np.linalg.det(matrix))
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_is_diagonal(components):
matrix = Matrix(components)
assert matrix.is_diagonal == (matrix.det == matrix.xx * matrix.yy * matrix.zz)
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_inverse(components):
matrix = Matrix(components)
if matrix.det == 0:
with pytest.raises(ZeroDivisionError):
assert matrix.inverse
else:
assert matrix.inverse == np.linalg.inv(matrix)
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_abs(components):
matrix = Matrix(components)
assert abs(matrix) == pytest.approx(np.linalg.det(matrix))
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_neg(components):
assert -Matrix(components) + Matrix(components) == Matrix.zeros()
@pytest.mark.parametrize("A", test_matrices)
@pytest.mark.parametrize("B", test_matrices)
def test_matrix_add(A, B):
expected_result = np.array(A) + np.array(B)
assert Matrix(A) + Matrix(B) == expected_result
@pytest.mark.parametrize("A", test_matrices)
@pytest.mark.parametrize("B", test_matrices)
def test_matrix_sub(A, B):
expected_result = np.array(A) - np.array(B)
assert Matrix(A) - Matrix(B) == expected_result
@pytest.mark.parametrize("k", [-1, 0, 1, np.pi])
@pytest.mark.parametrize("A", test_matrices)
def test_matrix_mul(A, k):
A = Matrix(A)
assert A * k == k * np.array(A)
@pytest.mark.parametrize("k", [-1, 0, 1, np.pi])
@pytest.mark.parametrize("A", test_matrices)
def test_matrix_rmul(A, k):
np_array = np.array(A)
A = Matrix(A)
assert k * A == k * np_array
@pytest.mark.parametrize("A", test_matrices)
@pytest.mark.parametrize("k", [-1, 1, np.pi, np.e])
def test_matrix_truediv(A, k):
A = Matrix(A)
assert A / k == np.array(A) / k
@pytest.mark.parametrize("A", test_matrices)
@pytest.mark.parametrize("B", test_matrices)
def test_matrix_matmul_matrices(A, B):
expected_result = np.dot(A, B)
assert Matrix(A) @ Matrix(B) == expected_result
@pytest.mark.parametrize("A", test_matrices)
@pytest.mark.parametrize("B", [[1, 2, 3], [-np.pi, 1, np.e], [3 * 1j, -2j, 0j]])
def test_matrix_matmul_vectors(A, B):
expected_result = np.dot(A, B)
assert Matrix(A) @ Vector(B) == expected_result
@pytest.mark.parametrize("k", [0, 1, 2, 3, 4, 5])
@pytest.mark.parametrize("A", test_matrices)
def test_matrix_pow(A, k):
A = Matrix(A)
assert A**k == np.linalg.matrix_power(A, k)
@pytest.mark.parametrize("matrix_components", test_matrices)
def test_matrix_eq(matrix_components):
matrix = Matrix(matrix_components)
assert matrix == matrix_components
assert (matrix == 2 * matrix) is False
@pytest.mark.parametrize("operation", [lambda i: i**2, lambda i: 1 / (i + 1.1)])
@pytest.mark.parametrize("matrix_components", test_matrices)
def test_matrix_element_wise(matrix_components, operation):
matrix = Matrix(matrix_components)
matrix = matrix.element_wise(operation)
assert Matrix(
[
[operation(matrix.xx), operation(matrix.xy), operation(matrix.xz)],
[operation(matrix.yx), operation(matrix.yy), operation(matrix.yz)],
[operation(matrix.zx), operation(matrix.zy), operation(matrix.zz)],
]
)
@pytest.mark.parametrize("A", test_matrices)
@pytest.mark.parametrize("B", test_matrices)
def test_matrix_dot(A, B):
A, B = Matrix(A), Matrix(B)
assert A.dot(B) == np.dot(A, B)
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_str(components):
matrix = Matrix(components)
assert str(matrix) == (
f"[{components[0][0]}, {components[0][1]}, {components[0][2]}]\n"
+ f"[{components[1][0]}, {components[1][1]}, {components[1][2]}]\n"
+ f"[{components[2][0]}, {components[2][1]}, {components[2][2]}]]"
)
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_repr(components):
matrix = Matrix(components)
assert repr(matrix) == (
f"Matrix([{components[0][0]}, {components[0][1]}, {components[0][2]}],\n"
+ f" [{components[1][0]}, {components[1][1]}, {components[1][2]}],\n"
+ f" [{components[2][0]}, {components[2][1]}, {components[2][2]}])"
)
def test_matrix_identity():
assert Matrix.identity() == np.eye(3)
def test_matrix_zeros():
assert Matrix.zeros() == np.zeros((3, 3))
def test_matrix_transformation():
# Check that the matrix is orthogonal
phi = 45 * np.pi / 180
n = Vector([1, 1, 1])
q0 = np.cos(phi / 2)
q1, q2, q3 = np.sin(phi / 2) * n.unit_vector
matrix = Matrix.transformation((q0, q1, q2, q3))
assert matrix @ matrix.transpose == Matrix.identity()
# Check that the matrix rotates the vector correctly
phi = np.pi / 2
n = Vector([1, 0, 0])
q0 = np.cos(phi / 2)
q1, q2, q3 = np.sin(phi / 2) * n
matrix = Matrix.transformation((q0, q1, q2, q3))
assert matrix @ Vector([0, 0, 1]) == Vector([0, -1, 0])
def test_matrix_transformation_euler_angles():
roll = np.pi / 2
pitch = np.pi / 2
roll2 = np.pi / 2
matrix = Matrix.transformation_euler_angles(roll, pitch, roll2)
matrix = matrix.round(12)
# Check that the matrix is orthogonal
assert matrix @ matrix.transpose == Matrix.identity()
# Check that the matrix rotates the vector correctly
assert matrix @ Vector([0, 0, 1]) == Vector([1, 0, 0])
def test_matrix_round():
matrix = [[2e-10, -2e-10, 0], [5.1234, -5.1234, 0], [0, 0, 9]]
matrix = Matrix(matrix).round(3)
assert matrix == Matrix([[0, 0, 0], [5.123, -5.123, 0], [0, 0, 9]])
@pytest.mark.parametrize("components", test_matrices)
def test_matrix_x_y_z(components):
matrix = Matrix(components)
assert matrix.xx == components[0][0]
assert matrix.xy == components[0][1]
assert matrix.xz == components[0][2]
assert matrix.yx == components[1][0]
assert matrix.yy == components[1][1]
assert matrix.yz == components[1][2]
assert matrix.zx == components[2][0]
assert matrix.zy == components[2][1]
assert matrix.zz == components[2][2]