Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - feat LinearAlgebra.Basis: add basis.restrictScalars #3707

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 56 additions & 1 deletion Mathlib/LinearAlgebra/Basis.lean
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Johannes Hölzl, Mario Carneiro, Alexander Bentkamp

! This file was ported from Lean 3 source module linear_algebra.basis
! leanprover-community/mathlib commit 2f4cdce0c2f2f3b8cd58f05d556d03b468e1eb2e
! leanprover-community/mathlib commit 04cdee31e196e30f507e8e9eb2d06e02c9ff6310
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
Expand Down Expand Up @@ -1649,3 +1649,58 @@ theorem quotient_prod_linearEquiv (p : Submodule K V) : Nonempty (((V ⧸ p) ×
#align quotient_prod_linear_equiv quotient_prod_linearEquiv

end DivisionRing

section RestrictScalars

variable {S : Type _} [CommRing R] [Ring S] [Nontrivial S] [AddCommGroup M]

variable [Algebra R S] [Module S M] [Module R M]

variable [IsScalarTower R S M] [NoZeroSMulDivisors R S] (b : Basis ι S M)

variable (R)

open Submodule

set_option synthInstance.etaExperiment true in
/-- Let `b` be a `S`-basis of `M`. Let `R` be a CommRing such that `Algebra R S` has no zero smul
divisors, then the submodule of `M` spanned by `b` over `R` admits `b` as a `R`-basis. -/
noncomputable def Basis.restrictScalars : Basis ι R (span R (Set.range b)) :=
Basis.span (b.linearIndependent.restrict_scalars (smul_left_injective R one_ne_zero))
#align basis.restrict_scalars Basis.restrictScalars

@[simp]
theorem Basis.restrictScalars_apply (i : ι) : (b.restrictScalars R i : M) = b i := by
simp only [Basis.restrictScalars, Basis.span_apply]
#align basis.restrict_scalars_apply Basis.restrictScalars_apply

set_option synthInstance.etaExperiment true in
@[simp]
theorem Basis.restrictScalars_repr_apply (m : span R (Set.range b)) (i : ι) :
algebraMap R S ((b.restrictScalars R).repr m i) = b.repr m i := by
suffices
Finsupp.mapRange.linearMap (Algebra.linearMap R S) ∘ₗ (b.restrictScalars R).repr.toLinearMap =
((b.repr : M →ₗ[S] ι →₀ S).restrictScalars R).domRestrict _
by exact FunLike.congr_fun (LinearMap.congr_fun this m) i
refine Basis.ext (b.restrictScalars R) fun _ => ?_
simp only [LinearMap.coe_comp, LinearEquiv.coe_toLinearMap, Function.comp_apply, map_one,
Basis.repr_self, Finsupp.mapRange.linearMap_apply, Finsupp.mapRange_single,
Algebra.linearMap_apply, LinearMap.domRestrict_apply, LinearEquiv.coe_coe,
Basis.restrictScalars_apply, LinearMap.coe_restrictScalars]
#align basis.restrict_scalars_repr_apply Basis.restrictScalars_repr_apply

/-- Let `b` be a `S`-basis of `M`. Then `m : M` lies in the `R`-module spanned by `b` iff all the
coordinates of `m` on the basis `b` are in `R` (see `Basis.mem_span` for the case `R = S`). -/
theorem Basis.mem_span_iff_repr_mem (m : M) :
m ∈ span R (Set.range b) ↔ ∀ i, b.repr m i ∈ Set.range (algebraMap R S) := by
refine
⟨fun hm i => ⟨(b.restrictScalars R).repr ⟨m, hm⟩ i, b.restrictScalars_repr_apply R ⟨m, hm⟩ i⟩,
fun h => ?_⟩
rw [← b.total_repr m, Finsupp.total_apply S _]
refine sum_mem fun i _ => ?_
obtain ⟨_, h⟩ := h i
simp_rw [← h, algebraMap_smul]
exact smul_mem _ _ (subset_span (Set.mem_range_self i))
#align basis.mem_span_iff_repr_mem Basis.mem_span_iff_repr_mem

end RestrictScalars