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

Commit 888e75b

Browse files
sgouezelkim-emmergify[bot]
authored
refactor(*/multilinear): better right curryfication (#1985)
* feat(data/fin): append * Update fin.lean * Update fintype.lean * replace but_last with init * cons and append commute * feat(*/multilinear): better multilinear * docstrings * snoc * fix build * comp_snoc and friends * fix docstring * typo Co-authored-by: Scott Morrison <scott@tqft.net> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent eeedc6a commit 888e75b

File tree

3 files changed

+264
-102
lines changed

3 files changed

+264
-102
lines changed

src/analysis/normed_space/multilinear.lean

Lines changed: 108 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -507,18 +507,17 @@ section currying
507507
508508
We associate to a continuous multilinear map in `n+1` variables (i.e., based on `fin n.succ`) two
509509
curried functions, named `f.curry_left` (which is a continuous linear map on `E 0` taking values
510-
in continuous multilinear maps in `n` variables) and `f.curry_right` (wich is a continuous
511-
multilinear map in `n` variables taking values in continuous linear maps on `E 0`). In both
512-
constructions, the variable that is singled out is `0`, to take advantage of the operations
513-
`cons` and `tail` on `fin n`. The inverse operations are called `uncurry_left` and `uncurry_right`.
510+
in continuous multilinear maps in `n` variables) and `f.curry_right` (which is a continuous
511+
multilinear map in `n` variables taking values in continuous linear maps on `E (last n)`).
512+
The inverse operations are called `uncurry_left` and `uncurry_right`.
514513
515514
We also register continuous linear equiv versions of these correspondences, in
516515
`continuous_multilinear_curry_left_equiv` and `continuous_multilinear_curry_right_equiv`.
517516
-/
518-
set_option class.instance_max_depth 140
517+
set_option class.instance_max_depth 360
519518
open fin function
520519

521-
lemma continuous_linear_map.norm_map_tail_right_le
520+
lemma continuous_linear_map.norm_map_tail_le
522521
(f : E 0 →L[𝕜] (continuous_multilinear_map 𝕜 (λ(i : fin n), E i.succ) E₂)) (m : Πi, E i) :
523522
∥f (m 0) (tail m)∥ ≤ ∥f∥ * univ.prod (λi, ∥m i∥) :=
524523
calc
@@ -528,15 +527,15 @@ calc
528527
... = ∥f∥ * (∥m 0∥ * univ.prod (λi, ∥(tail m) i∥)) : by ring
529528
... = ∥f∥ * univ.prod (λi, ∥m i∥) : by { rw prod_univ_succ, refl }
530529

531-
lemma continuous_multilinear_map.norm_map_tail_left_le
532-
(f : continuous_multilinear_map 𝕜 (λ(i : fin n), E i.succ) (E 0 →L[𝕜] E₂)) (m : Πi, E i) :
533-
∥f (tail m) (m 0)∥ ≤ ∥f∥ * univ.prod (λi, ∥m i∥) :=
530+
lemma continuous_multilinear_map.norm_map_init_le
531+
(f : continuous_multilinear_map 𝕜 (λ(i : fin n), E i.cast_succ) (E (last n) →L[𝕜] E₂)) (m : Πi, E i) :
532+
∥f (init m) (m (last n))∥ ≤ ∥f∥ * univ.prod (λi, ∥m i∥) :=
534533
calc
535-
∥f (tail m) (m 0)∥ ≤ ∥f (tail m)∥ * ∥m 0∥ : (f (tail m)).le_op_norm _
536-
... ≤ (∥f∥ * univ.prod (λi, ∥(tail m) i∥)) * ∥m 0∥ :
534+
∥f (init m) (m (last n))∥ ≤ ∥f (init m)∥ * ∥m (last n)∥ : (f (init m)).le_op_norm _
535+
... ≤ (∥f∥ * univ.prod (λi, ∥(init m) i∥)) * ∥m (last n)∥ :
537536
mul_le_mul_of_nonneg_right (f.le_op_norm _) (norm_nonneg _)
538-
... = ∥f∥ * (∥m 0∥ * univ.prod (λi, ∥(tail m) i∥)) : by ring
539-
... = ∥f∥ * univ.prod (λi, ∥m i∥) : by { rw prod_univ_succ, refl }
537+
... = ∥f∥ * (univ.prod (λi, ∥(init m) i∥) * ∥m (last n)∥) : mul_assoc _ _ _
538+
... = ∥f∥ * univ.prod (λi, ∥m i∥) : by { rw prod_univ_cast_succ, refl }
540539

541540
lemma continuous_multilinear_map.norm_map_cons_le
542541
(f : continuous_multilinear_map 𝕜 E E₂) (x : E 0) (m : Π(i : fin n), E i.succ) :
@@ -545,6 +544,15 @@ calc
545544
∥f (cons x m)∥ ≤ ∥f∥ * univ.prod (λ(i : fin n.succ), ∥cons x m i∥) : f.le_op_norm _
546545
... = (∥f∥ * ∥x∥) * univ.prod (λi, ∥m i∥) : by { rw prod_univ_succ, simp [mul_assoc] }
547546

547+
lemma continuous_multilinear_map.norm_map_snoc_le
548+
(f : continuous_multilinear_map 𝕜 E E₂) (m : Π(i : fin n), E i.cast_succ) (x : E (last n)) :
549+
∥f (snoc m x)∥ ≤ ∥f∥ * univ.prod (λi, ∥m i∥) * ∥x∥ :=
550+
calc
551+
∥f (snoc m x)∥ ≤ ∥f∥ * univ.prod (λ(i : fin n.succ), ∥snoc m x i∥) : f.le_op_norm _
552+
... = ∥f∥ * univ.prod (λi, ∥m i∥) * ∥x∥ : by { rw prod_univ_cast_succ, simp [mul_assoc] }
553+
554+
/-! #### Left curryfication -/
555+
548556
/-- Given a continuous linear map `f` from `E 0` to continuous multilinear maps on `n` variables,
549557
construct the corresponding continuous multilinear map on `n+1` variables obtained by concatenating
550558
the variables, given by `m ↦ f (m 0) (tail m)`-/
@@ -553,7 +561,7 @@ def continuous_linear_map.uncurry_left
553561
continuous_multilinear_map 𝕜 E E₂ :=
554562
(@linear_map.uncurry_left 𝕜 n E E₂ _ _ _ _ _
555563
(continuous_multilinear_map.to_multilinear_map_linear.comp f.to_linear_map)).mk_continuous
556-
(∥f∥) (λm, continuous_linear_map.norm_map_tail_right_le f m)
564+
(∥f∥) (λm, continuous_linear_map.norm_map_tail_le f m)
557565

558566
@[simp] lemma continuous_linear_map.uncurry_left_apply
559567
(f : E 0 →L[𝕜] (continuous_multilinear_map 𝕜 (λ(i : fin n), E i.succ) E₂)) (m : Πi, E i) :
@@ -660,53 +668,59 @@ def continuous_multilinear_curry_left_equiv :
660668

661669
variables {𝕜 E E₂}
662670

671+
@[simp] lemma continuous_multilinear_curry_left_equiv_apply
672+
(f : E 0 →L[𝕜] (continuous_multilinear_map 𝕜 (λ(i : fin n), E i.succ) E₂)) (v : Π i, E i) :
673+
continuous_multilinear_curry_left_equiv 𝕜 E E₂ f v = f (v 0) (tail v) := rfl
674+
675+
@[simp] lemma continuous_multilinear_curry_left_equiv_symm_apply
676+
(f : continuous_multilinear_map 𝕜 E E₂) (x : E 0) (v : Π (i : fin n), E i.succ) :
677+
(continuous_multilinear_curry_left_equiv 𝕜 E E₂).symm f x v = f (cons x v) := rfl
678+
679+
/-! #### Right curryfication -/
680+
663681
/-- Given a continuous linear map `f` from continuous multilinear maps on `n` variables to
664682
continuous linear maps on `E 0`, construct the corresponding continuous multilinear map on `n+1`
665-
variables obtained by concatenating the variables, given by `m ↦ f (tail m) (m 0)`-/
683+
variables obtained by concatenating the variables, given by `m ↦ f (init m) (m (last n))`. -/
666684
def continuous_multilinear_map.uncurry_right
667-
(f : continuous_multilinear_map 𝕜 (λ(i : fin n), E i.succ) (E 0 →L[𝕜] E₂)) :
685+
(f : continuous_multilinear_map 𝕜 (λ(i : fin n), E i.cast_succ) (E (last n) →L[𝕜] E₂)) :
668686
continuous_multilinear_map 𝕜 E E₂ :=
669-
let f' : multilinear_map 𝕜 (λ(i : fin n), E i.succ) (E 0 →ₗ[𝕜] E₂) :=
687+
let f' : multilinear_map 𝕜 (λ(i : fin n), E i.cast_succ) (E (last n) →ₗ[𝕜] E₂) :=
670688
{ to_fun := λ m, (f m).to_linear_map,
671689
add := λ m i x y, by { simp, refl },
672690
smul := λ m i c x, by { simp, refl } } in
673691
(@multilinear_map.uncurry_right 𝕜 n E E₂ _ _ _ _ _ f').mk_continuous
674-
(∥f∥) (λm, f.norm_map_tail_left_le m)
692+
(∥f∥) (λm, f.norm_map_init_le m)
675693

676694
@[simp] lemma continuous_multilinear_map.uncurry_right_apply
677-
(f : continuous_multilinear_map 𝕜 (λ(i : fin n), E i.succ) (E 0 →L[𝕜] E₂)) (m : Πi, E i) :
678-
f.uncurry_right m = f (tail m) (m 0) := rfl
695+
(f : continuous_multilinear_map 𝕜 (λ(i : fin n), E i.cast_succ) (E (last n) →L[𝕜] E₂)) (m : Πi, E i) :
696+
f.uncurry_right m = f (init m) (m (last n)) := rfl
679697

680-
/-- Given a continuous multilinear map `f` in `n+1` variables, split the first variable to obtain
698+
/-- Given a continuous multilinear map `f` in `n+1` variables, split the last variable to obtain
681699
a continuous multilinear map in `n` variables into continuous linear maps, given by
682-
`m ↦ (x ↦ f (cons x m))`. -/
700+
`m ↦ (x ↦ f (snoc m x))`. -/
683701
def continuous_multilinear_map.curry_right
684702
(f : continuous_multilinear_map 𝕜 E E₂) :
685-
continuous_multilinear_map 𝕜 (λ(i : fin n), E i.succ) (E 0 →L[𝕜] E₂) :=
686-
let f' : multilinear_map 𝕜 (λ(i : fin n), E i.succ) (E 0 →L[𝕜] E₂) :=
703+
continuous_multilinear_map 𝕜 (λ(i : fin n), E i.cast_succ) (E (last n) →L[𝕜] E₂) :=
704+
let f' : multilinear_map 𝕜 (λ(i : fin n), E i.cast_succ) (E (last n) →L[𝕜] E₂) :=
687705
{ to_fun := λm, (f.to_multilinear_map.curry_right m).mk_continuous
688-
(∥f∥ * univ.prod (λ(i : fin n), ∥m i∥)) $ λx, begin
689-
change ∥f (cons x m)∥ ≤ ∥f∥ * finset.prod univ (λ (i : fin n), ∥m i∥) * ∥x∥,
690-
rw [mul_assoc, mul_comm _ (∥x∥), ← mul_assoc],
691-
exact f.norm_map_cons_le x m,
692-
end,
706+
(∥f∥ * univ.prod (λ(i : fin n), ∥m i∥)) $ λx, f.norm_map_snoc_le m x,
693707
add := λ m i x y, by { simp, refl },
694708
smul := λ m i c x, by { simp, refl } } in
695709
f'.mk_continuous (∥f∥) (λm, linear_map.mk_continuous_norm_le _
696710
(mul_nonneg' (norm_nonneg _) (prod_nonneg (λj hj, norm_nonneg _))) _)
697711

698712
@[simp] lemma continuous_multilinear_map.curry_right_apply
699-
(f : continuous_multilinear_map 𝕜 E E₂) (x : E 0) (m : Π(i : fin n), E i.succ) :
700-
f.curry_right m x = f (cons x m) := rfl
713+
(f : continuous_multilinear_map 𝕜 E E₂) (m : Π(i : fin n), E i.cast_succ) (x : E (last n)) :
714+
f.curry_right m x = f (snoc m x) := rfl
701715

702716
@[simp] lemma continuous_multilinear_map.curry_uncurry_right
703-
(f : continuous_multilinear_map 𝕜 (λ(i : fin n), E i.succ) (E 0 →L[𝕜] E₂)) :
717+
(f : continuous_multilinear_map 𝕜 (λ(i : fin n), E i.cast_succ) (E (last n) →L[𝕜] E₂)) :
704718
f.uncurry_right.curry_right = f :=
705719
begin
706720
ext m x,
707-
simp only [cons_zero, continuous_multilinear_map.curry_right_apply,
721+
simp only [snoc_last, continuous_multilinear_map.curry_right_apply,
708722
continuous_multilinear_map.uncurry_right_apply],
709-
rw tail_cons
723+
rw init_snoc
710724
end
711725

712726
@[simp] lemma continuous_multilinear_map.uncurry_curry_right
@@ -723,7 +737,7 @@ begin
723737
end
724738

725739
@[simp] lemma continuous_multilinear_map.uncurry_right_norm
726-
(f : continuous_multilinear_map 𝕜 (λ(i : fin n), E i.succ) (E 0 →L[𝕜] E₂)) :
740+
(f : continuous_multilinear_map 𝕜 (λ(i : fin n), E i.cast_succ) (E (last n) →L[𝕜] E₂)) :
727741
∥f.uncurry_right∥ = ∥f∥ :=
728742
begin
729743
refine le_antisymm (multilinear_map.mk_continuous_norm_le _ (norm_nonneg _) _) _,
@@ -735,9 +749,9 @@ end
735749
variables (𝕜 E E₂)
736750

737751
/-- The space of continuous multilinear maps on `Π(i : fin (n+1)), E i` is canonically isomorphic to
738-
the space of continuous multilinear maps on `Π(i : fin n), E i.succ` with values in the space of
739-
continuous linear maps on `E 0`, by separating the first variable. We register this isomorphism as a
740-
linear isomorphism in `continuous_multilinear_curry_right_equiv_aux 𝕜 E E₂`.
752+
the space of continuous multilinear maps on `Π(i : fin n), E i.cast_succ` with values in the space
753+
of continuous linear maps on `E (last n)`, by separating the last variable. We register this
754+
isomorphism as a linear equiv in `continuous_multilinear_curry_right_equiv_aux 𝕜 E E₂`.
741755
The algebraic version (without continuity assumption on the maps) is
742756
`multilinear_curry_right_equiv 𝕜 E E₂`, and the topological isomorphism (registering
743757
additionally that the isomorphism is continuous) is
@@ -746,7 +760,7 @@ additionally that the isomorphism is continuous) is
746760
The direct and inverse maps are given by `f.uncurry_right` and `f.curry_right`. Use these
747761
unless you need the full framework of linear equivs. -/
748762
def continuous_multilinear_curry_right_equiv_aux :
749-
(continuous_multilinear_map 𝕜 (λ(i : fin n), E i.succ) (E 0 →L[𝕜] E₂)) ≃ₗ[𝕜]
763+
(continuous_multilinear_map 𝕜 (λ(i : fin n), E i.cast_succ) (E (last n) →L[𝕜] E₂)) ≃ₗ[𝕜]
750764
(continuous_multilinear_map 𝕜 E E₂) :=
751765
{ to_fun := continuous_multilinear_map.uncurry_right,
752766
add := λf₁ f₂, by { ext m, refl },
@@ -756,15 +770,15 @@ def continuous_multilinear_curry_right_equiv_aux :
756770
right_inv := continuous_multilinear_map.uncurry_curry_right }
757771

758772
/-- The space of continuous multilinear maps on `Π(i : fin (n+1)), E i` is canonically isomorphic to
759-
the space of continuous multilinear maps on `Π(i : fin n), E i.succ` with values in the space of
760-
continuous linear maps on `E 0`, by separating the first variable. We register this isomorphism in
761-
`continuous_multilinear_curry_right_equiv 𝕜 E E₂`. The algebraic version (without topology) is given
762-
in `multilinear_curry_right_equiv 𝕜 E E₂`.
773+
the space of continuous multilinear maps on `Π(i : fin n), E i.cast_succ` with values in the space
774+
of continuous linear maps on `E (last n)`, by separating the last variable. We register this
775+
isomorphism as a continuous linear equiv in `continuous_multilinear_curry_right_equiv 𝕜 E E₂`.
776+
The algebraic version (without topology) is given in `multilinear_curry_right_equiv 𝕜 E E₂`.
763777
764778
The direct and inverse maps are given by `f.uncurry_right` and `f.curry_right`. Use these
765779
unless you need the full framework of continuous linear equivs. -/
766780
def continuous_multilinear_curry_right_equiv :
767-
(continuous_multilinear_map 𝕜 (λ(i : fin n), E i.succ) (E 0 →L[𝕜] E₂)) ≃L[𝕜]
781+
(continuous_multilinear_map 𝕜 (λ(i : fin n), E i.cast_succ) (E (last n) →L[𝕜] E₂)) ≃L[𝕜]
768782
(continuous_multilinear_map 𝕜 E E₂) :=
769783
{ continuous_to_fun := begin
770784
refine (continuous_multilinear_curry_right_equiv_aux 𝕜 E E₂).to_linear_map.continuous_of_bound
@@ -780,8 +794,21 @@ def continuous_multilinear_curry_right_equiv :
780794
end,
781795
.. continuous_multilinear_curry_right_equiv_aux 𝕜 E E₂ }
782796

797+
variables {𝕜 G E E₂}
798+
799+
@[simp] lemma continuous_multilinear_curry_right_equiv_apply
800+
(f : (continuous_multilinear_map 𝕜 (λ(i : fin n), E i.cast_succ) (E (last n) →L[𝕜] E₂)))
801+
(v : Π i, E i) :
802+
(continuous_multilinear_curry_right_equiv 𝕜 E E₂) f v = f (init v) (v (last n)) := rfl
803+
804+
@[simp] lemma continuous_multilinear_curry_right_equiv_symm_apply
805+
(f : continuous_multilinear_map 𝕜 E E₂)
806+
(v : Π (i : fin n), E i.cast_succ) (x : E (last n)) :
807+
(continuous_multilinear_curry_right_equiv 𝕜 E E₂).symm f v x = f (snoc v x) := rfl
808+
809+
783810
/-!
784-
### Currying with `0` variables
811+
#### Currying with `0` variables
785812
786813
The space of multilinear maps with `0` variables is trivial: such a multilinear map is just an
787814
arbitrary constant (note that multilinear maps in `0` variables need not map `0` to `0`!).
@@ -810,6 +837,10 @@ variable {G}
810837
(continuous_multilinear_map.curry0 𝕜 G x : ((fin 0) → G) → E₂) m = x := rfl
811838

812839
variable {𝕜}
840+
@[simp] lemma continuous_multilinear_map.uncurry0_apply
841+
(f : continuous_multilinear_map 𝕜 (λ (i : fin 0), G) E₂) :
842+
f.uncurry0 = f 0 := rfl
843+
813844
@[simp] lemma continuous_multilinear_map.uncurry0_curry0
814845
(f : continuous_multilinear_map 𝕜 (λ (i : fin 0), G) E₂) :
815846
continuous_multilinear_map.curry0 𝕜 G (f.uncurry0) = f :=
@@ -834,7 +865,7 @@ begin
834865
refine le_antisymm (by simpa using f.le_op_norm 0) _,
835866
have : ∥continuous_multilinear_map.curry0 𝕜 G (f.uncurry0)∥ ≤ ∥f.uncurry0∥ :=
836867
continuous_multilinear_map.op_norm_le_bound _ (norm_nonneg _) (λm, by simp),
837-
simpa
868+
simpa [-continuous_multilinear_map.uncurry0_apply]
838869
end
839870

840871
variables (𝕜 G E₂)
@@ -873,4 +904,35 @@ def continuous_multilinear_curry_fin0 :
873904
end,
874905
.. continuous_multilinear_curry_fin0_aux 𝕜 G E₂ }
875906

907+
variables {𝕜 G E₂}
908+
909+
@[simp] lemma continuous_multilinear_curry_fin0_apply
910+
(f : (continuous_multilinear_map 𝕜 (λ (i : fin 0), G) E₂)) :
911+
continuous_multilinear_curry_fin0 𝕜 G E₂ f = f 0 := rfl
912+
913+
@[simp] lemma continuous_multilinear_curry_fin0_symm_apply
914+
(x : E₂) (v : (fin 0) → G) :
915+
(continuous_multilinear_curry_fin0 𝕜 G E₂).symm x v = x := rfl
916+
917+
/-! #### With 1 variable -/
918+
919+
variables (𝕜 G E₂)
920+
921+
/-- Continuous multilinear maps from `G^1` to `E₂` are isomorphic with continuous linear maps from
922+
`G` to `E₂`. -/
923+
def continuous_multilinear_curry_fin1 :
924+
(continuous_multilinear_map 𝕜 (λ (i : fin 1), G) E₂) ≃L[𝕜] (G →L[𝕜] E₂) :=
925+
(continuous_multilinear_curry_right_equiv 𝕜 (λ (i : fin 1), G) E₂).symm.trans
926+
(continuous_multilinear_curry_fin0 𝕜 G (G →L[𝕜] E₂))
927+
928+
variables {𝕜 G E₂}
929+
930+
@[simp] lemma continuous_multilinear_curry_fin1_apply
931+
(f : (continuous_multilinear_map 𝕜 (λ (i : fin 1), G) E₂)) (x : G) :
932+
continuous_multilinear_curry_fin1 𝕜 G E₂ f x = f (fin.snoc 0 x) := rfl
933+
934+
@[simp] lemma continuous_multilinear_curry_fin1_symm_apply
935+
(f : G →L[𝕜] E₂) (v : (fin 1) → G) :
936+
(continuous_multilinear_curry_fin1 𝕜 G E₂).symm f v = f (v 0) := rfl
937+
876938
end currying

0 commit comments

Comments
 (0)