idris-matrix
A simple Idris library for manipulating matrices 🧙
Matrix.idr (4450B)
1 module Data.Matrix 2 3 import Data.Vect 4 5 ||| A matrix with fixed dimentions. 6 export 7 data Matrix : (n : Nat) -> (m : Nat) -> Type -> Type where 8 MkMatrix : Vect (S n) (Vect (S m) t) -> Matrix (S n) (S m) t 9 10 %name Matrix as, bs, cs, ds, xs, ys 11 12 ||| A type alias for a square matrix. 13 export 14 Square : Nat -> Type -> Type 15 Square n = Matrix n n 16 17 -- ============================ Conversions =================================== 18 19 implementation Cast (Vect (S n) (Vect (S m) t)) (Matrix (S n) (S m) t) where 20 cast = MkMatrix 21 22 implementation Cast (Matrix (S n) (S m) t) (Vect (S n) (Vect (S m) t)) where 23 cast (MkMatrix as) = as 24 25 ||| Generates a matrix from nested vectors. 26 export total 27 fromVect : Vect (S n) (Vect (S m) t) -> Matrix (S n) (S m) t 28 fromVect = cast 29 30 ||| Converts a matrix to nested vectors. 31 export total 32 toVect : Matrix (S n) (S m) t -> Vect (S n) (Vect (S m) t) 33 toVect = cast 34 35 implementation Cast (Matrix (S n) (S m) t) (List (List t)) where 36 cast = toList . map toList . toVect 37 38 -- =========================== Initialization ================================= 39 40 ||| Generates a matrix based on it's coordinates. 41 export total 42 fromCoords : (f : Fin (S n) -> Fin (S m) -> t) -> Matrix (S n) (S m) t 43 fromCoords f = MkMatrix (map (\i => map (f i) range) range) 44 45 ||| Returns a matrix whose coordinate-values are constant. 46 export total 47 replicate : t -> Matrix (S n) (S m) t 48 replicate x = fromVect (replicate _ (replicate _ x)) 49 50 -- =========================== Manipulations ================================== 51 52 ||| Combines two matrix with the same dimentions pairwise with some function. 53 export total 54 zipWith : (f : a -> b -> c) -> Matrix (S n) (S m) a 55 -> Matrix (S n) (S m) b 56 -> Matrix (S n) (S m) c 57 zipWith f (MkMatrix as) (MkMatrix bs) = MkMatrix (zipWith (zipWith f) as bs) 58 59 ||| Combines two matrices with the same dimentions into a matrix of tuples 60 export total 61 zip : Matrix (S n) (S m) a -> Matrix (S n) (S m) b -> Matrix (S n) (S m) (a, b) 62 zip = zipWith (\a => \b => (a, b)) 63 64 -- ============================== Indexing ==================================== 65 66 ||| Returns the value of a matrix coordinate 67 index : Fin (S n) -> Fin (S m) -> Matrix (S n) (S m) t -> t 68 index i j (MkMatrix as) = index j (index i as) 69 70 -- ======================== Basic Implementations ============================= 71 72 implementation Eq t => Eq (Matrix (S n) (S m) t) where 73 (MkMatrix as) == (MkMatrix bs) = as == bs 74 75 implementation Show t => Show (Matrix (S n) (S m) t) where 76 show as = unlines (map unwords (map (map show) as')) 77 where 78 as' : List (List t) 79 as' = cast as 80 81 implementation Functor (Matrix (S n) (S m)) where 82 map f (MkMatrix as) = MkMatrix (map (map f) as) 83 84 implementation Applicative (Matrix (S n) (S m)) where 85 pure = replicate 86 87 (<*>) = zipWith apply 88 89 implementation Semigroup t => Semigroup (Matrix (S n) (S m) t) where 90 (<+>) = zipWith (<+>) 91 92 implementation Monoid t => Monoid (Matrix (S n) (S m) t) where 93 neutral = pure neutral 94 95 -- =========================== Linear Algebra ================================= 96 97 ||| Returns the identity matrix. 98 export 99 ident : Num t => Matrix (S n) (S n) t 100 ident = fromCoords f 101 where 102 f i j = if i == j then 1 else 0 103 104 ||| Transposes the matrix. 105 export total 106 transpose : Matrix (S n) (S m) t -> Matrix (S m) (S n) t 107 transpose (MkMatrix as) = MkMatrix (transpose as) 108 109 ||| Adds two numeric matrices. 110 export total 111 (+) : Num t => Matrix (S n) (S m) t -> Matrix (S n) (S m) t 112 -> Matrix (S n) (S m) t 113 (+) = zipWith (+) 114 115 ||| Multiplies two numeric matrices. 116 export total 117 (*) : Num t => Matrix (S n) (S m) t -> Matrix (S m) (S p) t 118 -> Matrix (S n) (S p) t 119 (*) {n} {m} {p} (MkMatrix as) (MkMatrix bs) = fromCoords f 120 where 121 sum : Num t => Vect (S q) t -> t 122 sum = with Vect foldl1 (+) 123 bs' : Vect (S p) (Vect (S m) t) 124 bs' = transpose bs 125 f : Num t => Fin (S n) -> Fin (S p) -> t 126 f i j = sum (zipWith (*) (with Vect index i as) (with Vect index j bs')) 127 128 infixr 8 . 129 130 ||| Multiplies a matrix by a scalar. 131 export total 132 (.) : Num t => t -> Matrix (S n) (S m) t -> Matrix (S n) (S m) t 133 x . as = (x *) <$> as 134 135 export total 136 negate : Neg t => Matrix (S n) (S m) t -> Matrix (S n) (S m) t 137 negate = negate <$> 138 139 export total 140 (-) : Neg t => Matrix (S n) (S m) t -> Matrix (S n) (S m) t 141 -> Matrix (S n) (S m) t 142 (-) = zipWith (-) 143