module Algebra.Matrix.Structures where open import Level using (Level; _⊔_) open import Function open import Algebra open import Data.Nat as ℕ using (ℕ) open import Data.Fin using (Fin; _≟_) open import Data.List import Algebra.Matrix.Base as MBase open import Relation.Binary open import Relation.Nullary open import Algebra.BigOps private variable a ℓ : Level B : Set ℓ m n p k : ℕ module MAddition (_+_ : Op₂ B) where infixl 6 _+ᴹ_ open MBase public _+ᴹ_ : Op₂ (Matrix B m n) (xs +ᴹ ys) i j = xs i j + ys i j module MMonoid (rawMonoid : RawMonoid a ℓ) where infix 4 _≈ᴹ_ open RawMonoid rawMonoid renaming (Carrier to A) open MAddition _∙_ public open SumRawMonoid rawMonoid 0ᴹ : Matrix A m n 0ᴹ _ _ = ε _≈ᴹ_ : Rel (Matrix A m n) _ M ≈ᴹ N = ∀ i j → M i j ≈ N i j module MRing {a} {ℓ} (rawRing : RawRing a ℓ) where infixl 7 _*ᴹ_ infixl 5 _▹_ open RawRing rawRing renaming (Carrier to A) open SumRawRing rawRing public open MMonoid +-rawMonoid public private variable xs xs‵ ys zs : Matrix A m n 1ᴹ : Matrix A n n 1ᴹ = δ _*ᴹ_ : Matrix A m n → Matrix A n p → Matrix A m p (M *ᴹ N) i k = ∑ λ j → M i j * N j k record IsLinear (T : Matrix A m n → Matrix A k n) : Set (a ⊔ ℓ) where field transMat : (M : Matrix A m n) → Matrix A k m transEq : (M : Matrix A m n) → T M ≈ᴹ transMat M *ᴹ M record MatFunAreLinear (transMat : (M : Matrix A m n) → Matrix A k m) (T : Matrix A m n → Matrix A k n) : Set (a ⊔ ℓ) where field transEq : (M : Matrix A m n) → T M ≈ᴹ transMat M *ᴹ M swapMatrix : (p q : Fin n) → Matrix A n n swapMatrix p q i j with p ≟ i | q ≟ i ... | yes _ | _ = δ q j ... | _ | yes _ = δ p j ... | _ | _ = δ i j _[_]≔_*[_] : Matrix A m n → Fin m → A → Fin m → Matrix A m n (M [ p ]≔ r *[ q ]) i j with q ≟ i ... | yes _ = M i j + r * M p j ... | no _ = M i j addConstRowMatrix : (p q : Fin n) (r : A) → Matrix A n n addConstRowMatrix p q r i j with q ≟ i ... | yes _ = δ i j + r * δ p j ... | no _ = δ i j data MatrixOps (m n : ℕ) : Set a where swapOp : (p q : Fin m) → MatrixOps m n addCons : (p q : Fin m) (r : A) → MatrixOps m n matOps→mat : MatrixOps m n → Matrix A m m matOps→mat (swapOp p q) = swapMatrix p q matOps→mat (addCons p q r) = addConstRowMatrix p q r matOps→func : MatrixOps m n → Matrix A m n → Matrix A m n matOps→func (swapOp p q) = swap p q matOps→func (addCons p q r) xs = xs [ p ]≔ r *[ q ] listMatOps→mat : List (MatrixOps m n) → Matrix A m m listMatOps→mat = foldr (_*ᴹ_ ∘ matOps→mat) 1ᴹ listMatOps→func : List (MatrixOps m n) → Op₁ (Matrix A m n) listMatOps→func = foldr (λ mops → (matOps→func mops) ∘_) id data _▹_ : Rel (Matrix A m n) (a ⊔ ℓ) where idR : xs ≈ᴹ ys → xs ▹ ys rec : (mOps : MatrixOps m n) → xs ▹ ys → matOps→func mOps ys ≈ᴹ zs → xs ▹ zs ▹⇒listMops : {xs : Matrix A m n} → xs ▹ ys → List (MatrixOps m n) ▹⇒listMops (idR _) = [] ▹⇒listMops (rec mOps xs▹ys _) = mOps ∷ ▹⇒listMops xs▹ys