diff --git a/Mathlib.lean b/Mathlib.lean index b6292c78b1ffa9..7a725463b2a9c3 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1855,6 +1855,7 @@ public import Mathlib.Analysis.Complex.ValueDistribution.LogCounting.Asymptotic public import Mathlib.Analysis.Complex.ValueDistribution.LogCounting.Basic public import Mathlib.Analysis.Complex.ValueDistribution.Proximity.Basic public import Mathlib.Analysis.ConstantSpeed +public import Mathlib.Analysis.ContDiffMulAction public import Mathlib.Analysis.Convex.AmpleSet public import Mathlib.Analysis.Convex.Approximation public import Mathlib.Analysis.Convex.Basic diff --git a/Mathlib/Analysis/ContDiffMulAction.lean b/Mathlib/Analysis/ContDiffMulAction.lean new file mode 100644 index 00000000000000..021d597d4c30e2 --- /dev/null +++ b/Mathlib/Analysis/ContDiffMulAction.lean @@ -0,0 +1,280 @@ +/- +Copyright (c) 2026 Archibald Browne. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Archibald Browne +-/ +module + + +public import Mathlib.Analysis.Calculus.ContDiff.Operations + +/-! +# Continuously differentiable monoid actions + +In this file we define the class `ContDiffSMul`. `ContDiffSMul π•œ M X n` holds if `M` acts on `X` and +the map `(c, x) ↦ c β€’ x` is `n` times continuously differentiable on `M Γ— X`. + +## Main definitions + +* `ContDiffSMul π•œ M X n` : typeclass saying that the map `(c, x) ↦ c β€’ x` is `n` times continuously + differentiable on `M Γ— X` + +## Main results + +`ContDiffSMul.of_retraction`, `ContinuousLinearEquiv.contDiffSMul` and `ContDiffSMul.comp` prove +results about pullbacks of continuously differentiable actions. `ContDiff.contdiff_smul` +provides dot-syntax for `ContDiffSMul`. Many of the results here are the continuously differentiable +analogues of the results in the module `Mathlib.Topology.Algebra.MulAction`. +-/ + +@[expose] public section + +open Topology Pointwise +open Filter + + +/-- The class `ContDiffVAdd π•œ M X n` says that the additive action `(+α΅₯) : M β†’ X β†’ X` +is `n` times continuously differentiable on `M Γ— X`. -/ +class ContDiffVAdd (π•œ M X : Type*) (n : WithTop β„•βˆž) [VAdd M X] [NormedAddCommGroup X] + [NontriviallyNormedField π•œ] [NormedAddCommGroup M] [NormedSpace π•œ M] + [NormedSpace π•œ X] : Prop where + /-- The additive action `(+α΅₯)` is continuous. -/ + contdiff_vadd : ContDiff π•œ n fun p : M Γ— X => p.1 +α΅₯ p.2 + + + +/-- The class `ContDiffSMul π•œ M X n` says that the scalar multiplication `(β€’) : M β†’ X β†’ X` is `n` +times continuously differentiable on `M Γ— X`. -/ +@[to_additive] +class ContDiffSMul (π•œ M X : Type*) (n : WithTop β„•βˆž) [SMul M X] [NormedAddCommGroup X] + [NontriviallyNormedField π•œ] [NormedAddCommGroup M] [NormedSpace π•œ M] + [NormedSpace π•œ X] : Prop where + /-- The scalar multiplication `(β€’)` is continuously differentiable. -/ + contdiff_smul : ContDiff π•œ n fun p : M Γ— X => p.1 β€’ p.2 + +export ContDiffSMul (contdiff_smul) + + + +export ContDiffVAdd (contdiff_vadd) + + +attribute [continuity, fun_prop] contdiff_smul contdiff_vadd + +@[to_additive] +-- Cannot be an instance: `π•œ` and `n` don't appear in the conclusion +theorem ContDiffSMul.toContinuousSMul (π•œ : Type*) {M X : Type*} (n : WithTop β„•βˆž) + [NontriviallyNormedField π•œ] [SMul M X] + [NormedAddCommGroup M] [NormedSpace π•œ M] + [NormedAddCommGroup X] [NormedSpace π•œ X] + [ContDiffSMul π•œ M X n] : ContinuousSMul M X where + continuous_smul := (contdiff_smul (π•œ := π•œ) (n := n)).continuous + +section Main + +variable {π•œ M X Y Ξ± : Type*} {n : WithTop β„•βˆž} [NontriviallyNormedField π•œ] + [NormedAddCommGroup M] [NormedSpace π•œ M] + [NormedAddCommGroup X] [NormedSpace π•œ X] + +theorem ContDiffSMul.of_le {m : WithTop β„•βˆž} [SMul M X] [ContDiffSMul π•œ M X n] (h : m ≀ n) : + ContDiffSMul π•œ M X m where + contdiff_smul := contdiff_smul.of_le h + + +section SMul + +variable [SMul M X] [ContDiffSMul π•œ M X n] + +@[to_additive] +lemma IsScalarTower.contdiffSMul {M : Type*} (N : Type*) {Ξ± : Type*} [Monoid N] [SMul M N] + [MulAction N Ξ±] [SMul M Ξ±] [IsScalarTower M N Ξ±] + [NormedAddCommGroup Ξ±] [NormedAddCommGroup M] [NormedAddCommGroup N] [NormedSpace π•œ M] + [NormedSpace π•œ N] [NormedSpace π•œ Ξ±] [ContDiffSMul π•œ M N n] + [ContDiffSMul π•œ N Ξ± n] : ContDiffSMul π•œ M Ξ± n where + contdiff_smul := by + suffices ContDiff π•œ n (fun p : M Γ— Ξ± ↦ (p.1 β€’ (1 : N)) β€’ p.2) by + simpa [smul_one_smul N] + have h1 : ContDiff π•œ n (fun p : M Γ— Ξ± ↦ p.1 β€’ (1 : N)) := + (ContDiffSMul.contdiff_smul (π•œ := π•œ) (M := M) (X := N) (n := n)).comp + (ContDiff.prodMk contDiff_fst contDiff_const) + exact (ContDiffSMul.contdiff_smul (π•œ := π•œ) (M := N) (X := Ξ±) (n := n)).comp + (ContDiff.prodMk h1 contDiff_snd) + +@[to_additive] +lemma MulOpposite.contDiff_op : ContDiff π•œ n (op : M β†’ Mᡐᡒᡖ) := + (MulOpposite.opContinuousLinearEquiv π•œ : M ≃L[π•œ] Mᡐᡒᡖ).contDiff + +lemma MulOpposite.contDiff_unop : ContDiff π•œ n (unop : Mᡐᡒᡖ β†’ M) := + (MulOpposite.opContinuousLinearEquiv π•œ : M ≃L[π•œ] Mᡐᡒᡖ).symm.contDiff + +@[to_additive] +instance ContDiffSMul.op [SMul Mᡐᡒᡖ X] [IsCentralScalar M X] : ContDiffSMul π•œ Mᡐᡒᡖ X n := + ⟨by + suffices ContDiff π•œ n fun p : M Γ— X => MulOpposite.op p.fst β€’ p.snd from + this.comp ((MulOpposite.contDiff_unop (n := n)).prodMap contDiff_id) + simpa only [op_smul_eq_smul] using (contdiff_smul : ContDiff π•œ n fun p : M Γ— X => _)⟩ + +@[to_additive] +instance MulOpposite.contDiffSMul : ContDiffSMul π•œ M Xᡐᡒᡖ n := + ⟨(MulOpposite.contDiff_op (n := n)).comp <| + contdiff_smul.comp <| contDiff_id.prodMap (MulOpposite.contDiff_unop (n := n))⟩ + +section Transfer + +variable {N Y : Type*} [NormedAddCommGroup N] [NormedSpace π•œ N] + [NormedAddCommGroup Y] [NormedSpace π•œ Y] + + +/-- Transfer `ContDiffSMul` along a `ContinuousLinearEquiv`. +Analogue of `Topology.IsInducing.continuousSMul` for the smooth setting. -/ +@[to_additive] +lemma ContinuousLinearEquiv.contDiffSMul [SMul N Y] {f : N β†’ M} + (g : Y ≃L[π•œ] X) (hf : ContDiff π•œ n f) + (hsmul : βˆ€ {c y}, g (c β€’ y) = f c β€’ g y) : + ContDiffSMul π•œ N Y n := ⟨by + set F := fun (p : N Γ— Y) => p.1 β€’ p.2 with hF + have hF' : F = (fun p ↦ g.symm (g (p.1 β€’ p.2))) := by + ext p; simp only [symm_apply_apply, hF] + simp_rw [hsmul] at hF' + rw [hF'] + exact g.symm.contDiff.comp + (contdiff_smul.comp (ContDiff.prodMk (hf.comp contDiff_fst) + (g.contDiff.comp contDiff_snd)))⟩ + +/-- Transfer `ContDiffSMul` via a retraction (continuous linear left inverse). +Analogue of `SMulMemClass.continuousSMul` for complemented subspaces. -/ +@[to_additive] +lemma ContDiffSMul.of_retraction [SMul M N] + (ΞΉ : N β†’L[π•œ] X) (Ο€ : X β†’L[π•œ] N) (hπι : βˆ€ x, Ο€ (ΞΉ x) = x) + (hsmul : βˆ€ (m : M) (x : N), ΞΉ (m β€’ x) = m β€’ ΞΉ x) : ContDiffSMul π•œ M N n := ⟨by + set F := fun (p : M Γ— N) => p.1 β€’ p.2 with hF + have hF' : F = fun p ↦ Ο€ (p.1 β€’ ΞΉ p.2) := by + ext p; rw [← hsmul p.1 p.2, hπι (p.1 β€’ p.2)] + rw [hF'] + exact Ο€.contDiff.comp (contdiff_smul.comp + (ContDiff.prodMk contDiff_fst (ΞΉ.contDiff.comp contDiff_snd)))⟩ + +/-- Transfer `ContDiffSMul` along a continuously differentiable map on the acting type. -/ +@[to_additive] +lemma ContDiffSMul.comp [SMul N X] {f : N β†’ M} + (hf : ContDiff π•œ n f) + (hsmul : βˆ€ (c : N) (x : X), c β€’ x = f c β€’ x) : + ContDiffSMul π•œ N X n := ⟨by + set F := fun p : N Γ— X => p.1 β€’ p.2 with hF + have : F = fun p => f p.1 β€’ p.2 := by + ext p; rw [← hsmul p.1 p.2] + simpa [this] using + contdiff_smul.comp (ContDiff.prodMk (hf.comp contDiff_fst) contDiff_snd)⟩ + +end Transfer + +variable {f : Y β†’ M} {g : Y β†’ X} {b : Y} {s : Set Y} [NormedAddCommGroup Y] [NormedSpace π•œ Y] + +@[to_additive] +theorem ContDiffWithinAt.contdiff_smul' + (hf : ContDiffWithinAt π•œ n f s b) (hg : ContDiffWithinAt π•œ n g s b) : + ContDiffWithinAt π•œ n (fun x => f x β€’ g x) s b := + ContDiffSMul.contdiff_smul.comp_contDiffWithinAt (ContDiffWithinAt.prodMk hf hg) + +@[to_additive] +theorem ContDiffAt.contdiff_smul (hf : ContDiffAt π•œ n f b) + (hg : ContDiffAt π•œ n g b) : + ContDiffAt π•œ n (fun x => f x β€’ g x) b := + ContDiffSMul.contdiff_smul.comp_contDiffAt _ (ContDiffAt.prodMk hf hg) + +@[to_additive] +theorem ContDiffOn.contdiff_smul (hf : ContDiffOn π•œ n f s) + (hg : ContDiffOn π•œ n g s) : + ContDiffOn π•œ n (fun x => f x β€’ g x) s := + fun x hx => (hf x hx).contdiff_smul' (hg x hx) + +@[to_additive] +theorem ContDiff.contdiff_smul (hf : ContDiff π•œ n f) (hg : ContDiff π•œ n g) : + ContDiff π•œ n (fun x => f x β€’ g x) := + ContDiffSMul.contdiff_smul.comp (ContDiff.prodMk hf hg) + +end SMul + +section Monoid + +variable [Monoid M] [MulAction M X] [ContDiffSMul π•œ M X n] + +theorem MulAction.contDiffSMul_compHom {N} [NormedAddCommGroup N] [NormedSpace π•œ N] + [Monoid N] {f : N β†’* M} (hf : ContDiff π•œ n f) : + letI := MulAction.compHom X f + ContDiffSMul π•œ N X n := by + letI := MulAction.compHom X f + exact ⟨(hf.comp contDiff_fst).contdiff_smul contDiff_snd⟩ + + +end Monoid + +section Normed + +variable {π•œ' : Type*} [NontriviallyNormedField π•œ'] [NormedAlgebra π•œ π•œ'] + +/-- Scalar multiplication by a normed field on a normed space is C^n. -/ +instance NormedSpace.contDiffSMul {F : Type*} [NormedAddCommGroup F] [NormedSpace π•œ F] + [Module π•œ' F] [IsBoundedSMul π•œ' F] [IsScalarTower π•œ π•œ' F] : + ContDiffSMul π•œ π•œ' F n where + contdiff_smul := contDiff_smul + + +/-- Multiplication in a normed algebra is C^n as a scalar action on itself. -/ +instance NormedAlgebra.contDiffSMul_self {A : Type*} [NormedRing A] [NormedAlgebra π•œ A] : + ContDiffSMul π•œ A A n where + contdiff_smul := contDiff_mul + +end Normed + +instance ContinuousLinearMap.contDiffSMul : + ContDiffSMul π•œ (M β†’L[π•œ] M) M n where + contdiff_smul := isBoundedBilinearMap_apply.contDiff + +variable [NormedAddCommGroup Y] [NormedSpace π•œ Y] + +instance Prod.contDiffSMul [SMul M X] [SMul M Y] [ContDiffSMul π•œ M X n] [ContDiffSMul π•œ M Y n] : + ContDiffSMul π•œ M (X Γ— Y) n where + contdiff_smul := by + suffices ContDiff π•œ n (fun p : M Γ— (X Γ— Y) => p.1 β€’ p.2) by + simpa only [Prod.smul_def] using this + refine ContDiff.prodMk ?_ ?_ + Β· exact ContDiff.contdiff_smul contDiff_fst (ContDiff.snd' contDiff_fst) + Β· exact ContDiff.contdiff_smul contDiff_fst (ContDiff.snd' contDiff_snd) + +instance {ΞΉ : Type*} [Fintype ΞΉ] {Ξ³ : ΞΉ β†’ Type*} [βˆ€ i, SMul M (Ξ³ i)] + [βˆ€ i, NormedAddCommGroup (Ξ³ i)] + [βˆ€ i, NormedSpace π•œ (Ξ³ i)] [βˆ€ i, ContDiffSMul π•œ M (Ξ³ i) n] : + ContDiffSMul π•œ M (βˆ€ i, Ξ³ i) n := + ⟨contDiff_pi.mpr fun i => by + simp only [Pi.smul_apply] + have hi : ContDiff π•œ n (fun x : M Γ— (βˆ€ i, Ξ³ i) => x.2 i) := + (ContinuousLinearMap.proj (R := π•œ) (ΞΉ := ΞΉ) (Ο† := Ξ³) i).contDiff.comp contDiff_snd + exact contDiff_fst.contdiff_smul hi⟩ + +end Main + +section Tendsto + +variable {π•œ M X Ξ± : Type*} + +@[to_additive] +theorem Filter.Tendsto.contdiff_smul (π•œ : Type*) [NontriviallyNormedField π•œ] + [NormedAddCommGroup M] [NormedSpace π•œ M] [NormedAddCommGroup X] [NormedSpace π•œ X] + [SMul M X] (n : WithTop β„•βˆž) [ContDiffSMul π•œ M X n] + {f : Ξ± β†’ M} {g : Ξ± β†’ X} {l : Filter Ξ±} {c : M} {a : X} + (hf : Tendsto f l (𝓝 c)) (hg : Tendsto g l (𝓝 a)) : + Tendsto (fun x => f x β€’ g x) l (𝓝 <| c β€’ a) := + (ContDiffSMul.contdiff_smul (π•œ := π•œ) (n := n) |>.continuous.tendsto _).comp + (hf.prodMk_nhds hg) + +@[to_additive] +theorem Filter.Tendsto.contdiff_smul_const (π•œ : Type*) [NontriviallyNormedField π•œ] + [NormedAddCommGroup M] [NormedSpace π•œ M] [NormedAddCommGroup X] [NormedSpace π•œ X] + [SMul M X] (n : WithTop β„•βˆž) [ContDiffSMul π•œ M X n] + {f : Ξ± β†’ M} {l : Filter Ξ±} {c : M} + (hf : Tendsto f l (𝓝 c)) (a : X) : + Tendsto (fun x => f x β€’ a) l (𝓝 (c β€’ a)) := + hf.contdiff_smul π•œ n tendsto_const_nhds + +end Tendsto