-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathenvelope_method.py
More file actions
83 lines (67 loc) · 2.59 KB
/
envelope_method.py
File metadata and controls
83 lines (67 loc) · 2.59 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
# -----------------------------------------------------------------
# envelope_method.py
#
# Implementing the envelope method
# This takes an input dict of points with a base (1 or 2)-tuple and
# an array of (2 or 3)-tuples with that base tuple as their first component
#
# For each base point, we `erode away` this array of possible points
# both from the highest value down and from the lowest value up
# by excluding points using sdpb until somethnig is not excluded
# -----------------------------------------------------------------
from point_generator import array2dict2D, array2dict3D
def approx(a, b, rel_tol=1e-09, abs_tol=0.0):
return abs(a - b) < max(rel_tol * max(abs(a), abs(b)), abs_tol)
def get_step(fiber):
assert sorted(fiber)
if len(fiber) == 1:
return None
else:
step = min([t2 - t1 for t1, t2 in zip(fiber[:-1], fiber[1:])])
if step == 0.0:
raise RuntimeError("There are repeated values in the list.")
else:
return step
def get_chunks(fiber):
step = get_step(fiber)
chunks = []
chunk = [fiber[0]]
if step is None:
return [chunk]
for i in range(1, len(fiber)):
if not approx(fiber[i] - fiber[i-1], step):
chunks.append(chunk)
chunk = [fiber[i]]
else:
chunk.append(fiber[i])
chunks.append(chunk)
return chunks
def erode(check, base_point, chunk, f=None):
assert sorted(chunk)
# Go down from the top until something isn't excluded
for above in range(len(chunk)-1, -1, -1):
point = tuple(list(base_point) + [chunk[above]])
if not check(point, f=f):
break
# Go down until something isn't excluded
for below in range(0, above):
point = tuple(list(base_point) + [chunk[below]])
if not check(point, f=f):
break
def envelope_loop3D(check, points, f=None):
base_points = array2dict3D(points)
for base_point, thetas in base_points.iteritems():
# Over each base point, you can assume positive values of theta (for now.. with this batch..)
# with uniform step size (in fact 0.01 for this batch)
# From there, get the connected components and erode
thetas.sort()
chunks = get_chunks(thetas)
for chunk in chunks:
erode(check, base_point, chunk, f=f)
def envelope_loop2D(check, points, f=None):
base_points = array2dict2D(points)
for base_point, epsilons in base_points.iteritems():
epsilons.sort()
chunks = get_chunks(epsilons)
for chunk in chunks:
erode(check, base_point, chunk, f=f)