@@ -105,28 +105,51 @@ def vec_transform(
105
105
transformed vectors
106
106
"""
107
107
108
- matrix = np .asarray (matrix , dtype = "f8" )
108
+ matrix = np .asarray (matrix )
109
+ vectors = np .asarray (vectors )
109
110
110
- if projection :
111
- vectors = vec_homogeneous (vectors , w = w , dtype = "f8" )
112
- if vectors .ndim == 1 :
113
- vectors = matrix @ vectors
114
- vectors [:- 1 ] /= vectors [- 1 ]
115
- vectors = vectors [:- 1 ]
116
- elif vectors .ndim == 2 :
117
- vectors = (matrix @ vectors .T ).T
118
- vectors = vectors [..., :- 1 ] / vectors [..., - 1 , None ]
119
- else :
120
- raise ValueError ("vectors must be a 1D or 2D array" )
111
+ # this code has been micro-optimized for the 1D and 2D cases
112
+ vectors_ndim = vectors .ndim
113
+ if vectors_ndim > 2 :
114
+ raise ValueError ("vectors must be a 1D or 2D array" )
115
+
116
+ # determine if we are working with a batch of vectors
117
+ batch = vectors_ndim != 1
118
+
119
+ # we don't need to work in homogeneous vector space
120
+ # if matrix is purely affine and vectors is a single vector
121
+ homogeneous = projection or batch
122
+
123
+ if homogeneous :
124
+ vectors = vec_homogeneous (vectors , w = w )
125
+ matmul_matrix = matrix
121
126
else :
122
- if vectors .ndim == 1 :
123
- vectors = matrix [:- 1 , :- 1 ] @ vectors + matrix [:- 1 , - 1 ]
124
- elif vectors .ndim == 2 :
125
- vectors = vec_homogeneous (vectors , w = w , dtype = "f8" )
126
- vectors = (matrix @ vectors .T ).T
127
- vectors = vectors [..., :- 1 ]
128
- else :
129
- raise ValueError ("vectors must be a 1D or 2D array" )
127
+ # if we are not working in homogeneous space, it's
128
+ # more efficient to matmul the 3x3 (scale + rotation)
129
+ # part of the matrix with the vectors and then add
130
+ # the translation part after
131
+ matmul_matrix = matrix [:- 1 , :- 1 ]
132
+
133
+ if batch :
134
+ # transposing the vectors array performs better
135
+ # than transposing the matrix
136
+ vectors = (matmul_matrix @ vectors .T ).T
137
+ else :
138
+ vectors = matmul_matrix @ vectors
139
+ if not homogeneous :
140
+ # as alluded to before, we add the translation
141
+ # part of the matrix after the matmul
142
+ # if we are not working in homogeneous space
143
+ vectors = vectors + matrix [:- 1 , - 1 ]
144
+
145
+ if projection :
146
+ # if we are projecting, we divide by the last
147
+ # element of the vectors array
148
+ vectors = vectors [..., :- 1 ] / vectors [..., - 1 , None ]
149
+ elif homogeneous :
150
+ # if we are NOT projecting but we are working in
151
+ # homogeneous space, just drop the last element
152
+ vectors = vectors [..., :- 1 ]
130
153
131
154
if out is None :
132
155
out = vectors
0 commit comments