func (m Mat2) Inv() Mat2 {
	det := m.Det()
	if FloatEqual(det, float32(0.0)) {
		return Mat2{}
	}
	retMat := Mat2{m[3], -m[1], -m[2], m[0]}
	return retMat.Mul(1 / det)
}
Inv computes the inverse of a square matrix. An inverse is a square matrix such that when multiplied by the
original, yields the identity.

M_inv * M = M * M_inv = I

In this library, the math is precomputed, and uses no loops, though the multiplications, additions, determinant calculation, and scaling
are still done. This can still be (relatively) expensive for a 4x4.

This function checks the determinant to see if the matrix is invertible.
If the determinant is 0.0, this function returns the zero matrix. However, due to floating point errors, it is
entirely plausible to get a false positive or negative.
In the future, an alternate function may be written which takes in a pre-computed determinant.
package mgl32
import (
	"bytes"
	"fmt"
	"golang.org/x/image/math/f32"
	"text/tabwriter"
)
type Mat2 [4]float32
type Mat2x3 [6]float32
type Mat2x4 [8]float32
type Mat3x2 [6]float32
type Mat3 f32.Mat3
type Mat3x4 [12]float32
type Mat4x2 [8]float32
type Mat4x3 [12]float32
type Mat4 f32.Mat4
func (m Mat2) Mat3() Mat3 {
	col0, col1 := m.Cols()
	return Mat3FromCols(
		col0.Vec3(0),
		col1.Vec3(0),
		Vec3{0, 0, 1},
	)
}
func (m Mat2) Mat4() Mat4 {
	col0, col1 := m.Cols()
	return Mat4FromCols(
		col0.Vec4(0, 0),
		col1.Vec4(0, 0),
		Vec4{0, 0, 1, 0},
		Vec4{0, 0, 0, 1},
	)
}
func (m Mat3) Mat2() Mat2 {
	col0, col1, _ := m.Cols()
	return Mat2FromCols(
		col0.Vec2(),
		col1.Vec2(),
	)
}
func (m Mat3) Mat4() Mat4 {
	col0, col1, col2 := m.Cols()
	return Mat4FromCols(
		col0.Vec4(0),
		col1.Vec4(0),
		col2.Vec4(0),
		Vec4{0, 0, 0, 1},
	)
}
func (m Mat4) Mat2() Mat2 {
	col0, col1, _, _ := m.Cols()
	return Mat2FromCols(
		col0.Vec2(),
		col1.Vec2(),
	)
}
func (m Mat4) Mat3() Mat3 {
	col0, col1, col2, _ := m.Cols()
	return Mat3FromCols(
		col0.Vec3(),
		col1.Vec3(),
		col2.Vec3(),
	)
}
func (m *Mat2) SetCol(col int, v Vec2) {
	m[col*2+0], m[col*2+1] = v[0], v[1]
}
func (m *Mat2) SetRow(row int, v Vec2) {
	m[row+0], m[row+2] = v[0], v[1]
}
func (m Mat2) Diag() Vec2 {
	return Vec2{m[0], m[3]}
}
func Ident2() Mat2 {
	return Mat2{1, 0, 0, 1}
}
func Diag2(v Vec2) Mat2 {
	var m Mat2
	m[0], m[3] = v[0], v[1]
	return m
}
func Mat2FromRows(row0, row1 Vec2) Mat2 {
	return Mat2{row0[0], row1[0], row0[1], row1[1]}
}
func Mat2FromCols(col0, col1 Vec2) Mat2 {
	return Mat2{col0[0], col0[1], col1[0], col1[1]}
}
func (m1 Mat2) Add(m2 Mat2) Mat2 {
	return Mat2{m1[0] + m2[0], m1[1] + m2[1], m1[2] + m2[2], m1[3] + m2[3]}
}
func (m1 Mat2) Sub(m2 Mat2) Mat2 {
	return Mat2{m1[0] - m2[0], m1[1] - m2[1], m1[2] - m2[2], m1[3] - m2[3]}
}
func (m1 Mat2) Mul(c float32) Mat2 {
	return Mat2{m1[0] * c, m1[1] * c, m1[2] * c, m1[3] * c}
}
func (m1 Mat2) Mul2x1(m2 Vec2) Vec2 {
	return Vec2{
		m1[0]*m2[0] + m1[2]*m2[1],
		m1[1]*m2[0] + m1[3]*m2[1],
	}
}
func (m1 Mat2) Mul2(m2 Mat2) Mat2 {
	return Mat2{
		m1[0]*m2[0] + m1[2]*m2[1],
		m1[1]*m2[0] + m1[3]*m2[1],
		m1[0]*m2[2] + m1[2]*m2[3],
		m1[1]*m2[2] + m1[3]*m2[3],
	}
}
func (m1 Mat2) Mul2x3(m2 Mat2x3) Mat2x3 {
	return Mat2x3{
		m1[0]*m2[0] + m1[2]*m2[1],
		m1[1]*m2[0] + m1[3]*m2[1],
		m1[0]*m2[2] + m1[2]*m2[3],
		m1[1]*m2[2] + m1[3]*m2[3],
		m1[0]*m2[4] + m1[2]*m2[5],
		m1[1]*m2[4] + m1[3]*m2[5],
	}
}
func (m1 Mat2) Mul2x4(m2 Mat2x4) Mat2x4 {
	return Mat2x4{
		m1[0]*m2[0] + m1[2]*m2[1],
		m1[1]*m2[0] + m1[3]*m2[1],
		m1[0]*m2[2] + m1[2]*m2[3],
		m1[1]*m2[2] + m1[3]*m2[3],
		m1[0]*m2[4] + m1[2]*m2[5],
		m1[1]*m2[4] + m1[3]*m2[5],
		m1[0]*m2[6] + m1[2]*m2[7],
		m1[1]*m2[6] + m1[3]*m2[7],
	}
}
func (m1 Mat2) Transpose() Mat2 {
	return Mat2{m1[0], m1[2], m1[1], m1[3]}
}
func (m Mat2) Det() float32 {
	return m[0]*m[3] - m[1]*m[2]
}