-- helper functions zero-vec : (n : ℕ) → vector ℕ n zero-vec zero = [] zero-vec (suc n) = zero ∷ zero-vec n -- zero-matrix : (n m : ℕ) → n by m matrix zero-matrix zero m = [] zero-matrix (suc n) m = zero-vec m ∷ zero-matrix n m
对角矩阵和单位矩阵:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
gen-vec : (n : ℕ) → (d : ℕ) → (pos : ℕ) → vector ℕ n gen-vec zero d pos = [] gen-vec (suc n) d pos with pos =ℕ n ... | true = d ∷ gen-vec n d pos ... | false = zero ∷ gen-vec n d pos
diag-calculation : (n : ℕ) → (m : ℕ) → (d : ℕ) -> m by n matrix diag-calculation n zero d = [] diag-calculation n (suc m) d = gen-vec n d m ∷ diag-calculation n m d -- diagonal-matrix : (n : ℕ) → (d : ℕ) → n by n matrix diagonal-matrix n d = diag-calculation n n d
identity-matrix : (n : ℕ) → n by n matrix identity-matrix n = diagonal-matrix n (suc zero)
一些有点考验代码能力,值得讲一讲的矩阵基本运算计算编程:
取出矩阵的 (i, j) 位置的元素:
1 2 3 4 5 6 7 8 9 10 11 12 13
vector-elt : {n : ℕ} → vector ℕ n → (i : ℕ) → i <ℕ n ≡ true → ℕ vector-elt {(suc n)} (x ∷ xs) zero p = x vector-elt {(suc n)} (x ∷ xs) (suc i) p = vector-elt {n} xs i p -- -- begin from 0,0 end in (n-1,m-1) matrix-elt : {n m : ℕ} → n by m matrix → (i j : ℕ) → i <ℕ n ≡ true → j <ℕ m ≡ true → ℕ matrix-elt {n} {m} (x ∷ xs) zero j p q = vector-elt x j q matrix-elt {(suc n)} {m} (x ∷ xs) (suc i) j p q = matrix-elt {n} {m} xs i j p q
在这个问题中,我们对矩阵逐层“剥皮”处理,先找到第 i 行,然后再在第 i 行中找到第 j 个元素。
zipWith : ∀ {A : Set } {B : Set } {C : Set }{n : ℕ} → (A → B → C) → vector A n → vector B n → vector C n zipWith f [] [] = [] zipWith f (x ∷ xs) (y ∷ ys) = (f x y) ∷ (zipWith f xs ys)
repeat-vec : ∀ {A : Set } → (x : A) → (n : ℕ) → vector A n repeat-vec x zero = [] repeat-vec x (suc n) = x ∷ (repeat-vec x n)
transpose : {n m : ℕ} → n by m matrix → m by n matrix transpose {n} {m} [] = repeat-vec [] m transpose (x ∷ xs) = zipWith (λ x y → x ∷ y) x (transpose xs)
open import natural open import Data.Bool using (true; false; Bool; if_then_else_) import Relation.Binary.PropositionalEquality as Eq open Eq using (_≡_; refl; cong) open Eq.≡-Reasoning using (begin_; step-≡; step-≡˘; _≡⟨⟩_; _∎) open import Data.List hiding (zipWith)
data vector (A : Set) : ℕ → Set where [] : vector A zero _∷_ : ∀ {n} → A → vector A n → vector A (suc n)
infixr 5 _∷_
_++v_ : ∀ {A n m} → vector A n → vector A m → vector A (n + m) [] ++v ys = ys (x ∷ xs) ++v ys = x ∷ (xs ++v ys)
headv : ∀ {A n} → vector A (suc n) → A headv (x ∷ xs) = x
tailv : ∀ {A n} → vector A n → vector A (pred n) tailv [] = [] tailv (x ∷ xs) = xs
mapv : ∀ {A B n} → (A → B) → vector A n → vector B n mapv f [] = [] mapv f (x ∷ xs) = f x ∷ mapv f xs
concatv : ∀ {A n m} → vector (vector A m) n → vector A (n * m) concatv [] = [] concatv (xs ∷ xss) = xs ++v concatv xss
nthv : ∀ {A : Set} {m : ℕ} → (n : ℕ) → (n <ℕ m) ≡ true → vector A m → A nthv zero _ (x ∷ xs) = x nthv (suc n) p (x ∷ xs) = nthv n p xs nthv (suc n) () [] nthv zero () []
repeatv : ∀ {A : Set} → (n : ℕ) → A → vector A n repeatv zero x = [] repeatv (suc n) x = x ∷ repeatv n x
_by_matrix : (n m : ℕ) → Set n by m matrix = vector (vector ℕ m) n
-- helper functions zero-vec : (n : ℕ) → vector ℕ n zero-vec zero = [] zero-vec (suc n) = zero ∷ zero-vec n -- zero-matrix : (n m : ℕ) → n by m matrix zero-matrix zero m = [] zero-matrix (suc n) m = zero-vec m ∷ zero-matrix n m
gen-vec : (n : ℕ) → (d : ℕ) → (pos : ℕ) → vector ℕ n gen-vec zero d pos = [] gen-vec (suc n) d pos with pos =ℕ n ... | true = d ∷ gen-vec n d pos ... | false = zero ∷ gen-vec n d pos
diag-calculation : (n : ℕ) → (m : ℕ) → (d : ℕ) -> m by n matrix diag-calculation n zero d = [] diag-calculation n (suc m) d = gen-vec n d m ∷ diag-calculation n m d -- diagonal-matrix : (n : ℕ) → (d : ℕ) → n by n matrix diagonal-matrix n d = diag-calculation n n d
identity-matrix : (n : ℕ) → n by n matrix identity-matrix n = diagonal-matrix n (suc zero)
vector-elt : {n : ℕ} → vector ℕ n → (i : ℕ) → i <ℕ n ≡ true → ℕ vector-elt {(suc n)} (x ∷ xs) zero p = x vector-elt {(suc n)} (x ∷ xs) (suc i) p = vector-elt {n} xs i p -- -- begin from 0,0 end in (n-1,m-1) matrix-elt : {n m : ℕ} → n by m matrix → (i j : ℕ) → i <ℕ n ≡ true → j <ℕ m ≡ true → ℕ matrix-elt {n} {m} (x ∷ xs) zero j p q = vector-elt x j q matrix-elt {(suc n)} {m} (x ∷ xs) (suc i) j p q = matrix-elt {n} {m} xs i j p q
zipWith : ∀ {A : Set } {B : Set } {C : Set }{n : ℕ} → (A → B → C) → vector A n → vector B n → vector C n zipWith f [] [] = [] zipWith f (x ∷ xs) (y ∷ ys) = (f x y) ∷ (zipWith f xs ys)
repeat-vec : ∀ {A : Set } → (x : A) → (n : ℕ) → vector A n repeat-vec x zero = [] repeat-vec x (suc n) = x ∷ (repeat-vec x n)
transpose : {n m : ℕ} → n by m matrix → m by n matrix transpose {n} {m} [] = repeat-vec [] m transpose (x ∷ xs) = zipWith (λ x y → x ∷ y) x (transpose xs)
_∙_ : {n : ℕ} → (x y : vector ℕ n) → ℕ (x ∷ xs) ∙ (y ∷ ys) = x * y + (xs ∙ ys) [] ∙ [] = zero