Skip to content

Commit ae6af68

Browse files
committed
introduce 'fast_det' for 2x2 and 3x3 matrices
1 parent 49d67d7 commit ae6af68

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

adaptive/learner/learnerND.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,19 @@
1313

1414
from ..notebook_integration import ensure_holoviews, ensure_plotly
1515
from .triangulation import (Triangulation, point_in_simplex,
16-
circumsphere, simplex_volume_in_embedding)
16+
circumsphere, simplex_volume_in_embedding,
17+
fast_det)
1718
from ..utils import restore, cache_latest
1819

1920

2021
def volume(simplex, ys=None):
2122
# Notice the parameter ys is there so you can use this volume method as
2223
# as loss function
23-
matrix = np.array(np.subtract(simplex[:-1], simplex[-1]), dtype=float)
24-
dim = len(simplex) - 1
24+
matrix = np.subtract(simplex[:-1], simplex[-1], dtype=float)
2525

2626
# See https://www.jstor.org/stable/2315353
27-
vol = np.abs(np.linalg.det(matrix)) / np.math.factorial(dim)
27+
dim = len(simplex) - 1
28+
vol = np.abs(fast_det(matrix)) / np.math.factorial(dim)
2829
return vol
2930

3031

adaptive/learner/triangulation.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,17 @@ def fast_3d_circumcircle(points):
126126
return center, radius
127127

128128

129+
def fast_det(matrix):
130+
matrix = np.asarray(matrix, dtype=float)
131+
if matrix.shape == (2, 2):
132+
return matrix[0][0] * matrix[1][1] - matrix[1][0] * matrix[0][1]
133+
elif matrix.shape == (3, 3):
134+
a, b, c, d, e, f, g, h, i = matrix.ravel()
135+
return a * (e*i - f*h) - b * (d*i - f*g) + c * (d*h - e*g)
136+
else:
137+
return np.linalg.det(matrix)
138+
139+
129140
def circumsphere(pts):
130141
dim = len(pts) - 1
131142
if dim == 2:
@@ -140,9 +151,9 @@ def circumsphere(pts):
140151
for i in range(1, len(pts)):
141152
r = np.delete(mat, i, 1)
142153
factor = (-1) ** (i + 1)
143-
center.append(factor * np.linalg.det(r))
154+
center.append(factor * fast_det(r))
144155

145-
a = np.linalg.det(np.delete(mat, 0, 1))
156+
a = fast_det(np.delete(mat, 0, 1))
146157
center = [x / (2 * a) for x in center]
147158

148159
x0 = pts[0]
@@ -227,7 +238,7 @@ def simplex_volume_in_embedding(vertices) -> float:
227238
sq_dists_mat = scipy.spatial.distance.squareform(bordered)
228239

229240
coeff = - (-2) ** (num_verts-1) * factorial(num_verts-1) ** 2
230-
vol_square = np.linalg.det(sq_dists_mat) / coeff
241+
vol_square = fast_det(sq_dists_mat) / coeff
231242

232243
if vol_square < 0:
233244
if abs(vol_square) < 1e-15:
@@ -587,7 +598,7 @@ def volume(self, simplex):
587598
prefactor = np.math.factorial(self.dim)
588599
vertices = np.array(self.get_vertices(simplex))
589600
vectors = vertices[1:] - vertices[0]
590-
return float(abs(np.linalg.det(vectors)) / prefactor)
601+
return float(abs(fast_det(vectors)) / prefactor)
591602

592603
def volumes(self):
593604
return [self.volume(sim) for sim in self.simplices]

0 commit comments

Comments
 (0)