Skip to content

Commit

Permalink
feat(linear_algebra/finsupp): span.repr gives an arbitrarily repres…
Browse files Browse the repository at this point in the history
…entation of `x : span R w` as a linear combination over `w` (#8339)

It's convenient to be able to get hold of such a representation, even when it is not unique. We prove the only lemma about this, then mark the definition is irreducible.



Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
  • Loading branch information
semorrison and semorrison committed Jul 19, 2021
1 parent 02ecb62 commit ad7ab8d
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 4 deletions.
8 changes: 7 additions & 1 deletion src/data/equiv/basic.lean
Expand Up @@ -1772,11 +1772,17 @@ noncomputable def of_injective {α β} (f : α → β) (hf : injective f) : α
equiv.of_left_inverse f
(λ h, by exactI function.inv_fun f) (λ h, by exactI function.left_inverse_inv_fun hf)


theorem apply_of_injective_symm {α β} (f : α → β) (hf : injective f) (b : set.range f) :
f ((of_injective f hf).symm b) = b :=
subtype.ext_iff.1 $ (of_injective f hf).apply_symm_apply b

@[simp] theorem of_injective_symm_apply {α β} (f : α → β) (hf : injective f) (a : α) :
(of_injective f hf).symm ⟨f a, ⟨a, rfl⟩⟩ = a :=
begin
apply (of_injective f hf).injective,
simp [apply_of_injective_symm f hf],
end

@[simp] lemma self_comp_of_injective_symm {α β} (f : α → β) (hf : injective f) :
f ∘ ((of_injective f hf).symm) = coe :=
funext (λ x, apply_of_injective_symm f hf x)
Expand Down
24 changes: 23 additions & 1 deletion src/linear_algebra/finsupp.lean
Expand Up @@ -473,7 +473,7 @@ theorem lmap_domain_total (f : α → α') (g : M →ₗ[R] M') (h : ∀ i, g (v
(finsupp.total α' M' R v').comp (lmap_domain R R f) = g.comp (finsupp.total α M R v) :=
by ext l; simp [total_apply, finsupp.sum_map_domain_index, add_smul, h]

theorem total_emb_domain (f : α ↪ α') (l : α →₀ R) :
@[simp] theorem total_emb_domain (f : α ↪ α') (l : α →₀ R) :
(finsupp.total α' M' R v') (emb_domain f l) = (finsupp.total α M' R (v' ∘ f)) l :=
by simp [total_apply, finsupp.sum, support_emb_domain, emb_domain_apply]

Expand All @@ -487,6 +487,10 @@ begin
apply total_emb_domain R ⟨f, hf⟩ l
end

@[simp] theorem total_equiv_map_domain (f : α ≃ α') (l : α →₀ R) :
(finsupp.total α' M' R v') (equiv_map_domain f l) = (finsupp.total α M' R (v' ∘ f)) l :=
by rw [equiv_map_domain_eq_map_domain, total_map_domain _ _ f.injective]

/-- A version of `finsupp.range_total` which is useful for going in the other direction -/
theorem span_eq_range_total (s : set M) :
span R s = (finsupp.total s M R coe).range :=
Expand Down Expand Up @@ -786,6 +790,24 @@ end finsupp
variables {R : Type*} {M : Type*} {N : Type*}
variables [semiring R] [add_comm_monoid M] [module R M] [add_comm_monoid N] [module R N]

section
variables (R)
/--
Pick some representation of `x : span R w` as a linear combination in `w`,
using the axiom of choice.
-/
def span.repr (w : set M) (x : span R w) :
w →₀ R :=
((finsupp.mem_span_iff_total _ _ _).mp x.2).some

@[simp] lemma span.finsupp_total_repr {w : set M} (x : span R w) :
finsupp.total w M R coe (span.repr R w x) = x :=
((finsupp.mem_span_iff_total _ _ _).mp x.2).some_spec

attribute [irreducible] span.repr

end

lemma submodule.finsupp_sum_mem {ι β : Type*} [has_zero β] (S : submodule R M) (f : ι →₀ β)
(g : ι → β → M) (h : ∀ c, f c ≠ 0 → g c (f c) ∈ S) : f.sum g ∈ S :=
S.to_add_submonoid.finsupp_sum_mem f g h
Expand Down
16 changes: 14 additions & 2 deletions src/linear_algebra/linear_independent.lean
Expand Up @@ -585,7 +585,7 @@ variables (hv : linear_independent R v)

/-- Canonical isomorphism between linear combinations and the span of linearly independent vectors.
-/
def linear_independent.total_equiv (hv : linear_independent R v) :
@[simps] def linear_independent.total_equiv (hv : linear_independent R v) :
(ι →₀ R) ≃ₗ[R] span R (range v) :=
begin
apply linear_equiv.of_bijective
Expand All @@ -610,7 +610,7 @@ It is simply one direction of `linear_independent.total_equiv`. -/
def linear_independent.repr (hv : linear_independent R v) :
span R (range v) →ₗ[R] ι →₀ R := hv.total_equiv.symm

lemma linear_independent.total_repr (x) : finsupp.total ι M R v (hv.repr x) = x :=
@[simp] lemma linear_independent.total_repr (x) : finsupp.total ι M R v (hv.repr x) = x :=
subtype.ext_iff.1 (linear_equiv.apply_symm_apply hv.total_equiv x)

lemma linear_independent.total_comp_repr :
Expand Down Expand Up @@ -644,6 +644,18 @@ begin
simp [finsupp.total_single, hx]
end

lemma linear_independent.span_repr_eq [nontrivial R] (x) :
span.repr R (set.range v) x = (hv.repr x).equiv_map_domain (equiv.of_injective _ hv.injective) :=
begin
have p : (span.repr R (set.range v) x).equiv_map_domain (equiv.of_injective _ hv.injective).symm =
hv.repr x,
{ apply (linear_independent.total_equiv hv).injective,
ext,
simp, },
ext ⟨_, ⟨i, rfl⟩⟩,
simp [←p],
end

-- TODO: why is this so slow?
lemma linear_independent_iff_not_smul_mem_span :
linear_independent R v ↔ (∀ (i : ι) (a : R), a • (v i) ∈ span R (v '' (univ \ {i})) → a = 0) :=
Expand Down

0 comments on commit ad7ab8d

Please sign in to comment.