{-# LANGUAGE FlexibleInstances #-}
module Data.Matrix.Class where
import Prelude ()
import Algebra.RingUtils
import Control.Applicative hiding ((<|>))
fingerprint :: m a -> [[Char]]
fingerprint m a
m = [[ if a -> Bool
forall a. AbelianGroupZ a => a -> Bool
isZero (Int -> Int -> m a -> a
forall (m :: * -> *) a.
(Matrix m, AbelianGroupZ a) =>
Int -> Int -> m a -> a
at Int
i Int
j m a
m) then Char
' ' else Char
'X' | Int
i <- [Int
0..Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1] ] | Int
j <- [Int
0..Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1]]
where x :: Int
x = m a -> Int
forall (m :: * -> *) a. Matrix m => m a -> Int
countColumns m a
m
y :: Int
y = m a -> Int
forall (m :: * -> *) a. Matrix m => m a -> Int
countRows m a
m
(t -> a
f *** :: (t -> a) -> (t -> b) -> (t, t) -> (a, b)
*** t -> b
g) (t
x,t
y) = (t -> a
f t
x,t -> b
g t
y)
data Dimension
= XD
| YD
deriving (Dimension -> Dimension -> Bool
(Dimension -> Dimension -> Bool)
-> (Dimension -> Dimension -> Bool) -> Eq Dimension
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Dimension -> Dimension -> Bool
$c/= :: Dimension -> Dimension -> Bool
== :: Dimension -> Dimension -> Bool
$c== :: Dimension -> Dimension -> Bool
Eq,Int -> Dimension -> ShowS
[Dimension] -> ShowS
Dimension -> [Char]
(Int -> Dimension -> ShowS)
-> (Dimension -> [Char])
-> ([Dimension] -> ShowS)
-> Show Dimension
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [Dimension] -> ShowS
$cshowList :: [Dimension] -> ShowS
show :: Dimension -> [Char]
$cshow :: Dimension -> [Char]
showsPrec :: Int -> Dimension -> ShowS
$cshowsPrec :: Int -> Dimension -> ShowS
Show)
quad :: m a -> m a -> m a -> m a -> m a
quad m a
a m a
b m a
c m a
d = (m a
a m a -> m a -> m a
forall a (m :: * -> *).
(AbelianGroup a, Matrix m) =>
m a -> m a -> m a
<|> m a
b) m a -> m a -> m a
forall a (m :: * -> *).
(AbelianGroup a, Matrix m) =>
m a -> m a -> m a
<-> (m a
c m a -> m a -> m a
forall a (m :: * -> *).
(AbelianGroup a, Matrix m) =>
m a -> m a -> m a
<|> m a
d)
nextDim :: Dimension -> Dimension
nextDim Dimension
XD = Dimension
YD
nextDim Dimension
YD = Dimension
XD
type Extent = (Int,Int)
ext :: Dimension -> (a, a) -> a
ext Dimension
XD (a
x,a
y) = a
x
ext Dimension
YD (a
x,a
y) = a
y
glueExt :: Dimension -> (a, b) -> (a, b) -> (a, b)
glueExt Dimension
XD (a
x1,b
y1) (a
x2,b
y2) = (a
x1a -> a -> a
forall a. AbelianGroup a => a -> a -> a
+a
x2,b
y1)
glueExt Dimension
YD (a
x1,b
y1) (a
x2,b
y2) = (a
x1,b
y1b -> b -> b
forall a. AbelianGroup a => a -> a -> a
+b
y2)
splitExt :: Dimension -> b -> (b, b) -> ((b, b), (b, b))
splitExt Dimension
XD b
k (b
x,b
y) = ((b
k,b
y),(b
xb -> b -> b
forall a. Num a => a -> a -> a
-b
k,b
y))
splitExt Dimension
YD b
k (b
x,b
y) = ((b
x,b
k),(b
x,b
yb -> b -> b
forall a. Num a => a -> a -> a
-b
k))
class Matrix m where
at :: AbelianGroupZ a => Int -> Int -> m a -> a
extent :: m a -> Extent
singleton :: AbelianGroupZ a => a -> m a
glue :: AbelianGroup a => Dimension -> m a -> m a -> m a
split :: AbelianGroupZ a => Dimension -> Int -> m a -> (m a, m a)
zeroMatrix :: AbelianGroup a => Int -> Int -> m a
instance Matrix m => Matrix (O Pair m) where
at :: forall a. AbelianGroupZ a => Int -> Int -> O Pair m a -> a
at Int
i Int
j (O (m a
x :/: m a
y)) = Int -> Int -> m a -> a
forall (m :: * -> *) a.
(Matrix m, AbelianGroupZ a) =>
Int -> Int -> m a -> a
at Int
i Int
j m a
x a -> a -> a
forall a. AbelianGroup a => a -> a -> a
+ Int -> Int -> m a -> a
forall (m :: * -> *) a.
(Matrix m, AbelianGroupZ a) =>
Int -> Int -> m a -> a
at Int
i Int
j m a
y
extent :: forall a. O Pair m a -> Extent
extent (O (m a
x :/: m a
y)) = m a -> Extent
forall (m :: * -> *) a. Matrix m => m a -> Extent
extent m a
x
glue :: forall a.
AbelianGroup a =>
Dimension -> O Pair m a -> O Pair m a -> O Pair m a
glue Dimension
d (O Pair (m a)
p) (O Pair (m a)
q) = Pair (m a) -> O Pair m a
forall (f :: * -> *) (g :: * -> *) a. f (g a) -> O f g a
O (Pair (m a) -> O Pair m a) -> Pair (m a) -> O Pair m a
forall a b. (a -> b) -> a -> b
$ Dimension -> m a -> m a -> m a
forall (m :: * -> *) a.
(Matrix m, AbelianGroup a) =>
Dimension -> m a -> m a -> m a
glue Dimension
d (m a -> m a -> m a) -> Pair (m a) -> Pair (m a -> m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Pair (m a)
p Pair (m a -> m a) -> Pair (m a) -> Pair (m a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Pair (m a)
q
split :: forall a.
AbelianGroupZ a =>
Dimension -> Int -> O Pair m a -> (O Pair m a, O Pair m a)
split Dimension
d Int
k (O (m a
x :/: m a
y)) = (Pair (m a) -> O Pair m a
forall (f :: * -> *) (g :: * -> *) a. f (g a) -> O f g a
O (Pair (m a) -> O Pair m a) -> Pair (m a) -> O Pair m a
forall a b. (a -> b) -> a -> b
$ m a
ax m a -> m a -> Pair (m a)
forall a. a -> a -> Pair a
:/: m a
ay, Pair (m a) -> O Pair m a
forall (f :: * -> *) (g :: * -> *) a. f (g a) -> O f g a
O (Pair (m a) -> O Pair m a) -> Pair (m a) -> O Pair m a
forall a b. (a -> b) -> a -> b
$ m a
bx m a -> m a -> Pair (m a)
forall a. a -> a -> Pair a
:/: m a
by)
where (m a
ax,m a
bx) = Dimension -> Int -> m a -> (m a, m a)
forall (m :: * -> *) a.
(Matrix m, AbelianGroupZ a) =>
Dimension -> Int -> m a -> (m a, m a)
split Dimension
d Int
k m a
x
(m a
ay,m a
by) = Dimension -> Int -> m a -> (m a, m a)
forall (m :: * -> *) a.
(Matrix m, AbelianGroupZ a) =>
Dimension -> Int -> m a -> (m a, m a)
split Dimension
d Int
k m a
y
zeroMatrix :: forall a. AbelianGroup a => Int -> Int -> O Pair m a
zeroMatrix Int
x Int
y = Pair (m a) -> O Pair m a
forall (f :: * -> *) (g :: * -> *) a. f (g a) -> O f g a
O (Pair (m a) -> O Pair m a) -> Pair (m a) -> O Pair m a
forall a b. (a -> b) -> a -> b
$ m a -> Pair (m a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int -> Int -> m a
forall (m :: * -> *) a.
(Matrix m, AbelianGroup a) =>
Int -> Int -> m a
zeroMatrix Int
x Int
y)
singleton :: forall a. AbelianGroupZ a => a -> O Pair m a
singleton a
x = Pair (m a) -> O Pair m a
forall (f :: * -> *) (g :: * -> *) a. f (g a) -> O f g a
O (Pair (m a) -> O Pair m a) -> Pair (m a) -> O Pair m a
forall a b. (a -> b) -> a -> b
$ m a -> Pair (m a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> m a
forall (m :: * -> *) a. (Matrix m, AbelianGroupZ a) => a -> m a
singleton a
x)
(<|>) :: (AbelianGroup a, Matrix m) => m a -> m a -> m a
<|> :: forall a (m :: * -> *).
(AbelianGroup a, Matrix m) =>
m a -> m a -> m a
(<|>) = Dimension -> m a -> m a -> m a
forall (m :: * -> *) a.
(Matrix m, AbelianGroup a) =>
Dimension -> m a -> m a -> m a
glue Dimension
XD
(<->) :: (AbelianGroup a, Matrix m) => m a -> m a -> m a
<-> :: forall a (m :: * -> *).
(AbelianGroup a, Matrix m) =>
m a -> m a -> m a
(<->) = Dimension -> m a -> m a -> m a
forall (m :: * -> *) a.
(Matrix m, AbelianGroup a) =>
Dimension -> m a -> m a -> m a
glue Dimension
YD
countColumns, countRows :: Matrix m => m a -> Int
countColumns :: forall (m :: * -> *) a. Matrix m => m a -> Int
countColumns = Dimension -> Extent -> Int
forall {a}. Dimension -> (a, a) -> a
ext Dimension
XD (Extent -> Int) -> (m a -> Extent) -> m a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> Extent
forall (m :: * -> *) a. Matrix m => m a -> Extent
extent
countRows :: forall (m :: * -> *) a. Matrix m => m a -> Int
countRows = Dimension -> Extent -> Int
forall {a}. Dimension -> (a, a) -> a
ext Dimension
YD (Extent -> Int) -> (m a -> Extent) -> m a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> Extent
forall (m :: * -> *) a. Matrix m => m a -> Extent
extent
chopLastColumn, chopFirstRow, chopFirstColumn, chopLastRow, lastColumn, firstRow :: (AbelianGroupZ a, Matrix m) => m a -> m a
chopFirstRow :: forall a (m :: * -> *). (AbelianGroupZ a, Matrix m) => m a -> m a
chopFirstRow = (m a, m a) -> m a
forall a b. (a, b) -> b
snd ((m a, m a) -> m a) -> (m a -> (m a, m a)) -> m a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dimension -> Int -> m a -> (m a, m a)
forall (m :: * -> *) a.
(Matrix m, AbelianGroupZ a) =>
Dimension -> Int -> m a -> (m a, m a)
split Dimension
YD Int
1
chopFirstColumn :: forall a (m :: * -> *). (AbelianGroupZ a, Matrix m) => m a -> m a
chopFirstColumn = (m a, m a) -> m a
forall a b. (a, b) -> b
snd ((m a, m a) -> m a) -> (m a -> (m a, m a)) -> m a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dimension -> Int -> m a -> (m a, m a)
forall (m :: * -> *) a.
(Matrix m, AbelianGroupZ a) =>
Dimension -> Int -> m a -> (m a, m a)
split Dimension
XD Int
1
chopLastColumn :: forall a (m :: * -> *). (AbelianGroupZ a, Matrix m) => m a -> m a
chopLastColumn m a
x = (m a, m a) -> m a
forall a b. (a, b) -> a
fst ((m a, m a) -> m a) -> (m a -> (m a, m a)) -> m a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dimension -> Int -> m a -> (m a, m a)
forall (m :: * -> *) a.
(Matrix m, AbelianGroupZ a) =>
Dimension -> Int -> m a -> (m a, m a)
split Dimension
XD (m a -> Int
forall (m :: * -> *) a. Matrix m => m a -> Int
countColumns m a
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (m a -> m a) -> m a -> m a
forall a b. (a -> b) -> a -> b
$ m a
x
firstRow :: forall a (m :: * -> *). (AbelianGroupZ a, Matrix m) => m a -> m a
firstRow = (m a, m a) -> m a
forall a b. (a, b) -> a
fst ((m a, m a) -> m a) -> (m a -> (m a, m a)) -> m a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dimension -> Int -> m a -> (m a, m a)
forall (m :: * -> *) a.
(Matrix m, AbelianGroupZ a) =>
Dimension -> Int -> m a -> (m a, m a)
split Dimension
YD Int
1
lastColumn :: forall a (m :: * -> *). (AbelianGroupZ a, Matrix m) => m a -> m a
lastColumn m a
x = (m a, m a) -> m a
forall a b. (a, b) -> b
snd ((m a, m a) -> m a) -> (m a -> (m a, m a)) -> m a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dimension -> Int -> m a -> (m a, m a)
forall (m :: * -> *) a.
(Matrix m, AbelianGroupZ a) =>
Dimension -> Int -> m a -> (m a, m a)
split Dimension
XD (m a -> Int
forall (m :: * -> *) a. Matrix m => m a -> Int
countColumns m a
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (m a -> m a) -> m a -> m a
forall a b. (a -> b) -> a -> b
$ m a
x
chopLastRow :: forall a (m :: * -> *). (AbelianGroupZ a, Matrix m) => m a -> m a
chopLastRow m a
x = (m a, m a) -> m a
forall a b. (a, b) -> a
fst ((m a, m a) -> m a) -> (m a -> (m a, m a)) -> m a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dimension -> Int -> m a -> (m a, m a)
forall (m :: * -> *) a.
(Matrix m, AbelianGroupZ a) =>
Dimension -> Int -> m a -> (m a, m a)
split Dimension
YD (m a -> Int
forall (m :: * -> *) a. Matrix m => m a -> Int
countRows m a
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (m a -> m a) -> m a -> m a
forall a b. (a -> b) -> a -> b
$ m a
x