Skip to content

Commit e0e4296

Browse files
author
andrewtliew
committed
- hpc.geometry.average_numba module.
1 parent 7fd2546 commit e0e4296

File tree

3 files changed

+283
-2
lines changed

3 files changed

+283
-2
lines changed

src/compas/geometry/average.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
from __future__ import print_function
21
from __future__ import absolute_import
32
from __future__ import division
3+
from __future__ import print_function
44

55
from compas.utilities import window
66

@@ -14,7 +14,7 @@
1414

1515

1616
__author__ = ['Tom Van Mele', ]
17-
__copyright__ = 'Copyright 2016 - Block Research Group, ETH Zurich'
17+
__copyright__ = 'Copyright 2017 - Block Research Group, ETH Zurich'
1818
__license__ = 'MIT License'
1919
__email__ = '[email protected]'
2020

src/compas/hpc/__init__.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
geometry
3434
========
3535
36+
basic
37+
-----
38+
3639
.. autosummary::
3740
:toctree: generated/
3841
:nosignatures:
@@ -78,6 +81,20 @@
7881
circle_from_points_numba
7982
circle_from_points_xy_numba
8083
84+
average
85+
-------
86+
87+
.. autosummary::
88+
:toctree: generated/
89+
:nosignatures:
90+
91+
centroid_points_numba
92+
centroid_points_xy_numba
93+
midpoint_point_point_numba
94+
midpoint_point_point_xy_numba
95+
center_of_mass_polyline_numba
96+
center_of_mass_polyline_xy_numba
97+
8198
8299
core
83100
====
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
from __future__ import absolute_import
2+
from __future__ import division
3+
from __future__ import print_function
4+
5+
from compas.hpc.geometry import add_vectors_numba
6+
from compas.hpc.geometry import add_vectors_xy_numba
7+
from compas.hpc.geometry import cross_vectors_numba
8+
from compas.hpc.geometry import dot_vectors_numba
9+
from compas.hpc.geometry import length_vector_numba
10+
from compas.hpc.geometry import length_vector_xy_numba
11+
from compas.hpc.geometry import scale_vector_numba
12+
from compas.hpc.geometry import scale_vector_xy_numba
13+
from compas.hpc.geometry import subtract_vectors_numba
14+
from compas.hpc.geometry import subtract_vectors_xy_numba
15+
from compas.hpc.geometry import sum_vectors_numba
16+
17+
from numba import f8
18+
from numba import i8
19+
from numba import jit
20+
from numba import prange
21+
22+
from numpy import array
23+
24+
25+
__author__ = ['Andrew Liew <[email protected]>']
26+
__copyright__ = 'Copyright 2017, BLOCK Research Group - ETH Zurich'
27+
__license__ = 'MIT License'
28+
__email__ = '[email protected]'
29+
30+
31+
__all__ = [
32+
'centroid_points_numba',
33+
'centroid_points_xy_numba',
34+
'midpoint_point_point_numba',
35+
'midpoint_point_point_xy_numba',
36+
'center_of_mass_polyline_numba',
37+
'center_of_mass_polyline_xy_numba',
38+
# 'center_of_mass_polyhedron_numba',
39+
]
40+
41+
42+
@jit(f8[:](f8[:, :]), nogil=True, nopython=True, parallel=True)
43+
def centroid_points_numba(u):
44+
"""Compute the centroid of a set of points.
45+
46+
Parameters
47+
----------
48+
u : array
49+
An array of XYZ coordinates.
50+
51+
Returns
52+
-------
53+
array
54+
Centroid of the points.
55+
"""
56+
m = u.shape[0]
57+
f = 1 / m
58+
return scale_vector_numba(sum_vectors_numba(u, axis=0), factor=f)
59+
60+
61+
@jit(f8[:](f8[:, :]), nogil=True, nopython=True, parallel=True)
62+
def centroid_points_xy_numba(u):
63+
"""Compute the centroid of a set of points lying in the XY plane.
64+
65+
Parameters
66+
----------
67+
u : array
68+
An array of XY(Z) coordinates in the XY plane.
69+
70+
Returns
71+
-------
72+
array
73+
Centroid of the points (Z = 0.0).
74+
"""
75+
u[:, 2] = 0
76+
return centroid_points_numba(u)
77+
78+
79+
@jit(f8[:](f8[:], f8[:]), nogil=True, nopython=True, parallel=True)
80+
def midpoint_point_point_numba(u, v):
81+
"""Compute the midpoint of two points.
82+
83+
Parameters
84+
----------
85+
u : array
86+
XYZ coordinates of the first point.
87+
v : array
88+
XYZ coordinates of the second point.
89+
90+
Returns
91+
-------
92+
array
93+
XYZ coordinates of the midpoint.
94+
"""
95+
return scale_vector_numba(add_vectors_numba(u, v), factor=0.5)
96+
97+
98+
@jit(f8[:](f8[:], f8[:]), nogil=True, nopython=True, parallel=True)
99+
def midpoint_point_point_xy_numba(u, v):
100+
"""Compute the midpoint of two points lying in the XY-plane.
101+
102+
Parameters
103+
----------
104+
u : array
105+
XY(Z) coordinates of the first point in the XY plane.
106+
v : array
107+
XY(Z) coordinates of the second point in the XY plane.
108+
109+
Returns
110+
-------
111+
array
112+
XYZ (Z = 0.0) coordinates of the midpoint.
113+
"""
114+
return scale_vector_xy_numba(add_vectors_xy_numba(u, v), factor=0.5)
115+
116+
117+
@jit(f8[:](f8[:, :]), nogil=True, nopython=True, parallel=False)
118+
def center_of_mass_polyline_numba(polyline):
119+
"""Compute the center of mass of polyline edges defined as an array of points.
120+
121+
Parameters
122+
----------
123+
polyline : array
124+
XYZ coordinates representing the corners of a polyline (m x 3).
125+
126+
Returns
127+
-------
128+
array
129+
The XYZ coordinates of the center of mass.
130+
"""
131+
L = 0
132+
cx = 0
133+
cy = 0
134+
cz = 0
135+
m = polyline.shape[0]
136+
ii = list(range(1, m)) + [0]
137+
for i in prange(m):
138+
p1 = polyline[i, :]
139+
p2 = polyline[ii[i], :]
140+
d = length_vector_numba(subtract_vectors_numba(p2, p1))
141+
cx += 0.5 * d * (p1[0] + p2[0])
142+
cy += 0.5 * d * (p1[1] + p2[1])
143+
cz += 0.5 * d * (p1[2] + p2[2])
144+
L += d
145+
c = array([cx, cy, cz])
146+
f = 1 / L
147+
return scale_vector_numba(c, factor=f)
148+
149+
150+
@jit(f8[:](f8[:, :]), nogil=True, nopython=True, parallel=False)
151+
def center_of_mass_polyline_xy_numba(polyline):
152+
"""Compute the center of mass of polyline edges in the XY plane, defined as an array of points.
153+
154+
Parameters
155+
----------
156+
polyline : array
157+
XY(Z) coordinates representing the corners of a polyline (m x 3).
158+
159+
Returns
160+
-------
161+
array
162+
The XY(Z) coordinates of the center of mass.
163+
"""
164+
L = 0
165+
cx = 0
166+
cy = 0
167+
m = polyline.shape[0]
168+
ii = list(range(1, m)) + [0]
169+
for i in prange(m):
170+
p1 = polyline[i, :]
171+
p2 = polyline[ii[i], :]
172+
d = length_vector_xy_numba(subtract_vectors_xy_numba(p2, p1))
173+
cx += 0.5 * d * (p1[0] + p2[0])
174+
cy += 0.5 * d * (p1[1] + p2[1])
175+
L += d
176+
c = array([cx, cy, 0.])
177+
f = 1 / L
178+
return scale_vector_numba(c, factor=f)
179+
180+
181+
@jit(f8[:](f8[:, :], i8[:, :]), nogil=True, nopython=True, parallel=False) # Needs checking
182+
def center_of_mass_polyhedron_numba(vertices, faces):
183+
"""Compute the center of mass of the edges of a polyhedron.
184+
185+
Parameters
186+
----------
187+
vertices : array
188+
Array containing the XYZ coordinates of the polyhedron vertices (n x 3).
189+
faces : array
190+
Array contianing the indices of triangle faces of the polyhedron (m x 3).
191+
192+
Return
193+
------
194+
array
195+
The XYZ coordinates of the polyhedron edges' centre of mass.
196+
"""
197+
m = faces.shape[0]
198+
V = 0.
199+
x = 0.
200+
y = 0.
201+
z = 0.
202+
ex = array([1., 0., 0.])
203+
ey = array([0., 1., 0.])
204+
ez = array([0., 0., 1.])
205+
ii = [1, 2, 0]
206+
207+
for i in prange(m):
208+
a = vertices[faces[i, 0]]
209+
b = vertices[faces[i, 1]]
210+
c = vertices[faces[i, 2]]
211+
ab = subtract_vectors_numba(b, a)
212+
ac = subtract_vectors_numba(c, a)
213+
n = cross_vectors_numba(ab, ac)
214+
V += dot_vectors_numba(a, n)
215+
nx = dot_vectors_numba(n, ex)
216+
ny = dot_vectors_numba(n, ey)
217+
nz = dot_vectors_numba(n, ez)
218+
219+
for k in prange(3):
220+
ab = add_vectors_numba(vertices[faces[i, k]], vertices[faces[i, ii[k]]])
221+
x += nx * dot_vectors_numba(ab, ex)**2
222+
y += ny * dot_vectors_numba(ab, ey)**2
223+
z += nz * dot_vectors_numba(ab, ez)**2
224+
225+
if V < 10**(-9):
226+
V = 0.
227+
d = 1. / 48.
228+
else:
229+
V /= 6.
230+
d = 1. / 48. / V
231+
x *= d
232+
y *= d
233+
z *= d
234+
235+
return array([x, y, z])
236+
237+
238+
# ==============================================================================
239+
# Main
240+
# ==============================================================================
241+
242+
if __name__ == "__main__":
243+
244+
from time import time
245+
246+
u = array([1., 2., 3.])
247+
v = array([4., 5., 6.])
248+
c = array([[0., 0., 1.], [3., 4., 1.], [6., 0., 1.]])
249+
d = array([[0, 1, 2], [1, 2, 0]])
250+
e = array([[0., 0., 0.], [1., 0., 0.], [1., 1., 0.], [0., 1., 0.]])
251+
252+
tic = time()
253+
254+
for i in range(10**5):
255+
256+
# centroid_points_numba(c)
257+
# centroid_points_xy_numba(c)
258+
# midpoint_point_point_numba(u, v)
259+
# midpoint_point_point_xy_numba(u, v)
260+
# center_of_mass_polyline_numba(c)
261+
# center_of_mass_polyline_xy_numba(c)
262+
center_of_mass_polyhedron_numba(c, array([[0, 1, 2]]))
263+
264+
print(time() - tic)

0 commit comments

Comments
 (0)