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

Commit cfd1a4c

Browse files
committed
feat(linear_algebra/bilinear_form): generalize some constructions to the noncomm case (#6824)
Introduce an operation `flip` on a bilinear form, which swaps the arguments. Generalize the construction `bilin_form.to_lin` (which currently exists for commutative rings) to a weaker construction `bilin_form.to_lin'` for arbitrary rings. Rename lemmas `sesq_form.map_sum_right` -> `sesq_form.sum_right` `sesq_form.map_sum_left` -> `sesq_form.sum_left` `bilin_form.map_sum_right` -> `bilin_form.sum_right` `bilin_form.map_sum_left` -> `bilin_form.sum_left` `to_linear_map_apply` (sic, no namespace) -> `bilin_form.to_lin_apply`
1 parent ec26d96 commit cfd1a4c

File tree

4 files changed

+164
-45
lines changed

4 files changed

+164
-45
lines changed

src/analysis/normed_space/inner_product.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,12 +451,12 @@ def bilin_form_of_real_inner : bilin_form ℝ F :=
451451
/-- An inner product with a sum on the left. -/
452452
lemma sum_inner {ι : Type*} (s : finset ι) (f : ι → E) (x : E) :
453453
⟪∑ i in s, f i, x⟫ = ∑ i in s, ⟪f i, x⟫ :=
454-
sesq_form.map_sum_right (sesq_form_of_inner) _ _ _
454+
sesq_form.sum_right (sesq_form_of_inner) _ _ _
455455

456456
/-- An inner product with a sum on the right. -/
457457
lemma inner_sum {ι : Type*} (s : finset ι) (f : ι → E) (x : E) :
458458
⟪x, ∑ i in s, f i⟫ = ∑ i in s, ⟪x, f i⟫ :=
459-
sesq_form.map_sum_left (sesq_form_of_inner) _ _ _
459+
sesq_form.sum_left (sesq_form_of_inner) _ _ _
460460

461461
/-- An inner product with a sum on the left, `finsupp` version. -/
462462
lemma finsupp.sum_inner {ι : Type*} (l : ι →₀ 𝕜) (v : ι → E) (x : E) :

src/linear_algebra/bilinear_form.lean

Lines changed: 153 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,18 @@ open_locale big_operators
5151
universes u v w
5252

5353
/-- `bilin_form R M` is the type of `R`-bilinear functions `M → M → R`. -/
54-
structure bilin_form (R : Type u) (M : Type v) [semiring R] [add_comm_monoid M] [semimodule R M] :=
54+
structure bilin_form (R : Type*) (M : Type*) [semiring R] [add_comm_monoid M] [semimodule R M] :=
5555
(bilin : M → M → R)
5656
(bilin_add_left : ∀ (x y z : M), bilin (x + y) z = bilin x z + bilin y z)
5757
(bilin_smul_left : ∀ (a : R) (x y : M), bilin (a • x) y = a * (bilin x y))
5858
(bilin_add_right : ∀ (x y z : M), bilin x (y + z) = bilin x y + bilin x z)
5959
(bilin_smul_right : ∀ (a : R) (x y : M), bilin x (a • y) = a * (bilin x y))
6060

61-
variables {R : Type u} {M : Type v} [semiring R] [add_comm_monoid M] [semimodule R M]
62-
variables {R₁ : Type u} {M₁ : Type v} [ring R₁] [add_comm_group M₁] [module R₁ M₁]
63-
variables {R₂ : Type u} {M₂ : Type v} [comm_semiring R₂] [add_comm_monoid M₂] [semimodule R₂ M₂]
64-
variables {R₃ : Type u} {M₃ : Type v} [comm_ring R₃] [add_comm_group M₃] [module R₃ M₃]
65-
variables {V : Type u} {K : Type v} [field K] [add_comm_group V] [vector_space K V]
61+
variables {R : Type*} {M : Type*} [semiring R] [add_comm_monoid M] [semimodule R M]
62+
variables {R₁ : Type*} {M₁ : Type*} [ring R₁] [add_comm_group M₁] [module R₁ M₁]
63+
variables {R₂ : Type*} {M₂ : Type*} [comm_semiring R₂] [add_comm_monoid M₂] [semimodule R₂ M₂]
64+
variables {R₃ : Type*} {M₃ : Type*} [comm_ring R₃] [add_comm_group M₃] [module R₃ M₃]
65+
variables {V : Type*} {K : Type*} [field K] [add_comm_group V] [vector_space K V]
6666
variables {B : bilin_form R M} {B₁ : bilin_form R₁ M₁} {B₂ : bilin_form R₂ M₂}
6767

6868
namespace bilin_form
@@ -157,11 +157,10 @@ instance : inhabited (bilin_form R M) := ⟨0⟩
157157

158158
section
159159

160-
/-- `quadratic_form A M` inherits the scalar action from any algebra over `A`.
160+
/-- `bilin_form R M` inherits the scalar action from any commutative subalgebra `R₂` of `R`.
161161
162-
When `A` is commutative, this provides an `A`-action via `algebra.id`. -/
163-
instance {R A : Type*} [comm_semiring R] [semiring A] [algebra R A] [semimodule A M] :
164-
semimodule R (bilin_form A M) :=
162+
When `R` itself is commutative, this provides an `R`-action via `algebra.id`. -/
163+
instance [algebra R₂ R] : semimodule R₂ (bilin_form R M) :=
165164
{ smul := λ c B,
166165
{ bilin := λ x y, c • B x y,
167166
bilin_add_left := λ x y z,
@@ -179,14 +178,132 @@ instance {R A : Type*} [comm_semiring R] [semiring A] [algebra R A] [semimodule
179178
zero_smul := λ B, by { ext, unfold coe_fn has_coe_to_fun.coe bilin, rw zero_smul },
180179
smul_zero := λ B, by { ext, unfold coe_fn has_coe_to_fun.coe bilin, rw smul_zero } }
181180

182-
@[simp]
183-
lemma smul_apply {R A : Type*} [comm_semiring R] [semiring A] [algebra R A] [semimodule A M]
184-
(B : bilin_form A M) (a : R) (x y : M) :
181+
@[simp] lemma smul_apply [algebra R₂ R] (B : bilin_form R M) (a : R₂) (x y : M) :
185182
(a • B) x y = a • (B x y) :=
186183
rfl
187184

188185
end
189186

187+
section flip
188+
189+
variables (R₂)
190+
191+
/-- Auxiliary construction for the flip of a bilinear form, obtained by exchanging the left and
192+
right arguments. This version is a `linear_map`; it is later upgraded to a `linear_equiv`
193+
in `flip_hom`. -/
194+
def flip_hom_aux [algebra R₂ R] : bilin_form R M →ₗ[R₂] bilin_form R M :=
195+
{ to_fun := λ A,
196+
{ bilin := λ i j, A j i,
197+
bilin_add_left := λ x y z, A.bilin_add_right z x y,
198+
bilin_smul_left := λ a x y, A.bilin_smul_right a y x,
199+
bilin_add_right := λ x y z, A.bilin_add_left y z x,
200+
bilin_smul_right := λ a x y, A.bilin_smul_left a y x },
201+
map_add' := λ A₁ A₂, by { ext, simp } ,
202+
map_smul' := λ c A, by { ext, simp } }
203+
204+
variables {R₂}
205+
206+
lemma flip_flip_aux [algebra R₂ R] (A : bilin_form R M) :
207+
(flip_hom_aux R₂) (flip_hom_aux R₂ A) = A :=
208+
by { ext A x y, simp [flip_hom_aux] }
209+
210+
variables (R₂)
211+
212+
/-- The flip of a bilinear form, obtained by exchanging the left and right arguments. This is a
213+
less structured version of the equiv which applies to general (noncommutative) rings `R` with a
214+
distinguished commutative subring `R₂`; over a commutative ring use `flip`. -/
215+
def flip_hom [algebra R₂ R] : bilin_form R M ≃ₗ[R₂] bilin_form R M :=
216+
{ inv_fun := flip_hom_aux R₂,
217+
left_inv := flip_flip_aux,
218+
right_inv := flip_flip_aux,
219+
.. flip_hom_aux R₂ }
220+
221+
variables {R₂}
222+
223+
@[simp] lemma flip_apply [algebra R₂ R] (A : bilin_form R M) (x y : M) :
224+
flip_hom R₂ A x y = A y x :=
225+
rfl
226+
227+
lemma flip_flip [algebra R₂ R] :
228+
(flip_hom R₂).trans (flip_hom R₂) = linear_equiv.refl R₂ (bilin_form R M) :=
229+
by { ext A x y, simp }
230+
231+
/-- The flip of a bilinear form over a ring, obtained by exchanging the left and right arguments,
232+
here considered as an `ℕ`-linear equivalence, i.e. an additive equivalence. -/
233+
abbreviation flip' : bilin_form R M ≃ₗ[ℕ] bilin_form R M := flip_hom ℕ
234+
235+
/-- The `flip` of a bilinear form over a commutative ring, obtained by exchanging the left and
236+
right arguments. -/
237+
abbreviation flip : bilin_form R₂ M₂ ≃ₗ[R₂] bilin_form R₂ M₂ := flip_hom R₂
238+
239+
end flip
240+
241+
section to_lin'
242+
243+
variables (R₂) [algebra R₂ R] [semimodule R₂ M] [is_scalar_tower R₂ R M]
244+
245+
/-- The linear map obtained from a `bilin_form` by fixing the left co-ordinate and evaluating in
246+
the right.
247+
This is the most general version of the construction; it is `R₂`-linear for some distinguished
248+
commutative subsemiring `R₂` of the scalar ring. Over a semiring with no particular distinguished
249+
such subsemiring, use `to_lin'`, which is `ℕ`-linear. Over a commutative semiring, use `to_lin`,
250+
which is linear. -/
251+
def to_lin_hom : bilin_form R M →ₗ[R₂] M →ₗ[R₂] M →ₗ[R] R :=
252+
{ to_fun := λ A,
253+
{ to_fun := λ x,
254+
{ to_fun := λ y, A x y,
255+
map_add' := A.bilin_add_right x,
256+
map_smul' := λ c, A.bilin_smul_right c x },
257+
map_add' := λ x₁ x₂, by { ext, simp },
258+
map_smul' := λ c x, by { ext y, simpa using smul_left (c • (1 : R)) x y } },
259+
map_add' := λ A₁ A₂, by { ext, simp },
260+
map_smul' := λ c A, by { ext, simp } }
261+
262+
variables {R₂}
263+
264+
@[simp] lemma to_lin'_apply (A : bilin_form R M) (x : M) :
265+
⇑(to_lin_hom R₂ A x) = A x :=
266+
rfl
267+
268+
/-- The linear map obtained from a `bilin_form` by fixing the left co-ordinate and evaluating in
269+
the right.
270+
Over a commutative semiring, use `to_lin`, which is linear rather than `ℕ`-linear. -/
271+
abbreviation to_lin' : bilin_form R M →ₗ[ℕ] M →ₗ[ℕ] M →ₗ[R] R := to_lin_hom ℕ
272+
273+
@[simp]
274+
lemma sum_left {α} (t : finset α) (g : α → M) (w : M) :
275+
B (∑ i in t, g i) w = ∑ i in t, B (g i) w :=
276+
(bilin_form.to_lin' B).map_sum₂ t g w
277+
278+
@[simp]
279+
lemma sum_right {α} (t : finset α) (w : M) (g : α → M) :
280+
B w (∑ i in t, g i) = ∑ i in t, B w (g i) :=
281+
(bilin_form.to_lin' B w).map_sum
282+
283+
variables (R₂)
284+
285+
/-- The linear map obtained from a `bilin_form` by fixing the right co-ordinate and evaluating in
286+
the left.
287+
This is the most general version of the construction; it is `R₂`-linear for some distinguished
288+
commutative subsemiring `R₂` of the scalar ring. Over semiring with no particular distinguished
289+
such subsemiring, use `to_lin'_flip`, which is `ℕ`-linear. Over a commutative semiring, use
290+
`to_lin_flip`, which is linear. -/
291+
def to_lin_hom_flip : bilin_form R M →ₗ[R₂] M →ₗ[R₂] M →ₗ[R] R :=
292+
(to_lin_hom R₂).comp (flip_hom R₂).to_linear_map
293+
294+
variables {R₂}
295+
296+
@[simp] lemma to_lin'_flip_apply (A : bilin_form R M) (x : M) :
297+
⇑(to_lin_hom_flip R₂ A x) = λ y, A y x :=
298+
rfl
299+
300+
/-- The linear map obtained from a `bilin_form` by fixing the right co-ordinate and evaluating in
301+
the left.
302+
Over a commutative semiring, use `to_lin_flip`, which is linear rather than `ℕ`-linear. -/
303+
abbreviation to_lin'_flip : bilin_form R M →ₗ[ℕ] M →ₗ[ℕ] M →ₗ[R] R := to_lin_hom_flip ℕ
304+
305+
end to_lin'
306+
190307
end bilin_form
191308

192309
section equiv_lin
@@ -202,19 +319,16 @@ def linear_map.to_bilin_aux (f : M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂) : bil
202319
bilin_add_right := λ x y z, linear_map.map_add (f x) y z,
203320
bilin_smul_right := λ a x y, linear_map.map_smul (f x) a y }
204321

205-
/-- A map with two arguments that is linear in both is linearly equivalent to bilinear form. -/
206-
def linear_map.to_bilin : (M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂) ≃ₗ[R₂] bilin_form R₂ M₂ :=
207-
{ to_fun := linear_map.to_bilin_aux,
208-
inv_fun := λ F, linear_map.mk₂ R₂ F
209-
F.bilin_add_left F.bilin_smul_left F.bilin_add_right F.bilin_smul_right,
210-
map_add' := λ B D, rfl,
211-
map_smul' := λ a B, rfl,
212-
left_inv := λ B, by { ext, refl },
213-
right_inv := λ B, by { ext, refl } }
214-
215322
/-- Bilinear forms are linearly equivalent to maps with two arguments that are linear in both. -/
216323
def bilin_form.to_lin : bilin_form R₂ M₂ ≃ₗ[R₂] (M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂) :=
217-
linear_map.to_bilin.symm
324+
{ inv_fun := linear_map.to_bilin_aux,
325+
left_inv := λ B, by { ext, simp [linear_map.to_bilin_aux] },
326+
right_inv := λ B, by { ext, simp [linear_map.to_bilin_aux] },
327+
.. bilin_form.to_lin_hom R₂ }
328+
329+
/-- A map with two arguments that is linear in both is linearly equivalent to bilinear form. -/
330+
def linear_map.to_bilin : (M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂) ≃ₗ[R₂] bilin_form R₂ M₂ :=
331+
bilin_form.to_lin.symm
218332

219333
@[simp] lemma linear_map.to_bilin_aux_eq (f : M₂ →ₗ[R₂] M₂ →ₗ[R₂] R₂) :
220334
linear_map.to_bilin_aux f = linear_map.to_bilin f :=
@@ -228,19 +342,7 @@ rfl
228342
linear_map.to_bilin.symm_symm
229343

230344
@[simp, norm_cast]
231-
lemma to_linear_map_apply (x : M₂) : ⇑(bilin_form.to_lin B₂ x) = B₂ x := rfl
232-
233-
@[simp]
234-
lemma map_sum_left {α} (t : finset α) (g : α → M₂) (w : M₂) :
235-
B₂ (∑ i in t, g i) w = ∑ i in t, B₂ (g i) w :=
236-
show bilin_form.to_lin B₂ (∑ i in t, g i) w = ∑ i in t, bilin_form.to_lin B₂ (g i) w,
237-
by rw [linear_map.map_sum, linear_map.coe_fn_sum, finset.sum_apply]
238-
239-
@[simp]
240-
lemma map_sum_right {α} (t : finset α) (w : M₂) (g : α → M₂) :
241-
B₂ w (∑ i in t, g i) = ∑ i in t, B₂ w (g i) :=
242-
show bilin_form.to_lin B₂ w (∑ i in t, g i) = ∑ i in t, bilin_form.to_lin B₂ w (g i),
243-
from linear_map.map_sum _
345+
lemma bilin_form.to_lin_apply (x : M₂) : ⇑(bilin_form.to_lin B₂ x) = B₂ x := rfl
244346

245347
end equiv_lin
246348

@@ -442,7 +544,7 @@ begin
442544
by_cases (i = j),
443545
{ rw [if_pos h] },
444546
{ rw [if_neg h, is_Ortho_def.1 hv₁ _ _ h, mul_zero] } },
445-
simp_rw [map_sum_left, smul_left, hsum, finset.sum_ite_eq] at this,
547+
simp_rw [sum_left, smul_left, hsum, finset.sum_ite_eq] at this,
446548
rw [if_pos, mul_eq_zero] at this,
447549
cases this,
448550
{ assumption },
@@ -466,7 +568,7 @@ lemma sum_repr_mul_repr_mul (x y : M₃) :
466568
(hb.repr x).sum (λ i xi, (hb.repr y).sum (λ j yj, xi • yj • B₃ (b i) (b j))) = B₃ x y :=
467569
begin
468570
conv_rhs { rw [← hb.total_repr x, ← hb.total_repr y] },
469-
simp_rw [finsupp.total_apply, finsupp.sum, map_sum_left, map_sum_right,
571+
simp_rw [finsupp.total_apply, finsupp.sum, sum_left, sum_right,
470572
smul_left, smul_right, smul_eq_mul]
471573
end
472574

@@ -814,6 +916,17 @@ lemma is_refl : refl_bilin_form.is_refl B := λ x y H1, H x y ▸ H1
814916
lemma ortho_sym {x y : M} :
815917
is_ortho B x y ↔ is_ortho B y x := refl_bilin_form.ortho_sym (is_refl H)
816918

919+
lemma is_sym_iff_flip' [algebra R₂ R] : is_sym B ↔ flip_hom R₂ B = B :=
920+
begin
921+
split,
922+
{ intros h,
923+
ext x y,
924+
exact h y x },
925+
{ intros h x y,
926+
conv_lhs { rw ← h },
927+
simp }
928+
end
929+
817930
end sym_bilin_form
818931

819932
namespace alt_bilin_form
@@ -1201,7 +1314,7 @@ begin
12011314
rw linear_map.ker_eq_bot',
12021315
split; intro h,
12031316
{ refine λ m hm, h _ (λ x, _),
1204-
rw [← to_linear_map_apply, hm], refl },
1317+
rw [← to_lin_apply, hm], refl },
12051318
{ intros m hm, apply h,
12061319
ext, exact hm x }
12071320
end

src/linear_algebra/sesquilinear_form.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,11 @@ lemma is_add_monoid_hom_right (S : sesq_form R M I) (x : M) : is_add_monoid_hom
125125
{ map_add := λ z y, sesq_add_right S _ _ _,
126126
map_zero := zero_right x }
127127

128-
lemma map_sum_left {α : Type*} (S : sesq_form R M I) (t : finset α) (g : α → M) (w : M) :
128+
lemma sum_left {α : Type*} (S : sesq_form R M I) (t : finset α) (g : α → M) (w : M) :
129129
S (∑ i in t, g i) w = ∑ i in t, S (g i) w :=
130130
by haveI s_inst := is_add_monoid_hom_left S w; exact (finset.sum_hom t (λ z, S z w)).symm
131131

132-
lemma map_sum_right {α : Type*} (S : sesq_form R M I) (t : finset α) (g : α → M) (w : M) :
132+
lemma sum_right {α : Type*} (S : sesq_form R M I) (t : finset α) (g : α → M) (w : M) :
133133
S w (∑ i in t, g i) = ∑ i in t, S w (g i) :=
134134
by haveI s_inst := is_add_monoid_hom_right S w; exact (finset.sum_hom t (λ z, S w z)).symm
135135

src/linear_algebra/tensor_product.lean

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ variables [smul_comm_class S R P] [smul_comm_class S R P']
4848
include R
4949

5050
variables (R S)
51-
/-- Create a bilinear map from a function that is linear in each component.
51+
/-- Create a bilinear map from a function that is linear in each component.
5252
See `mk₂` for the special case where both arguments come from modules over the same ring. -/
5353
def mk₂' (f : M → N → P)
5454
(H1 : ∀ m₁ m₂ n, f (m₁ + m₂) n = f m₁ n + f m₂ n)
@@ -85,6 +85,8 @@ end
8585

8686
@[simp] theorem flip_apply (f : M →ₗ[R] N →ₗ[S] P) (m : M) (n : N) : flip f n m = f m n := rfl
8787

88+
open_locale big_operators
89+
8890
variables {R}
8991
theorem flip_inj {f g : M →ₗ[R] N →ₗ[S] P} (H : flip f = flip g) : f = g :=
9092
ext₂ $ λ m n, show flip f n m = flip g n m, by rw H
@@ -104,6 +106,10 @@ theorem map_add₂ (f : M →ₗ[R] N →ₗ[S] P) (x₁ x₂ y) : f (x₁ + x
104106
theorem map_smul₂ (f : M →ₗ[R] N →ₗ[S] P) (r : R) (x y) : f (r • x) y = r • f x y :=
105107
(flip f y).map_smul _ _
106108

109+
theorem map_sum₂ {ι : Type*} (f : M →ₗ[R] N →ₗ[S] P) (t : finset ι) (x : ι → M) (y) :
110+
f (∑ i in t, x i) y = ∑ i in t, f (x i) y :=
111+
(flip f y).map_sum
112+
107113
end semiring
108114

109115
section comm_semiring

0 commit comments

Comments
 (0)