Skip to content
Peter Corke edited this page Sep 27, 2020 · 3 revisions

Data obtained using a 3.6 GHz 10-Core Intel Core i9, Python 3.8.5 and Numpy 1.19.1.

Base package timing to create a rotation matrix, and to convert between SO(3) and SE(3) NumPy matrices

transforms.rotx:     3.6 μs
transforms.trotx:    5 μs
transforms.t2r:      0.469 μs
transforms.r2t:      0.987 μs

The spatial math class adds overhead

SE3.Rx:              10.9 μs

largely in the instance constructor process, we see that the constructor adds 5.9 μs to the cost of an SE(3) rotation matrix base.trotx. A chunk of this is attributable to the cost of calling getvector to process the possible list of values and the constructor creating time

getvector(x):        1.46 μs
SE3():               2.93 μs

The effect of value checking can be seen when creating an SE3 instance from a NumPy matrix value

SE3(T1):             36.4 μs
SE3(T1 check=False): 1.35 μs

Multiplication using the overloaded class operator vs native NumPy also shows some constructor overhead

SE3 *:               4.72 μs
4x4 @:               1.17 μs
T1 * T2 (R, t):      2.2 μs

but the NumPy @ operator if faster than coding the multiplication in terms of the R and t partitions of the SE(3) matrix.

Inverse also shows some constructor overhead

SE3.inv:             7.24 μs
base.trinv:          4.15 μs
np.linalg.inv:       4.65 μs

but it is interesting to note that exploiting the structure of the SE(3) matrix makes trinv() ~10% faster than the general matrix inverse in NumPy.

Notes

To build an SE(3) matrix it is fastest to

T = np.zeros((4,4))
T[3,3] = 1
T[:3,:3] = R
T[:3,3] = t

np.eye(4) is slower even though the bottom right element doesn't need to be explicitly set. np.pad or stack is way slower. np.empty is faster than np.zeros but we more than lose the advantage having to initialise the bottom row.

Clone this wiki locally