0
# Batch Operations
1
2
Optimized vectorized operations for processing arrays of rotations and transformations. These functions provide significant performance improvements (400-1000x faster) over iterative approaches by operating on entire arrays simultaneously.
3
4
## Capabilities
5
6
### Batch Rotation Operations
7
8
Vectorized operations for processing arrays of rotations with optimized algorithms.
9
10
```python { .api }
11
def norm_vectors(V):
12
"""
13
Normalize batch of vectors to unit length.
14
15
Parameters:
16
- V: array, shape (..., 3) - Batch of vectors
17
18
Returns:
19
- V_norm: array, shape (..., 3) - Normalized vectors
20
"""
21
22
def angles_between_vectors(A, B):
23
"""Compute angles between batches of vectors."""
24
25
def cross_product_matrices(V):
26
"""Convert batch of vectors to skew-symmetric matrices."""
27
28
def norm_axis_angles(A):
29
"""Normalize batch of axis-angle representations."""
30
```
31
32
### Batch Matrix Conversions
33
34
Efficient conversions between rotation matrices and other representations.
35
36
```python { .api }
37
def matrices_from_quaternions(Q):
38
"""
39
Convert batch of quaternions to rotation matrices.
40
41
Parameters:
42
- Q: array, shape (..., 4) - Batch of quaternions
43
44
Returns:
45
- R: array, shape (..., 3, 3) - Batch of rotation matrices
46
"""
47
48
def quaternions_from_matrices(R):
49
"""Convert batch of rotation matrices to quaternions."""
50
51
def matrices_from_compact_axis_angles(A):
52
"""Convert batch of compact axis-angles to matrices."""
53
54
def axis_angles_from_matrices(R):
55
"""Convert batch of matrices to axis-angles."""
56
57
def active_matrices_from_angles(angles):
58
"""Convert batch of 2D angles to rotation matrices."""
59
60
def active_matrices_from_intrinsic_euler_angles(E, axes):
61
"""Convert batch of intrinsic Euler angles to matrices."""
62
63
def active_matrices_from_extrinsic_euler_angles(E, axes):
64
"""Convert batch of extrinsic Euler angles to matrices."""
65
```
66
67
### Batch Quaternion Operations
68
69
Optimized operations for arrays of quaternions.
70
71
```python { .api }
72
def batch_concatenate_quaternions(Q1, Q2):
73
"""
74
Compose batches of quaternions.
75
76
Parameters:
77
- Q1: array, shape (..., 4) - First batch of quaternions
78
- Q2: array, shape (..., 4) - Second batch of quaternions
79
80
Returns:
81
- Q: array, shape (..., 4) - Composed quaternions (Q2 * Q1)
82
"""
83
84
def batch_q_conj(Q):
85
"""Compute conjugates of batch of quaternions."""
86
87
def smooth_quaternion_trajectory(Q):
88
"""
89
Smooth quaternion trajectory by removing sign flips.
90
91
Parameters:
92
- Q: array, shape (n_steps, 4) - Quaternion trajectory
93
94
Returns:
95
- Q_smooth: array, shape (n_steps, 4) - Smoothed trajectory
96
"""
97
98
def quaternion_slerp_batch(start, end, t):
99
"""Batch SLERP between quaternion arrays."""
100
101
def axis_angles_from_quaternions(Q):
102
"""Convert batch of quaternions to axis-angles."""
103
104
def batch_quaternion_wxyz_from_xyzw(Q):
105
"""Convert batch from [x,y,z,w] to [w,x,y,z] format."""
106
107
def batch_quaternion_xyzw_from_wxyz(Q):
108
"""Convert batch from [w,x,y,z] to [x,y,z,w] format."""
109
```
110
111
### Batch Transformation Operations
112
113
Vectorized operations for arrays of 3D transformations.
114
115
```python { .api }
116
def invert_transforms(A2B):
117
"""
118
Invert batch of transformation matrices.
119
120
Parameters:
121
- A2B: array, shape (..., 4, 4) - Batch of transformations
122
123
Returns:
124
- B2A: array, shape (..., 4, 4) - Inverted transformations
125
"""
126
127
def concat_one_to_many(A2B, B2C):
128
"""Concatenate one transform with batch of transforms."""
129
130
def concat_many_to_one(A2B, B2C):
131
"""Concatenate batch of transforms with one transform."""
132
133
def concat_many_to_many(A2B, B2C):
134
"""Concatenate two batches of transforms element-wise."""
135
136
def concat_dynamic(*args):
137
"""Dynamically concatenate transforms based on array shapes."""
138
```
139
140
### Batch Position-Quaternion Operations
141
142
Operations for arrays of position-quaternion representations.
143
144
```python { .api }
145
def transforms_from_pqs(pqs):
146
"""
147
Convert batch of position-quaternions to transformations.
148
149
Parameters:
150
- pqs: array, shape (..., 7) - Position-quaternions [x,y,z,qw,qx,qy,qz]
151
152
Returns:
153
- A2B: array, shape (..., 4, 4) - Transformation matrices
154
"""
155
156
def pqs_from_transforms(A2B):
157
"""Extract position-quaternions from batch of transforms."""
158
```
159
160
### Batch Dual Quaternion Operations
161
162
Vectorized operations for dual quaternion arrays.
163
164
```python { .api }
165
def dual_quaternions_from_transforms(A2B):
166
"""Convert batch of transforms to dual quaternions."""
167
168
def transforms_from_dual_quaternions(dqs):
169
"""Convert batch of dual quaternions to transforms."""
170
171
def dual_quaternions_from_pqs(pqs):
172
"""Convert batch of position-quaternions to dual quaternions."""
173
174
def pqs_from_dual_quaternions(dqs):
175
"""Convert batch of dual quaternions to position-quaternions."""
176
177
def batch_concatenate_dual_quaternions(dq1, dq2):
178
"""Compose batches of dual quaternions."""
179
180
def batch_dq_conj(dqs):
181
"""Conjugate batch of dual quaternions."""
182
183
def batch_dq_q_conj(dqs):
184
"""Quaternion conjugate batch of dual quaternions."""
185
186
def batch_dq_prod_vector(dqs, V):
187
"""Transform batch of vectors using dual quaternions."""
188
189
def dual_quaternions_power(dqs, t):
190
"""Dual quaternion power for batch."""
191
192
def dual_quaternions_sclerp(start, end, t):
193
"""Batch screw LERP between dual quaternion arrays."""
194
```
195
196
### Batch Screw Operations
197
198
Operations for arrays of screw parameters and exponential coordinates.
199
200
```python { .api }
201
def transforms_from_exponential_coordinates(Stheta):
202
"""
203
Convert batch of exponential coordinates to transforms.
204
205
Parameters:
206
- Stheta: array, shape (..., 6) - Exponential coordinates
207
208
Returns:
209
- A2B: array, shape (..., 4, 4) - Transformation matrices
210
"""
211
212
def exponential_coordinates_from_transforms(A2B):
213
"""Extract exponential coordinates from batch of transforms."""
214
215
def dual_quaternions_from_screw_parameters(S):
216
"""Convert batch of screw parameters to dual quaternions."""
217
218
def screw_parameters_from_dual_quaternions(dqs):
219
"""Convert batch of dual quaternions to screw parameters."""
220
221
def mirror_screw_axis_direction(S):
222
"""Mirror direction of screw axis."""
223
```
224
225
### Random Generation
226
227
Functions for generating random batches of transformations.
228
229
```python { .api }
230
def random_trajectories(n_steps, random_state=None):
231
"""
232
Generate random transformation trajectory.
233
234
Parameters:
235
- n_steps: int - Number of trajectory steps
236
- random_state: RandomState, optional - Random number generator
237
238
Returns:
239
- trajectory: array, shape (n_steps, 4, 4) - Random trajectory
240
"""
241
```
242
243
## Usage Examples
244
245
### Batch Rotation Conversions
246
247
```python
248
import numpy as np
249
import pytransform3d.batch_rotations as pbr
250
251
# Create batch of random quaternions
252
n_rotations = 1000
253
Q = np.random.randn(n_rotations, 4)
254
Q = Q / np.linalg.norm(Q, axis=1, keepdims=True) # normalize
255
256
# Convert all quaternions to matrices at once
257
R = pbr.matrices_from_quaternions(Q)
258
print(f"Converted {n_rotations} quaternions to matrices")
259
print(f"Result shape: {R.shape}")
260
261
# Convert back to verify
262
Q_recovered = pbr.quaternions_from_matrices(R)
263
264
# Smooth trajectory by removing sign flips
265
Q_smooth = pbr.smooth_quaternion_trajectory(Q_recovered)
266
```
267
268
### Batch Transformation Operations
269
270
```python
271
import numpy as np
272
import pytransform3d.trajectories as ptr
273
274
# Create batch of transformations
275
n_transforms = 500
276
transforms = np.tile(np.eye(4), (n_transforms, 1, 1))
277
transforms[:, :3, 3] = np.random.randn(n_transforms, 3) # random translations
278
279
# Invert all transformations at once
280
transforms_inv = ptr.invert_transforms(transforms)
281
282
# Extract position-quaternions
283
pqs = ptr.pqs_from_transforms(transforms)
284
print(f"Extracted {n_transforms} position-quaternions")
285
print(f"PQ shape: {pqs.shape}")
286
287
# Convert to dual quaternions
288
dqs = ptr.dual_quaternions_from_pqs(pqs)
289
```
290
291
### Batch Composition
292
293
```python
294
import pytransform3d.trajectories as ptr
295
296
# Create two transformation sequences
297
T1 = ptr.random_trajectories(100) # 100 random transforms
298
T2 = ptr.random_trajectories(100) # 100 random transforms
299
300
# Compose all pairs element-wise
301
T_composed = ptr.concat_many_to_many(T1, T2)
302
print(f"Composed {len(T1)} transformation pairs")
303
304
# Apply one transform to many
305
single_transform = np.eye(4)
306
single_transform[:3, 3] = [1, 0, 0] # translation
307
T_offset = ptr.concat_one_to_many(single_transform, T1)
308
```
309
310
### Performance Comparison
311
312
```python
313
import time
314
import numpy as np
315
import pytransform3d.rotations as pr
316
import pytransform3d.batch_rotations as pbr
317
318
# Create test data
319
n = 10000
320
Q = np.random.randn(n, 4)
321
Q = Q / np.linalg.norm(Q, axis=1, keepdims=True)
322
323
# Batch operation
324
start = time.time()
325
R_batch = pbr.matrices_from_quaternions(Q)
326
batch_time = time.time() - start
327
328
# Iterative operation
329
start = time.time()
330
R_iter = np.array([pr.matrix_from_quaternion(q) for q in Q])
331
iter_time = time.time() - start
332
333
print(f"Batch operation: {batch_time:.4f}s")
334
print(f"Iterative operation: {iter_time:.4f}s")
335
print(f"Speedup: {iter_time/batch_time:.1f}x")
336
```
337
338
### Trajectory Smoothing
339
340
```python
341
import pytransform3d.batch_rotations as pbr
342
import pytransform3d.trajectories as ptr
343
344
# Create trajectory with potential quaternion sign flips
345
trajectory_pqs = ptr.random_trajectories(200) # 200 transformation steps
346
pqs = ptr.pqs_from_transforms(trajectory_pqs)
347
348
# Extract quaternions and smooth
349
Q = pqs[:, 3:] # quaternion part [qw, qx, qy, qz]
350
Q_smooth = pbr.smooth_quaternion_trajectory(Q)
351
352
# Reconstruct smooth trajectory
353
pqs_smooth = pqs.copy()
354
pqs_smooth[:, 3:] = Q_smooth
355
trajectory_smooth = ptr.transforms_from_pqs(pqs_smooth)
356
```