1
1
import itertools
2
2
from collections import Counter
3
3
from math import factorial
4
+ from typing import List , Optional , Tuple , Union
4
5
5
6
import numpy as np
6
7
import pytest
8
+ from numpy import ndarray
7
9
8
10
from adaptive .learner .triangulation import Triangulation
9
11
10
12
with_dimension = pytest .mark .parametrize ("dim" , [2 , 3 , 4 ])
11
13
12
14
13
- def _make_triangulation (points ) :
15
+ def _make_triangulation (points : ndarray ) -> Triangulation :
14
16
num_vertices = points .shape [1 ] + 1
15
17
first_simplex , points = points [:num_vertices ], points [num_vertices :]
16
18
t = Triangulation (first_simplex )
@@ -19,16 +21,16 @@ def _make_triangulation(points):
19
21
return t
20
22
21
23
22
- def _make_standard_simplex (dim ) :
24
+ def _make_standard_simplex (dim : int ) -> ndarray :
23
25
"""Return the vertices of the standard simplex in dimension 'dim'."""
24
26
return np .vstack ((np .zeros (dim ), np .eye (dim )))
25
27
26
28
27
- def _standard_simplex_volume (dim ) :
29
+ def _standard_simplex_volume (dim : int ) -> float :
28
30
return 1 / factorial (dim )
29
31
30
32
31
- def _check_simplices_are_valid (t ) :
33
+ def _check_simplices_are_valid (t : Triangulation ) -> None :
32
34
"""Check that 'simplices' and 'vertex_to_simplices' are consistent."""
33
35
vertex_to_simplices = [set () for _ in t .vertices ]
34
36
@@ -38,26 +40,42 @@ def _check_simplices_are_valid(t):
38
40
assert vertex_to_simplices == t .vertex_to_simplices
39
41
40
42
41
- def _check_faces_are_valid (t ) :
43
+ def _check_faces_are_valid (t : Triangulation ) -> None :
42
44
"""Check that a 'dim-1'-D face is shared by no more than 2 simplices."""
43
45
counts = Counter (t .faces ())
44
46
assert not any (i > 2 for i in counts .values ()), counts
45
47
46
48
47
- def _check_hull_is_valid (t ) :
49
+ def _check_hull_is_valid (t : Triangulation ) -> None :
48
50
"""Check that the stored hull is consistent with one computed from scratch."""
49
51
counts = Counter (t .faces ())
50
52
hull = {point for face , count in counts .items () if count == 1 for point in face }
51
53
assert t .hull == hull
52
54
53
55
54
- def _check_triangulation_is_valid (t ) :
56
+ def _check_triangulation_is_valid (t : Triangulation ) -> None :
55
57
_check_simplices_are_valid (t )
56
58
_check_faces_are_valid (t )
57
59
_check_hull_is_valid (t )
58
60
59
61
60
- def _add_point_with_check (tri , point , simplex = None ):
62
+ def _add_point_with_check (
63
+ tri : Triangulation ,
64
+ point : Union [
65
+ ndarray ,
66
+ Tuple [float , float , float , float ],
67
+ Tuple [float , float ],
68
+ List [int ],
69
+ Tuple [float , float , float ],
70
+ ],
71
+ simplex : Optional [
72
+ Union [
73
+ Tuple [int , int , int , int ],
74
+ Tuple [int , int , int ],
75
+ Tuple [int , int , int , int , int ],
76
+ ]
77
+ ] = None ,
78
+ ) -> None :
61
79
"""Check that the difference in simplices before and after adding a point
62
80
is returned by tri.add_point"""
63
81
old_simplices = tri .simplices .copy ()
@@ -68,15 +86,15 @@ def _add_point_with_check(tri, point, simplex=None):
68
86
assert created_simplices == new_simplices - old_simplices
69
87
70
88
71
- def test_triangulation_raises_exception_for_1d_list ():
89
+ def test_triangulation_raises_exception_for_1d_list () -> None :
72
90
# We could support 1d, but we don't for now, because it is not relevant
73
91
# so a user has to be aware
74
92
pts = [0 , 1 ]
75
93
with pytest .raises (TypeError ):
76
94
Triangulation (pts )
77
95
78
96
79
- def test_triangulation_raises_exception_for_1d_points ():
97
+ def test_triangulation_raises_exception_for_1d_points () -> None :
80
98
# We could support 1d, but we don't for now, because it is not relevant
81
99
# so a user has to be aware
82
100
pts = [(0 ,), (1 ,)]
@@ -85,7 +103,7 @@ def test_triangulation_raises_exception_for_1d_points():
85
103
86
104
87
105
@with_dimension
88
- def test_triangulation_of_standard_simplex (dim ) :
106
+ def test_triangulation_of_standard_simplex (dim : int ) -> None :
89
107
t = Triangulation (_make_standard_simplex (dim ))
90
108
expected_simplex = tuple (range (dim + 1 ))
91
109
assert t .simplices == {expected_simplex }
@@ -94,7 +112,7 @@ def test_triangulation_of_standard_simplex(dim):
94
112
95
113
96
114
@with_dimension
97
- def test_zero_volume_initial_simplex_raises_exception (dim ) :
115
+ def test_zero_volume_initial_simplex_raises_exception (dim : int ) -> None :
98
116
points = _make_standard_simplex (dim )[:- 1 ]
99
117
linearly_dependent_point = np .dot (np .random .random (dim ), points )
100
118
zero_volume_simplex = np .vstack ((points , linearly_dependent_point ))
@@ -106,7 +124,9 @@ def test_zero_volume_initial_simplex_raises_exception(dim):
106
124
107
125
108
126
@with_dimension
109
- def test_adding_point_outside_circumscribed_hypersphere_in_positive_orthant (dim ):
127
+ def test_adding_point_outside_circumscribed_hypersphere_in_positive_orthant (
128
+ dim : int ,
129
+ ) -> None :
110
130
t = Triangulation (_make_standard_simplex (dim ))
111
131
112
132
point_outside_circumscribed_sphere = (1.1 ,) * dim
@@ -133,7 +153,7 @@ def test_adding_point_outside_circumscribed_hypersphere_in_positive_orthant(dim)
133
153
134
154
135
155
@with_dimension
136
- def test_adding_point_outside_standard_simplex_in_negative_orthant (dim ) :
156
+ def test_adding_point_outside_standard_simplex_in_negative_orthant (dim : int ) -> None :
137
157
t = Triangulation (_make_standard_simplex (dim ))
138
158
new_point = list (range (- dim , 0 ))
139
159
@@ -168,7 +188,7 @@ def test_adding_point_outside_standard_simplex_in_negative_orthant(dim):
168
188
169
189
@with_dimension
170
190
@pytest .mark .parametrize ("provide_simplex" , [True , False ])
171
- def test_adding_point_inside_standard_simplex (dim , provide_simplex ) :
191
+ def test_adding_point_inside_standard_simplex (dim : int , provide_simplex : bool ) -> None :
172
192
t = Triangulation (_make_standard_simplex (dim ))
173
193
first_simplex = tuple (range (dim + 1 ))
174
194
inside_simplex = (0.1 ,) * dim
@@ -192,7 +212,7 @@ def test_adding_point_inside_standard_simplex(dim, provide_simplex):
192
212
193
213
194
214
@with_dimension
195
- def test_adding_point_on_standard_simplex_face (dim ) :
215
+ def test_adding_point_on_standard_simplex_face (dim : int ) -> None :
196
216
pts = _make_standard_simplex (dim )
197
217
t = Triangulation (pts )
198
218
on_simplex = np .average (pts [1 :], axis = 0 )
@@ -213,7 +233,7 @@ def test_adding_point_on_standard_simplex_face(dim):
213
233
214
234
215
235
@with_dimension
216
- def test_adding_point_on_standard_simplex_edge (dim ) :
236
+ def test_adding_point_on_standard_simplex_edge (dim : int ) -> None :
217
237
pts = _make_standard_simplex (dim )
218
238
t = Triangulation (pts )
219
239
on_edge = np .average (pts [:2 ], axis = 0 )
@@ -231,7 +251,7 @@ def test_adding_point_on_standard_simplex_edge(dim):
231
251
232
252
233
253
@with_dimension
234
- def test_adding_point_colinear_with_first_edge (dim ) :
254
+ def test_adding_point_colinear_with_first_edge (dim : int ) -> None :
235
255
pts = _make_standard_simplex (dim )
236
256
t = Triangulation (pts )
237
257
edge_extension = np .multiply (pts [1 ], 2 )
@@ -246,7 +266,7 @@ def test_adding_point_colinear_with_first_edge(dim):
246
266
247
267
248
268
@with_dimension
249
- def test_adding_point_coplanar_with_a_face (dim ) :
269
+ def test_adding_point_coplanar_with_a_face (dim : int ) -> None :
250
270
pts = _make_standard_simplex (dim )
251
271
t = Triangulation (pts )
252
272
face_extension = np .sum (pts [:- 1 ], axis = 0 ) * 2
@@ -261,7 +281,7 @@ def test_adding_point_coplanar_with_a_face(dim):
261
281
262
282
263
283
@with_dimension
264
- def test_adding_point_inside_circumscribed_circle (dim ) :
284
+ def test_adding_point_inside_circumscribed_circle (dim : int ) -> None :
265
285
pts = _make_standard_simplex (dim )
266
286
t = Triangulation (pts )
267
287
on_simplex = (0.6 ,) * dim
@@ -280,7 +300,7 @@ def test_adding_point_inside_circumscribed_circle(dim):
280
300
281
301
282
302
@with_dimension
283
- def test_triangulation_volume_is_less_than_bounding_box (dim ) :
303
+ def test_triangulation_volume_is_less_than_bounding_box (dim : int ) -> None :
284
304
eps = 1e-8
285
305
points = np .random .random ((10 , dim )) # all within the unit hypercube
286
306
t = _make_triangulation (points )
@@ -290,23 +310,23 @@ def test_triangulation_volume_is_less_than_bounding_box(dim):
290
310
291
311
292
312
@with_dimension
293
- def test_triangulation_is_deterministic (dim ) :
313
+ def test_triangulation_is_deterministic (dim : int ) -> None :
294
314
points = np .random .random ((10 , dim ))
295
315
t1 = _make_triangulation (points )
296
316
t2 = _make_triangulation (points )
297
317
assert t1 .simplices == t2 .simplices
298
318
299
319
300
320
@with_dimension
301
- def test_initialisation_raises_when_not_enough_points (dim ) :
321
+ def test_initialisation_raises_when_not_enough_points (dim : int ) -> None :
302
322
deficient_simplex = _make_standard_simplex (dim )[:- 1 ]
303
323
304
324
with pytest .raises (ValueError ):
305
325
Triangulation (deficient_simplex )
306
326
307
327
308
328
@with_dimension
309
- def test_initialisation_raises_when_points_coplanar (dim ) :
329
+ def test_initialisation_raises_when_points_coplanar (dim : int ) -> None :
310
330
zero_volume_simplex = _make_standard_simplex (dim )[:- 1 ]
311
331
312
332
new_point1 = np .average (zero_volume_simplex , axis = 0 )
@@ -318,7 +338,7 @@ def test_initialisation_raises_when_points_coplanar(dim):
318
338
319
339
320
340
@with_dimension
321
- def test_initialisation_accepts_more_than_one_simplex (dim ) :
341
+ def test_initialisation_accepts_more_than_one_simplex (dim : int ) -> None :
322
342
points = _make_standard_simplex (dim )
323
343
new_point = [1.1 ] * dim # Point oposing the origin but outside circumsphere
324
344
points = np .vstack ((points , new_point ))
0 commit comments