Мне нужно вычислить область со знаком из множества треугольников в 2D, заданную массивом фигур (2, 3, n)
(координата x / y, узел в треугольнике, количество треугольников).Я ищу способ сделать это быстро, и лучшее, что я мог придумать, это
def mix(p):
return (
+ p[0][2] * (p[1][0] - p[1][1])
+ p[0][0] * (p[1][1] - p[1][2])
+ p[0][1] * (p[1][2] - p[1][0])
) / 2
Другие попытки медленнее:
import numpy
import perfplot
def six(p):
return (
+ p[0][2]*p[1][0] + p[0][0]*p[1][1] + p[0][1]*p[1][2]
- p[0][2]*p[1][1] - p[0][0]*p[1][2] - p[0][1]*p[1][0]
) / 2
def mix(p):
return (
+ p[0][2] * (p[1][0] - p[1][1])
+ p[0][0] * (p[1][1] - p[1][2])
+ p[0][1] * (p[1][2] - p[1][0])
) / 2
def mix2(p):
p1 = p[1] - p[1][[1, 2, 0]]
return (
+ p[0][2] * p1[0]
+ p[0][0] * p1[1]
+ p[0][1] * p1[2]
) / 2
def cross(p):
e1 = p[:, 1] - p[:, 0]
e2 = p[:, 2] - p[:, 0]
return (e1[0]*e2[1] - e1[1]*e2[0]) / 2
def einsum(p):
return (
+ numpy.einsum('ij,ij->j', p[0][[2, 0, 1]], p[1][[0, 1, 2]])
- numpy.einsum('ij,ij->j', p[0][[2, 0, 1]], p[1][[1, 2, 0]])
) / 2
def einsum2(p):
return numpy.einsum(
'ij,ij->j',
p[0][[2, 0, 1]],
p[1] - p[1][[1, 2, 0]]
) / 2
def einsum3(p):
return numpy.einsum(
'ij,ij->j',
numpy.roll(p[0], 1, axis=0),
p[1] - numpy.roll(p[1], 2, axis=0)
) / 2
perfplot.show(
setup=lambda n: numpy.random.rand(2, 3, n),
kernels=[six, mix, mix2, cross, einsum, einsum2, einsum3],
n_range=[2**k for k in range(19)],
logx=True,
logy=True,
)
Любые подсказки о том, каксделать его еще более эффективным?
