{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs                  #-}
{-# LANGUAGE MultiParamTypeClasses  #-}
-- | Minimil linear algebra lib.
module Math.Regression.Simple.LinAlg (
    -- * Operations
    Add (..),
    Eye (..),
    Mult (..),
    Det (..),
    Inv (..),
    -- * Zeros
    zerosLin,
    zerosQuad,
    optimaQuad,
    -- * Two dimensions
    V2 (..),
    M22 (..),
    SM22 (..),
    -- * Three dimensions
    V3 (..),
    M33 (..),
    SM33 (..),
) where

import Control.DeepSeq (NFData (..))
import Data.Complex    (Complex (..))

-------------------------------------------------------------------------------
-- Classes
-------------------------------------------------------------------------------

-- | Addition
class Add a where
    zero :: a
    add  :: a -> a -> a

-- | Identity
class Eye a where
    eye :: a

-- | Multiplication of different things.
class Eye a => Mult a b c | a b -> c where
    mult :: a -> b -> c

-- | Determinant
class Eye a => Det a where
    det :: a -> Double

-- | Inverse
class Det a => Inv a where
    inv :: a -> a

infixl 6 `add`
infixl 7 `mult`

instance Eye Double where
    eye :: Double
eye = Double
1

instance Add Double where
    zero :: Double
zero = Double
0
    add :: Double -> Double -> Double
add = forall a. Num a => a -> a -> a
(+)

instance Mult Double Double Double where
    mult :: Double -> Double -> Double
mult = forall a. Num a => a -> a -> a
(*)

instance Det Double where
    det :: Double -> Double
det = forall a. a -> a
id

instance Inv Double where
    inv :: Double -> Double
inv = forall a. Fractional a => a -> a
recip

-------------------------------------------------------------------------------
-- Zeros
-------------------------------------------------------------------------------

-- | Solve linear equation.
--
-- >>> zerosLin (V2 1 2)
-- -2.0
--
zerosLin :: V2 -> Double
zerosLin :: V2 -> Double
zerosLin (V2 Double
a Double
b) = forall a. Num a => a -> a
negate (Double
b forall a. Fractional a => a -> a -> a
/ Double
a)

-- | Solve quadratic equation.
--
-- >>> zerosQuad (V3 2 0 (-1))
-- Right (-0.7071067811865476,0.7071067811865476)
--
-- >>> zerosQuad (V3 2 0 1)
-- Left ((-0.0) :+ (-0.7071067811865476),(-0.0) :+ 0.7071067811865476)
--
-- Double root is not treated separately:
--
-- >>> zerosQuad (V3 1 0 0)
-- Right (-0.0,0.0)
--
-- >>> zerosQuad (V3 1 (-2) 1)
-- Right (1.0,1.0)
--
zerosQuad :: V3 -> Either (Complex Double, Complex Double) (Double, Double)
zerosQuad :: V3 -> Either (Complex Double, Complex Double) (Double, Double)
zerosQuad (V3 Double
a Double
b Double
c)
    | Double
delta forall a. Ord a => a -> a -> Bool
< Double
0 = forall a b. a -> Either a b
Left ((-Double
bforall a. Fractional a => a -> a -> a
/Double
da) forall a. a -> a -> Complex a
:+ (-Double
sqrtNDeltaforall a. Fractional a => a -> a -> a
/Double
da), (-Double
bforall a. Fractional a => a -> a -> a
/Double
da) forall a. a -> a -> Complex a
:+ (Double
sqrtNDeltaforall a. Fractional a => a -> a -> a
/Double
da))
    | Bool
otherwise = forall a b. b -> Either a b
Right ((- Double
b forall a. Num a => a -> a -> a
- Double
sqrtDelta) forall a. Fractional a => a -> a -> a
/ Double
da, (-Double
b forall a. Num a => a -> a -> a
+ Double
sqrtDelta) forall a. Fractional a => a -> a -> a
/ Double
da)
  where
    delta :: Double
delta = Double
bforall a. Num a => a -> a -> a
*Double
b forall a. Num a => a -> a -> a
- Double
4 forall a. Num a => a -> a -> a
* Double
a forall a. Num a => a -> a -> a
* Double
c
    sqrtDelta :: Double
sqrtDelta = forall a. Floating a => a -> a
sqrt Double
delta
    sqrtNDelta :: Double
sqrtNDelta = forall a. Floating a => a -> a
sqrt (- Double
delta)
    da :: Double
da = Double
2 forall a. Num a => a -> a -> a
* Double
a

-- | Find an optima point.
--
-- >>> optimaQuad (V3 1 (-2) 0)
-- 1.0
--
-- compare to
--
-- >>> zerosQuad (V3 1 (-2) 0)
-- Right (0.0,2.0)
--
optimaQuad :: V3 -> Double
optimaQuad :: V3 -> Double
optimaQuad (V3 Double
a Double
b Double
_) = V2 -> Double
zerosLin (Double -> Double -> V2
V2 (Double
2 forall a. Num a => a -> a -> a
* Double
a) Double
b)

-------------------------------------------------------------------------------
-- 2 dimensions
-------------------------------------------------------------------------------

-- | 2d vector. Strict pair of 'Double's.
--
-- Also used to represent linear polynomial: @V2 a b@  \(= a x + b\).
--
data V2 = V2 !Double !Double
  deriving (V2 -> V2 -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: V2 -> V2 -> Bool
$c/= :: V2 -> V2 -> Bool
== :: V2 -> V2 -> Bool
$c== :: V2 -> V2 -> Bool
Eq, Int -> V2 -> ShowS
[V2] -> ShowS
V2 -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [V2] -> ShowS
$cshowList :: [V2] -> ShowS
show :: V2 -> String
$cshow :: V2 -> String
showsPrec :: Int -> V2 -> ShowS
$cshowsPrec :: Int -> V2 -> ShowS
Show)

instance NFData V2 where
    rnf :: V2 -> ()
rnf V2 {} = ()

instance Add V2 where
    zero :: V2
zero = Double -> Double -> V2
V2 Double
0 Double
0
    add :: V2 -> V2 -> V2
add (V2 Double
x Double
y) (V2 Double
x' Double
y') = Double -> Double -> V2
V2 (Double
x forall a. Num a => a -> a -> a
+ Double
x') (Double
y forall a. Num a => a -> a -> a
+ Double
y')
    {-# INLINE zero #-}
    {-# INLINE add #-}

instance Mult Double V2 V2 where
    mult :: Double -> V2 -> V2
mult Double
k (V2 Double
x Double
y) = Double -> Double -> V2
V2 (Double
k forall a. Num a => a -> a -> a
* Double
x) (Double
k forall a. Num a => a -> a -> a
* Double
y)
    {-# INLINE mult #-}

-- | 2×2 matrix.
data M22 = M22 !Double !Double !Double !Double
  deriving (M22 -> M22 -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: M22 -> M22 -> Bool
$c/= :: M22 -> M22 -> Bool
== :: M22 -> M22 -> Bool
$c== :: M22 -> M22 -> Bool
Eq, Int -> M22 -> ShowS
[M22] -> ShowS
M22 -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [M22] -> ShowS
$cshowList :: [M22] -> ShowS
show :: M22 -> String
$cshow :: M22 -> String
showsPrec :: Int -> M22 -> ShowS
$cshowsPrec :: Int -> M22 -> ShowS
Show)

instance NFData M22 where
    rnf :: M22 -> ()
rnf M22 {} = ()

instance Add M22 where
    zero :: M22
zero = Double -> Double -> Double -> Double -> M22
M22 Double
0 Double
0 Double
0 Double
0
    add :: M22 -> M22 -> M22
add (M22 Double
a Double
b Double
c Double
d) (M22 Double
a' Double
b' Double
c' Double
d') = Double -> Double -> Double -> Double -> M22
M22 (Double
a forall a. Num a => a -> a -> a
+ Double
a') (Double
b forall a. Num a => a -> a -> a
+ Double
b') (Double
c forall a. Num a => a -> a -> a
+ Double
c') (Double
d forall a. Num a => a -> a -> a
+ Double
d')
    {-# INLINE zero #-}
    {-# INLINE add #-}

instance Eye M22 where
    eye :: M22
eye = Double -> Double -> Double -> Double -> M22
M22 Double
1 Double
0 Double
0 Double
1
    {-# INLINE eye #-}

instance Det M22 where det :: M22 -> Double
det = M22 -> Double
det2
instance Inv M22 where inv :: M22 -> M22
inv = M22 -> M22
inv2

instance Mult Double M22 M22 where
    mult :: Double -> M22 -> M22
mult Double
k (M22 Double
a Double
b Double
c Double
d) = Double -> Double -> Double -> Double -> M22
M22 (Double
k forall a. Num a => a -> a -> a
* Double
a) (Double
k forall a. Num a => a -> a -> a
* Double
b) (Double
k forall a. Num a => a -> a -> a
* Double
c) (Double
k forall a. Num a => a -> a -> a
* Double
d)
    {-# INLINE mult #-}

instance Mult M22 V2 V2 where
    mult :: M22 -> V2 -> V2
mult (M22 Double
a Double
b Double
c Double
d) (V2 Double
u Double
v) = Double -> Double -> V2
V2 (Double
a forall a. Num a => a -> a -> a
* Double
u forall a. Num a => a -> a -> a
+ Double
b forall a. Num a => a -> a -> a
* Double
v) (Double
c forall a. Num a => a -> a -> a
* Double
u forall a. Num a => a -> a -> a
+ Double
d forall a. Num a => a -> a -> a
* Double
v)
    {-# INLINE mult #-}

-- | >>> M22 1 2 3 4 `mult` eye @M22
-- M22 1.0 2.0 3.0 4.0
instance Mult M22 M22 M22 where
    mult :: M22 -> M22 -> M22
mult (M22 Double
a Double
b Double
c Double
d) (M22 Double
x Double
y Double
z Double
w) = Double -> Double -> Double -> Double -> M22
M22
        (Double
a forall a. Num a => a -> a -> a
* Double
x forall a. Num a => a -> a -> a
+ Double
b forall a. Num a => a -> a -> a
* Double
z) (Double
a forall a. Num a => a -> a -> a
* Double
y forall a. Num a => a -> a -> a
+ Double
b forall a. Num a => a -> a -> a
* Double
w)
        (Double
c forall a. Num a => a -> a -> a
* Double
x forall a. Num a => a -> a -> a
+ Double
d forall a. Num a => a -> a -> a
* Double
z) (Double
c forall a. Num a => a -> a -> a
* Double
y forall a. Num a => a -> a -> a
+ Double
d forall a. Num a => a -> a -> a
* Double
w)
    {-# INLINE mult #-}

det2 :: M22 -> Double
det2 :: M22 -> Double
det2 (M22 Double
a Double
b Double
c Double
d) = Double
a forall a. Num a => a -> a -> a
* Double
d forall a. Num a => a -> a -> a
- Double
b forall a. Num a => a -> a -> a
* Double
c
{-# INLINE det2 #-}

inv2 :: M22 -> M22
inv2 :: M22 -> M22
inv2 m :: M22
m@(M22 Double
a Double
b Double
c Double
d) = Double -> Double -> Double -> Double -> M22
M22
    (  Double
d forall a. Fractional a => a -> a -> a
/ Double
detm) (- Double
b forall a. Fractional a => a -> a -> a
/ Double
detm)
    (- Double
c forall a. Fractional a => a -> a -> a
/ Double
detm) (  Double
a forall a. Fractional a => a -> a -> a
/ Double
detm)
  where
    detm :: Double
detm = M22 -> Double
det2 M22
m
{-# INLINE inv2 #-}

-- | Symmetric 2x2 matrix.
data SM22 = SM22 !Double !Double !Double
  deriving (SM22 -> SM22 -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SM22 -> SM22 -> Bool
$c/= :: SM22 -> SM22 -> Bool
== :: SM22 -> SM22 -> Bool
$c== :: SM22 -> SM22 -> Bool
Eq, Int -> SM22 -> ShowS
[SM22] -> ShowS
SM22 -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SM22] -> ShowS
$cshowList :: [SM22] -> ShowS
show :: SM22 -> String
$cshow :: SM22 -> String
showsPrec :: Int -> SM22 -> ShowS
$cshowsPrec :: Int -> SM22 -> ShowS
Show)

instance NFData SM22 where
    rnf :: SM22 -> ()
rnf SM22 {} = ()

instance Add SM22 where
    zero :: SM22
zero = Double -> Double -> Double -> SM22
SM22 Double
0 Double
0 Double
0
    add :: SM22 -> SM22 -> SM22
add (SM22 Double
a Double
b Double
d) (SM22 Double
a' Double
b' Double
d') = Double -> Double -> Double -> SM22
SM22 (Double
a forall a. Num a => a -> a -> a
+ Double
a') (Double
b forall a. Num a => a -> a -> a
+ Double
b') (Double
d forall a. Num a => a -> a -> a
+ Double
d')
    {-# INLINE zero #-}
    {-# INLINE add #-}

instance Eye SM22 where
    eye :: SM22
eye = Double -> Double -> Double -> SM22
SM22 Double
1 Double
0 Double
1
    {-# INLINE eye #-}

instance Det SM22 where det :: SM22 -> Double
det = SM22 -> Double
detS2
instance Inv SM22 where inv :: SM22 -> SM22
inv = SM22 -> SM22
invS2

instance Mult Double SM22 SM22 where
    mult :: Double -> SM22 -> SM22
mult Double
k (SM22 Double
a Double
b Double
d) = Double -> Double -> Double -> SM22
SM22 (Double
k forall a. Num a => a -> a -> a
* Double
a) (Double
k forall a. Num a => a -> a -> a
* Double
b) (Double
k forall a. Num a => a -> a -> a
* Double
d)
    {-# INLINE mult #-}

instance Mult SM22 V2 V2 where
    mult :: SM22 -> V2 -> V2
mult (SM22 Double
a Double
b Double
d) (V2 Double
u Double
v) = Double -> Double -> V2
V2 (Double
a forall a. Num a => a -> a -> a
* Double
u forall a. Num a => a -> a -> a
+ Double
b forall a. Num a => a -> a -> a
* Double
v) (Double
b forall a. Num a => a -> a -> a
* Double
u forall a. Num a => a -> a -> a
+ Double
d forall a. Num a => a -> a -> a
* Double
v)
    {-# INLINE mult #-}

detS2 :: SM22 -> Double
detS2 :: SM22 -> Double
detS2 (SM22 Double
a Double
b Double
d) = Double
a forall a. Num a => a -> a -> a
* Double
d forall a. Num a => a -> a -> a
- Double
b forall a. Num a => a -> a -> a
* Double
b
{-# INLINE detS2 #-}

invS2 :: SM22 -> SM22
invS2 :: SM22 -> SM22
invS2 m :: SM22
m@(SM22 Double
a Double
b Double
d) = Double -> Double -> Double -> SM22
SM22
    (  Double
d forall a. Fractional a => a -> a -> a
/ Double
detm)
    (- Double
b forall a. Fractional a => a -> a -> a
/ Double
detm) (  Double
a forall a. Fractional a => a -> a -> a
/ Double
detm)
  where
    detm :: Double
detm = SM22 -> Double
detS2 SM22
m
{-# INLINE invS2 #-}

-------------------------------------------------------------------------------
-- 3 dimensions
-------------------------------------------------------------------------------

-- | 3d vector. Strict triple of 'Double's.
--
-- Also used to represent quadratic polynomial: @V3 a b c@  \(= a x^2 + b x + c\).
data V3 = V3 !Double !Double !Double
  deriving (V3 -> V3 -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: V3 -> V3 -> Bool
$c/= :: V3 -> V3 -> Bool
== :: V3 -> V3 -> Bool
$c== :: V3 -> V3 -> Bool
Eq, Int -> V3 -> ShowS
[V3] -> ShowS
V3 -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [V3] -> ShowS
$cshowList :: [V3] -> ShowS
show :: V3 -> String
$cshow :: V3 -> String
showsPrec :: Int -> V3 -> ShowS
$cshowsPrec :: Int -> V3 -> ShowS
Show)

instance NFData V3 where
    rnf :: V3 -> ()
rnf V3 {} = ()

instance Add V3 where
    zero :: V3
zero = Double -> Double -> Double -> V3
V3 Double
0 Double
0 Double
0
    add :: V3 -> V3 -> V3
add (V3 Double
x Double
y Double
z) (V3 Double
x' Double
y' Double
z') = Double -> Double -> Double -> V3
V3 (Double
x forall a. Num a => a -> a -> a
+ Double
x') (Double
y forall a. Num a => a -> a -> a
+ Double
y') (Double
z forall a. Num a => a -> a -> a
+ Double
z')
    {-# INLINE zero #-}
    {-# INLINE add #-}

instance Mult Double V3 V3 where
    mult :: Double -> V3 -> V3
mult Double
k (V3 Double
x Double
y Double
z) = Double -> Double -> Double -> V3
V3 (Double
k forall a. Num a => a -> a -> a
* Double
x) (Double
k forall a. Num a => a -> a -> a
* Double
y) (Double
k forall a. Num a => a -> a -> a
* Double
z)
    {-# INLINE mult #-}

-- | 3×3 matrix.
data M33 = M33
    !Double !Double !Double
    !Double !Double !Double
    !Double !Double !Double
  deriving (M33 -> M33 -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: M33 -> M33 -> Bool
$c/= :: M33 -> M33 -> Bool
== :: M33 -> M33 -> Bool
$c== :: M33 -> M33 -> Bool
Eq, Int -> M33 -> ShowS
[M33] -> ShowS
M33 -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [M33] -> ShowS
$cshowList :: [M33] -> ShowS
show :: M33 -> String
$cshow :: M33 -> String
showsPrec :: Int -> M33 -> ShowS
$cshowsPrec :: Int -> M33 -> ShowS
Show)

instance NFData M33 where
    rnf :: M33 -> ()
rnf M33 {} = ()

instance Add M33 where
    zero :: M33
zero = Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> M33
M33 Double
0 Double
0 Double
0 Double
0 Double
0 Double
0 Double
0 Double
0 Double
0

    add :: M33 -> M33 -> M33
add (M33 Double
a Double
b Double
c Double
d Double
e Double
f Double
g Double
h Double
i) (M33 Double
a' Double
b' Double
c' Double
d' Double
e' Double
f' Double
g' Double
h' Double
i') = Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> M33
M33
        (Double
a forall a. Num a => a -> a -> a
+ Double
a') (Double
b forall a. Num a => a -> a -> a
+ Double
b') (Double
c forall a. Num a => a -> a -> a
+ Double
c')
        (Double
d forall a. Num a => a -> a -> a
+ Double
d') (Double
e forall a. Num a => a -> a -> a
+ Double
e') (Double
f forall a. Num a => a -> a -> a
+ Double
f')
        (Double
g forall a. Num a => a -> a -> a
+ Double
g') (Double
h forall a. Num a => a -> a -> a
+ Double
h') (Double
i forall a. Num a => a -> a -> a
+ Double
i')
    {-# INLINE zero #-}
    {-# INLINE add #-}

instance Eye M33 where
    eye :: M33
eye = Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> M33
M33 Double
1 Double
0 Double
0
              Double
0 Double
1 Double
0
              Double
0 Double
0 Double
1
    {-# INLINE eye #-}

instance Det M33 where det :: M33 -> Double
det = M33 -> Double
det3
instance Inv M33 where inv :: M33 -> M33
inv = M33 -> M33
inv3

instance Mult Double M33 M33 where
    mult :: Double -> M33 -> M33
mult Double
k (M33 Double
a Double
b Double
c Double
d Double
e Double
f Double
g Double
h Double
i) = Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> M33
M33
        (Double
k forall a. Num a => a -> a -> a
* Double
a) (Double
k forall a. Num a => a -> a -> a
* Double
b) (Double
k forall a. Num a => a -> a -> a
* Double
c)
        (Double
k forall a. Num a => a -> a -> a
* Double
d) (Double
k forall a. Num a => a -> a -> a
* Double
e) (Double
k forall a. Num a => a -> a -> a
* Double
f)
        (Double
k forall a. Num a => a -> a -> a
* Double
g) (Double
k forall a. Num a => a -> a -> a
* Double
h) (Double
k forall a. Num a => a -> a -> a
* Double
i)
    {-# INLINE mult #-}

instance Mult M33 V3 V3 where
    mult :: M33 -> V3 -> V3
mult (M33 Double
a Double
b Double
c
           Double
d Double
e Double
f
           Double
g Double
h Double
i) (V3 Double
u Double
v Double
w) = Double -> Double -> Double -> V3
V3
        (Double
a forall a. Num a => a -> a -> a
* Double
u forall a. Num a => a -> a -> a
+ Double
b forall a. Num a => a -> a -> a
* Double
v forall a. Num a => a -> a -> a
+ Double
c forall a. Num a => a -> a -> a
* Double
w)
        (Double
d forall a. Num a => a -> a -> a
* Double
u forall a. Num a => a -> a -> a
+ Double
e forall a. Num a => a -> a -> a
* Double
v forall a. Num a => a -> a -> a
+ Double
f forall a. Num a => a -> a -> a
* Double
w)
        (Double
g forall a. Num a => a -> a -> a
* Double
u forall a. Num a => a -> a -> a
+ Double
h forall a. Num a => a -> a -> a
* Double
v forall a. Num a => a -> a -> a
+ Double
i forall a. Num a => a -> a -> a
* Double
w)
    {-# INLINE mult #-}

-- TODO: instance Mult M33 M33 M33 where

det3 :: M33 -> Double
det3 :: M33 -> Double
det3 (M33 Double
a Double
b Double
c
          Double
d Double
e Double
f
          Double
g Double
h Double
i)
    = Double
a forall a. Num a => a -> a -> a
* (Double
eforall a. Num a => a -> a -> a
*Double
iforall a. Num a => a -> a -> a
-Double
fforall a. Num a => a -> a -> a
*Double
h) forall a. Num a => a -> a -> a
- Double
d forall a. Num a => a -> a -> a
* (Double
bforall a. Num a => a -> a -> a
*Double
iforall a. Num a => a -> a -> a
-Double
cforall a. Num a => a -> a -> a
*Double
h) forall a. Num a => a -> a -> a
+ Double
g forall a. Num a => a -> a -> a
* (Double
bforall a. Num a => a -> a -> a
*Double
fforall a. Num a => a -> a -> a
-Double
cforall a. Num a => a -> a -> a
*Double
e)
{-# INLINE det3 #-}

inv3 :: M33 -> M33
inv3 :: M33 -> M33
inv3 m :: M33
m@(M33 Double
a Double
b Double
c
            Double
d Double
e Double
f
            Double
g Double
h Double
i)
    = Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> Double
-> M33
M33 Double
a' Double
b' Double
c'
          Double
d' Double
e' Double
f'
          Double
g' Double
h' Double
i'
  where
    a' :: Double
a' = Double -> Double -> Double -> Double -> Double
cofactor Double
e Double
f Double
h Double
i forall a. Fractional a => a -> a -> a
/ Double
detm
    b' :: Double
b' = Double -> Double -> Double -> Double -> Double
cofactor Double
c Double
b Double
i Double
h forall a. Fractional a => a -> a -> a
/ Double
detm
    c' :: Double
c' = Double -> Double -> Double -> Double -> Double
cofactor Double
b Double
c Double
e Double
f forall a. Fractional a => a -> a -> a
/ Double
detm
    d' :: Double
d' = Double -> Double -> Double -> Double -> Double
cofactor Double
f Double
d Double
i Double
g forall a. Fractional a => a -> a -> a
/ Double
detm
    e' :: Double
e' = Double -> Double -> Double -> Double -> Double
cofactor Double
a Double
c Double
g Double
i forall a. Fractional a => a -> a -> a
/ Double
detm
    f' :: Double
f' = Double -> Double -> Double -> Double -> Double
cofactor Double
c Double
a Double
f Double
d forall a. Fractional a => a -> a -> a
/ Double
detm
    g' :: Double
g' = Double -> Double -> Double -> Double -> Double
cofactor Double
d Double
e Double
g Double
h forall a. Fractional a => a -> a -> a
/ Double
detm
    h' :: Double
h' = Double -> Double -> Double -> Double -> Double
cofactor Double
b Double
a Double
h Double
g forall a. Fractional a => a -> a -> a
/ Double
detm
    i' :: Double
i' = Double -> Double -> Double -> Double -> Double
cofactor Double
a Double
b Double
d Double
e forall a. Fractional a => a -> a -> a
/ Double
detm
    cofactor :: Double -> Double -> Double -> Double -> Double
cofactor Double
q Double
r Double
s Double
t = M22 -> Double
det2 (Double -> Double -> Double -> Double -> M22
M22 Double
q Double
r Double
s Double
t)
    detm :: Double
detm = M33 -> Double
det3 M33
m
{-# INLINE inv3 #-}

-- | Symmetric 3×3 matrix.
data SM33 = SM33
    !Double
    !Double !Double
    !Double !Double !Double
  deriving (SM33 -> SM33 -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SM33 -> SM33 -> Bool
$c/= :: SM33 -> SM33 -> Bool
== :: SM33 -> SM33 -> Bool
$c== :: SM33 -> SM33 -> Bool
Eq, Int -> SM33 -> ShowS
[SM33] -> ShowS
SM33 -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SM33] -> ShowS
$cshowList :: [SM33] -> ShowS
show :: SM33 -> String
$cshow :: SM33 -> String
showsPrec :: Int -> SM33 -> ShowS
$cshowsPrec :: Int -> SM33 -> ShowS
Show)

instance NFData SM33 where
    rnf :: SM33 -> ()
rnf SM33 {} = ()

instance Add SM33 where
    zero :: SM33
zero = Double -> Double -> Double -> Double -> Double -> Double -> SM33
SM33 Double
0 Double
0 Double
0 Double
0 Double
0 Double
0

    add :: SM33 -> SM33 -> SM33
add (SM33 Double
a Double
d Double
e Double
g Double
h Double
i) (SM33 Double
a' Double
d' Double
e' Double
g' Double
h' Double
i') = Double -> Double -> Double -> Double -> Double -> Double -> SM33
SM33
        (Double
a forall a. Num a => a -> a -> a
+ Double
a')
        (Double
d forall a. Num a => a -> a -> a
+ Double
d') (Double
e forall a. Num a => a -> a -> a
+ Double
e')
        (Double
g forall a. Num a => a -> a -> a
+ Double
g') (Double
h forall a. Num a => a -> a -> a
+ Double
h') (Double
i forall a. Num a => a -> a -> a
+ Double
i')
    {-# INLINE zero #-}
    {-# INLINE add #-}

instance Eye SM33 where
    eye :: SM33
eye = Double -> Double -> Double -> Double -> Double -> Double -> SM33
SM33 Double
1
               Double
0 Double
1
               Double
0 Double
0 Double
1
    {-# INLINE eye #-}

instance Det SM33 where det :: SM33 -> Double
det = SM33 -> Double
detS3
instance Inv SM33 where inv :: SM33 -> SM33
inv = SM33 -> SM33
invS3

instance Mult Double SM33 SM33 where
    mult :: Double -> SM33 -> SM33
mult Double
k (SM33 Double
a Double
d Double
e Double
g Double
h Double
i) = Double -> Double -> Double -> Double -> Double -> Double -> SM33
SM33
        (Double
k forall a. Num a => a -> a -> a
* Double
a)
        (Double
k forall a. Num a => a -> a -> a
* Double
d) (Double
k forall a. Num a => a -> a -> a
* Double
e)
        (Double
k forall a. Num a => a -> a -> a
* Double
g) (Double
k forall a. Num a => a -> a -> a
* Double
h) (Double
k forall a. Num a => a -> a -> a
* Double
i)
    {-# INLINE mult #-}

instance Mult SM33 V3 V3 where
    mult :: SM33 -> V3 -> V3
mult (SM33 Double
a
               Double
d Double
e
               Double
g Double
h Double
i) (V3 Double
u Double
v Double
w) = Double -> Double -> Double -> V3
V3
        (Double
a forall a. Num a => a -> a -> a
* Double
u forall a. Num a => a -> a -> a
+ Double
d forall a. Num a => a -> a -> a
* Double
v forall a. Num a => a -> a -> a
+ Double
g forall a. Num a => a -> a -> a
* Double
w)
        (Double
d forall a. Num a => a -> a -> a
* Double
u forall a. Num a => a -> a -> a
+ Double
e forall a. Num a => a -> a -> a
* Double
v forall a. Num a => a -> a -> a
+ Double
h forall a. Num a => a -> a -> a
* Double
w)
        (Double
g forall a. Num a => a -> a -> a
* Double
u forall a. Num a => a -> a -> a
+ Double
h forall a. Num a => a -> a -> a
* Double
v forall a. Num a => a -> a -> a
+ Double
i forall a. Num a => a -> a -> a
* Double
w)
    {-# INLINE mult #-}

detS3 :: SM33 -> Double
detS3 :: SM33 -> Double
detS3 (SM33 Double
a
            Double
d Double
e
            Double
g Double
h Double
i)
    = Double
a forall a. Num a => a -> a -> a
* (Double
eforall a. Num a => a -> a -> a
*Double
iforall a. Num a => a -> a -> a
-Double
hforall a. Num a => a -> a -> a
*Double
h) forall a. Num a => a -> a -> a
- Double
d forall a. Num a => a -> a -> a
* (Double
dforall a. Num a => a -> a -> a
*Double
iforall a. Num a => a -> a -> a
-Double
gforall a. Num a => a -> a -> a
*Double
h) forall a. Num a => a -> a -> a
+ Double
g forall a. Num a => a -> a -> a
* (Double
dforall a. Num a => a -> a -> a
*Double
hforall a. Num a => a -> a -> a
-Double
gforall a. Num a => a -> a -> a
*Double
e)
{-# INLINE detS3 #-}

invS3 :: SM33 -> SM33
invS3 :: SM33 -> SM33
invS3 m :: SM33
m@(SM33 Double
a
              Double
d Double
e
              Double
g Double
h Double
i)
     = Double -> Double -> Double -> Double -> Double -> Double -> SM33
SM33 Double
a'
            Double
d' Double
e'
            Double
g' Double
h' Double
i'
  where
    a' :: Double
a' = Double -> Double -> Double -> Double -> Double
cofactor Double
e Double
h Double
h Double
i forall a. Fractional a => a -> a -> a
/ Double
detm
    d' :: Double
d' = Double -> Double -> Double -> Double -> Double
cofactor Double
h Double
d Double
i Double
g forall a. Fractional a => a -> a -> a
/ Double
detm
    e' :: Double
e' = Double -> Double -> Double -> Double -> Double
cofactor Double
a Double
g Double
g Double
i forall a. Fractional a => a -> a -> a
/ Double
detm
    g' :: Double
g' = Double -> Double -> Double -> Double -> Double
cofactor Double
d Double
e Double
g Double
h forall a. Fractional a => a -> a -> a
/ Double
detm
    h' :: Double
h' = Double -> Double -> Double -> Double -> Double
cofactor Double
d Double
a Double
h Double
g forall a. Fractional a => a -> a -> a
/ Double
detm
    i' :: Double
i' = Double -> Double -> Double -> Double -> Double
cofactor Double
a Double
d Double
d Double
e forall a. Fractional a => a -> a -> a
/ Double
detm
    cofactor :: Double -> Double -> Double -> Double -> Double
cofactor Double
q Double
r Double
s Double
t = M22 -> Double
det2 (Double -> Double -> Double -> Double -> M22
M22 Double
q Double
r Double
s Double
t)
    detm :: Double
detm = SM33 -> Double
detS3 SM33
m
{-# INLINE invS3 #-}