{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE RankNTypes #-}

-- | Adapted from [Linear.Matrix](https://hackage.haskell.org/package/linear-1.21.8/docs/Linear-Matrix.html)
module Nonlinear.Matrix
  ( (!*!),
    (!*),
    (*!),
    (!!*),
    (*!!),
    (!!/),
    column,
    diagonal,
    trace,
    M22,
    M23,
    M24,
    M32,
    M33,
    M34,
    M42,
    M43,
    M44,
    det22,
    det33,
    det44,
    inv22,
    inv33,
    inv44,
    identity,
    transpose,
    fromQuaternion,
    _m22,
    _m23,
    _m24,
    _m32,
    _m33,
    _m34,
    _m42,
    _m43,
    _m44,
  )
where

import Control.Applicative
import Control.Monad (join)
import Data.Foldable as Foldable
import Nonlinear.Internal (Lens', lens, set, view)
import Nonlinear.Quaternion
import Nonlinear.V2
import Nonlinear.V3
import Nonlinear.V4
import Nonlinear.Vector (Vec, scaled, (*^))

-- | This is more restrictive than linear's @LensLike (Context a b) s t a b -> Lens (f s) (f t) (f a) (f b)@, but in return we get a much simpler implementation which should suffice in 99% of cases.
column ::
  Vec v =>
  Lens' a b ->
  Lens' (v a) (v b)
column :: Lens' a b -> Lens' (v a) (v b)
column Lens' a b
l = (v a -> v b) -> (v a -> v b -> v a) -> Lens' (v a) (v b)
forall s a. (s -> a) -> (s -> a -> s) -> Lens' s a
lens ((a -> b) -> v a -> v b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> v a -> v b) -> (a -> b) -> v a -> v b
forall a b. (a -> b) -> a -> b
$ Lens' a b -> a -> b
forall s a. Lens' s a -> s -> a
view Lens' a b
l) ((a -> b -> a) -> v a -> v b -> v a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 ((b -> a -> a) -> a -> b -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((b -> a -> a) -> a -> b -> a) -> (b -> a -> a) -> a -> b -> a
forall a b. (a -> b) -> a -> b
$ ASetter' a b -> b -> a -> a
forall s a. ASetter' s a -> a -> s -> s
set ASetter' a b
Lens' a b
l))
{-# INLINE column #-}

diagonal :: Vec v => v (v a) -> v a
diagonal :: v (v a) -> v a
diagonal = v (v a) -> v a
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join

trace :: (Vec v, Num a) => v (v a) -> a
trace :: v (v a) -> a
trace = v a -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (v a -> a) -> (v (v a) -> v a) -> v (v a) -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v (v a) -> v a
forall (v :: * -> *) a. Vec v => v (v a) -> v a
diagonal

infixl 7 !*!

-- | Matrix product
--
-- >>> V2 (V3 1 2 3) (V3 4 5 6) !*! V3 (V2 1 2) (V2 3 4) (V2 4 5)
-- V2 (V2 19 25) (V2 43 58)
(!*!) :: (Vec m, Vec t, Vec n, Num a) => m (t a) -> t (n a) -> m (n a)
m (t a)
f !*! :: m (t a) -> t (n a) -> m (n a)
!*! t (n a)
g = (t a -> n a) -> m (t a) -> m (n a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\t a
f' -> (n a -> n a -> n a) -> n a -> t (n a) -> n a
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Foldable.foldl' ((a -> a -> a) -> n a -> n a -> n a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Num a => a -> a -> a
(+)) (a -> n a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
0) (t (n a) -> n a) -> t (n a) -> n a
forall a b. (a -> b) -> a -> b
$ (a -> n a -> n a) -> t a -> t (n a) -> t (n a)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> n a -> n a
forall (f :: * -> *) a. (Vec f, Num a) => a -> f a -> f a
(*^) t a
f' t (n a)
g) m (t a)
f

infixl 7 !*

-- | Matrix * column vector
--
-- >>> V2 (V3 1 2 3) (V3 4 5 6) !* V3 7 8 9
-- V2 50 122
(!*) :: (Vec m, Vec r, Num a) => m (r a) -> r a -> m a
m (r a)
m !* :: m (r a) -> r a -> m a
!* r a
v = (r a -> a) -> m (r a) -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\r a
r -> r a -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
Foldable.sum (r a -> a) -> r a -> a
forall a b. (a -> b) -> a -> b
$ (a -> a -> a) -> r a -> r a -> r a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Num a => a -> a -> a
(*) r a
r r a
v) m (r a)
m

infixl 7 *!

-- | Row vector * matrix
--
-- >>> V2 1 2 *! V2 (V3 3 4 5) (V3 6 7 8)
-- V3 15 18 21

-- (*!) :: (Metric r, Additive n, Num a) => r a -> r (n a) -> n a
-- f *! g = dot f <$> distribute g

(*!) :: (Vec f, Vec t, Num a, Num (f a)) => t a -> t (f a) -> f a
t a
f *! :: t a -> t (f a) -> f a
*! t (f a)
g = t (f a) -> f a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (t (f a) -> f a) -> t (f a) -> f a
forall a b. (a -> b) -> a -> b
$ (a -> f a -> f a) -> t a -> t (f a) -> t (f a)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> f a -> f a
forall (f :: * -> *) a. (Vec f, Num a) => a -> f a -> f a
(*^) t a
f t (f a)
g

infixl 7 *!!

-- | Scalar-matrix product
--
-- >>> 5 *!! V2 (V2 1 2) (V2 3 4)
-- V2 (V2 5 10) (V2 15 20)
(*!!) :: (Vec m, Vec r, Num a) => a -> m (r a) -> m (r a)
a
s *!! :: a -> m (r a) -> m (r a)
*!! m (r a)
m = (r a -> r a) -> m (r a) -> m (r a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a
s a -> r a -> r a
forall (f :: * -> *) a. (Vec f, Num a) => a -> f a -> f a
*^) m (r a)
m
{-# INLINE (*!!) #-}

infixl 7 !!*

-- | Matrix-scalar product
--
-- >>> V2 (V2 1 2) (V2 3 4) !!* 5
-- V2 (V2 5 10) (V2 15 20)
(!!*) :: (Vec m, Vec r, Num a) => m (r a) -> a -> m (r a)
!!* :: m (r a) -> a -> m (r a)
(!!*) = (a -> m (r a) -> m (r a)) -> m (r a) -> a -> m (r a)
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> m (r a) -> m (r a)
forall (m :: * -> *) (r :: * -> *) a.
(Vec m, Vec r, Num a) =>
a -> m (r a) -> m (r a)
(*!!)
{-# INLINE (!!*) #-}

infixl 7 !!/

-- | Matrix-scalar division
(!!/) :: (Vec r, Vec m, Fractional (r a), Fractional a) => m (r a) -> a -> m (r a)
m (r a)
m !!/ :: m (r a) -> a -> m (r a)
!!/ a
s = (r a -> r a) -> m (r a) -> m (r a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (r a -> r a -> r a
forall a. Fractional a => a -> a -> a
/ a -> r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
s) m (r a)
m
{-# INLINE (!!/) #-}

-- * Matrices

-- | A 2x2 matrix with row-major representation
type M22 a = V2 (V2 a)

-- | A 2x3 matrix with row-major representation
type M23 a = V2 (V3 a)

-- | A 2x4 matrix with row-major representation
type M24 a = V2 (V4 a)

-- | A 3x2 matrix with row-major representation
type M32 a = V3 (V2 a)

-- | A 3x3 matrix with row-major representation
type M33 a = V3 (V3 a)

-- | A 3x4 matrix with row-major representation
type M34 a = V3 (V4 a)

-- | A 4x2 matrix with row-major representation
type M42 a = V4 (V2 a)

-- | A 4x3 matrix with row-major representation
type M43 a = V4 (V3 a)

-- | A 4x4 matrix with row-major representation
type M44 a = V4 (V4 a)

-- | Build a rotation matrix from a unit 'Quaternion'.
fromQuaternion :: Num a => Quaternion a -> M33 a
fromQuaternion :: Quaternion a -> M33 a
fromQuaternion (Quaternion a
w (V3 a
x a
y a
z)) =
  V3 a -> V3 a -> V3 a -> M33 a
forall a. a -> a -> a -> V3 a
V3
    (a -> a -> a -> V3 a
forall a. a -> a -> a -> V3 a
V3 (a
1 a -> a -> a
forall a. Num a => a -> a -> a
- a
2 a -> a -> a
forall a. Num a => a -> a -> a
* (a
y2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
z2)) (a
2 a -> a -> a
forall a. Num a => a -> a -> a
* (a
xy a -> a -> a
forall a. Num a => a -> a -> a
- a
zw)) (a
2 a -> a -> a
forall a. Num a => a -> a -> a
* (a
xz a -> a -> a
forall a. Num a => a -> a -> a
+ a
yw)))
    (a -> a -> a -> V3 a
forall a. a -> a -> a -> V3 a
V3 (a
2 a -> a -> a
forall a. Num a => a -> a -> a
* (a
xy a -> a -> a
forall a. Num a => a -> a -> a
+ a
zw)) (a
1 a -> a -> a
forall a. Num a => a -> a -> a
- a
2 a -> a -> a
forall a. Num a => a -> a -> a
* (a
x2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
z2)) (a
2 a -> a -> a
forall a. Num a => a -> a -> a
* (a
yz a -> a -> a
forall a. Num a => a -> a -> a
- a
xw)))
    (a -> a -> a -> V3 a
forall a. a -> a -> a -> V3 a
V3 (a
2 a -> a -> a
forall a. Num a => a -> a -> a
* (a
xz a -> a -> a
forall a. Num a => a -> a -> a
- a
yw)) (a
2 a -> a -> a
forall a. Num a => a -> a -> a
* (a
yz a -> a -> a
forall a. Num a => a -> a -> a
+ a
xw)) (a
1 a -> a -> a
forall a. Num a => a -> a -> a
- a
2 a -> a -> a
forall a. Num a => a -> a -> a
* (a
x2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
y2)))
  where
    x2 :: a
x2 = a
x a -> a -> a
forall a. Num a => a -> a -> a
* a
x
    y2 :: a
y2 = a
y a -> a -> a
forall a. Num a => a -> a -> a
* a
y
    z2 :: a
z2 = a
z a -> a -> a
forall a. Num a => a -> a -> a
* a
z
    xy :: a
xy = a
x a -> a -> a
forall a. Num a => a -> a -> a
* a
y
    xz :: a
xz = a
x a -> a -> a
forall a. Num a => a -> a -> a
* a
z
    xw :: a
xw = a
x a -> a -> a
forall a. Num a => a -> a -> a
* a
w
    yz :: a
yz = a
y a -> a -> a
forall a. Num a => a -> a -> a
* a
z
    yw :: a
yw = a
y a -> a -> a
forall a. Num a => a -> a -> a
* a
w
    zw :: a
zw = a
z a -> a -> a
forall a. Num a => a -> a -> a
* a
w
{-# INLINE fromQuaternion #-}

-- | The identity matrix for any dimension vector.
--
--  >>> identity :: M44 Int
--  V4 (V4 1 0 0 0) (V4 0 1 0 0) (V4 0 0 1 0) (V4 0 0 0 1)
--  >>> identity :: V3 (V3 Int)
--  V3 (V3 1 0 0) (V3 0 1 0) (V3 0 0 1)
identity :: (Vec v, Num a) => v (v a)
identity :: v (v a)
identity = v a -> v (v a)
forall (t :: * -> *) a. (Vec t, Num a) => t a -> t (t a)
scaled (a -> v a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
1)
{-# INLINE identity #-}

-- | Extract a 2x2 matrix from a matrix of higher dimensions by dropping excess
--  rows and columns.
_m22 :: (Vec t, R2 t, R2 v) => Lens' (t (v a)) (M22 a)
_m22 :: Lens' (t (v a)) (M22 a)
_m22 = Lens' (v a) (V2 a) -> Lens' (t (v a)) (t (V2 a))
forall (v :: * -> *) a b. Vec v => Lens' a b -> Lens' (v a) (v b)
column Lens' (v a) (V2 a)
forall (t :: * -> *) a. R2 t => Lens' (t a) (V2 a)
_xy ((t (V2 a) -> m (t (V2 a))) -> t (v a) -> m (t (v a)))
-> ((M22 a -> m (M22 a)) -> t (V2 a) -> m (t (V2 a)))
-> (M22 a -> m (M22 a))
-> t (v a)
-> m (t (v a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (M22 a -> m (M22 a)) -> t (V2 a) -> m (t (V2 a))
forall (t :: * -> *) a. R2 t => Lens' (t a) (V2 a)
_xy

-- | Extract a 2x3 matrix from a matrix of higher dimensions by dropping excess
--  rows and columns.
_m23 :: (Vec t, R2 t, R3 v) => Lens' (t (v a)) (M23 a)
_m23 :: Lens' (t (v a)) (M23 a)
_m23 = Lens' (v a) (V3 a) -> Lens' (t (v a)) (t (V3 a))
forall (v :: * -> *) a b. Vec v => Lens' a b -> Lens' (v a) (v b)
column Lens' (v a) (V3 a)
forall (t :: * -> *) a. R3 t => Lens' (t a) (V3 a)
_xyz ((t (V3 a) -> m (t (V3 a))) -> t (v a) -> m (t (v a)))
-> ((M23 a -> m (M23 a)) -> t (V3 a) -> m (t (V3 a)))
-> (M23 a -> m (M23 a))
-> t (v a)
-> m (t (v a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (M23 a -> m (M23 a)) -> t (V3 a) -> m (t (V3 a))
forall (t :: * -> *) a. R2 t => Lens' (t a) (V2 a)
_xy

-- | Extract a 2x4 matrix from a matrix of higher dimensions by dropping excess
--  rows and columns.
_m24 :: (Vec t, R2 t, R4 v) => Lens' (t (v a)) (M24 a)
_m24 :: Lens' (t (v a)) (M24 a)
_m24 = Lens' (v a) (V4 a) -> Lens' (t (v a)) (t (V4 a))
forall (v :: * -> *) a b. Vec v => Lens' a b -> Lens' (v a) (v b)
column Lens' (v a) (V4 a)
forall (t :: * -> *) a. R4 t => Lens' (t a) (V4 a)
_xyzw ((t (V4 a) -> m (t (V4 a))) -> t (v a) -> m (t (v a)))
-> ((M24 a -> m (M24 a)) -> t (V4 a) -> m (t (V4 a)))
-> (M24 a -> m (M24 a))
-> t (v a)
-> m (t (v a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (M24 a -> m (M24 a)) -> t (V4 a) -> m (t (V4 a))
forall (t :: * -> *) a. R2 t => Lens' (t a) (V2 a)
_xy

-- | Extract a 3x2 matrix from a matrix of higher dimensions by dropping excess
--  rows and columns.
_m32 :: (Vec t, R3 t, R2 v) => Lens' (t (v a)) (M32 a)
_m32 :: Lens' (t (v a)) (M32 a)
_m32 = Lens' (v a) (V2 a) -> Lens' (t (v a)) (t (V2 a))
forall (v :: * -> *) a b. Vec v => Lens' a b -> Lens' (v a) (v b)
column Lens' (v a) (V2 a)
forall (t :: * -> *) a. R2 t => Lens' (t a) (V2 a)
_xy ((t (V2 a) -> m (t (V2 a))) -> t (v a) -> m (t (v a)))
-> ((M32 a -> m (M32 a)) -> t (V2 a) -> m (t (V2 a)))
-> (M32 a -> m (M32 a))
-> t (v a)
-> m (t (v a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (M32 a -> m (M32 a)) -> t (V2 a) -> m (t (V2 a))
forall (t :: * -> *) a. R3 t => Lens' (t a) (V3 a)
_xyz

-- | Extract a 3x3 matrix from a matrix of higher dimensions by dropping excess
--  rows and columns.
_m33 :: (Vec t, R3 t, R3 v) => Lens' (t (v a)) (M33 a)
_m33 :: Lens' (t (v a)) (M33 a)
_m33 = Lens' (v a) (V3 a) -> Lens' (t (v a)) (t (V3 a))
forall (v :: * -> *) a b. Vec v => Lens' a b -> Lens' (v a) (v b)
column Lens' (v a) (V3 a)
forall (t :: * -> *) a. R3 t => Lens' (t a) (V3 a)
_xyz ((t (V3 a) -> m (t (V3 a))) -> t (v a) -> m (t (v a)))
-> ((M33 a -> m (M33 a)) -> t (V3 a) -> m (t (V3 a)))
-> (M33 a -> m (M33 a))
-> t (v a)
-> m (t (v a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (M33 a -> m (M33 a)) -> t (V3 a) -> m (t (V3 a))
forall (t :: * -> *) a. R3 t => Lens' (t a) (V3 a)
_xyz

-- | Extract a 3x4 matrix from a matrix of higher dimensions by dropping excess
--  rows and columns.
_m34 :: (Vec t, R3 t, R4 v) => Lens' (t (v a)) (M34 a)
_m34 :: Lens' (t (v a)) (M34 a)
_m34 = Lens' (v a) (V4 a) -> Lens' (t (v a)) (t (V4 a))
forall (v :: * -> *) a b. Vec v => Lens' a b -> Lens' (v a) (v b)
column Lens' (v a) (V4 a)
forall (t :: * -> *) a. R4 t => Lens' (t a) (V4 a)
_xyzw ((t (V4 a) -> m (t (V4 a))) -> t (v a) -> m (t (v a)))
-> ((M34 a -> m (M34 a)) -> t (V4 a) -> m (t (V4 a)))
-> (M34 a -> m (M34 a))
-> t (v a)
-> m (t (v a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (M34 a -> m (M34 a)) -> t (V4 a) -> m (t (V4 a))
forall (t :: * -> *) a. R3 t => Lens' (t a) (V3 a)
_xyz

-- | Extract a 4x2 matrix from a matrix of higher dimensions by dropping excess
--  rows and columns.
_m42 :: (Vec t, R4 t, R2 v) => Lens' (t (v a)) (M42 a)
_m42 :: Lens' (t (v a)) (M42 a)
_m42 = Lens' (v a) (V2 a) -> Lens' (t (v a)) (t (V2 a))
forall (v :: * -> *) a b. Vec v => Lens' a b -> Lens' (v a) (v b)
column Lens' (v a) (V2 a)
forall (t :: * -> *) a. R2 t => Lens' (t a) (V2 a)
_xy ((t (V2 a) -> m (t (V2 a))) -> t (v a) -> m (t (v a)))
-> ((M42 a -> m (M42 a)) -> t (V2 a) -> m (t (V2 a)))
-> (M42 a -> m (M42 a))
-> t (v a)
-> m (t (v a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (M42 a -> m (M42 a)) -> t (V2 a) -> m (t (V2 a))
forall (t :: * -> *) a. R4 t => Lens' (t a) (V4 a)
_xyzw

-- | Extract a 4x3 matrix from a matrix of higher dimensions by dropping excess
--  rows and columns.
_m43 :: (Vec t, R4 t, R3 v) => Lens' (t (v a)) (M43 a)
_m43 :: Lens' (t (v a)) (M43 a)
_m43 = Lens' (v a) (V3 a) -> Lens' (t (v a)) (t (V3 a))
forall (v :: * -> *) a b. Vec v => Lens' a b -> Lens' (v a) (v b)
column Lens' (v a) (V3 a)
forall (t :: * -> *) a. R3 t => Lens' (t a) (V3 a)
_xyz ((t (V3 a) -> m (t (V3 a))) -> t (v a) -> m (t (v a)))
-> ((M43 a -> m (M43 a)) -> t (V3 a) -> m (t (V3 a)))
-> (M43 a -> m (M43 a))
-> t (v a)
-> m (t (v a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (M43 a -> m (M43 a)) -> t (V3 a) -> m (t (V3 a))
forall (t :: * -> *) a. R4 t => Lens' (t a) (V4 a)
_xyzw

-- | Extract a 4x4 matrix from a matrix of higher dimensions by dropping excess
--  rows and columns.
_m44 :: (Vec t, R4 t, R4 v) => Lens' (t (v a)) (M44 a)
_m44 :: Lens' (t (v a)) (M44 a)
_m44 = Lens' (v a) (V4 a) -> Lens' (t (v a)) (t (V4 a))
forall (v :: * -> *) a b. Vec v => Lens' a b -> Lens' (v a) (v b)
column Lens' (v a) (V4 a)
forall (t :: * -> *) a. R4 t => Lens' (t a) (V4 a)
_xyzw ((t (V4 a) -> m (t (V4 a))) -> t (v a) -> m (t (v a)))
-> ((M44 a -> m (M44 a)) -> t (V4 a) -> m (t (V4 a)))
-> (M44 a -> m (M44 a))
-> t (v a)
-> m (t (v a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (M44 a -> m (M44 a)) -> t (V4 a) -> m (t (V4 a))
forall (t :: * -> *) a. R4 t => Lens' (t a) (V4 a)
_xyzw

-- | 2x2 matrix determinant.
--
--  >>> det22 (V2 (V2 a b) (V2 c d))
--  a * d - b * c
det22 :: Num a => M22 a -> a
det22 :: M22 a -> a
det22 (V2 (V2 a
a a
b) (V2 a
c a
d)) = a
a a -> a -> a
forall a. Num a => a -> a -> a
* a
d a -> a -> a
forall a. Num a => a -> a -> a
- a
b a -> a -> a
forall a. Num a => a -> a -> a
* a
c
{-# INLINE det22 #-}

-- | 3x3 matrix determinant.
--
--  >>> det33 (V3 (V3 a b c) (V3 d e f) (V3 g h i))
--  a * (e * i - f * h) - d * (b * i - c * h) + g * (b * f - c * e)
det33 :: Num a => M33 a -> a
det33 :: M33 a -> a
det33
  ( V3
      (V3 a
a a
b a
c)
      (V3 a
d a
e a
f)
      (V3 a
g a
h a
i)
    ) = a
a a -> a -> a
forall a. Num a => a -> a -> a
* (a
e a -> a -> a
forall a. Num a => a -> a -> a
* a
i a -> a -> a
forall a. Num a => a -> a -> a
- a
f a -> a -> a
forall a. Num a => a -> a -> a
* a
h) a -> a -> a
forall a. Num a => a -> a -> a
- a
d a -> a -> a
forall a. Num a => a -> a -> a
* (a
b a -> a -> a
forall a. Num a => a -> a -> a
* a
i a -> a -> a
forall a. Num a => a -> a -> a
- a
c a -> a -> a
forall a. Num a => a -> a -> a
* a
h) a -> a -> a
forall a. Num a => a -> a -> a
+ a
g a -> a -> a
forall a. Num a => a -> a -> a
* (a
b a -> a -> a
forall a. Num a => a -> a -> a
* a
f a -> a -> a
forall a. Num a => a -> a -> a
- a
c a -> a -> a
forall a. Num a => a -> a -> a
* a
e)
{-# INLINE det33 #-}

-- | 4x4 matrix determinant.
det44 :: Num a => M44 a -> a
det44 :: M44 a -> a
det44
  ( V4
      (V4 a
i00 a
i01 a
i02 a
i03)
      (V4 a
i10 a
i11 a
i12 a
i13)
      (V4 a
i20 a
i21 a
i22 a
i23)
      (V4 a
i30 a
i31 a
i32 a
i33)
    ) =
    let s0 :: a
s0 = a
i00 a -> a -> a
forall a. Num a => a -> a -> a
* a
i11 a -> a -> a
forall a. Num a => a -> a -> a
- a
i10 a -> a -> a
forall a. Num a => a -> a -> a
* a
i01
        s1 :: a
s1 = a
i00 a -> a -> a
forall a. Num a => a -> a -> a
* a
i12 a -> a -> a
forall a. Num a => a -> a -> a
- a
i10 a -> a -> a
forall a. Num a => a -> a -> a
* a
i02
        s2 :: a
s2 = a
i00 a -> a -> a
forall a. Num a => a -> a -> a
* a
i13 a -> a -> a
forall a. Num a => a -> a -> a
- a
i10 a -> a -> a
forall a. Num a => a -> a -> a
* a
i03
        s3 :: a
s3 = a
i01 a -> a -> a
forall a. Num a => a -> a -> a
* a
i12 a -> a -> a
forall a. Num a => a -> a -> a
- a
i11 a -> a -> a
forall a. Num a => a -> a -> a
* a
i02
        s4 :: a
s4 = a
i01 a -> a -> a
forall a. Num a => a -> a -> a
* a
i13 a -> a -> a
forall a. Num a => a -> a -> a
- a
i11 a -> a -> a
forall a. Num a => a -> a -> a
* a
i03
        s5 :: a
s5 = a
i02 a -> a -> a
forall a. Num a => a -> a -> a
* a
i13 a -> a -> a
forall a. Num a => a -> a -> a
- a
i12 a -> a -> a
forall a. Num a => a -> a -> a
* a
i03

        c5 :: a
c5 = a
i22 a -> a -> a
forall a. Num a => a -> a -> a
* a
i33 a -> a -> a
forall a. Num a => a -> a -> a
- a
i32 a -> a -> a
forall a. Num a => a -> a -> a
* a
i23
        c4 :: a
c4 = a
i21 a -> a -> a
forall a. Num a => a -> a -> a
* a
i33 a -> a -> a
forall a. Num a => a -> a -> a
- a
i31 a -> a -> a
forall a. Num a => a -> a -> a
* a
i23
        c3 :: a
c3 = a
i21 a -> a -> a
forall a. Num a => a -> a -> a
* a
i32 a -> a -> a
forall a. Num a => a -> a -> a
- a
i31 a -> a -> a
forall a. Num a => a -> a -> a
* a
i22
        c2 :: a
c2 = a
i20 a -> a -> a
forall a. Num a => a -> a -> a
* a
i33 a -> a -> a
forall a. Num a => a -> a -> a
- a
i30 a -> a -> a
forall a. Num a => a -> a -> a
* a
i23
        c1 :: a
c1 = a
i20 a -> a -> a
forall a. Num a => a -> a -> a
* a
i32 a -> a -> a
forall a. Num a => a -> a -> a
- a
i30 a -> a -> a
forall a. Num a => a -> a -> a
* a
i22
        c0 :: a
c0 = a
i20 a -> a -> a
forall a. Num a => a -> a -> a
* a
i31 a -> a -> a
forall a. Num a => a -> a -> a
- a
i30 a -> a -> a
forall a. Num a => a -> a -> a
* a
i21
     in a
s0 a -> a -> a
forall a. Num a => a -> a -> a
* a
c5 a -> a -> a
forall a. Num a => a -> a -> a
- a
s1 a -> a -> a
forall a. Num a => a -> a -> a
* a
c4 a -> a -> a
forall a. Num a => a -> a -> a
+ a
s2 a -> a -> a
forall a. Num a => a -> a -> a
* a
c3 a -> a -> a
forall a. Num a => a -> a -> a
+ a
s3 a -> a -> a
forall a. Num a => a -> a -> a
* a
c2 a -> a -> a
forall a. Num a => a -> a -> a
- a
s4 a -> a -> a
forall a. Num a => a -> a -> a
* a
c1 a -> a -> a
forall a. Num a => a -> a -> a
+ a
s5 a -> a -> a
forall a. Num a => a -> a -> a
* a
c0
{-# INLINE det44 #-}

-- | 2x2 matrix inverse.
--
--  >>> inv22 $ V2 (V2 1 2) (V2 3 4)
--  V2 (V2 (-2.0) 1.0) (V2 1.5 (-0.5))
inv22 :: Fractional a => M22 a -> M22 a
inv22 :: M22 a -> M22 a
inv22 m :: M22 a
m@(V2 (V2 a
a a
b) (V2 a
c a
d)) = (a
1 a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
det) a -> M22 a -> M22 a
forall (m :: * -> *) (r :: * -> *) a.
(Vec m, Vec r, Num a) =>
a -> m (r a) -> m (r a)
*!! V2 a -> V2 a -> M22 a
forall a. a -> a -> V2 a
V2 (a -> a -> V2 a
forall a. a -> a -> V2 a
V2 a
d (-a
b)) (a -> a -> V2 a
forall a. a -> a -> V2 a
V2 (-a
c) a
a)
  where
    det :: a
det = M22 a -> a
forall a. Num a => M22 a -> a
det22 M22 a
m
{-# INLINE inv22 #-}

-- | 3x3 matrix inverse.
--
--  >>> inv33 $ V3 (V3 1 2 4) (V3 4 2 2) (V3 1 1 1)
--  V3 (V3 0.0 0.5 (-1.0)) (V3 (-0.5) (-0.75) 3.5) (V3 0.5 0.25 (-1.5))
inv33 :: Fractional a => M33 a -> M33 a
inv33 :: M33 a -> M33 a
inv33
  m :: M33 a
m@( V3
        (V3 a
a a
b a
c)
        (V3 a
d a
e a
f)
        (V3 a
g a
h a
i)
      ) =
    (a
1 a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
det)
      a -> M33 a -> M33 a
forall (m :: * -> *) (r :: * -> *) a.
(Vec m, Vec r, Num a) =>
a -> m (r a) -> m (r a)
*!! V3 a -> V3 a -> V3 a -> M33 a
forall a. a -> a -> a -> V3 a
V3
        (a -> a -> a -> V3 a
forall a. a -> a -> a -> V3 a
V3 a
a' a
b' a
c')
        (a -> a -> a -> V3 a
forall a. a -> a -> a -> V3 a
V3 a
d' a
e' a
f')
        (a -> a -> a -> V3 a
forall a. a -> a -> a -> V3 a
V3 a
g' a
h' a
i')
    where
      a' :: a
a' = (a, a, a, a) -> a
forall a. Num a => (a, a, a, a) -> a
cofactor (a
e, a
f, a
h, a
i)
      b' :: a
b' = (a, a, a, a) -> a
forall a. Num a => (a, a, a, a) -> a
cofactor (a
c, a
b, a
i, a
h)
      c' :: a
c' = (a, a, a, a) -> a
forall a. Num a => (a, a, a, a) -> a
cofactor (a
b, a
c, a
e, a
f)
      d' :: a
d' = (a, a, a, a) -> a
forall a. Num a => (a, a, a, a) -> a
cofactor (a
f, a
d, a
i, a
g)
      e' :: a
e' = (a, a, a, a) -> a
forall a. Num a => (a, a, a, a) -> a
cofactor (a
a, a
c, a
g, a
i)
      f' :: a
f' = (a, a, a, a) -> a
forall a. Num a => (a, a, a, a) -> a
cofactor (a
c, a
a, a
f, a
d)
      g' :: a
g' = (a, a, a, a) -> a
forall a. Num a => (a, a, a, a) -> a
cofactor (a
d, a
e, a
g, a
h)
      h' :: a
h' = (a, a, a, a) -> a
forall a. Num a => (a, a, a, a) -> a
cofactor (a
b, a
a, a
h, a
g)
      i' :: a
i' = (a, a, a, a) -> a
forall a. Num a => (a, a, a, a) -> a
cofactor (a
a, a
b, a
d, a
e)
      cofactor :: (a, a, a, a) -> a
cofactor (a
q, a
r, a
s, a
t) = M22 a -> a
forall a. Num a => M22 a -> a
det22 (V2 a -> V2 a -> M22 a
forall a. a -> a -> V2 a
V2 (a -> a -> V2 a
forall a. a -> a -> V2 a
V2 a
q a
r) (a -> a -> V2 a
forall a. a -> a -> V2 a
V2 a
s a
t))
      det :: a
det = M33 a -> a
forall a. Num a => M33 a -> a
det33 M33 a
m
{-# INLINE inv33 #-}

-- | 'transpose' is just an alias for 'distribute'
--
-- > transpose (V3 (V2 1 2) (V2 3 4) (V2 5 6))
-- V2 (V3 1 3 5) (V3 2 4 6)
transpose :: (Vec f, Vec g) => f (g a) -> g (f a)
transpose :: f (g a) -> g (f a)
transpose = f (g a) -> g (f a)
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA
{-# INLINE transpose #-}

-- | 4x4 matrix inverse.
inv44 :: Fractional a => M44 a -> M44 a
inv44 :: M44 a -> M44 a
inv44
  ( V4
      (V4 a
i00 a
i01 a
i02 a
i03)
      (V4 a
i10 a
i11 a
i12 a
i13)
      (V4 a
i20 a
i21 a
i22 a
i23)
      (V4 a
i30 a
i31 a
i32 a
i33)
    ) =
    let s0 :: a
s0 = a
i00 a -> a -> a
forall a. Num a => a -> a -> a
* a
i11 a -> a -> a
forall a. Num a => a -> a -> a
- a
i10 a -> a -> a
forall a. Num a => a -> a -> a
* a
i01
        s1 :: a
s1 = a
i00 a -> a -> a
forall a. Num a => a -> a -> a
* a
i12 a -> a -> a
forall a. Num a => a -> a -> a
- a
i10 a -> a -> a
forall a. Num a => a -> a -> a
* a
i02
        s2 :: a
s2 = a
i00 a -> a -> a
forall a. Num a => a -> a -> a
* a
i13 a -> a -> a
forall a. Num a => a -> a -> a
- a
i10 a -> a -> a
forall a. Num a => a -> a -> a
* a
i03
        s3 :: a
s3 = a
i01 a -> a -> a
forall a. Num a => a -> a -> a
* a
i12 a -> a -> a
forall a. Num a => a -> a -> a
- a
i11 a -> a -> a
forall a. Num a => a -> a -> a
* a
i02
        s4 :: a
s4 = a
i01 a -> a -> a
forall a. Num a => a -> a -> a
* a
i13 a -> a -> a
forall a. Num a => a -> a -> a
- a
i11 a -> a -> a
forall a. Num a => a -> a -> a
* a
i03
        s5 :: a
s5 = a
i02 a -> a -> a
forall a. Num a => a -> a -> a
* a
i13 a -> a -> a
forall a. Num a => a -> a -> a
- a
i12 a -> a -> a
forall a. Num a => a -> a -> a
* a
i03
        c5 :: a
c5 = a
i22 a -> a -> a
forall a. Num a => a -> a -> a
* a
i33 a -> a -> a
forall a. Num a => a -> a -> a
- a
i32 a -> a -> a
forall a. Num a => a -> a -> a
* a
i23
        c4 :: a
c4 = a
i21 a -> a -> a
forall a. Num a => a -> a -> a
* a
i33 a -> a -> a
forall a. Num a => a -> a -> a
- a
i31 a -> a -> a
forall a. Num a => a -> a -> a
* a
i23
        c3 :: a
c3 = a
i21 a -> a -> a
forall a. Num a => a -> a -> a
* a
i32 a -> a -> a
forall a. Num a => a -> a -> a
- a
i31 a -> a -> a
forall a. Num a => a -> a -> a
* a
i22
        c2 :: a
c2 = a
i20 a -> a -> a
forall a. Num a => a -> a -> a
* a
i33 a -> a -> a
forall a. Num a => a -> a -> a
- a
i30 a -> a -> a
forall a. Num a => a -> a -> a
* a
i23
        c1 :: a
c1 = a
i20 a -> a -> a
forall a. Num a => a -> a -> a
* a
i32 a -> a -> a
forall a. Num a => a -> a -> a
- a
i30 a -> a -> a
forall a. Num a => a -> a -> a
* a
i22
        c0 :: a
c0 = a
i20 a -> a -> a
forall a. Num a => a -> a -> a
* a
i31 a -> a -> a
forall a. Num a => a -> a -> a
- a
i30 a -> a -> a
forall a. Num a => a -> a -> a
* a
i21
        det :: a
det = a
s0 a -> a -> a
forall a. Num a => a -> a -> a
* a
c5 a -> a -> a
forall a. Num a => a -> a -> a
- a
s1 a -> a -> a
forall a. Num a => a -> a -> a
* a
c4 a -> a -> a
forall a. Num a => a -> a -> a
+ a
s2 a -> a -> a
forall a. Num a => a -> a -> a
* a
c3 a -> a -> a
forall a. Num a => a -> a -> a
+ a
s3 a -> a -> a
forall a. Num a => a -> a -> a
* a
c2 a -> a -> a
forall a. Num a => a -> a -> a
- a
s4 a -> a -> a
forall a. Num a => a -> a -> a
* a
c1 a -> a -> a
forall a. Num a => a -> a -> a
+ a
s5 a -> a -> a
forall a. Num a => a -> a -> a
* a
c0
        invDet :: a
invDet = a -> a
forall a. Fractional a => a -> a
recip a
det
     in a
invDet
          a -> M44 a -> M44 a
forall (m :: * -> *) (r :: * -> *) a.
(Vec m, Vec r, Num a) =>
a -> m (r a) -> m (r a)
*!! V4 a -> V4 a -> V4 a -> V4 a -> M44 a
forall a. a -> a -> a -> a -> V4 a
V4
            ( a -> a -> a -> a -> V4 a
forall a. a -> a -> a -> a -> V4 a
V4
                (a
i11 a -> a -> a
forall a. Num a => a -> a -> a
* a
c5 a -> a -> a
forall a. Num a => a -> a -> a
- a
i12 a -> a -> a
forall a. Num a => a -> a -> a
* a
c4 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i13 a -> a -> a
forall a. Num a => a -> a -> a
* a
c3)
                (-a
i01 a -> a -> a
forall a. Num a => a -> a -> a
* a
c5 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i02 a -> a -> a
forall a. Num a => a -> a -> a
* a
c4 a -> a -> a
forall a. Num a => a -> a -> a
- a
i03 a -> a -> a
forall a. Num a => a -> a -> a
* a
c3)
                (a
i31 a -> a -> a
forall a. Num a => a -> a -> a
* a
s5 a -> a -> a
forall a. Num a => a -> a -> a
- a
i32 a -> a -> a
forall a. Num a => a -> a -> a
* a
s4 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i33 a -> a -> a
forall a. Num a => a -> a -> a
* a
s3)
                (-a
i21 a -> a -> a
forall a. Num a => a -> a -> a
* a
s5 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i22 a -> a -> a
forall a. Num a => a -> a -> a
* a
s4 a -> a -> a
forall a. Num a => a -> a -> a
- a
i23 a -> a -> a
forall a. Num a => a -> a -> a
* a
s3)
            )
            ( a -> a -> a -> a -> V4 a
forall a. a -> a -> a -> a -> V4 a
V4
                (-a
i10 a -> a -> a
forall a. Num a => a -> a -> a
* a
c5 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i12 a -> a -> a
forall a. Num a => a -> a -> a
* a
c2 a -> a -> a
forall a. Num a => a -> a -> a
- a
i13 a -> a -> a
forall a. Num a => a -> a -> a
* a
c1)
                (a
i00 a -> a -> a
forall a. Num a => a -> a -> a
* a
c5 a -> a -> a
forall a. Num a => a -> a -> a
- a
i02 a -> a -> a
forall a. Num a => a -> a -> a
* a
c2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i03 a -> a -> a
forall a. Num a => a -> a -> a
* a
c1)
                (-a
i30 a -> a -> a
forall a. Num a => a -> a -> a
* a
s5 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i32 a -> a -> a
forall a. Num a => a -> a -> a
* a
s2 a -> a -> a
forall a. Num a => a -> a -> a
- a
i33 a -> a -> a
forall a. Num a => a -> a -> a
* a
s1)
                (a
i20 a -> a -> a
forall a. Num a => a -> a -> a
* a
s5 a -> a -> a
forall a. Num a => a -> a -> a
- a
i22 a -> a -> a
forall a. Num a => a -> a -> a
* a
s2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i23 a -> a -> a
forall a. Num a => a -> a -> a
* a
s1)
            )
            ( a -> a -> a -> a -> V4 a
forall a. a -> a -> a -> a -> V4 a
V4
                (a
i10 a -> a -> a
forall a. Num a => a -> a -> a
* a
c4 a -> a -> a
forall a. Num a => a -> a -> a
- a
i11 a -> a -> a
forall a. Num a => a -> a -> a
* a
c2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i13 a -> a -> a
forall a. Num a => a -> a -> a
* a
c0)
                (-a
i00 a -> a -> a
forall a. Num a => a -> a -> a
* a
c4 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i01 a -> a -> a
forall a. Num a => a -> a -> a
* a
c2 a -> a -> a
forall a. Num a => a -> a -> a
- a
i03 a -> a -> a
forall a. Num a => a -> a -> a
* a
c0)
                (a
i30 a -> a -> a
forall a. Num a => a -> a -> a
* a
s4 a -> a -> a
forall a. Num a => a -> a -> a
- a
i31 a -> a -> a
forall a. Num a => a -> a -> a
* a
s2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i33 a -> a -> a
forall a. Num a => a -> a -> a
* a
s0)
                (-a
i20 a -> a -> a
forall a. Num a => a -> a -> a
* a
s4 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i21 a -> a -> a
forall a. Num a => a -> a -> a
* a
s2 a -> a -> a
forall a. Num a => a -> a -> a
- a
i23 a -> a -> a
forall a. Num a => a -> a -> a
* a
s0)
            )
            ( a -> a -> a -> a -> V4 a
forall a. a -> a -> a -> a -> V4 a
V4
                (-a
i10 a -> a -> a
forall a. Num a => a -> a -> a
* a
c3 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i11 a -> a -> a
forall a. Num a => a -> a -> a
* a
c1 a -> a -> a
forall a. Num a => a -> a -> a
- a
i12 a -> a -> a
forall a. Num a => a -> a -> a
* a
c0)
                (a
i00 a -> a -> a
forall a. Num a => a -> a -> a
* a
c3 a -> a -> a
forall a. Num a => a -> a -> a
- a
i01 a -> a -> a
forall a. Num a => a -> a -> a
* a
c1 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i02 a -> a -> a
forall a. Num a => a -> a -> a
* a
c0)
                (-a
i30 a -> a -> a
forall a. Num a => a -> a -> a
* a
s3 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i31 a -> a -> a
forall a. Num a => a -> a -> a
* a
s1 a -> a -> a
forall a. Num a => a -> a -> a
- a
i32 a -> a -> a
forall a. Num a => a -> a -> a
* a
s0)
                (a
i20 a -> a -> a
forall a. Num a => a -> a -> a
* a
s3 a -> a -> a
forall a. Num a => a -> a -> a
- a
i21 a -> a -> a
forall a. Num a => a -> a -> a
* a
s1 a -> a -> a
forall a. Num a => a -> a -> a
+ a
i22 a -> a -> a
forall a. Num a => a -> a -> a
* a
s0)
            )
{-# INLINE inv44 #-}