Module: Gsplat::Math::Mat
- Extended by:
- SmallMatrixPrimitives
- Defined in:
- lib/gsplat/math/mat.rb
Overview
Closed-form batched operations for small matrices.
Class Method Summary collapse
-
.det2x2(matrices, dtype: nil) ⇒ Numo::NArray
Determinant of batched 2x2 matrices.
-
.det3x3(matrices, dtype: nil) ⇒ Numo::NArray
Determinant of batched 3x3 matrices.
-
.eigvals2x2(matrices, dtype: nil) ⇒ Numo::NArray
Ordered real eigenvalues of batched 2x2 matrices.
-
.inv2x2(matrices, dtype: nil, epsilon: nil) ⇒ Numo::NArray
Inverse of batched 2x2 matrices.
-
.inv3x3(matrices, dtype: nil, epsilon: nil) ⇒ Numo::NArray
Inverse of batched 3x3 matrices.
-
.matmul_batch(left, right, dtype: nil) ⇒ Numo::NArray
Batched matrix multiplication for small matrices.
Class Method Details
.det2x2(matrices, dtype: nil) ⇒ Numo::NArray
Determinant of batched 2x2 matrices.
19 20 21 22 23 |
# File 'lib/gsplat/math/mat.rb', line 19 def det2x2(matrices, dtype: nil) _, leading_shape, flat = prepare_matrix(matrices, 2, dtype) determinant = (flat[true, 0, 0] * flat[true, 1, 1]) - (flat[true, 0, 1] * flat[true, 1, 0]) reshape_vector(determinant, leading_shape) end |
.det3x3(matrices, dtype: nil) ⇒ Numo::NArray
Determinant of batched 3x3 matrices.
66 67 68 69 70 |
# File 'lib/gsplat/math/mat.rb', line 66 def det3x3(matrices, dtype: nil) _, leading_shape, flat = prepare_matrix(matrices, 3, dtype) determinant = determinant3(flat) reshape_vector(determinant, leading_shape) end |
.eigvals2x2(matrices, dtype: nil) ⇒ Numo::NArray
Ordered real eigenvalues of batched 2x2 matrices.
48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/gsplat/math/mat.rb', line 48 def eigvals2x2(matrices, dtype: nil) typed, leading_shape, flat = prepare_matrix(matrices, 2, dtype) half_trace = (flat[true, 0, 0] + flat[true, 1, 1]) * 0.5 half_difference = (flat[true, 0, 0] - flat[true, 1, 1]) * 0.5 discriminant = (half_difference**2) + (flat[true, 0, 1] * flat[true, 1, 0]) discriminant[discriminant.lt(0)] = 0 root = discriminant**0.5 output = typed.class.zeros(flat.shape[0], 2) output[true, 0] = half_trace - root output[true, 1] = half_trace + root reshape_matrix(output, leading_shape, 2) end |
.inv2x2(matrices, dtype: nil, epsilon: nil) ⇒ Numo::NArray
Inverse of batched 2x2 matrices.
31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/gsplat/math/mat.rb', line 31 def inv2x2(matrices, dtype: nil, epsilon: nil) typed, leading_shape, flat = prepare_matrix(matrices, 2, dtype) determinant = (flat[true, 0, 0] * flat[true, 1, 1]) - (flat[true, 0, 1] * flat[true, 1, 0]) ensure_invertible!(determinant, epsilon || default_epsilon(typed.class)) output = typed.class.zeros(flat.shape[0], 2, 2) output[true, 0, 0] = flat[true, 1, 1] / determinant output[true, 0, 1] = -flat[true, 0, 1] / determinant output[true, 1, 0] = -flat[true, 1, 0] / determinant output[true, 1, 1] = flat[true, 0, 0] / determinant reshape_matrix(output, leading_shape, 2, 2) end |
.inv3x3(matrices, dtype: nil, epsilon: nil) ⇒ Numo::NArray
Inverse of batched 3x3 matrices.
78 79 80 81 82 83 84 85 |
# File 'lib/gsplat/math/mat.rb', line 78 def inv3x3(matrices, dtype: nil, epsilon: nil) typed, leading_shape, flat = prepare_matrix(matrices, 3, dtype) determinant = determinant3(flat) ensure_invertible!(determinant, epsilon || default_epsilon(typed.class)) output = typed.class.zeros(flat.shape[0], 3, 3) fill_inverse3!(output, flat, determinant) reshape_matrix(output, leading_shape, 3, 3) end |
.matmul_batch(left, right, dtype: nil) ⇒ Numo::NArray
Batched matrix multiplication for small matrices.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/gsplat/math/mat.rb', line 93 def matmul_batch(left, right, dtype: nil) left = cast_float(left, dtype) right = cast_float(right, left.class) validate_rank!(left, 2) validate_rank!(right, 2) leading_shape = left.shape[0...-2] unless right.shape[0...-2] == leading_shape && left.shape[-1] == right.shape[-2] raise ShapeError, "matmul shape mismatch: left #{left.shape.inspect}, right #{right.shape.inspect}" end rows = left.shape[-2] shared = left.shape[-1] columns = right.shape[-1] batch_size = leading_shape.empty? ? 1 : leading_shape.inject(:*) left_flat = left.reshape(batch_size, rows, shared) right_flat = right.reshape(batch_size, shared, columns) output = multiply_flat(left_flat, right_flat, rows, shared, columns) reshape_matrix(output, leading_shape, rows, columns) end |