...
|
...
|
@@ -47,16 +47,25 @@ def std_loss(simplex, ys):
|
47
|
47
|
|
48
|
48
|
|
49
|
49
|
def simplex_volume(vertices) -> float:
|
50
|
|
- """
|
51
|
|
- Return the volume of the simplex with given vertices.
|
|
50
|
+ """Calculate the volume of a simplex in a higher dimensional embedding.
|
|
51
|
+ That is: dim > len(vertices) - 1. For example if you would like to know the
|
|
52
|
+ surface area of a triangle in a 3d space.
|
52
|
53
|
|
53
|
|
- If vertices are given they must be in a arraylike with shape (N+1, N):
|
54
|
|
- the position vectors of the N+1 vertices in N dimensions. If the sides
|
55
|
|
- are given, they must be the compressed pairwise distance matrix as
|
56
|
|
- returned from scipy.spatial.distance.pdist.
|
|
54
|
+ Parameters
|
|
55
|
+ ----------
|
|
56
|
+ vertices: arraylike (2 dimensional)
|
|
57
|
+ array of points
|
57
|
58
|
|
58
|
|
- Raises a ValueError if the vertices do not form a simplex (for example,
|
59
|
|
- because they are coplanar, colinear or coincident).
|
|
59
|
+ Returns
|
|
60
|
+ -------
|
|
61
|
+ volume: int
|
|
62
|
+ the volume of the simplex with given vertices.
|
|
63
|
+
|
|
64
|
+ Raises
|
|
65
|
+ ------
|
|
66
|
+ ValueError:
|
|
67
|
+ if the vertices do not form a simplex (for example,
|
|
68
|
+ because they are coplanar, colinear or coincident).
|
60
|
69
|
|
61
|
70
|
Warning: this algorithm has not been tested for numerical stability.
|
62
|
71
|
"""
|
...
|
...
|
@@ -96,7 +105,9 @@ def default_loss(simplex, ys):
|
96
|
105
|
def choose_point_in_simplex(simplex, transform=None):
|
97
|
106
|
"""Choose a new point in inside a simplex.
|
98
|
107
|
|
99
|
|
- Pick the center of the longest edge of this simplex
|
|
108
|
+ Pick the center of the simplex if the shape is nice (that is, the
|
|
109
|
+ circumcenter lies within the simplex). Otherwise take the middle of the
|
|
110
|
+ longest edge.
|
100
|
111
|
|
101
|
112
|
Parameters
|
102
|
113
|
----------
|
...
|
...
|
@@ -107,7 +118,7 @@ def choose_point_in_simplex(simplex, transform=None):
|
107
|
118
|
|
108
|
119
|
Returns
|
109
|
120
|
-------
|
110
|
|
- point : numpy array
|
|
121
|
+ point : numpy array of length N
|
111
|
122
|
The coordinates of the suggested new point.
|
112
|
123
|
"""
|
113
|
124
|
|
...
|
...
|
@@ -115,20 +126,23 @@ def choose_point_in_simplex(simplex, transform=None):
|
115
|
126
|
if transform is not None:
|
116
|
127
|
simplex = np.dot(simplex, transform)
|
117
|
128
|
|
118
|
|
- # choose center iff the shape of the simplex is nice,
|
119
|
|
- # otherwise the longest edge
|
|
129
|
+ # choose center if and only if the shape of the simplex is nice,
|
|
130
|
+ # otherwise: the longest edge
|
120
|
131
|
center, _radius = circumsphere(simplex)
|
121
|
132
|
if point_in_simplex(center, simplex):
|
122
|
133
|
point = np.average(simplex, axis=0)
|
123
|
134
|
else:
|
124
|
135
|
distances = scipy.spatial.distance.pdist(simplex)
|
125
|
136
|
distance_matrix = scipy.spatial.distance.squareform(distances)
|
126
|
|
- i, j = np.unravel_index(np.argmax(distance_matrix),
|
|
137
|
+ i, j = np.unravel_index(np.argmax(distance_matrix),
|
127
|
138
|
distance_matrix.shape)
|
128
|
139
|
|
129
|
140
|
point = (simplex[i, :] + simplex[j, :]) / 2
|
130
|
141
|
|
131
|
|
- return np.linalg.solve(transform, point) # undo the transform
|
|
142
|
+ if transform is not None:
|
|
143
|
+ point = np.linalg.solve(transform, point) # undo the transform
|
|
144
|
+
|
|
145
|
+ return point
|
132
|
146
|
|
133
|
147
|
|
134
|
148
|
class LearnerND(BaseLearner):
|