open import Algebra.DecidableField
module MatrixFuncNormalization.ElimZeros.Base {c ℓ₁ ℓ₂} (dField : DecidableField c ℓ₁ ℓ₂) where
open import Algebra
open import Function
open import Data.Product
open import Data.Fin as F using (Fin; zero; suc; toℕ)
open import Data.Maybe as Maybe
open import Data.Bool using (Bool; false; true; T)
open import Data.Nat using (ℕ)
open import Data.Vec.Functional as V
open import Relation.Nullary
open import Relation.Nullary.Construct.Add.Supremum
open import Vector
open import Algebra.Matrix
open import Algebra.MatrixData renaming (Matrix to MatrixData)
open import MatrixFuncNormalization.normBef dField using (findNonZeroPos)
open import MatrixFuncNormalization.NormAfter.Base dField
open DecidableField dField renaming (Carrier to F; heytingField to hField)
private variable
m n : ℕ
is≠0 : F → Bool
is≠0 x = does $ x ≟ 0#
divideVec : Op₁ $ Vector F n
divideVec {n = n} xs = fromMaybe xs (Maybe.map (λ (_ , inv) i → inv * xs i) (findFirstWithProp xs fMaybe))
where
fMaybe : (x : F) → Maybe F
fMaybe x = Maybe.map (proj₁ ∘ #⇒invertible) (dec⇒maybe $ x ≟ 0#)
divideByCoeff : Op₁ $ Matrix F n m
divideByCoeff = V.map divideVec
normalizeAndDivide : Op₁ $ Matrix F n m
normalizeAndDivide = divideByCoeff ∘ normalize
func⇒op₁⇒data : Op₁ $ Matrix F n m → Op₁ $ MatrixData F n m
func⇒op₁⇒data f = matrixFunc→Data ∘ f ∘ matrixData→Fun
normalizeData : Op₁ $ MatrixData F n m
normalizeData = func⇒op₁⇒data normalize
normalizeAndDivideData : Op₁ $ MatrixData F n m
normalizeAndDivideData = func⇒op₁⇒data normalizeAndDivide
findZeroEnd : ∀ (pivs : Vector (Fin m ⁺) n) → Fin $ ℕ.suc n
findZeroEnd {n = ℕ.zero} pivs = F.zero
findZeroEnd {n = ℕ.suc n} pivs with pivs F.zero
... | just _ = F.zero
... | ⊥₋ = F.suc $ findZeroEnd (tail pivs)
eliminateZerosEnd : ∀ (xs : Matrix F n m) (pivs : Vector (Fin m ⁺) n) → Matrix F (toℕ (findZeroEnd pivs)) m
eliminateZerosEnd xs _ = xs ∘ F.inject!
normalizeAndEliminateZeros : (xs : Matrix F n m) → Σ[ n ∈ ℕ ] (Matrix F n m)
normalizeAndEliminateZeros xs = _ , eliminateZerosEnd (normalizeAndDivide xs) (V.map findNonZeroPos xs)