module Math.ExpPairs.Matrix3 (Matrix3 (..), Vector3 (..), fromList, toList, det, multCol, normalize, prettyMatrix) where
import qualified Data.List as List
import Data.Monoid
data Vector3 t = Vector3 {
a1 :: t,
a2 :: t,
a3 :: t
}
deriving (Eq, Show)
data Matrix3 t = Matrix3 {
a11 :: t,
a12 :: t,
a13 :: t,
a21 :: t,
a22 :: t,
a23 :: t,
a31 :: t,
a32 :: t,
a33 :: t
}
deriving (Eq, Show)
instance Num t => Num (Matrix3 t) where
a + b = Matrix3 {
a11 = a11 a + a11 b,
a12 = a12 a + a12 b,
a13 = a13 a + a13 b,
a21 = a21 a + a21 b,
a22 = a22 a + a22 b,
a23 = a23 a + a23 b,
a31 = a31 a + a31 b,
a32 = a32 a + a32 b,
a33 = a33 a + a33 b
}
a * b = Matrix3 {
a11 = a11 a * a11 b + a12 a * a21 b + a13 a * a31 b,
a12 = a11 a * a12 b + a12 a * a22 b + a13 a * a32 b,
a13 = a11 a * a13 b + a12 a * a23 b + a13 a * a33 b,
a21 = a21 a * a11 b + a22 a * a21 b + a23 a * a31 b,
a22 = a21 a * a12 b + a22 a * a22 b + a23 a * a32 b,
a23 = a21 a * a13 b + a22 a * a23 b + a23 a * a33 b,
a31 = a31 a * a11 b + a32 a * a21 b + a33 a * a31 b,
a32 = a31 a * a12 b + a32 a * a22 b + a33 a * a32 b,
a33 = a31 a * a13 b + a32 a * a23 b + a33 a * a33 b
}
negate a = Matrix3 {
a11 = a11 a,
a12 = a12 a,
a13 = a13 a,
a21 = a21 a,
a22 = a22 a,
a23 = a23 a,
a31 = a31 a,
a32 = a32 a,
a33 = a33 a
}
abs = undefined
signum = undefined
fromInteger n = Matrix3 {
a11 = fromInteger n,
a12 = 0,
a13 = 0,
a21 = 0,
a22 = fromInteger n,
a23 = 0,
a31 = 0,
a32 = 0,
a33 = fromInteger n
}
det :: (Num t) => Matrix3 t -> t
det a =
a11 a * (a22 a * a33 a a32 a * a23 a)
a12 a * (a21 a * a33 a a23 a * a31 a)
+ a13 a * (a21 a * a32 a a22 a * a31 a)
instance Fractional t => Fractional (Matrix3 t) where
fromRational n = Matrix3 {
a11 = fromRational n,
a12 = 0,
a13 = 0,
a21 = 0,
a22 = fromRational n,
a23 = 0,
a31 = 0,
a32 = 0,
a33 = fromRational n
}
recip a = Matrix3 {
a11 = (a22 a * a33 a a32 a * a23 a) / d,
a12 = (a21 a * a33 a a23 a * a31 a) / d,
a13 = (a21 a * a32 a a22 a * a31 a) / d,
a21 = (a12 a * a33 a a13 a * a32 a) / d,
a22 = (a11 a * a33 a a13 a * a31 a) / d,
a23 = (a11 a * a32 a a12 a * a31 a) / d,
a31 = (a12 a * a23 a a13 a * a22 a) / d,
a32 = (a11 a * a23 a a13 a * a21 a) / d,
a33 = (a11 a * a22 a a12 a * a21 a) / d
} where d = det a
instance Num t => Monoid (Matrix3 t) where
mempty = 1
mappend = (*)
toList :: Matrix3 t -> [t]
toList a = [a11 a, a12 a, a13 a, a21 a, a22 a, a23 a, a31 a, a32 a, a33 a]
fromList :: [t] -> Matrix3 t
fromList as = Matrix3 {
a11 = as!!0,
a12 = as!!1,
a13 = as!!2,
a21 = as!!3,
a22 = as!!4,
a23 = as!!5,
a31 = as!!6,
a32 = as!!7,
a33 = as!!8
}
instance Functor Matrix3 where
fmap f = fromList . List.map f . toList
normalize :: Integral t => Matrix3 t -> Matrix3 t
normalize m = m' where
l = toList m
d = foldl1 gcd l
m' = if d==0 then m else fromList $ List.map (`div`d) l
maximum :: Ord t => Matrix3 t -> t
maximum = List.maximum . toList
prettyMatrix :: (Show t) => Matrix3 t -> String
prettyMatrix m =
show (a11 m) ++ " " ++
show (a12 m) ++ " " ++
show (a13 m) ++ "\n" ++
show (a21 m) ++ " " ++
show (a22 m) ++ " " ++
show (a23 m) ++ "\n" ++
show (a31 m) ++ " " ++
show (a32 m) ++ " " ++
show (a33 m)
multCol :: (Num t) => Matrix3 t -> Vector3 t -> Vector3 t
multCol m v = Vector3 {
a1 = a11 m * a1 v + a12 m * a2 v + a13 m * a3 v,
a2 = a21 m * a1 v + a22 m * a2 v + a23 m * a3 v,
a3 = a31 m * a1 v + a32 m * a2 v + a33 m * a3 v
}