Module: Gsplat::Math::Quaternion
- Defined in:
- lib/gsplat/math/quaternion.rb
Overview
Batched wxyz quaternion normalization, rotation conversion, and VJPs.
Class Method Summary collapse
-
.normalize(quaternions, dtype: nil, epsilon: nil) ⇒ Numo::NArray
Normalizes wxyz quaternions along the last dimension.
-
.normalize_vjp(quaternions, grad_output, dtype: nil, epsilon: nil) ⇒ Numo::NArray
VJP of quaternion normalization.
-
.to_rotmat(quaternions, dtype: nil) ⇒ Numo::NArray
Converts wxyz quaternions to rotation matrices.
-
.to_rotmat_vjp(quaternions, grad_output, dtype: nil) ⇒ Numo::NArray
VJP of quaternion-to-rotation-matrix conversion.
Class Method Details
.normalize(quaternions, dtype: nil, epsilon: nil) ⇒ Numo::NArray
Normalizes wxyz quaternions along the last dimension.
15 16 17 18 19 |
# File 'lib/gsplat/math/quaternion.rb', line 15 def normalize(quaternions, dtype: nil, epsilon: nil) typed, leading_shape, flat = prepare(quaternions, 4, dtype) denominator = norm_denominator(flat, epsilon || default_epsilon(typed.class)) (flat / denominator.reshape(flat.shape[0], 1)).reshape(*(leading_shape + [4])) end |
.normalize_vjp(quaternions, grad_output, dtype: nil, epsilon: nil) ⇒ Numo::NArray
VJP of quaternion normalization.
28 29 30 31 32 33 34 35 36 |
# File 'lib/gsplat/math/quaternion.rb', line 28 def normalize_vjp(quaternions, grad_output, dtype: nil, epsilon: nil) typed, leading_shape, flat = prepare(quaternions, 4, dtype) gradient, = prepare_matching(grad_output, leading_shape, 4, typed.class) denominator = norm_denominator(flat, epsilon || default_epsilon(typed.class)) normalized = flat / denominator.reshape(flat.shape[0], 1) dot = (normalized * gradient).sum(axis: 1) result = (gradient - (normalized * dot.reshape(flat.shape[0], 1))) / denominator.reshape(flat.shape[0], 1) result.reshape(*(leading_shape + [4])) end |
.to_rotmat(quaternions, dtype: nil) ⇒ Numo::NArray
Converts wxyz quaternions to rotation matrices.
43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/gsplat/math/quaternion.rb', line 43 def to_rotmat(quaternions, dtype: nil) typed, leading_shape, = prepare(quaternions, 4, dtype) flat = normalize(typed).reshape(typed.size / 4, 4) quat_w = flat[true, 0] quat_x = flat[true, 1] quat_y = flat[true, 2] quat_z = flat[true, 3] output = typed.class.zeros(flat.shape[0], 3, 3) fill_rotation!(output, quat_w, quat_x, quat_y, quat_z) output.reshape(*(leading_shape + [3, 3])) end |
.to_rotmat_vjp(quaternions, grad_output, dtype: nil) ⇒ Numo::NArray
VJP of quaternion-to-rotation-matrix conversion.
61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/gsplat/math/quaternion.rb', line 61 def to_rotmat_vjp(quaternions, grad_output, dtype: nil) typed, leading_shape, = prepare(quaternions, 4, dtype) gradient = cast_float(grad_output, typed.class) unless gradient.shape == leading_shape + [3, 3] raise ShapeError, "expected gradient #{(leading_shape + [3, 3]).inspect}, got #{gradient.shape.inspect}" end normalized = normalize(typed).reshape(typed.size / 4, 4) grad_matrix = gradient.reshape(normalized.shape[0], 3, 3) grad_normalized = rotation_vjp(normalized, grad_matrix) normalize_vjp(typed, grad_normalized.reshape(*(leading_shape + [4]))) end |