{-# OPTIONS --type-in-type #-}

open import NeilPrelude
open import Vector
open import Nat

module VectorMaths (A : Set) (zero : A) (one : A) (plus : Op A) (mult : Op A) where

vector :   Set
vector = Vec A

vecZero : {n : }  vector n
vecZero = vec zero

vecOne : {n : }  vector n
vecOne = vec one

vec+vec : {n : }  vector n  vector n  vector n
vec+vec = vzipWith plus

vdot : {n : }  vector n  vector n  A
vdot v1 v2 = vfoldl plus zero (vzipWith mult v1 v2)


-- Matrices ------------

matrix :     Set
matrix = Matrix A

matZero : {m n : }  matrix m n
matZero = mat zero

matOne : {m n : }  matrix m n
matOne = mat one

matId : {n : }  matrix n n
matId {O}   = []
matId {S n} = _∷_ (one  vec zero) (vmap (_∷_ zero) (matId {n}))

vec*mat : {m n : }  vector m  matrix m n  vector n
vec*mat v m = vmap (vdot v) m

mat*vec : {m n : }  matrix m n  vector n  vector m
mat*vec m v = vec*mat v (transpose m)

mat*mat : {l m n : }  matrix l m  matrix m n  matrix l n
mat*mat m1 m2 = vmap (mat*vec m1) m2

mat+mat : {m n : }  matrix m n  matrix m n  matrix m n
mat+mat = mzipWith plus