symgeoalg

symbolic geometric algebra calculations
git clone git://git.rr3.xyz/symgeoalg
Log | Files | Refs | README | LICENSE

commit 884f33c2c9174935dfa5e258bdba4accb40c7d10
parent 46dd895a67dabea8178d8849a2f7a76e3aed31be
Author: Robert Russell <robertrussell.72001@gmail.com>
Date:   Thu, 25 Jul 2024 23:13:33 -0700

Move stuff around; add cool repeatBasis function

Diffstat:
MMain.lean | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 80 insertions(+), 31 deletions(-)

diff --git a/Main.lean b/Main.lean @@ -53,14 +53,8 @@ def inv := @MulGroup.inv -- Convention: (∀a. div a 0 = 0) and (inv 0 = 0). class Field (F : Type) extends AddGroup F, MulGroup F -instance : Field Rat where - zero := 0 - add := Rat.add - sub := Rat.sub - one := 1 - mul := Rat.mul - div := Rat.div - +-- F is an outParam, because usually V will only be a vector space over one +-- field, and this allows us to leave F implicit in many cases. class VectorSpace (F : outParam Type) [Field F] (V : Type) [AddGroup V] where smul : F -> V -> V @@ -72,20 +66,6 @@ instance [Field F] [AddGroup V] [VectorSpace F V] : SMul F V where instance [Field F] : VectorSpace F F where smul := MulSemigroup.mul --- Given a type X and a vector space V over F, the type of functions X -> V is a --- vector space over F. -def FunctionSpace (X V : Type) : Type := X -> V -instance [AddGroup V] : AddGroup (FunctionSpace X V) where - zero := fun _ => 0 - add f g := fun x => f x + g x - sub f g := fun x => f x - g x -instance [Field F] [AddGroup V] [VectorSpace F V] : VectorSpace F (FunctionSpace X V) where - smul a f := fun x => a ⋅ f x - --- Function spaces with finite domain -abbrev NSpace (n : Nat) (V : Type) : Type := FunctionSpace (Fin n) V -def vec (coords : List V) : NSpace coords.length V := coords.get - -- We could define Coordinates V n = NSpace n F, but I think it's important to -- recognize the conceptual difference between these two types: Coordinates V n -- is necessarily a tuple of scalars, with no further inherent structure, @@ -96,24 +76,30 @@ def Coordinates [Field F] (V : Type) [AddGroup V] [VectorSpace F V] (n : Nat) : instance [Field F] [ToString F] [AddGroup V] [VectorSpace F V] : ToString (Coordinates V n) where toString coords := - let coordToString i acc := toString (coords i) :: acc - s!"({String.intercalate ", " $ Fin.foldr n coordToString []})" + match n with + | 1 => toString (coords 0) + | n => + let consCoordString i acc := toString (coords i) :: acc + s!"({String.intercalate ", " $ Fin.foldr n consCoordString []})" structure FiniteBasis [Field F] (V : Type) [AddGroup V] [VectorSpace F V] (n : Nat) where basis : Fin n -> V - coords : V -> Coordinates F n + coords : V -> Coordinates V n def FiniteBasis.vector [Field F] [AddGroup V] [VectorSpace F V] (b : FiniteBasis V n) (coords : Coordinates V n) : V := Fin.foldl n (fun acc i => acc + coords i ⋅ b.basis i) 0 +def fieldBasis [Field F] : FiniteBasis F 1 := + ⟨fun 0 => 1, fun a 0 => a⟩ + -- OrthoQuadraticForm V B is a quadratic form on V with respect to which the -- finite basis B is orthogonal. -structure OrthoQuadraticForm [Field F] (V : Type) [AddGroup V] [VectorSpace F V] (_ : FiniteBasis V n) where +structure OrthoQuadraticForm [Field F] [AddGroup V] [VectorSpace F V] (_ : FiniteBasis V n) where evalBasis : Fin n -> F def OrthoQuadraticForm.eval [Field F] [AddGroup V] [VectorSpace F V] - {b : FiniteBasis V n} (q : OrthoQuadraticForm V b) (v : V) : F := + {b : FiniteBasis V n} (q : OrthoQuadraticForm b) (v : V) : F := let vCoords := b.coords v -- q v = q (∑ vCoords i ⋅ b.basis i) -- = ∑ q (vCoords i ⋅ b.basis i) (orthogonality of b wrt q) @@ -123,6 +109,7 @@ def OrthoQuadraticForm.eval [Field F] [AddGroup V] [VectorSpace F V] --class Algebra (F : Type) [Field F] (A : Type) [AddGroup A] [MulMonoid A] extends VectorSpace F A +-- TODO: Rename to FiniteBasisSet? Usually "Blade" means something more general. structure Blade (n : Nat) : Type where bits : BitVec n @@ -143,19 +130,21 @@ instance : ToString (Blade n) where else "" -structure GeometricAlgebra (F : Type) [Field F] (n : Nat) (q : OrthoQuadraticForm F V n) : Type where +structure GeometricAlgebra [Field F] [AddGroup V] [VectorSpace F V] + {b : FiniteBasis V n} (q : OrthoQuadraticForm b) : Type where fn : FunctionSpace (Blade n) F -instance [Field F] {q : QuadraticForm F n} : AddGroup (GeometricAlgebra F n q) where +instance [Field F] [AddGroup V] [VectorSpace F V] {b : FiniteBasis V n} + {q : OrthoQuadraticForm b} : AddGroup (GeometricAlgebra q) where zero := ⟨0⟩ add u v := ⟨u.fn + v.fn⟩ sub u v := ⟨u.fn - v.fn⟩ -instance [Field F] {q : QuadraticForm F n} : VectorSpace F (GeometricAlgebra F n q) where +instance [Field F] [AddGroup V] [VectorSpace F V] {b : FiniteBasis V n} + {q : OrthoQuadraticForm b} : VectorSpace F (GeometricAlgebra q) where smul a v := ⟨a ⋅ v.fn⟩ -- TODO: Rename variables. - -- Given u,v : GeometricAlgebra F n and b : Blade n, the b-th component of the -- product u * v is a sum of 2^n terms, where each term is the product of the -- l-th component of u and the r-th component of v, for all l,r : Blade n that multiply to b (modulo a scalar). The type @@ -200,6 +189,66 @@ instance [Field F] [ToString F] {q : QuadraticForm F n} : ToString (GeometricAlg toString (v.fn b) ++ if b.bits != 0 then s!" * {toString b}" else "" String.intercalate " + " (termToString <$> Blade.enum n) +-------------------------------------------------------------------------------- + +-- TODO: Remaining instances for products. +instance [AddSemigroup A] [AddSemigroup B] : AddSemigroup (A × B) where + add x y := (x.1 + y.1, x.2 + y.2) +instance [AddMonoid A] [AddMonoid B] : AddMonoid (A × B) where + zero := (0, 0) +instance [AddGroup A] [AddGroup B] : AddGroup (A × B) where + sub x y := (x.1 - y.1, x.2 - y.2) + +instance : Field Rat where + zero := 0 + add := Rat.add + sub := Rat.sub + one := 1 + mul := Rat.mul + div := Rat.div + +-- Given a type X and a vector space V over F, the type of functions X -> V is a +-- vector space over F. +def FunctionSpace (X V : Type) : Type := X -> V +instance [AddGroup V] : AddGroup (FunctionSpace X V) where + zero := fun _ => 0 + add f g := fun x => f x + g x + sub f g := fun x => f x - g x +instance [Field F] [AddGroup V] [VectorSpace F V] : VectorSpace F (FunctionSpace X V) where + smul a f := fun x => a ⋅ f x + +-- Function spaces with finite domain +abbrev NSpace (n : Nat) (V : Type) : Type := FunctionSpace (Fin n) V + +def divmod (i : Fin (m * n)) : Fin m × Fin n := + let mul_gt_zero_imp_gt_zero {m n : Nat} : (m * n > 0) -> (m > 0) := by + intro + rw [<-Nat.zero_div n] + apply Nat.div_lt_of_lt_mul + rw [Nat.mul_comm] + assumption + have mn_gt_zero : m * n > 0 := Fin.pos i + have m_gt_zero : m > 0 := mul_gt_zero_imp_gt_zero mn_gt_zero + have nm_gt_zero : n * m > 0 := by rw [Nat.mul_comm]; exact mn_gt_zero + have n_gt_zero : n > 0 := mul_gt_zero_imp_gt_zero nm_gt_zero + let q := Fin.ofNat' (i.val / n) m_gt_zero + let r := Fin.ofNat' (i.val % n) n_gt_zero + (q, r) + +def repeatBasis [Field F] [AddGroup V] [VectorSpace F V] (b : FiniteBasis V m) + (n : Nat) : FiniteBasis (NSpace n V) (m * n) := + let basis i := + let ⟨iq, ir⟩ := divmod i + fun j => if j = ir then b.basis iq else 0 + let coords v i := + let ⟨iq, ir⟩ := divmod i + b.coords (v ir) iq + ⟨basis, coords⟩ + +def vec (coords : List V) : NSpace coords.length V := coords.get + +-------------------------------------------------------------------------------- + def main : IO Unit := let F : Type := Rat let n : Nat := 3