{-# OPTIONS --safe --cubical-compatible --guardedness --exact-split --double-check #-}
module ALMA.Physics.Quantum.Stochastic where
open import Data.Nat.Base as Nat using (ℕ)
open import Data.Fin.Base using (Fin; zero; suc)
open import Data.Rational using (ℚ; 0ℚ; 1ℚ; _+_; _*_)
open import Data.Rational.Properties using
(+-identityˡ; *-comm; *-zeroʳ; *-identityʳ; *-distribˡ-+)
open import Function.Base using (_∘_)
open import Relation.Binary.PropositionalEquality using
(_≡_; refl; sym; cong; module ≡-Reasoning)
open import ALMA.Physics.Quantum.FiniteVec using (sumFin; sumFin-cong)
open import ALMA.Physics.RationalKit using (+interchange)
private
sumFin-zero : ∀ n → sumFin {n} (λ (_ : Fin n) → 0ℚ) ≡ 0ℚ
sumFin-zero Nat.zero = refl
sumFin-zero (Nat.suc n) = let open ≡-Reasoning in begin
0ℚ + sumFin {n} (λ _ → 0ℚ)
≡⟨ +-identityˡ _ ⟩
sumFin {n} (λ _ → 0ℚ)
≡⟨ sumFin-zero n ⟩
0ℚ ∎
sumFin-+ : ∀ {n} (g h : Fin n → ℚ) →
sumFin (λ i → g i + h i) ≡ sumFin g + sumFin h
sumFin-+ {Nat.zero} g h = sym (+-identityˡ 0ℚ)
sumFin-+ {Nat.suc n} g h = let open ≡-Reasoning in begin
(g zero + h zero) + sumFin (λ i → g (suc i) + h (suc i))
≡⟨ cong ((g zero + h zero) +_)
(sumFin-+ (g ∘ suc) (h ∘ suc)) ⟩
(g zero + h zero) + (sumFin (g ∘ suc) + sumFin (h ∘ suc))
≡⟨ +interchange (g zero) (h zero)
(sumFin (g ∘ suc)) (sumFin (h ∘ suc)) ⟩
(g zero + sumFin (g ∘ suc)) + (h zero + sumFin (h ∘ suc)) ∎
sumFin-*ˡ : ∀ {n} (c : ℚ) (f : Fin n → ℚ) →
sumFin (λ i → c * f i) ≡ c * sumFin f
sumFin-*ˡ {Nat.zero} c f = sym (*-zeroʳ c)
sumFin-*ˡ {Nat.suc n} c f = let open ≡-Reasoning in begin
c * f zero + sumFin (λ i → c * f (suc i))
≡⟨ cong (c * f zero +_) (sumFin-*ˡ c (f ∘ suc)) ⟩
c * f zero + c * sumFin (f ∘ suc)
≡⟨ sym (*-distribˡ-+ c (f zero) (sumFin (f ∘ suc))) ⟩
c * (f zero + sumFin (f ∘ suc)) ∎
sumFin-comm : ∀ {m p} (a : Fin m → Fin p → ℚ) →
sumFin (λ i → sumFin (λ k → a i k)) ≡
sumFin (λ k → sumFin (λ i → a i k))
sumFin-comm {Nat.zero} {p} a = sym (sumFin-zero p)
sumFin-comm {Nat.suc m} {p} a = let open ≡-Reasoning in begin
sumFin (a zero) + sumFin (λ i → sumFin (λ k → a (suc i) k))
≡⟨ cong (sumFin (a zero) +_) (sumFin-comm (a ∘ suc)) ⟩
sumFin (a zero) +
sumFin (λ k → sumFin (λ i → a (suc i) k))
≡⟨ sym (sumFin-+ (a zero) (λ k → sumFin (λ i → a (suc i) k))) ⟩
sumFin (λ k → a zero k + sumFin (λ i → a (suc i) k)) ∎
record Kernel (m n : ℕ) : Set where
field
cell : Fin m → Fin n → ℚ
totals : (j : Fin n) → sumFin (λ i → cell i j) ≡ 1ℚ
open Kernel
comp : ∀ {m p n} → Kernel p n → Kernel m p → Kernel m n
comp {m} {p} {n} V U = record
{ cell = λ i j → sumFin (λ k → cell U i k * cell V k j)
; totals = totals-comp
}
where
open ≡-Reasoning
inner : ∀ (j : Fin n) (k : Fin p) →
sumFin (λ i → cell U i k * cell V k j) ≡ cell V k j
inner j k = begin
sumFin (λ i → cell U i k * cell V k j)
≡⟨ sumFin-cong (λ i → *-comm (cell U i k) (cell V k j)) ⟩
sumFin (λ i → cell V k j * cell U i k)
≡⟨ sumFin-*ˡ (cell V k j) (λ i → cell U i k) ⟩
cell V k j * sumFin (λ i → cell U i k)
≡⟨ cong (cell V k j *_) (totals U k) ⟩
cell V k j * 1ℚ
≡⟨ *-identityʳ (cell V k j) ⟩
cell V k j ∎
totals-comp : ∀ (j : Fin n) →
sumFin (λ i → sumFin
(λ k → cell U i k * cell V k j)) ≡ 1ℚ
totals-comp j = begin
sumFin (λ i → sumFin (λ k → cell U i k * cell V k j))
≡⟨ sumFin-comm (λ i k → cell U i k * cell V k j) ⟩
sumFin (λ k → sumFin (λ i → cell U i k * cell V k j))
≡⟨ sumFin-cong (inner j) ⟩
sumFin (λ k → cell V k j)
≡⟨ totals V j ⟩
1ℚ ∎