Try doing some basic maths questions in the Lean Theorem Prover. Functions, real numbers, equivalence relations and groups. Click on README.md and then on "Open in CoCalc with one click".
License: APACHE
/-
Copyright (c) 2019 SΓ©bastien GouΓ«zel. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: SΓ©bastien GouΓ«zel
-/
import analysis.normed_space.operator_norm linear_algebra.finite_dimensional tactic.omega
/-!
# Finite dimensional normed spaces over complete fields
Over a complete nondiscrete field, in finite dimension, all norms are equivalent and all linear maps
are continuous. Moreover, a finite-dimensional subspace is always complete and closed.
## Main results:
* `linear_map.continuous_of_finite_dimensional` : a linear map on a finite-dimensional space over a
complete field is continuous.
* `finite_dimensional.complete` : a finite-dimensional space over a complete field is complete. This
is not registered as an instance, as the field would be an unknown metavariable in typeclass
resolution.
* `submodule.closed_of_finite_dimensional` : a finite-dimensional subspace over a complete field is
closed
* `finite_dimensional.proper` : a finite-dimensional space over a proper field is proper. This
is not registered as an instance, as the field would be an unknown metavariable in typeclass
resolution. It is however registered as an instance for `π = β` and `π = β`. As properness
implies completeness, there is no need to also register `finite_dimensional.complete` on `β` or
`β`.
## Implementation notes
The fact that all norms are equivalent is not written explicitly, as it would mean having two norms
on a single space, which is not the way type classes work. However, if one has a
finite-dimensional vector space `E` with a norm, and a copy `E'` of this type with another norm,
then the identities from `E` to `E'` and from `E'`to `E` are continuous thanks to
`linear_map.continuous_of_finite_dimensional`. This gives the desired norm equivalence.
-/
universes u v w x
open set finite_dimensional
open_locale classical
-- To get a reasonable compile time for `continuous_equiv_fun_basis`, typeclass inference needs
-- to be guided.
local attribute [instance, priority 10000] pi.module normed_space.to_module
submodule.add_comm_group submodule.module
linear_map.finite_dimensional_range Pi.complete nondiscrete_normed_field.to_normed_field
set_option class.instance_max_depth 100
/-- A linear map on `ΞΉ β π` (where `ΞΉ` is a fintype) is continuous -/
lemma linear_map.continuous_on_pi {ΞΉ : Type w} [fintype ΞΉ] {π : Type u} [normed_field π]
{E : Type v} [add_comm_group E] [vector_space π E] [topological_space E]
[topological_add_group E] [topological_vector_space π E] (f : (ΞΉ β π) ββ[π] E) : continuous f :=
begin
-- for the proof, write `f` in the standard basis, and use that each coordinate is a continuous
-- function.
have : (f : (ΞΉ β π) β E) =
(Ξ»x, finset.sum finset.univ (Ξ»i:ΞΉ, x i β’ (f (Ξ»j, if i = j then 1 else 0)))),
by { ext x, exact f.pi_apply_eq_sum_univ x },
rw this,
refine continuous_finset_sum _ (Ξ»i hi, _),
exact (continuous_apply i).smul continuous_const
end
section complete_field
variables {π : Type u} [nondiscrete_normed_field π]
{E : Type v} [normed_group E] [normed_space π E]
{F : Type w} [normed_group F] [normed_space π F]
{F' : Type x} [add_comm_group F'] [vector_space π F'] [topological_space F']
[topological_add_group F'] [topological_vector_space π F']
[complete_space π]
set_option class.instance_max_depth 150
/-- In finite dimension over a complete field, the canonical identification (in terms of a basis)
with `π^n` together with its sup norm is continuous. This is the nontrivial part in the fact that
all norms are equivalent in finite dimension.
Do not use this statement as its formulation is awkward (in terms of the dimension `n`, as the proof
is done by induction over `n`) and it is superceded by the fact that every linear map on a
finite-dimensional space is continuous, in `linear_map.continuous_of_finite_dimensional`. -/
lemma continuous_equiv_fun_basis {n : β} {ΞΉ : Type v} [fintype ΞΉ] (ΞΎ : ΞΉ β E)
(hn : fintype.card ΞΉ = n) (hΞΎ : is_basis π ΞΎ) : continuous (equiv_fun_basis hΞΎ) :=
begin
unfreezeI,
induction n with n IH generalizing ΞΉ E,
{ apply linear_map.continuous_of_bound _ 0 (Ξ»x, _),
have : equiv_fun_basis hΞΎ x = 0,
by { ext i, exact (fintype.card_eq_zero_iff.1 hn i).elim },
change β₯equiv_fun_basis hΞΎ xβ₯ β€ 0 * β₯xβ₯,
rw this,
simp [norm_nonneg] },
{ haveI : finite_dimensional π E := of_finite_basis hΞΎ,
-- first step: thanks to the inductive assumption, any n-dimensional subspace is equivalent
-- to a standard space of dimension n, hence it is complete and therefore closed.
have Hβ : βs : submodule π E, findim π s = n β is_closed (s : set E),
{ assume s s_dim,
rcases exists_is_basis_finite π s with β¨b, b_basis, b_finiteβ©,
letI : fintype b := finite.fintype b_finite,
have U : uniform_embedding (equiv_fun_basis b_basis).symm,
{ have : fintype.card b = n,
by { rw β s_dim, exact (findim_eq_card_basis b_basis).symm },
have : continuous (equiv_fun_basis b_basis) := IH (subtype.val : b β s) this b_basis,
exact (equiv_fun_basis b_basis).symm.uniform_embedding (linear_map.continuous_on_pi _) this },
have : is_complete (range ((equiv_fun_basis b_basis).symm)),
{ rw [β image_univ, is_complete_image_iff U],
convert complete_univ,
change complete_space (b β π),
apply_instance },
have : is_complete (range (subtype.val : s β E)),
{ change is_complete (range ((equiv_fun_basis b_basis).symm.to_equiv)) at this,
rw equiv.range_eq_univ at this,
rwa [β image_univ, is_complete_image_iff],
exact isometry_subtype_val.uniform_embedding },
apply is_closed_of_is_complete,
rwa subtype.val_range at this },
-- second step: any linear form is continuous, as its kernel is closed by the first step
have Hβ : βf : E ββ[π] π, continuous f,
{ assume f,
have : findim π f.ker = n β¨ findim π f.ker = n.succ,
{ have Z := f.findim_range_add_findim_ker,
rw [findim_eq_card_basis hΞΎ, hn] at Z,
have : findim π f.range = 0 β¨ findim π f.range = 1,
{ have I : β(k : β), k β€ 1 β k = 0 β¨ k = 1, by omega manual,
have : findim π f.range β€ findim π π := submodule.findim_le _,
rwa [findim_of_field, I] at this },
cases this,
{ rw this at Z,
right,
simpa using Z },
{ left,
rw [this, add_comm, nat.add_one] at Z,
exact nat.succ_inj Z } },
have : is_closed (f.ker : set E),
{ cases this,
{ exact Hβ _ this },
{ have : f.ker = β€,
by { apply eq_top_of_findim_eq, rw [findim_eq_card_basis hΞΎ, hn, this] },
simp [this] } },
exact linear_map.continuous_iff_is_closed_ker.2 this },
-- third step: applying the continuity to the linear form corresponding to a coefficient in the
-- basis decomposition, deduce that all such coefficients are controlled in terms of the norm
have : βi:ΞΉ, βC, 0 β€ C β§ β(x:E), β₯equiv_fun_basis hΞΎ x iβ₯ β€ C * β₯xβ₯,
{ assume i,
let f : E ββ[π] π := (linear_map.proj i).comp (equiv_fun_basis hΞΎ),
let f' : E βL[π] π := { cont := Hβ f, ..f },
exact β¨β₯f'β₯, norm_nonneg _, Ξ»x, continuous_linear_map.le_op_norm f' xβ© },
-- fourth step: combine the bound on each coefficient to get a global bound and the continuity
choose C0 hC0 using this,
let C := finset.sum finset.univ C0,
have C_nonneg : 0 β€ C := finset.sum_nonneg (Ξ»i hi, (hC0 i).1),
have C0_le : βi, C0 i β€ C :=
Ξ»i, finset.single_le_sum (Ξ»j hj, (hC0 j).1) (finset.mem_univ _),
apply linear_map.continuous_of_bound _ C (Ξ»x, _),
rw pi_norm_le_iff,
{ exact Ξ»i, le_trans ((hC0 i).2 x) (mul_le_mul_of_nonneg_right (C0_le i) (norm_nonneg _)) },
{ exact mul_nonneg C_nonneg (norm_nonneg _) } }
end
/-- Any linear map on a finite dimensional space over a complete field is continuous. -/
theorem linear_map.continuous_of_finite_dimensional [finite_dimensional π E] (f : E ββ[π] F') :
continuous f :=
begin
-- for the proof, go to a model vector space `b β π` thanks to `continuous_equiv_fun_basis`, and
-- argue that all linear maps there are continuous.
rcases exists_is_basis_finite π E with β¨b, b_basis, b_finiteβ©,
letI : fintype b := finite.fintype b_finite,
have A : continuous (equiv_fun_basis b_basis) :=
continuous_equiv_fun_basis _ rfl b_basis,
have B : continuous (f.comp ((equiv_fun_basis b_basis).symm : (b β π) ββ[π] E)) :=
linear_map.continuous_on_pi _,
have : continuous ((f.comp ((equiv_fun_basis b_basis).symm : (b β π) ββ[π] E))
β (equiv_fun_basis b_basis)) := B.comp A,
convert this,
ext x,
simp only [linear_equiv.coe_apply, function.comp_app, coe_fn_coe_base, linear_map.comp_apply],
rw linear_equiv.symm_apply_apply
end
/-- The continuous linear map induced by a linear map on a finite dimensional space -/
def linear_map.to_continuous_linear_map [finite_dimensional π E] (f : E ββ[π] F') : E βL[π] F' :=
{ cont := f.continuous_of_finite_dimensional, ..f }
/-- The continuous linear equivalence induced by a linear equivalence on a finite dimensional space. -/
def linear_equiv.to_continuous_linear_equiv [finite_dimensional π E] (e : E ββ[π] F) : E βL[π] F :=
{ continuous_to_fun := e.to_linear_map.continuous_of_finite_dimensional,
continuous_inv_fun := begin
haveI : finite_dimensional π F := e.finite_dimensional,
exact e.symm.to_linear_map.continuous_of_finite_dimensional
end,
..e }
/-- Any finite-dimensional vector space over a complete field is complete.
We do not register this as an instance to avoid an instance loop when trying to prove the
completeness of `π`, and the search for `π` as an unknown metavariable. Declare the instance
explicitly when needed. -/
variables (π E)
lemma finite_dimensional.complete [finite_dimensional π E] : complete_space E :=
begin
rcases exists_is_basis_finite π E with β¨b, b_basis, b_finiteβ©,
letI : fintype b := finite.fintype b_finite,
have : uniform_embedding (equiv_fun_basis b_basis).symm :=
linear_equiv.uniform_embedding _ (linear_map.continuous_of_finite_dimensional _)
(linear_map.continuous_of_finite_dimensional _),
have : is_complete ((equiv_fun_basis b_basis).symm.to_equiv '' univ) :=
(is_complete_image_iff this).mpr complete_univ,
rw [image_univ, equiv.range_eq_univ] at this,
exact complete_space_of_is_complete_univ this
end
variables {π E}
/-- A finite-dimensional subspace is complete. -/
lemma submodule.complete_of_finite_dimensional (s : submodule π E) [finite_dimensional π s] :
is_complete (s : set E) :=
begin
haveI : complete_space s := finite_dimensional.complete π s,
have : is_complete (range (subtype.val : s β E)),
{ rw [β image_univ, is_complete_image_iff],
{ exact complete_univ },
{ exact isometry_subtype_val.uniform_embedding } },
rwa subtype.val_range at this
end
/-- A finite-dimensional subspace is closed. -/
lemma submodule.closed_of_finite_dimensional (s : submodule π E) [finite_dimensional π s] :
is_closed (s : set E) :=
is_closed_of_is_complete s.complete_of_finite_dimensional
end complete_field
section proper_field
variables (π : Type u) [nondiscrete_normed_field π]
(E : Type v) [normed_group E] [normed_space π E] [proper_space π]
/-- Any finite-dimensional vector space over a proper field is proper.
We do not register this as an instance to avoid an instance loop when trying to prove the
properness of `π`, and the search for `π` as an unknown metavariable. Declare the instance
explicitly when needed. -/
lemma finite_dimensional.proper [finite_dimensional π E] : proper_space E :=
begin
rcases exists_is_basis_finite π E with β¨b, b_basis, b_finiteβ©,
letI : fintype b := finite.fintype b_finite,
let e := equiv_fun_basis b_basis,
let f : E βL[π] (b β π) :=
{ cont := linear_map.continuous_of_finite_dimensional _, ..e.to_linear_map },
refine metric.proper_image_of_proper e.symm
(linear_map.continuous_of_finite_dimensional _) _ (β₯fβ₯) (Ξ»x y, _),
{ exact equiv.range_eq_univ e.symm.to_equiv },
{ have A : e (e.symm x) = x := linear_equiv.apply_symm_apply _ _,
have B : e (e.symm y) = y := linear_equiv.apply_symm_apply _ _,
conv_lhs { rw [β A, β B] },
change dist (f (e.symm x)) (f (e.symm y)) β€ β₯fβ₯ * dist (e.symm x) (e.symm y),
exact f.lipschitz _ _ }
end
end proper_field
/- Over the real numbers, we can register the previous statement as an instance as it will not
cause problems in instance resolution since the properness of `β` is already known. -/
instance finite_dimensional.proper_real
(E : Type u) [normed_group E] [normed_space β E] [finite_dimensional β E] : proper_space E :=
finite_dimensional.proper β E
attribute [instance, priority 900] finite_dimensional.proper_real