Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 017acae

Browse files
committed
feat(linear_algebra/dual): adds dual annihilators (#6078)
1 parent 7c267df commit 017acae

File tree

3 files changed

+194
-1
lines changed

3 files changed

+194
-1
lines changed

src/linear_algebra/basic.lean

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,16 @@ def applyₗ : M →ₗ[R] (M →ₗ[R] M₂) →ₗ[R] M₂ :=
390390
map_smul' := λ x y, linear_map.ext $ λ f, f.map_smul _ _,
391391
..applyₗ' R }
392392

393+
/-- Alternative version of `dom_restrict` as a linear map. -/
394+
def dom_restrict'
395+
(p : submodule R M) : (M →ₗ[R] M₂) →ₗ[R] (p →ₗ[R] M₂) :=
396+
{ to_fun := λ φ, φ.dom_restrict p,
397+
map_add' := by simp [linear_map.ext_iff],
398+
map_smul' := by simp [linear_map.ext_iff] }
399+
400+
@[simp] lemma dom_restrict'_apply (f : M →ₗ[R] M₂) (p : submodule R M) (x : p) :
401+
dom_restrict' p f x = f x := rfl
402+
393403
end comm_semiring
394404

395405
section semiring
@@ -2239,6 +2249,12 @@ noncomputable def quot_ker_equiv_range : f.ker.quotient ≃ₗ[R] f.range :=
22392249
submodule.ker_liftq_eq_bot _ _ _ (le_refl f.ker)).trans
22402250
(linear_equiv.of_eq _ _ $ submodule.range_liftq _ _ _)
22412251

2252+
/-- The first isomorphism theorem for surjective linear maps. -/
2253+
noncomputable def quot_ker_equiv_of_surjective
2254+
(f : M →ₗ[R] M₂) (hf : function.surjective f) : f.ker.quotient ≃ₗ[R] M₂ :=
2255+
f.quot_ker_equiv_range.trans
2256+
(linear_equiv.of_top f.range (linear_map.range_eq_top.2 hf))
2257+
22422258
@[simp] lemma quot_ker_equiv_range_apply_mk (x : M) :
22432259
(f.quot_ker_equiv_range (submodule.quotient.mk x) : M₂) = f x :=
22442260
rfl

src/linear_algebra/dual.lean

Lines changed: 156 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Johan Commelin, Fabian Glöckle
55
-/
66
import linear_algebra.finite_dimensional
7-
import tactic.apply_fun
7+
import linear_algebra.projection
8+
89
noncomputable theory
910

1011
/-!
@@ -18,12 +19,14 @@ The dual space of an R-module M is the R-module of linear maps `M → R`.
1819
* Given a basis for a K-vector space `V`, `is_basis.to_dual` produces a map from `V` to `dual K V`.
1920
* Given families of vectors `e` and `ε`, `dual_pair e ε` states that these families have the
2021
characteristic properties of a basis and a dual.
22+
* `dual_annihilator W` is the submodule of `dual R M` where every element annihilates `W`.
2123
2224
## Main results
2325
2426
* `to_dual_equiv` : the dual space is linearly equivalent to the primal space.
2527
* `dual_pair.is_basis` and `dual_pair.eq_dual`: if `e` and `ε` form a dual pair, `e` is a basis and
2628
`ε` is its dual basis.
29+
* `quot_equiv_annihilator`: the quotient by a subspace is isomorphic to its dual annihilator.
2730
2831
## Notation
2932
@@ -32,6 +35,7 @@ We sometimes use `V'` as local notation for `dual K V`.
3235
-/
3336

3437
namespace module
38+
3539
variables (R : Type*) (M : Type*)
3640
variables [comm_ring R] [add_comm_group M] [module R M]
3741

@@ -69,12 +73,16 @@ lemma transpose_comp (u : M' →ₗ[R] M'') (v : M →ₗ[R] M') :
6973
transpose (u.comp v) = (transpose v).comp (transpose u) := rfl
7074

7175
end dual
76+
7277
end module
7378

7479
namespace is_basis
80+
7581
universes u v w
82+
7683
variables {K : Type u} {V : Type v} {ι : Type w}
7784
variables [field K] [add_comm_group V] [vector_space K V]
85+
7886
open vector_space module module.dual submodule linear_map cardinal function
7987

8088
variables [de : decidable_eq ι]
@@ -296,6 +304,7 @@ section dual_pair
296304
open vector_space module module.dual linear_map function
297305

298306
universes u v w
307+
299308
variables {K : Type u} {V : Type v} {ι : Type w} [decidable_eq ι]
300309
variables [field K] [add_comm_group V] [vector_space K V]
301310

@@ -398,3 +407,149 @@ begin
398407
end
399408

400409
end dual_pair
410+
411+
namespace submodule
412+
413+
universes u v w
414+
415+
variables {R : Type u} {M : Type v} [comm_ring R] [add_comm_group M] [module R M]
416+
variable {W : submodule R M}
417+
418+
/-- The `dual_restrict` of a submodule `W` of `M` is the linear map from the
419+
dual of `M` to the dual of `W` such that the domain of each linear map is
420+
restricted to `W`. -/
421+
def dual_restrict (W : submodule R M) :
422+
module.dual R M →ₗ[R] module.dual R W :=
423+
linear_map.dom_restrict' W
424+
425+
@[simp] lemma dual_restrict_apply
426+
(W : submodule R M) (φ : module.dual R M) (x : W) :
427+
W.dual_restrict φ x = φ (x : M) := rfl
428+
429+
/-- The `dual_annihilator` of a submodule `W` is the set of linear maps `φ` such
430+
that `φ w = 0` for all `w ∈ W`. -/
431+
def dual_annihilator {R : Type u} {M : Type v} [comm_ring R] [add_comm_group M]
432+
[module R M] (W : submodule R M) : submodule R $ module.dual R M :=
433+
W.dual_restrict.ker
434+
435+
@[simp] lemma mem_dual_annihilator (φ : module.dual R M) :
436+
φ ∈ W.dual_annihilator ↔ ∀ w ∈ W, φ w = 0 :=
437+
begin
438+
refine linear_map.mem_ker.trans _,
439+
simp_rw [linear_map.ext_iff, dual_restrict_apply],
440+
exact ⟨λ h w hw, h ⟨w, hw⟩, λ h w, h w.1 w.2
441+
end
442+
443+
lemma dual_restrict_ker_eq_dual_annihilator (W : submodule R M) :
444+
W.dual_restrict.ker = W.dual_annihilator :=
445+
rfl
446+
447+
end submodule
448+
449+
namespace subspace
450+
451+
open submodule linear_map
452+
453+
universes u v w
454+
455+
-- We work in vector spaces because `exists_is_compl` only hold for vector spaces
456+
variables {K : Type u} {V : Type v} [field K] [add_comm_group V] [vector_space K V]
457+
458+
/-- Given a subspace `W` of `V` and an element of its dual `φ`, `dual_lift W φ` is
459+
the natural extension of `φ` to an element of the dual of `V`.
460+
That is, `dual_lift W φ` sends `w ∈ W` to `φ x` and `x` in the complement of `W` to `0`. -/
461+
noncomputable def dual_lift (W : subspace K V) :
462+
module.dual K W →ₗ[K] module.dual K V :=
463+
let h := classical.indefinite_description _ W.exists_is_compl in
464+
(linear_map.of_is_compl_prod h.2).comp (linear_map.inl _ _ _)
465+
466+
variable {W : subspace K V}
467+
468+
@[simp] lemma dual_lift_of_subtype {φ : module.dual K W} (w : W) :
469+
W.dual_lift φ (w : V) = φ w :=
470+
by { erw of_is_compl_left_apply _ w, refl }
471+
472+
lemma dual_lift_of_mem {φ : module.dual K W} {w : V} (hw : w ∈ W) :
473+
W.dual_lift φ w = φ ⟨w, hw⟩ :=
474+
dual_lift_of_subtype ⟨w, hw⟩
475+
476+
@[simp] lemma dual_restrict_comp_dual_lift (W : subspace K V) :
477+
W.dual_restrict.comp W.dual_lift = 1 :=
478+
by { ext φ x, simp }
479+
480+
lemma dual_restrict_left_inverse (W : subspace K V) :
481+
function.left_inverse W.dual_restrict W.dual_lift :=
482+
λ x, show W.dual_restrict.comp W.dual_lift x = x,
483+
by { rw [dual_restrict_comp_dual_lift], refl }
484+
485+
lemma dual_lift_right_inverse (W : subspace K V) :
486+
function.right_inverse W.dual_lift W.dual_restrict :=
487+
W.dual_restrict_left_inverse
488+
489+
lemma dual_restrict_surjective :
490+
function.surjective W.dual_restrict :=
491+
W.dual_lift_right_inverse.surjective
492+
493+
lemma dual_lift_injective : function.injective W.dual_lift :=
494+
W.dual_restrict_left_inverse.injective
495+
496+
/-- The quotient by the `dual_annihilator` of a subspace is isomorphic to the
497+
dual of that subspace. -/
498+
noncomputable def quot_annihilator_equiv (W : subspace K V) :
499+
W.dual_annihilator.quotient ≃ₗ[K] module.dual K W :=
500+
(quot_equiv_of_eq _ _ W.dual_restrict_ker_eq_dual_annihilator).symm.trans $
501+
W.dual_restrict.quot_ker_equiv_of_surjective dual_restrict_surjective
502+
503+
/-- The natural isomorphism forom the dual of a subspace `W` to `W.dual_lift.range`. -/
504+
noncomputable def dual_equiv_dual (W : subspace K V) :
505+
module.dual K W ≃ₗ[K] W.dual_lift.range :=
506+
linear_equiv.of_injective _ $ ker_eq_bot.2 dual_lift_injective
507+
508+
lemma dual_equiv_dual_def (W : subspace K V) :
509+
W.dual_equiv_dual.to_linear_map = W.dual_lift.range_restrict := rfl
510+
511+
@[simp] lemma dual_equiv_dual_apply (φ : module.dual K W) :
512+
W.dual_equiv_dual φ = ⟨W.dual_lift φ, mem_range.2 ⟨φ, rfl⟩⟩ := rfl
513+
514+
section
515+
516+
open_locale classical
517+
518+
open finite_dimensional
519+
520+
variables {V₁ : Type*} [add_comm_group V₁] [vector_space K V₁]
521+
522+
instance [H : finite_dimensional K V] : finite_dimensional K (module.dual K V) :=
523+
begin
524+
refine @linear_equiv.finite_dimensional _ _ _ _ _ _ _ _ _ H,
525+
have hB := classical.some_spec (exists_is_basis_finite K V),
526+
haveI := classical.choice hB.2,
527+
exact is_basis.to_dual_equiv _ hB.1
528+
end
529+
530+
variables [finite_dimensional K V] [finite_dimensional K V₁]
531+
532+
/-- The quotient by the dual is isomorphic to its dual annihilator. -/
533+
noncomputable def quot_dual_equiv_annihilator (W : subspace K V) :
534+
W.dual_lift.range.quotient ≃ₗ[K] W.dual_annihilator :=
535+
linear_equiv.quot_equiv_of_quot_equiv $
536+
linear_equiv.trans W.quot_annihilator_equiv W.dual_equiv_dual
537+
538+
/-- The quotient by a subspace is isomorphic to its dual annihilator. -/
539+
noncomputable def quot_equiv_annihilator (W : subspace K V) :
540+
W.quotient ≃ₗ[K] W.dual_annihilator :=
541+
begin
542+
refine linear_equiv.trans _ W.quot_dual_equiv_annihilator,
543+
refine linear_equiv.quot_equiv_of_equiv _ _,
544+
{ refine linear_equiv.trans _ W.dual_equiv_dual,
545+
have hB := classical.some_spec (exists_is_basis_finite K W),
546+
haveI := classical.choice hB.2,
547+
exact is_basis.to_dual_equiv _ hB.1 },
548+
{ have hB := classical.some_spec (exists_is_basis_finite K V),
549+
haveI := classical.choice hB.2,
550+
exact is_basis.to_dual_equiv _ hB.1 },
551+
end
552+
553+
end
554+
555+
end subspace

src/linear_algebra/finite_dimensional.lean

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,28 @@ lemma eq_of_le_of_findim_eq {S₁ S₂ : submodule K V} [finite_dimensional K S
715715
(hd : findim K S₁ = findim K S₂) : S₁ = S₂ :=
716716
eq_of_le_of_findim_le hle hd.ge
717717

718+
variables [finite_dimensional K V] [finite_dimensional K V₂]
719+
720+
/-- Given isomorphic subspaces `p q` of vector spaces `V` and `V₁` respectively,
721+
`p.quotient` is isomorphic to `q.quotient`. -/
722+
noncomputable def linear_equiv.quot_equiv_of_equiv
723+
{p : subspace K V} {q : subspace K V₂}
724+
(f₁ : p ≃ₗ[K] q) (f₂ : V ≃ₗ[K] V₂) : p.quotient ≃ₗ[K] q.quotient :=
725+
linear_equiv.of_findim_eq _ _
726+
begin
727+
rw [← @add_right_cancel_iff _ _ (findim K p), submodule.findim_quotient_add_findim,
728+
linear_equiv.findim_eq f₁, submodule.findim_quotient_add_findim, linear_equiv.findim_eq f₂],
729+
end
730+
731+
/-- Given the subspaces `p q`, if `p.quotient ≃ₗ[K] q`, then `q.quotient ≃ₗ[K] p` -/
732+
noncomputable def linear_equiv.quot_equiv_of_quot_equiv
733+
{p q : subspace K V} (f : p.quotient ≃ₗ[K] q) : q.quotient ≃ₗ[K] p :=
734+
linear_equiv.of_findim_eq _ _
735+
begin
736+
rw [← @add_right_cancel_iff _ _ (findim K q), submodule.findim_quotient_add_findim,
737+
← linear_equiv.findim_eq f, add_comm, submodule.findim_quotient_add_findim]
738+
end
739+
718740
end finite_dimensional
719741

720742
namespace linear_map

0 commit comments

Comments
 (0)