-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathrotate_vector_collection.py
97 lines (79 loc) · 3.68 KB
/
rotate_vector_collection.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"""
A function to rotate collectios of n-dimensional vectors
"""
from __future__ import (division, print_function, absolute_import,
unicode_literals)
import numpy as np
from rotations.vector_utilities import (elementwise_dot, elementwise_norm,
normalized_vectors, angles_between_list_of_vectors)
__all__=['rotate_vector_collection',]
__author__ = ['Duncan Campbell', 'Andrew Hearin']
def rotate_vector_collection(rotation_matrices, vectors, optimize=False):
r"""
Given a collection of rotation matrices and a collection of n-dimensional vectors,
apply an asscoiated matrix to rotate corresponding vector(s).
Parameters
----------
rotation_matrices : ndarray
The options are:
1.) array of shape (npts, ndim, ndim) storing a collection of rotation matrices.
2.) array of shape (ndim, ndim) storing a single rotation matrix
3.) array of shape (nsets, ndim, ndim) storing a collection of rotation matrices.
vectors : ndarray
The corresponding options for above are:
1.) array of shape (npts, ndim) storing a collection of ndim-dimensional vectors
2.) array of shape (npts, ndim) storing a collection of ndim-dimensional vectors
3.) array of shape (nsets, npts, ndim) storing a collection of ndim-dimensional vectors
Returns
-------
rotated_vectors : ndarray
Numpy array of shape (npts, ndim) storing a collection of ndim-dimensional vectors
Notes
-----
This function is set up to preform either:
1. rotation operations on a single collection of vectors,
either applying a single rotation matrix to all vectors in the collection,
or applying a unique rotation matrix to each vector in the set.
2. applying a one rotation matrix to each collection of vectors.
The behavior of the function is determined by the arguments supplied by the user.
Examples
--------
In this example, we'll randomly generate two sets of unit-vectors, `v0` and `v1`.
We'll use the `rotation_matrices_from_vectors` function to generate the
rotation matrices that rotate each `v0` into the corresponding `v1`.
Then we'll use the `rotate_vector_collection` function to apply each
rotation, and verify that we recover each of the `v1`.
>>> npts, ndim = int(1e4), 3
>>> v0 = normalized_vectors(np.random.random((npts, ndim)))
>>> v1 = normalized_vectors(np.random.random((npts, ndim)))
>>> rotation_matrices = rotation_matrices_from_vectors(v0, v1)
>>> v2 = rotate_vector_collection(rotation_matrices, v0)
>>> assert np.allclose(v1, v2)
"""
ndim_rotm = np.shape(rotation_matrices)[-1]
ndim_vec = np.shape(vectors)[-1]
assert ndim_rotm==ndim_vec
if len(np.shape(vectors))==2:
ntps, ndim = np.shape(vectors)
nsets = 0
elif len(np.shape(vectors))==3:
nsets, ntps, ndim = np.shape(vectors)
# apply same rotation matrix to all vectors
if (len(np.shape(rotation_matrices)) == 2):
if nsets == 1:
vectors = vectors[0]
return np.dot(rotation_matrices, vectors.T).T
# rotate each vector by associated rotation matrix
else:
# n1 sets of n2 vectors of ndim dimension
if len(np.shape(vectors))==3:
ein_string = 'ikl,ijl->ijk'
n1, n2, ndim = np.shape(vectors)
# n1 vectors of ndim dimension
elif len(np.shape(vectors))==2:
ein_string = 'ijk,ik->ij'
n1, ndim = np.shape(vectors)
try:
return np.einsum(ein_string, rotation_matrices, vectors, optimize=optimize)
except TypeError:
return np.einsum(ein_string, rotation_matrices, vectors)