Repository: bitshifter/glam-rs
Pull request #543 (2024-08-02 11:38:00)

Add Mat2::from_mat3_minor and Mat3::from_mat4_minor methods


Patch:
diff --git a/codegen/templates/macros.rs.tera b/codegen/templates/macros.rs.tera
index a6de047..475ec78 100644
--- a/codegen/templates/macros.rs.tera
+++ b/codegen/templates/macros.rs.tera
@@ -5,3 +5,69 @@
         {%- endfor -%}
     )
 {% endmacro make_tuple_t %}
+
+{% macro impl_mat3_minor(mat3_t, align="") %}
+    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 2.
+    #[inline]
+    #[must_use]
+    pub fn from_mat3{{ align }}_minor(m: {{ mat3_t }}, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
+            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
+            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
+            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
+            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
+            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
+            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
+            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
+            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
+            _ => panic!("index out of bounds"),
+        }
+    }
+{% endmacro impl_mat3_minor %}
+
+{% macro impl_mat4_minor(mat4_t, vec3_t) %}
+    {% if vec3_t == "Vec3A" %}
+        {% set w = "w" %}
+        {% set b = "Vec3A::from_vec4(" %}
+        {% set e = ")" %}
+    {% else %}
+        {% set w = "" %}
+        {% set b = "" %}
+        {% set e = "" %}
+    {% endif %}
+    /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 3.
+    #[inline]
+    #[must_use]
+    pub fn from_mat4_minor(m: {{ mat4_t }}, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols({{ b }}m.y_axis.yzw{{ w }}(){{ e }}, {{ b }}m.z_axis.yzw{{ w }}(){{ e }}, {{ b }}m.w_axis.yzw{{ w }}(){{ e }}),
+            (0, 1) => Self::from_cols({{ b }}m.y_axis.xzw{{ w }}(){{ e }}, {{ b }}m.z_axis.xzw{{ w }}(){{ e }}, {{ b }}m.w_axis.xzw{{ w }}(){{ e }}),
+            (0, 2) => Self::from_cols({{ b }}m.y_axis.xyw{{ w }}(){{ e }}, {{ b }}m.z_axis.xyw{{ w }}(){{ e }}, {{ b }}m.w_axis.xyw{{ w }}(){{ e }}),
+            (0, 3) => Self::from_cols({{ b }}m.y_axis.xyz{{ w }}(){{ e }}, {{ b }}m.z_axis.xyz{{ w }}(){{ e }}, {{ b }}m.w_axis.xyz{{ w }}(){{ e }}),
+            (1, 0) => Self::from_cols({{ b }}m.x_axis.yzw{{ w }}(){{ e }}, {{ b }}m.z_axis.yzw{{ w }}(){{ e }}, {{ b }}m.w_axis.yzw{{ w }}(){{ e }}),
+            (1, 1) => Self::from_cols({{ b }}m.x_axis.xzw{{ w }}(){{ e }}, {{ b }}m.z_axis.xzw{{ w }}(){{ e }}, {{ b }}m.w_axis.xzw{{ w }}(){{ e }}),
+            (1, 2) => Self::from_cols({{ b }}m.x_axis.xyw{{ w }}(){{ e }}, {{ b }}m.z_axis.xyw{{ w }}(){{ e }}, {{ b }}m.w_axis.xyw{{ w }}(){{ e }}),
+            (1, 3) => Self::from_cols({{ b }}m.x_axis.xyz{{ w }}(){{ e }}, {{ b }}m.z_axis.xyz{{ w }}(){{ e }}, {{ b }}m.w_axis.xyz{{ w }}(){{ e }}),
+            (2, 0) => Self::from_cols({{ b }}m.x_axis.yzw{{ w }}(){{ e }}, {{ b }}m.y_axis.yzw{{ w }}(){{ e }}, {{ b }}m.w_axis.yzw{{ w }}(){{ e }}),
+            (2, 1) => Self::from_cols({{ b }}m.x_axis.xzw{{ w }}(){{ e }}, {{ b }}m.y_axis.xzw{{ w }}(){{ e }}, {{ b }}m.w_axis.xzw{{ w }}(){{ e }}),
+            (2, 2) => Self::from_cols({{ b }}m.x_axis.xyw{{ w }}(){{ e }}, {{ b }}m.y_axis.xyw{{ w }}(){{ e }}, {{ b }}m.w_axis.xyw{{ w }}(){{ e }}),
+            (2, 3) => Self::from_cols({{ b }}m.x_axis.xyz{{ w }}(){{ e }}, {{ b }}m.y_axis.xyz{{ w }}(){{ e }}, {{ b }}m.w_axis.xyz{{ w }}(){{ e }}),
+            (3, 0) => Self::from_cols({{ b }}m.x_axis.yzw{{ w }}(){{ e }}, {{ b }}m.y_axis.yzw{{ w }}(){{ e }}, {{ b }}m.z_axis.yzw{{ w }}(){{ e }}),
+            (3, 1) => Self::from_cols({{ b }}m.x_axis.xzw{{ w }}(){{ e }}, {{ b }}m.y_axis.xzw{{ w }}(){{ e }}, {{ b }}m.z_axis.xzw{{ w }}(){{ e }}),
+            (3, 2) => Self::from_cols({{ b }}m.x_axis.xyw{{ w }}(){{ e }}, {{ b }}m.y_axis.xyw{{ w }}(){{ e }}, {{ b }}m.z_axis.xyw{{ w }}(){{ e }}),
+            (3, 3) => Self::from_cols({{ b }}m.x_axis.xyz{{ w }}(){{ e }}, {{ b }}m.y_axis.xyz{{ w }}(){{ e }}, {{ b }}m.z_axis.xyz{{ w }}(){{ e }}),
+            _ => panic!("index out of bounds"),
+        }
+    }
+{% endmacro impl_mat4_minor %}
diff --git a/codegen/templates/mat.rs.tera b/codegen/templates/mat.rs.tera
index 67b0700..fdb0f6e 100644
--- a/codegen/templates/mat.rs.tera
+++ b/codegen/templates/mat.rs.tera
@@ -1,3 +1,4 @@
+{% import "macros.rs.tera" as macros %}
 {% import "coresimd.rs.tera" as coresimd %}
 {% import "neon.rs.tera" as neon %}
 {% import "sse2.rs.tera" as sse2 %}
@@ -437,6 +438,8 @@ impl {{ self_t }} {
         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
     }
 
+    {{ macros::impl_mat3_minor(mat3_t=mat3_t) }}
+
 {% if scalar_t == "f32" %}
     /// Creates a {{ nxn }} matrix from a 3x3 matrix, discarding the 2nd row and column.
     #[inline]
@@ -445,6 +448,8 @@ impl {{ self_t }} {
         {# TODO: SIMD optimise #}
         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
     }
+
+    {{ macros::impl_mat3_minor(mat3_t="Mat3A", align="a") }}
 {% endif %}
 
 {% elif dim == 3 %}
@@ -459,6 +464,8 @@ impl {{ self_t }} {
         )
     }
 
+    {{ macros::impl_mat4_minor(mat4_t=mat4_t, vec3_t=col_t) }}
+
     /// Creates a 3D rotation matrix from the given quaternion.
     ///
     /// # Panics
diff --git a/codegen/templates/swizzle_impl.rs.tera b/codegen/templates/swizzle_impl.rs.tera
index c982a38..2da0c10 100644
--- a/codegen/templates/swizzle_impl.rs.tera
+++ b/codegen/templates/swizzle_impl.rs.tera
@@ -53,7 +53,7 @@ impl Vec{{ dim }}Swizzles for {{ self_t }} {
         {% for j0 in indices | slice(end=dim) %}
             {% for j1 in indices | slice(end=dim) %}
                 {% if i == 2 %}
-                    {% set skip = dim == 2 and j0 == "x" and j1 == "y" %}
+                    {% set skip = dim == 2 and j0 == 0 and j1 == 1 %}
                     {% if not skip %}
     #[inline]
     #[must_use]
@@ -64,7 +64,7 @@ impl Vec{{ dim }}Swizzles for {{ self_t }} {
                 {% else %}
                     {% for j2 in indices | slice(end=dim) %}
                         {% if i == 3 %}
-                            {% set skip = dim == 3 and j0 == "x" and j1 == "y" and j2 == "z" %}
+                            {% set skip = dim == 3 and j0 == 0 and j1 == 1 and j2 == 2 %}
                             {% if not skip %}
     #[inline]
     #[must_use]
@@ -82,7 +82,7 @@ impl Vec{{ dim }}Swizzles for {{ self_t }} {
                             {% endif %}
                         {% else %}
                             {% for j3 in indices | slice(end=dim) %}
-                                {% set skip = dim == 4 and j0 == "x" and j1 == "y" and j2 == "z" and j3 == "w" %}
+                                {% set skip = dim == 4 and j0 == 0 and j1 == 1 and j2 == 2 and j3 == 3 %}
                                 {% if not skip %}
     #[inline]
     #[must_use]
diff --git a/src/f32/coresimd/mat2.rs b/src/f32/coresimd/mat2.rs
index ce2ccd2..ffcb3ea 100644
--- a/src/f32/coresimd/mat2.rs
+++ b/src/f32/coresimd/mat2.rs
@@ -114,6 +114,29 @@ impl Mat2 {
         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
     }
 
+    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 2.
+    #[inline]
+    #[must_use]
+    pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
+            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
+            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
+            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
+            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
+            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
+            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
+            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
+            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
     #[inline]
     #[must_use]
@@ -121,6 +144,29 @@ impl Mat2 {
         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
     }
 
+    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 2.
+    #[inline]
+    #[must_use]
+    pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
+            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
+            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
+            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
+            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
+            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
+            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
+            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
+            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 2x2 matrix from the first 4 values in `slice`.
     ///
     /// # Panics
diff --git a/src/f32/coresimd/mat3a.rs b/src/f32/coresimd/mat3a.rs
index 841b35e..6e6b29e 100644
--- a/src/f32/coresimd/mat3a.rs
+++ b/src/f32/coresimd/mat3a.rs
@@ -164,6 +164,100 @@ impl Mat3A {
         )
     }
 
+    /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 3.
+    #[inline]
+    #[must_use]
+    pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (0, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (0, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (0, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (1, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (1, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (1, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (1, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (2, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (2, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (2, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (2, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (3, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+            ),
+            (3, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+            ),
+            (3, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+            ),
+            (3, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+            ),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 3D rotation matrix from the given quaternion.
     ///
     /// # Panics
diff --git a/src/f32/mat3.rs b/src/f32/mat3.rs
index 3205d02..ba22c32 100644
--- a/src/f32/mat3.rs
+++ b/src/f32/mat3.rs
@@ -165,6 +165,36 @@ impl Mat3 {
         )
     }
 
+    /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 3.
+    #[inline]
+    #[must_use]
+    pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(m.y_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
+            (0, 1) => Self::from_cols(m.y_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
+            (0, 2) => Self::from_cols(m.y_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
+            (0, 3) => Self::from_cols(m.y_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
+            (1, 0) => Self::from_cols(m.x_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
+            (1, 1) => Self::from_cols(m.x_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
+            (1, 2) => Self::from_cols(m.x_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
+            (1, 3) => Self::from_cols(m.x_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
+            (2, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.w_axis.yzw()),
+            (2, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.w_axis.xzw()),
+            (2, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.w_axis.xyw()),
+            (2, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.w_axis.xyz()),
+            (3, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.z_axis.yzw()),
+            (3, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.z_axis.xzw()),
+            (3, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.z_axis.xyw()),
+            (3, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.z_axis.xyz()),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 3D rotation matrix from the given quaternion.
     ///
     /// # Panics
diff --git a/src/f32/neon/mat2.rs b/src/f32/neon/mat2.rs
index f0b27cb..e1b0d80 100644
--- a/src/f32/neon/mat2.rs
+++ b/src/f32/neon/mat2.rs
@@ -130,6 +130,29 @@ impl Mat2 {
         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
     }
 
+    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 2.
+    #[inline]
+    #[must_use]
+    pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
+            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
+            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
+            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
+            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
+            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
+            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
+            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
+            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
     #[inline]
     #[must_use]
@@ -137,6 +160,29 @@ impl Mat2 {
         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
     }
 
+    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 2.
+    #[inline]
+    #[must_use]
+    pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
+            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
+            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
+            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
+            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
+            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
+            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
+            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
+            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 2x2 matrix from the first 4 values in `slice`.
     ///
     /// # Panics
diff --git a/src/f32/neon/mat3a.rs b/src/f32/neon/mat3a.rs
index 9423ffb..3e2448d 100644
--- a/src/f32/neon/mat3a.rs
+++ b/src/f32/neon/mat3a.rs
@@ -164,6 +164,100 @@ impl Mat3A {
         )
     }
 
+    /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 3.
+    #[inline]
+    #[must_use]
+    pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (0, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (0, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (0, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (1, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (1, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (1, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (1, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (2, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (2, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (2, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (2, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (3, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+            ),
+            (3, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+            ),
+            (3, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+            ),
+            (3, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+            ),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 3D rotation matrix from the given quaternion.
     ///
     /// # Panics
diff --git a/src/f32/scalar/mat2.rs b/src/f32/scalar/mat2.rs
index 262c13d..3f6dfdc 100644
--- a/src/f32/scalar/mat2.rs
+++ b/src/f32/scalar/mat2.rs
@@ -119,6 +119,29 @@ impl Mat2 {
         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
     }
 
+    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 2.
+    #[inline]
+    #[must_use]
+    pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
+            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
+            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
+            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
+            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
+            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
+            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
+            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
+            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
     #[inline]
     #[must_use]
@@ -126,6 +149,29 @@ impl Mat2 {
         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
     }
 
+    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 2.
+    #[inline]
+    #[must_use]
+    pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
+            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
+            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
+            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
+            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
+            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
+            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
+            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
+            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 2x2 matrix from the first 4 values in `slice`.
     ///
     /// # Panics
diff --git a/src/f32/scalar/mat3a.rs b/src/f32/scalar/mat3a.rs
index 0a1e255..7bcb767 100644
--- a/src/f32/scalar/mat3a.rs
+++ b/src/f32/scalar/mat3a.rs
@@ -165,6 +165,100 @@ impl Mat3A {
         )
     }
 
+    /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 3.
+    #[inline]
+    #[must_use]
+    pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (0, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (0, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (0, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (1, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (1, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (1, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (1, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (2, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (2, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (2, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (2, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (3, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+            ),
+            (3, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+            ),
+            (3, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+            ),
+            (3, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+            ),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 3D rotation matrix from the given quaternion.
     ///
     /// # Panics
diff --git a/src/f32/sse2/mat2.rs b/src/f32/sse2/mat2.rs
index dda2157..8821006 100644
--- a/src/f32/sse2/mat2.rs
+++ b/src/f32/sse2/mat2.rs
@@ -133,6 +133,29 @@ impl Mat2 {
         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
     }
 
+    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 2.
+    #[inline]
+    #[must_use]
+    pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
+            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
+            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
+            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
+            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
+            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
+            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
+            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
+            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
     #[inline]
     #[must_use]
@@ -140,6 +163,29 @@ impl Mat2 {
         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
     }
 
+    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 2.
+    #[inline]
+    #[must_use]
+    pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
+            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
+            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
+            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
+            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
+            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
+            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
+            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
+            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 2x2 matrix from the first 4 values in `slice`.
     ///
     /// # Panics
diff --git a/src/f32/sse2/mat3a.rs b/src/f32/sse2/mat3a.rs
index 8d235c5..c6e6ad2 100644
--- a/src/f32/sse2/mat3a.rs
+++ b/src/f32/sse2/mat3a.rs
@@ -167,6 +167,100 @@ impl Mat3A {
         )
     }
 
+    /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 3.
+    #[inline]
+    #[must_use]
+    pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (0, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (0, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (0, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (1, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (1, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (1, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (1, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (2, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (2, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (2, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (2, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (3, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+            ),
+            (3, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+            ),
+            (3, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+            ),
+            (3, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+            ),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 3D rotation matrix from the given quaternion.
     ///
     /// # Panics
diff --git a/src/f32/wasm32/mat2.rs b/src/f32/wasm32/mat2.rs
index fc2d0a6..59bd5e7 100644
--- a/src/f32/wasm32/mat2.rs
+++ b/src/f32/wasm32/mat2.rs
@@ -114,6 +114,29 @@ impl Mat2 {
         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
     }
 
+    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 2.
+    #[inline]
+    #[must_use]
+    pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
+            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
+            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
+            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
+            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
+            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
+            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
+            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
+            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
     #[inline]
     #[must_use]
@@ -121,6 +144,29 @@ impl Mat2 {
         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
     }
 
+    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 2.
+    #[inline]
+    #[must_use]
+    pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
+            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
+            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
+            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
+            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
+            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
+            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
+            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
+            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 2x2 matrix from the first 4 values in `slice`.
     ///
     /// # Panics
diff --git a/src/f32/wasm32/mat3a.rs b/src/f32/wasm32/mat3a.rs
index 4e35b9b..bbaffd6 100644
--- a/src/f32/wasm32/mat3a.rs
+++ b/src/f32/wasm32/mat3a.rs
@@ -164,6 +164,100 @@ impl Mat3A {
         )
     }
 
+    /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 3.
+    #[inline]
+    #[must_use]
+    pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (0, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (0, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (0, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (1, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (1, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (1, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (1, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (2, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.w_axis.yzww()),
+            ),
+            (2, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.w_axis.xzww()),
+            ),
+            (2, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.w_axis.xyww()),
+            ),
+            (2, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.w_axis.xyzw()),
+            ),
+            (3, 0) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.yzww()),
+                Vec3A::from_vec4(m.y_axis.yzww()),
+                Vec3A::from_vec4(m.z_axis.yzww()),
+            ),
+            (3, 1) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xzww()),
+                Vec3A::from_vec4(m.y_axis.xzww()),
+                Vec3A::from_vec4(m.z_axis.xzww()),
+            ),
+            (3, 2) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyww()),
+                Vec3A::from_vec4(m.y_axis.xyww()),
+                Vec3A::from_vec4(m.z_axis.xyww()),
+            ),
+            (3, 3) => Self::from_cols(
+                Vec3A::from_vec4(m.x_axis.xyzw()),
+                Vec3A::from_vec4(m.y_axis.xyzw()),
+                Vec3A::from_vec4(m.z_axis.xyzw()),
+            ),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 3D rotation matrix from the given quaternion.
     ///
     /// # Panics
diff --git a/src/f64/dmat2.rs b/src/f64/dmat2.rs
index b1e975d..5798c51 100644
--- a/src/f64/dmat2.rs
+++ b/src/f64/dmat2.rs
@@ -115,6 +115,29 @@ impl DMat2 {
         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
     }
 
+    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 2.
+    #[inline]
+    #[must_use]
+    pub fn from_mat3_minor(m: DMat3, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
+            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
+            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
+            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
+            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
+            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
+            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
+            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
+            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 2x2 matrix from the first 4 values in `slice`.
     ///
     /// # Panics
diff --git a/src/f64/dmat3.rs b/src/f64/dmat3.rs
index 687d176..4f84b1a 100644
--- a/src/f64/dmat3.rs
+++ b/src/f64/dmat3.rs
@@ -165,6 +165,36 @@ impl DMat3 {
         )
     }
 
+    /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column
+    /// and `j`th row.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` or `j` is greater than 3.
+    #[inline]
+    #[must_use]
+    pub fn from_mat4_minor(m: DMat4, i: usize, j: usize) -> Self {
+        match (i, j) {
+            (0, 0) => Self::from_cols(m.y_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
+            (0, 1) => Self::from_cols(m.y_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
+            (0, 2) => Self::from_cols(m.y_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
+            (0, 3) => Self::from_cols(m.y_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
+            (1, 0) => Self::from_cols(m.x_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
+            (1, 1) => Self::from_cols(m.x_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
+            (1, 2) => Self::from_cols(m.x_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
+            (1, 3) => Self::from_cols(m.x_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
+            (2, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.w_axis.yzw()),
+            (2, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.w_axis.xzw()),
+            (2, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.w_axis.xyw()),
+            (2, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.w_axis.xyz()),
+            (3, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.z_axis.yzw()),
+            (3, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.z_axis.xzw()),
+            (3, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.z_axis.xyw()),
+            (3, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.z_axis.xyz()),
+            _ => panic!("index out of bounds"),
+        }
+    }
+
     /// Creates a 3D rotation matrix from the given quaternion.
     ///
     /// # Panics
diff --git a/src/swizzles/coresimd/vec3a_impl.rs b/src/swizzles/coresimd/vec3a_impl.rs
index 36cb9ae..c9cc420 100644
--- a/src/swizzles/coresimd/vec3a_impl.rs
+++ b/src/swizzles/coresimd/vec3a_impl.rs
@@ -122,12 +122,6 @@ impl Vec3Swizzles for Vec3A {
         Vec3A(simd_swizzle!(self.0, [0, 1, 1, 0]).into())
     }
 
-    #[inline]
-    #[must_use]
-    fn xyz(self) -> Vec3A {
-        Vec3A(simd_swizzle!(self.0, [0, 1, 2, 0]).into())
-    }
-
     #[inline]
     #[must_use]
     fn xzx(self) -> Vec3A {
diff --git a/src/swizzles/coresimd/vec4_impl.rs b/src/swizzles/coresimd/vec4_impl.rs
index a546c89..57cd39c 100644
--- a/src/swizzles/coresimd/vec4_impl.rs
+++ b/src/swizzles/coresimd/vec4_impl.rs
@@ -701,12 +701,6 @@ impl Vec4Swizzles for Vec4 {
         Vec4(simd_swizzle!(self.0, [0, 1, 2, 2]))
     }
 
-    #[inline]
-    #[must_use]
-    fn xyzw(self) -> Vec4 {
-        Vec4(simd_swizzle!(self.0, [0, 1, 2, 3]))
-    }
-
     #[inline]
     #[must_use]
     fn xywx(self) -> Vec4 {
diff --git a/src/swizzles/dvec2_impl.rs b/src/swizzles/dvec2_impl.rs
index 9cd33e2..14bbc4a 100644
--- a/src/swizzles/dvec2_impl.rs
+++ b/src/swizzles/dvec2_impl.rs
@@ -16,15 +16,6 @@ impl Vec2Swizzles for DVec2 {
         }
     }
 
-    #[inline]
-    #[must_use]
-    fn xy(self) -> DVec2 {
-        DVec2 {
-            x: self.x,
-            y: self.y,
-        }
-    }
-
     #[inline]
     #[must_use]
     fn yx(self) -> DVec2 {
diff --git a/src/swizzles/dvec3_impl.rs b/src/swizzles/dvec3_impl.rs
index c8a1d81..97751a8 100644
--- a/src/swizzles/dvec3_impl.rs
+++ b/src/swizzles/dvec3_impl.rs
@@ -118,12 +118,6 @@ impl Vec3Swizzles for DVec3 {
         DVec3::new(self.x, self.y, self.y)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyz(self) -> DVec3 {
-        DVec3::new(self.x, self.y, self.z)
-    }
-
     #[inline]
     #[must_use]
     fn xzx(self) -> DVec3 {
diff --git a/src/swizzles/dvec4_impl.rs b/src/swizzles/dvec4_impl.rs
index b5d9561..95406f0 100644
--- a/src/swizzles/dvec4_impl.rs
+++ b/src/swizzles/dvec4_impl.rs
@@ -697,12 +697,6 @@ impl Vec4Swizzles for DVec4 {
         DVec4::new(self.x, self.y, self.z, self.z)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyzw(self) -> DVec4 {
-        DVec4::new(self.x, self.y, self.z, self.w)
-    }
-
     #[inline]
     #[must_use]
     fn xywx(self) -> DVec4 {
diff --git a/src/swizzles/i16vec2_impl.rs b/src/swizzles/i16vec2_impl.rs
index 0bb0157..ac1b7ce 100644
--- a/src/swizzles/i16vec2_impl.rs
+++ b/src/swizzles/i16vec2_impl.rs
@@ -16,15 +16,6 @@ impl Vec2Swizzles for I16Vec2 {
         }
     }
 
-    #[inline]
-    #[must_use]
-    fn xy(self) -> I16Vec2 {
-        I16Vec2 {
-            x: self.x,
-            y: self.y,
-        }
-    }
-
     #[inline]
     #[must_use]
     fn yx(self) -> I16Vec2 {
diff --git a/src/swizzles/i16vec3_impl.rs b/src/swizzles/i16vec3_impl.rs
index cf5752a..8435637 100644
--- a/src/swizzles/i16vec3_impl.rs
+++ b/src/swizzles/i16vec3_impl.rs
@@ -118,12 +118,6 @@ impl Vec3Swizzles for I16Vec3 {
         I16Vec3::new(self.x, self.y, self.y)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyz(self) -> I16Vec3 {
-        I16Vec3::new(self.x, self.y, self.z)
-    }
-
     #[inline]
     #[must_use]
     fn xzx(self) -> I16Vec3 {
diff --git a/src/swizzles/i16vec4_impl.rs b/src/swizzles/i16vec4_impl.rs
index 22b744c..8687c94 100644
--- a/src/swizzles/i16vec4_impl.rs
+++ b/src/swizzles/i16vec4_impl.rs
@@ -697,12 +697,6 @@ impl Vec4Swizzles for I16Vec4 {
         I16Vec4::new(self.x, self.y, self.z, self.z)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyzw(self) -> I16Vec4 {
-        I16Vec4::new(self.x, self.y, self.z, self.w)
-    }
-
     #[inline]
     #[must_use]
     fn xywx(self) -> I16Vec4 {
diff --git a/src/swizzles/i64vec2_impl.rs b/src/swizzles/i64vec2_impl.rs
index 42cd9fc..12f3822 100644
--- a/src/swizzles/i64vec2_impl.rs
+++ b/src/swizzles/i64vec2_impl.rs
@@ -16,15 +16,6 @@ impl Vec2Swizzles for I64Vec2 {
         }
     }
 
-    #[inline]
-    #[must_use]
-    fn xy(self) -> I64Vec2 {
-        I64Vec2 {
-            x: self.x,
-            y: self.y,
-        }
-    }
-
     #[inline]
     #[must_use]
     fn yx(self) -> I64Vec2 {
diff --git a/src/swizzles/i64vec3_impl.rs b/src/swizzles/i64vec3_impl.rs
index ebed87c..c4cbc3b 100644
--- a/src/swizzles/i64vec3_impl.rs
+++ b/src/swizzles/i64vec3_impl.rs
@@ -118,12 +118,6 @@ impl Vec3Swizzles for I64Vec3 {
         I64Vec3::new(self.x, self.y, self.y)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyz(self) -> I64Vec3 {
-        I64Vec3::new(self.x, self.y, self.z)
-    }
-
     #[inline]
     #[must_use]
     fn xzx(self) -> I64Vec3 {
diff --git a/src/swizzles/i64vec4_impl.rs b/src/swizzles/i64vec4_impl.rs
index b936afa..a2f6141 100644
--- a/src/swizzles/i64vec4_impl.rs
+++ b/src/swizzles/i64vec4_impl.rs
@@ -697,12 +697,6 @@ impl Vec4Swizzles for I64Vec4 {
         I64Vec4::new(self.x, self.y, self.z, self.z)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyzw(self) -> I64Vec4 {
-        I64Vec4::new(self.x, self.y, self.z, self.w)
-    }
-
     #[inline]
     #[must_use]
     fn xywx(self) -> I64Vec4 {
diff --git a/src/swizzles/ivec2_impl.rs b/src/swizzles/ivec2_impl.rs
index 849c61c..1764564 100644
--- a/src/swizzles/ivec2_impl.rs
+++ b/src/swizzles/ivec2_impl.rs
@@ -16,15 +16,6 @@ impl Vec2Swizzles for IVec2 {
         }
     }
 
-    #[inline]
-    #[must_use]
-    fn xy(self) -> IVec2 {
-        IVec2 {
-            x: self.x,
-            y: self.y,
-        }
-    }
-
     #[inline]
     #[must_use]
     fn yx(self) -> IVec2 {
diff --git a/src/swizzles/ivec3_impl.rs b/src/swizzles/ivec3_impl.rs
index 47cf490..707a44e 100644
--- a/src/swizzles/ivec3_impl.rs
+++ b/src/swizzles/ivec3_impl.rs
@@ -118,12 +118,6 @@ impl Vec3Swizzles for IVec3 {
         IVec3::new(self.x, self.y, self.y)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyz(self) -> IVec3 {
-        IVec3::new(self.x, self.y, self.z)
-    }
-
     #[inline]
     #[must_use]
     fn xzx(self) -> IVec3 {
diff --git a/src/swizzles/ivec4_impl.rs b/src/swizzles/ivec4_impl.rs
index 34635a5..523a302 100644
--- a/src/swizzles/ivec4_impl.rs
+++ b/src/swizzles/ivec4_impl.rs
@@ -697,12 +697,6 @@ impl Vec4Swizzles for IVec4 {
         IVec4::new(self.x, self.y, self.z, self.z)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyzw(self) -> IVec4 {
-        IVec4::new(self.x, self.y, self.z, self.w)
-    }
-
     #[inline]
     #[must_use]
     fn xywx(self) -> IVec4 {
diff --git a/src/swizzles/neon/vec3a_impl.rs b/src/swizzles/neon/vec3a_impl.rs
index 99963c5..b5c87fc 100644
--- a/src/swizzles/neon/vec3a_impl.rs
+++ b/src/swizzles/neon/vec3a_impl.rs
@@ -118,12 +118,6 @@ impl Vec3Swizzles for Vec3A {
         Vec3A::new(self.x, self.y, self.y)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyz(self) -> Vec3A {
-        Vec3A::new(self.x, self.y, self.z)
-    }
-
     #[inline]
     #[must_use]
     fn xzx(self) -> Vec3A {
diff --git a/src/swizzles/neon/vec4_impl.rs b/src/swizzles/neon/vec4_impl.rs
index 00ad1ce..1186e27 100644
--- a/src/swizzles/neon/vec4_impl.rs
+++ b/src/swizzles/neon/vec4_impl.rs
@@ -697,12 +697,6 @@ impl Vec4Swizzles for Vec4 {
         Vec4::new(self.x, self.y, self.z, self.z)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyzw(self) -> Vec4 {
-        Vec4::new(self.x, self.y, self.z, self.w)
-    }
-
     #[inline]
     #[must_use]
     fn xywx(self) -> Vec4 {
diff --git a/src/swizzles/scalar/vec3a_impl.rs b/src/swizzles/scalar/vec3a_impl.rs
index 99963c5..b5c87fc 100644
--- a/src/swizzles/scalar/vec3a_impl.rs
+++ b/src/swizzles/scalar/vec3a_impl.rs
@@ -118,12 +118,6 @@ impl Vec3Swizzles for Vec3A {
         Vec3A::new(self.x, self.y, self.y)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyz(self) -> Vec3A {
-        Vec3A::new(self.x, self.y, self.z)
-    }
-
     #[inline]
     #[must_use]
     fn xzx(self) -> Vec3A {
diff --git a/src/swizzles/scalar/vec4_impl.rs b/src/swizzles/scalar/vec4_impl.rs
index 00ad1ce..1186e27 100644
--- a/src/swizzles/scalar/vec4_impl.rs
+++ b/src/swizzles/scalar/vec4_impl.rs
@@ -697,12 +697,6 @@ impl Vec4Swizzles for Vec4 {
         Vec4::new(self.x, self.y, self.z, self.z)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyzw(self) -> Vec4 {
-        Vec4::new(self.x, self.y, self.z, self.w)
-    }
-
     #[inline]
     #[must_use]
     fn xywx(self) -> Vec4 {
diff --git a/src/swizzles/sse2/vec3a_impl.rs b/src/swizzles/sse2/vec3a_impl.rs
index 7ae6379..eb56569 100644
--- a/src/swizzles/sse2/vec3a_impl.rs
+++ b/src/swizzles/sse2/vec3a_impl.rs
@@ -125,12 +125,6 @@ impl Vec3Swizzles for Vec3A {
         Vec3A((unsafe { _mm_shuffle_ps(self.0, self.0, 0b00_01_01_00) }).into())
     }
 
-    #[inline]
-    #[must_use]
-    fn xyz(self) -> Vec3A {
-        Vec3A((unsafe { _mm_shuffle_ps(self.0, self.0, 0b00_10_01_00) }).into())
-    }
-
     #[inline]
     #[must_use]
     fn xzx(self) -> Vec3A {
diff --git a/src/swizzles/sse2/vec4_impl.rs b/src/swizzles/sse2/vec4_impl.rs
index e9a3f39..c00586b 100644
--- a/src/swizzles/sse2/vec4_impl.rs
+++ b/src/swizzles/sse2/vec4_impl.rs
@@ -704,12 +704,6 @@ impl Vec4Swizzles for Vec4 {
         Vec4(unsafe { _mm_shuffle_ps(self.0, self.0, 0b10_10_01_00) })
     }
 
-    #[inline]
-    #[must_use]
-    fn xyzw(self) -> Vec4 {
-        Vec4(unsafe { _mm_shuffle_ps(self.0, self.0, 0b11_10_01_00) })
-    }
-
     #[inline]
     #[must_use]
     fn xywx(self) -> Vec4 {
diff --git a/src/swizzles/u16vec2_impl.rs b/src/swizzles/u16vec2_impl.rs
index 086140b..13180d1 100644
--- a/src/swizzles/u16vec2_impl.rs
+++ b/src/swizzles/u16vec2_impl.rs
@@ -16,15 +16,6 @@ impl Vec2Swizzles for U16Vec2 {
         }
     }
 
-    #[inline]
-    #[must_use]
-    fn xy(self) -> U16Vec2 {
-        U16Vec2 {
-            x: self.x,
-            y: self.y,
-        }
-    }
-
     #[inline]
     #[must_use]
     fn yx(self) -> U16Vec2 {
diff --git a/src/swizzles/u16vec3_impl.rs b/src/swizzles/u16vec3_impl.rs
index bce679f..aa76b5f 100644
--- a/src/swizzles/u16vec3_impl.rs
+++ b/src/swizzles/u16vec3_impl.rs
@@ -118,12 +118,6 @@ impl Vec3Swizzles for U16Vec3 {
         U16Vec3::new(self.x, self.y, self.y)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyz(self) -> U16Vec3 {
-        U16Vec3::new(self.x, self.y, self.z)
-    }
-
     #[inline]
     #[must_use]
     fn xzx(self) -> U16Vec3 {
diff --git a/src/swizzles/u16vec4_impl.rs b/src/swizzles/u16vec4_impl.rs
index 738dc7b..a3904dc 100644
--- a/src/swizzles/u16vec4_impl.rs
+++ b/src/swizzles/u16vec4_impl.rs
@@ -697,12 +697,6 @@ impl Vec4Swizzles for U16Vec4 {
         U16Vec4::new(self.x, self.y, self.z, self.z)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyzw(self) -> U16Vec4 {
-        U16Vec4::new(self.x, self.y, self.z, self.w)
-    }
-
     #[inline]
     #[must_use]
     fn xywx(self) -> U16Vec4 {
diff --git a/src/swizzles/u64vec2_impl.rs b/src/swizzles/u64vec2_impl.rs
index 18375bf..0acef19 100644
--- a/src/swizzles/u64vec2_impl.rs
+++ b/src/swizzles/u64vec2_impl.rs
@@ -16,15 +16,6 @@ impl Vec2Swizzles for U64Vec2 {
         }
     }
 
-    #[inline]
-    #[must_use]
-    fn xy(self) -> U64Vec2 {
-        U64Vec2 {
-            x: self.x,
-            y: self.y,
-        }
-    }
-
     #[inline]
     #[must_use]
     fn yx(self) -> U64Vec2 {
diff --git a/src/swizzles/u64vec3_impl.rs b/src/swizzles/u64vec3_impl.rs
index 95c3ad9..ae62b10 100644
--- a/src/swizzles/u64vec3_impl.rs
+++ b/src/swizzles/u64vec3_impl.rs
@@ -118,12 +118,6 @@ impl Vec3Swizzles for U64Vec3 {
         U64Vec3::new(self.x, self.y, self.y)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyz(self) -> U64Vec3 {
-        U64Vec3::new(self.x, self.y, self.z)
-    }
-
     #[inline]
     #[must_use]
     fn xzx(self) -> U64Vec3 {
diff --git a/src/swizzles/u64vec4_impl.rs b/src/swizzles/u64vec4_impl.rs
index 5ac02d2..c6ddd2b 100644
--- a/src/swizzles/u64vec4_impl.rs
+++ b/src/swizzles/u64vec4_impl.rs
@@ -697,12 +697,6 @@ impl Vec4Swizzles for U64Vec4 {
         U64Vec4::new(self.x, self.y, self.z, self.z)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyzw(self) -> U64Vec4 {
-        U64Vec4::new(self.x, self.y, self.z, self.w)
-    }
-
     #[inline]
     #[must_use]
     fn xywx(self) -> U64Vec4 {
diff --git a/src/swizzles/uvec2_impl.rs b/src/swizzles/uvec2_impl.rs
index 6e50c3e..b9b51d9 100644
--- a/src/swizzles/uvec2_impl.rs
+++ b/src/swizzles/uvec2_impl.rs
@@ -16,15 +16,6 @@ impl Vec2Swizzles for UVec2 {
         }
     }
 
-    #[inline]
-    #[must_use]
-    fn xy(self) -> UVec2 {
-        UVec2 {
-            x: self.x,
-            y: self.y,
-        }
-    }
-
     #[inline]
     #[must_use]
     fn yx(self) -> UVec2 {
diff --git a/src/swizzles/uvec3_impl.rs b/src/swizzles/uvec3_impl.rs
index 8f82b43..885a109 100644
--- a/src/swizzles/uvec3_impl.rs
+++ b/src/swizzles/uvec3_impl.rs
@@ -118,12 +118,6 @@ impl Vec3Swizzles for UVec3 {
         UVec3::new(self.x, self.y, self.y)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyz(self) -> UVec3 {
-        UVec3::new(self.x, self.y, self.z)
-    }
-
     #[inline]
     #[must_use]
     fn xzx(self) -> UVec3 {
diff --git a/src/swizzles/uvec4_impl.rs b/src/swizzles/uvec4_impl.rs
index 832d223..5f4c27e 100644
--- a/src/swizzles/uvec4_impl.rs
+++ b/src/swizzles/uvec4_impl.rs
@@ -697,12 +697,6 @@ impl Vec4Swizzles for UVec4 {
         UVec4::new(self.x, self.y, self.z, self.z)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyzw(self) -> UVec4 {
-        UVec4::new(self.x, self.y, self.z, self.w)
-    }
-
     #[inline]
     #[must_use]
     fn xywx(self) -> UVec4 {
diff --git a/src/swizzles/vec2_impl.rs b/src/swizzles/vec2_impl.rs
index d60f692..d7899d2 100644
--- a/src/swizzles/vec2_impl.rs
+++ b/src/swizzles/vec2_impl.rs
@@ -16,15 +16,6 @@ impl Vec2Swizzles for Vec2 {
         }
     }
 
-    #[inline]
-    #[must_use]
-    fn xy(self) -> Vec2 {
-        Vec2 {
-            x: self.x,
-            y: self.y,
-        }
-    }
-
     #[inline]
     #[must_use]
     fn yx(self) -> Vec2 {
diff --git a/src/swizzles/vec3_impl.rs b/src/swizzles/vec3_impl.rs
index 9fcf880..9a07e4a 100644
--- a/src/swizzles/vec3_impl.rs
+++ b/src/swizzles/vec3_impl.rs
@@ -118,12 +118,6 @@ impl Vec3Swizzles for Vec3 {
         Vec3::new(self.x, self.y, self.y)
     }
 
-    #[inline]
-    #[must_use]
-    fn xyz(self) -> Vec3 {
-        Vec3::new(self.x, self.y, self.z)
-    }
-
     #[inline]
     #[must_use]
     fn xzx(self) -> Vec3 {
diff --git a/src/swizzles/wasm32/vec3a_impl.rs b/src/swizzles/wasm32/vec3a_impl.rs
index 7bfe7cc..85a57e8 100644
--- a/src/swizzles/wasm32/vec3a_impl.rs
+++ b/src/swizzles/wasm32/vec3a_impl.rs
@@ -122,12 +122,6 @@ impl Vec3Swizzles for Vec3A {
         Vec3A(i32x4_shuffle::<0, 1, 5, 4>(self.0, self.0).into())
     }
 
-    #[inline]
-    #[must_use]
-    fn xyz(self) -> Vec3A {
-        Vec3A(i32x4_shuffle::<0, 1, 6, 4>(self.0, self.0).into())
-    }
-
     #[inline]
     #[must_use]
     fn xzx(self) -> Vec3A {
diff --git a/src/swizzles/wasm32/vec4_impl.rs b/src/swizzles/wasm32/vec4_impl.rs
index 6d42d1b..8fd5b2e 100644
--- a/src/swizzles/wasm32/vec4_impl.rs
+++ b/src/swizzles/wasm32/vec4_impl.rs
@@ -701,12 +701,6 @@ impl Vec4Swizzles for Vec4 {
         Vec4(i32x4_shuffle::<0, 1, 6, 6>(self.0, self.0))
     }
 
-    #[inline]
-    #[must_use]
-    fn xyzw(self) -> Vec4 {
-        Vec4(i32x4_shuffle::<0, 1, 6, 7>(self.0, self.0))
-    }
-
     #[inline]
     #[must_use]
     fn xywx(self) -> Vec4 {


Test patch:
diff --git a/tests/mat2.rs b/tests/mat2.rs
index 0b3d199..2746e56 100644
--- a/tests/mat2.rs
+++ b/tests/mat2.rs
@@ -4,19 +4,18 @@ mod support;
 macro_rules! impl_mat2_tests {
     ($t:ident, $newmat2:ident, $mat2:ident, $mat3:ident, $newvec2:ident, $vec2:ident) => {
         const IDENTITY: [[$t; 2]; 2] = [[1.0, 0.0], [0.0, 1.0]];
-
-        const MATRIX: [[$t; 2]; 2] = [[1.0, 2.0], [3.0, 4.0]];
-
-        const MATRIX1D: [$t; 4] = [1.0, 2.0, 3.0, 4.0];
+        const ARRAY2X2: [[$t; 2]; 2] = [[1.0, 2.0], [3.0, 4.0]];
+        const ARRAY1X4: [$t; 4] = [1.0, 2.0, 3.0, 4.0];
+        const ARRAY3X3: [[$t; 3]; 3] = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]];
 
         glam_test!(test_const, {
             const M0: $mat2 = $mat2::from_cols($newvec2(1.0, 2.0), $newvec2(3.0, 4.0));
-            const M1: $mat2 = $mat2::from_cols_array(&MATRIX1D);
-            const M2: $mat2 = $mat2::from_cols_array_2d(&MATRIX);
+            const M1: $mat2 = $mat2::from_cols_array(&ARRAY1X4);
+            const M2: $mat2 = $mat2::from_cols_array_2d(&ARRAY2X2);
 
-            assert_eq!(MATRIX1D, M0.to_cols_array());
-            assert_eq!(MATRIX1D, M1.to_cols_array());
-            assert_eq!(MATRIX1D, M2.to_cols_array());
+            assert_eq!(ARRAY1X4, M0.to_cols_array());
+            assert_eq!(ARRAY1X4, M1.to_cols_array());
+            assert_eq!(ARRAY1X4, M2.to_cols_array());
         });
 
         glam_test!(test_mat2_identity, {
@@ -42,7 +41,7 @@ macro_rules! impl_mat2_tests {
             let mut m = $mat2::ZERO;
             m.x_axis = $vec2::new(1.0, 2.0);
             m.y_axis = $vec2::new(3.0, 4.0);
-            assert_eq!($mat2::from_cols_array_2d(&MATRIX), m);
+            assert_eq!($mat2::from_cols_array_2d(&ARRAY2X2), m);
             assert_eq!($vec2::new(1.0, 2.0), m.x_axis);
             assert_eq!($vec2::new(3.0, 4.0), m.y_axis);
 
@@ -66,8 +65,8 @@ macro_rules! impl_mat2_tests {
         });
 
         glam_test!(test_mat2_from_axes, {
-            let a = $mat2::from_cols_array_2d(&[[1.0, 2.0], [3.0, 4.0]]);
-            assert_eq!(MATRIX, a.to_cols_array_2d());
+            let a = $mat2::from_cols_array_2d(&ARRAY2X2);
+            assert_eq!(ARRAY2X2, a.to_cols_array_2d());
             let b = $mat2::from_cols($newvec2(1.0, 2.0), $newvec2(3.0, 4.0));
             assert_eq!(a, b);
             let c = $newmat2($newvec2(1.0, 2.0), $newvec2(3.0, 4.0));
@@ -103,12 +102,23 @@ macro_rules! impl_mat2_tests {
         });
 
         glam_test!(test_from_mat3, {
-            let m3 =
-                $mat3::from_cols_array_2d(&[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]);
+            let m3 = $mat3::from_cols_array_2d(&ARRAY3X3);
             let m2 = $mat2::from_mat3(m3);
             assert_eq!($mat2::from_cols_array_2d(&[[1.0, 2.0], [4.0, 5.0]]), m2);
         });
 
+        glam_test!(test_from_mat3_minor, {
+            let m3 = $mat3::from_cols_array_2d(&ARRAY3X3);
+            for i in 0..3 {
+                for j in 0..3 {
+                    let m2 = $mat2::from_mat3_minor(m3, i, j);
+                    test_matrix_minor!(3, m2, m3, i, j);
+                }
+            }
+            should_panic!({ $mat2::from_mat3_minor(m3, 3, 0) });
+            should_panic!({ $mat2::from_mat3_minor(m3, 0, 3) });
+        });
+
         glam_test!(test_mat2_transpose, {
             let m = $newmat2($newvec2(1.0, 2.0), $newvec2(3.0, 4.0));
             let mt = m.transpose();
@@ -128,7 +138,7 @@ macro_rules! impl_mat2_tests {
             );
             assert_eq!(
                 1.0 * 4.0 - 2.0 * 3.0,
-                $mat2::from_cols_array(&[1.0, 2.0, 3.0, 4.0]).determinant()
+                $mat2::from_cols_array(&ARRAY1X4).determinant()
             );
         });
 
@@ -156,7 +166,7 @@ macro_rules! impl_mat2_tests {
         });
 
         glam_test!(test_mat2_ops, {
-            let m0 = $mat2::from_cols_array_2d(&MATRIX);
+            let m0 = $mat2::from_cols_array_2d(&ARRAY2X2);
             let m0x2 = $mat2::from_cols_array_2d(&[[2.0, 4.0], [6.0, 8.0]]);
             let m0_neg = $mat2::from_cols_array_2d(&[[-1.0, -2.0], [-3.0, -4.0]]);
             assert_eq!(m0x2, m0 * 2.0);
@@ -191,17 +201,17 @@ macro_rules! impl_mat2_tests {
         });
 
         glam_test!(test_mat2_fmt, {
-            let a = $mat2::from_cols_array_2d(&MATRIX);
+            let a = $mat2::from_cols_array_2d(&ARRAY2X2);
             assert_eq!(format!("{}", a), "[[1, 2], [3, 4]]");
             assert_eq!(format!("{:.2}", a), "[[1.00, 2.00], [3.00, 4.00]]");
         });
 
         glam_test!(test_mat2_to_from_slice, {
-            let m = $mat2::from_cols_slice(&MATRIX1D);
-            assert_eq!($mat2::from_cols_array(&MATRIX1D), m);
+            let m = $mat2::from_cols_slice(&ARRAY1X4);
+            assert_eq!($mat2::from_cols_array(&ARRAY1X4), m);
             let mut out: [$t; 4] = Default::default();
             m.write_cols_to_slice(&mut out);
-            assert_eq!(MATRIX1D, out);
+            assert_eq!(ARRAY1X4, out);
 
             should_panic!({ $mat2::from_cols_slice(&[0.0; 3]) });
             should_panic!({ $mat2::IDENTITY.write_cols_to_slice(&mut [0.0; 3]) });
@@ -231,20 +241,20 @@ macro_rules! impl_mat2_tests {
 macro_rules! impl_as_ref_tests {
     ($mat:ident) => {
         glam_test!(test_as_ref, {
-            let m = $mat::from_cols_array_2d(&MATRIX);
-            assert_eq!(MATRIX1D, *m.as_ref());
+            let m = $mat::from_cols_array_2d(&ARRAY2X2);
+            assert_eq!(ARRAY1X4, *m.as_ref());
         });
         glam_test!(test_as_mut, {
             let mut m = $mat::ZERO;
-            *m.as_mut() = MATRIX1D;
-            assert_eq!($mat::from_cols_array_2d(&MATRIX), m);
+            *m.as_mut() = ARRAY1X4;
+            assert_eq!($mat::from_cols_array_2d(&ARRAY2X2), m);
         });
     };
 }
 
 mod mat2 {
     use super::support::deg;
-    use glam::{mat2, swizzles::*, vec2, Mat2, Mat3, Vec2};
+    use glam::{mat2, swizzles::*, vec2, Mat2, Mat3, Mat3A, Vec2};
 
     glam_test!(test_align, {
         use std::mem;
@@ -257,12 +267,23 @@ mod mat2 {
     });
 
     glam_test!(test_from_mat3a, {
-        use glam::Mat3A;
-        let m3 = Mat3A::from_cols_array_2d(&[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]);
+        let m3 = Mat3A::from_cols_array_2d(&ARRAY3X3);
         let m2 = Mat2::from_mat3a(m3);
         assert_eq!(Mat2::from_cols_array_2d(&[[1.0, 2.0], [4.0, 5.0]]), m2);
     });
 
+    glam_test!(test_from_mat3a_minor, {
+        let m3 = Mat3A::from_cols_array_2d(&ARRAY3X3);
+        for i in 0..3 {
+            for j in 0..3 {
+                let m2 = Mat2::from_mat3a_minor(m3, i, j);
+                test_matrix_minor!(3, m2, m3, i, j);
+            }
+        }
+        should_panic!({ Mat2::from_mat3a_minor(m3, 3, 0) });
+        should_panic!({ Mat2::from_mat3a_minor(m3, 0, 3) });
+    });
+
     glam_test!(test_as, {
         use glam::DMat2;
         assert_eq!(
diff --git a/tests/mat3.rs b/tests/mat3.rs
index a881d6c..ef36606 100644
--- a/tests/mat3.rs
+++ b/tests/mat3.rs
@@ -4,10 +4,14 @@ mod support;
 macro_rules! impl_mat3_tests {
     ($t:ident, $newmat3:ident, $mat3:ident, $mat2:ident, $mat4:ident, $quat:ident, $newvec3:ident, $vec3:ident, $vec2:ident) => {
         const IDENTITY: [[$t; 3]; 3] = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]];
-
-        const MATRIX: [[$t; 3]; 3] = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]];
-
-        const MATRIX1D: [$t; 9] = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
+        const ARRAY3X3: [[$t; 3]; 3] = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]];
+        const ARRAY1X9: [$t; 9] = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
+        const ARRAY4X4: [[$t; 4]; 4] = [
+            [1.0, 2.0, 3.0, 4.0],
+            [5.0, 6.0, 7.0, 8.0],
+            [9.0, 10.0, 11.0, 12.0],
+            [13.0, 14.0, 15.0, 16.0],
+        ];
 
         glam_test!(test_const, {
             const M0: $mat3 = $mat3::from_cols(
@@ -15,12 +19,12 @@ macro_rules! impl_mat3_tests {
                 $newvec3(4.0, 5.0, 6.0),
                 $newvec3(7.0, 8.0, 9.0),
             );
-            const M1: $mat3 = $mat3::from_cols_array(&MATRIX1D);
-            const M2: $mat3 = $mat3::from_cols_array_2d(&MATRIX);
+            const M1: $mat3 = $mat3::from_cols_array(&ARRAY1X9);
+            const M2: $mat3 = $mat3::from_cols_array_2d(&ARRAY3X3);
 
-            assert_eq!(MATRIX1D, M0.to_cols_array());
-            assert_eq!(MATRIX1D, M1.to_cols_array());
-            assert_eq!(MATRIX1D, M2.to_cols_array());
+            assert_eq!(ARRAY1X9, M0.to_cols_array());
+            assert_eq!(ARRAY1X9, M1.to_cols_array());
+            assert_eq!(ARRAY1X9, M2.to_cols_array());
         });
 
         glam_test!(test_mat3_identity, {
@@ -57,7 +61,7 @@ macro_rules! impl_mat3_tests {
             m.x_axis = $newvec3(1.0, 2.0, 3.0);
             m.y_axis = $newvec3(4.0, 5.0, 6.0);
             m.z_axis = $newvec3(7.0, 8.0, 9.0);
-            assert_eq!($mat3::from_cols_array_2d(&MATRIX), m);
+            assert_eq!($mat3::from_cols_array_2d(&ARRAY3X3), m);
             assert_eq!($newvec3(1.0, 2.0, 3.0), m.x_axis);
             assert_eq!($newvec3(4.0, 5.0, 6.0), m.y_axis);
             assert_eq!($newvec3(7.0, 8.0, 9.0), m.z_axis);
@@ -87,7 +91,7 @@ macro_rules! impl_mat3_tests {
 
         glam_test!(test_mat3_from_axes, {
             let a = $mat3::from_cols_array_2d(&[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]);
-            assert_eq!(MATRIX, a.to_cols_array_2d());
+            assert_eq!(ARRAY3X3, a.to_cols_array_2d());
             let b = $mat3::from_cols(
                 $newvec3(1.0, 2.0, 3.0),
                 $newvec3(4.0, 5.0, 6.0),
@@ -214,12 +218,7 @@ macro_rules! impl_mat3_tests {
         });
 
         glam_test!(test_from_mat4, {
-            let m4 = $mat4::from_cols_array_2d(&[
-                [1.0, 2.0, 3.0, 4.0],
-                [5.0, 6.0, 7.0, 8.0],
-                [9.0, 10.0, 11.0, 12.0],
-                [13.0, 14.0, 15.0, 16.0],
-            ]);
+            let m4 = $mat4::from_cols_array_2d(&ARRAY4X4);
             let m3 = $mat3::from_mat4(m4);
             assert_eq!(
                 $mat3::from_cols_array_2d(&[[1.0, 2.0, 3.0], [5.0, 6.0, 7.0], [9.0, 10.0, 11.0]]),
@@ -227,6 +226,18 @@ macro_rules! impl_mat3_tests {
             );
         });
 
+        glam_test!(test_from_mat4_minor, {
+            let m4 = $mat4::from_cols_array_2d(&ARRAY4X4);
+            for i in 0..4 {
+                for j in 0..4 {
+                    let m3 = $mat3::from_mat4_minor(m4, i, j);
+                    test_matrix_minor!(4, m3, m4, i, j);
+                }
+            }
+            should_panic!({ $mat3::from_mat4_minor(m4, 4, 0) });
+            should_panic!({ $mat3::from_mat4_minor(m4, 0, 4) });
+        });
+
         glam_test!(test_mat3_transpose, {
             let m = $newmat3(
                 $newvec3(1.0, 2.0, 3.0),
@@ -283,7 +294,7 @@ macro_rules! impl_mat3_tests {
         });
 
         glam_test!(test_mat3_ops, {
-            let m0 = $mat3::from_cols_array_2d(&MATRIX);
+            let m0 = $mat3::from_cols_array_2d(&ARRAY3X3);
             let m0x2 = $mat3::from_cols_array_2d(&[
                 [2.0, 4.0, 6.0],
                 [8.0, 10.0, 12.0],
@@ -326,7 +337,7 @@ macro_rules! impl_mat3_tests {
         });
 
         glam_test!(test_mat3_fmt, {
-            let a = $mat3::from_cols_array_2d(&MATRIX);
+            let a = $mat3::from_cols_array_2d(&ARRAY3X3);
             assert_eq!(format!("{}", a), "[[1, 2, 3], [4, 5, 6], [7, 8, 9]]");
             assert_eq!(
                 format!("{:.1}", a),
@@ -335,11 +346,11 @@ macro_rules! impl_mat3_tests {
         });
 
         glam_test!(test_mat3_to_from_slice, {
-            let m = $mat3::from_cols_slice(&MATRIX1D);
-            assert_eq!($mat3::from_cols_array(&MATRIX1D), m);
+            let m = $mat3::from_cols_slice(&ARRAY1X9);
+            assert_eq!($mat3::from_cols_array(&ARRAY1X9), m);
             let mut out: [$t; 9] = Default::default();
             m.write_cols_to_slice(&mut out);
-            assert_eq!(MATRIX1D, out);
+            assert_eq!(ARRAY1X9, out);
 
             should_panic!({ $mat3::from_cols_slice(&[0.0; 8]) });
             should_panic!({ $mat3::IDENTITY.write_cols_to_slice(&mut [0.0; 8]) });
@@ -369,13 +380,13 @@ macro_rules! impl_mat3_tests {
 macro_rules! impl_as_ref_tests {
     ($mat:ident) => {
         glam_test!(test_as_ref, {
-            let m = $mat::from_cols_array_2d(&MATRIX);
-            assert_eq!(MATRIX1D, *m.as_ref());
+            let m = $mat::from_cols_array_2d(&ARRAY3X3);
+            assert_eq!(ARRAY1X9, *m.as_ref());
         });
         glam_test!(test_as_mut, {
             let mut m = $mat::ZERO;
-            *m.as_mut() = MATRIX1D;
-            assert_eq!($mat::from_cols_array_2d(&MATRIX), m);
+            *m.as_mut() = ARRAY1X9;
+            assert_eq!($mat::from_cols_array_2d(&ARRAY3X3), m);
         });
     };
 }
diff --git a/tests/mat4.rs b/tests/mat4.rs
index 06c202e..d903633 100644
--- a/tests/mat4.rs
+++ b/tests/mat4.rs
@@ -9,16 +9,16 @@ macro_rules! impl_mat4_tests {
             [0.0, 0.0, 1.0, 0.0],
             [0.0, 0.0, 0.0, 1.0],
         ];
-        const MATRIX: [[$t; 4]; 4] = [
+        const ARRAY4X4: [[$t; 4]; 4] = [
             [1.0, 2.0, 3.0, 4.0],
             [5.0, 6.0, 7.0, 8.0],
             [9.0, 10.0, 11.0, 12.0],
             [13.0, 14.0, 15.0, 16.0],
         ];
-
-        const MATRIX1D: [$t; 16] = [
+        const ARRAY1X16: [$t; 16] = [
             1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
         ];
+        const ARRAY3X3: [[$t; 3]; 3] = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]];
 
         glam_test!(test_const, {
             const M0: $mat4 = $mat4::from_cols(
@@ -27,12 +27,12 @@ macro_rules! impl_mat4_tests {
                 $newvec4(9.0, 10.0, 11.0, 12.0),
                 $newvec4(13.0, 14.0, 15.0, 16.0),
             );
-            const M1: $mat4 = $mat4::from_cols_array(&MATRIX1D);
-            const M2: $mat4 = $mat4::from_cols_array_2d(&MATRIX);
+            const M1: $mat4 = $mat4::from_cols_array(&ARRAY1X16);
+            const M2: $mat4 = $mat4::from_cols_array_2d(&ARRAY4X4);
 
-            assert_eq!(MATRIX1D, M0.to_cols_array());
-            assert_eq!(MATRIX1D, M1.to_cols_array());
-            assert_eq!(MATRIX1D, M2.to_cols_array());
+            assert_eq!(ARRAY1X16, M0.to_cols_array());
+            assert_eq!(ARRAY1X16, M1.to_cols_array());
+            assert_eq!(ARRAY1X16, M2.to_cols_array());
         });
 
         glam_test!(test_mat4_identity, {
@@ -76,7 +76,7 @@ macro_rules! impl_mat4_tests {
             m.y_axis = $vec4::new(5.0, 6.0, 7.0, 8.0);
             m.z_axis = $vec4::new(9.0, 10.0, 11.0, 12.0);
             m.w_axis = $vec4::new(13.0, 14.0, 15.0, 16.0);
-            assert_eq!($mat4::from_cols_array_2d(&MATRIX), m);
+            assert_eq!($mat4::from_cols_array_2d(&ARRAY4X4), m);
             assert_eq!($vec4::new(1.0, 2.0, 3.0, 4.0), m.x_axis);
             assert_eq!($vec4::new(5.0, 6.0, 7.0, 8.0), m.y_axis);
             assert_eq!($vec4::new(9.0, 10.0, 11.0, 12.0), m.z_axis);
@@ -116,7 +116,7 @@ macro_rules! impl_mat4_tests {
                 [9.0, 10.0, 11.0, 12.0],
                 [13.0, 14.0, 15.0, 16.0],
             ]);
-            assert_eq!(MATRIX, a.to_cols_array_2d());
+            assert_eq!(ARRAY4X4, a.to_cols_array_2d());
             let b = $mat4::from_cols(
                 $newvec4(1.0, 2.0, 3.0, 4.0),
                 $newvec4(5.0, 6.0, 7.0, 8.0),
@@ -168,7 +168,7 @@ macro_rules! impl_mat4_tests {
 
         glam_test!(test_from_mat3, {
             let m3 =
-                $mat3::from_cols_array_2d(&[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]);
+                $mat3::from_cols_array_2d(&ARRAY3X3);
             let m4 = $mat4::from_mat3(m3);
             assert_eq!(
                 $mat4::from_cols_array_2d(&[
@@ -584,7 +584,7 @@ macro_rules! impl_mat4_tests {
         });
 
         glam_test!(test_mat4_ops, {
-            let m0 = $mat4::from_cols_array_2d(&MATRIX);
+            let m0 = $mat4::from_cols_array_2d(&ARRAY4X4);
             let m0x2 = $mat4::from_cols_array_2d(&[
                 [2.0, 4.0, 6.0, 8.0],
                 [10.0, 12.0, 14.0, 16.0],
@@ -629,7 +629,7 @@ macro_rules! impl_mat4_tests {
         });
 
         glam_test!(test_mat4_fmt, {
-            let a = $mat4::from_cols_array_2d(&MATRIX);
+            let a = $mat4::from_cols_array_2d(&ARRAY4X4);
             assert_eq!(
                 format!("{}", a),
                 "[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]"
@@ -641,11 +641,11 @@ macro_rules! impl_mat4_tests {
         });
 
         glam_test!(test_mat4_to_from_slice, {
-            let m = $mat4::from_cols_slice(&MATRIX1D);
-            assert_eq!($mat4::from_cols_array(&MATRIX1D), m);
+            let m = $mat4::from_cols_slice(&ARRAY1X16);
+            assert_eq!($mat4::from_cols_array(&ARRAY1X16), m);
             let mut out: [$t; 16] = Default::default();
             m.write_cols_to_slice(&mut out);
-            assert_eq!(MATRIX1D, out);
+            assert_eq!(ARRAY1X16, out);
 
             should_panic!({ $mat4::from_cols_slice(&[0.0; 15]) });
             should_panic!({ $mat4::IDENTITY.write_cols_to_slice(&mut [0.0; 15]) });
@@ -697,13 +697,13 @@ macro_rules! impl_mat4_tests {
 macro_rules! impl_as_ref_tests {
     ($mat:ident) => {
         glam_test!(test_as_ref, {
-            let m = $mat::from_cols_array_2d(&MATRIX);
-            assert_eq!(MATRIX1D, *m.as_ref());
+            let m = $mat::from_cols_array_2d(&ARRAY4X4);
+            assert_eq!(ARRAY1X16, *m.as_ref());
         });
         glam_test!(test_as_mut, {
             let mut m = $mat::ZERO;
-            *m.as_mut() = MATRIX1D;
-            assert_eq!($mat::from_cols_array_2d(&MATRIX), m);
+            *m.as_mut() = ARRAY1X16;
+            assert_eq!($mat::from_cols_array_2d(&ARRAY4X4), m);
         });
     };
 }
@@ -720,7 +720,7 @@ mod mat4 {
 
     glam_test!(test_from_mat3a, {
         use glam::Mat3A;
-        let m3 = Mat3A::from_cols_array_2d(&[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]);
+        let m3 = Mat3A::from_cols_array_2d(&ARRAY3X3);
         let m4 = Mat4::from_mat3a(m3);
         assert_eq!(
             Mat4::from_cols_array_2d(&[
diff --git a/tests/support/macros.rs b/tests/support/macros.rs
index 12d5450..4babd87 100644
--- a/tests/support/macros.rs
+++ b/tests/support/macros.rs
@@ -247,3 +247,22 @@ macro_rules! vec2_float_test_vectors {
         ]
     };
 }
+
+#[macro_export]
+macro_rules! test_matrix_minor {
+    ($n:expr, $minor:expr, $input:expr, $i:expr, $j:expr) => {
+        let mut yy = 0;
+        for y in 0..$n {
+            if y != $j {
+                let mut xx = 0;
+                for x in 0..$n {
+                    if x != $i {
+                        assert_eq!($minor.col(xx)[yy], $input.col(x)[y]);
+                        xx += 1;
+                    }
+                }
+                yy += 1;
+            }
+        }
+    };
+}