1

I have a list (L1) of points and a rotation matrix (R1) made using numpy as shown below

L1 = [[1.1,2.3,-5.5],[3.4,2.0,3.0]]
R1 = [[ 0.99214145 -0.09280282 -0.08392241]
 [-0.09280282 -0.09592336 -0.99105315]
 [ 0.08392241  0.99105315 -0.10378191]]

I would like to rotate each point in L1 using R1, but instead of two points, I have >1000000 points in L1.

I have used the following code to do the rotations but they take in excess of 8 minutes for 30 lists like L1 and I would like to know if there is any faster way using numpy or any other module. Thank you so much.

#make new list of rotated points
rotatedpoints = []
#do the inverse rotation for each point in dome
for point in L1:
        rotatedpoint = list((np.dot(R1, point)) )
        rotatedpoints.append(rotatedpoint)

2 Answers 2

1

EDIT:

numpy operates on np arrays much faster. Consider converting your lists to numpy arrays.

In [72]: L1                                                                                     
Out[72]: [[1.1, 2.3, -5.5], [3.4, 2.0, 3.0]]

In [73]: R1                                                                                     
Out[73]: 
[[0.99214145, -0.09280282, -0.08392241],
 [-0.09280282, -0.09592336, -0.99105315],
 [0.08392241, 0.99105315, -0.10378191]]

In [75]: %timeit np.dot(L1, R1)                                                                 
7.81 µs ± 30 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [76]: L2 = np.array(L1)                                                                      

In [78]: R2 = np.array(R1)                                                                      

In [79]: %timeit np.dot(L2, R2)                                                                 
1.51 µs ± 7.72 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [80]: %timeit L2 @ R2                                                                        
3.35 µs ± 12.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

OLD ANSWER:

You may consider applying your own dot product function too.

In [8]: from operator import mul

In [11]: %timeit sum(map(mul, L1[0], R1[0])) # just to  see how long it takes                                                    
873 ns ± 1.82 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [6]: %timeit np.dot(L1[0], R1)                                                               
5.63 µs ± 29.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

I'm not into numpy much, there might be more optimal solutions though, but one thing for sure is np shines where you have huge amounts of data to operate on. If you're dealing with relatively small arrays etc, handmade solutions might be better options.

Sign up to request clarification or add additional context in comments.

Comments

1

You can perform matrix multiplication here, basically matrix multiplication is the same as vector multiplication for each row:

You can thus obtain the result for your rotatedpoints as in your sample program with:

rotatedpoints = L1 @ np.transpose(R1)

Your rotatedpoints had as result:

>>> rotatedpoints
[[1.3394823640000002, 5.1280854950000005, 2.942537401], [2.93590806, -3.4805357580000003, 1.956096764]]

The matrix multiplication has as result:

>>> L1 @ np.transpose(R1)
array([[ 1.33948236,  5.1280855 ,  2.9425374 ],
       [ 2.93590806, -3.48053576,  1.95609676]])

With L1 a list of lists of floats with shape 1'000'000×3, and for 10 runs, we get as benchmarks:

>>> timeit(f, number=10)
5.256122357001004

We thus can rotate 1'000'000 points on average in 525 milliseconds (this includes converting L1 and R1 to numpy arrays), or approximately 0.5μs per vector.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.