Skip to content

Commit

Permalink
chore(analysis/normed_space): define norm_one_class (#4323)
Browse files Browse the repository at this point in the history
Many normed rings have `∥1⊫1`. Add a typeclass mixin for this property.

API changes:

* drop `normed_field.norm_one`, use `norm_one` instead;
* same with `normed_field.nnnorm_one`;
* new typeclass `norm_one_class` for `∥1∥ = 1`;
* add `list.norm_prod_le`, `list.norm_prod_le`, `finset.norm_prod_le`, `finset.norm_prod_le'`:
  norm of the product of finitely many elements is less than or equal to the product of their norms;
  versions with prime assume that a `list` or a `finset` is nonempty, while the other versions
  assume `[norm_one_class]`;
* rename `norm_pow_le` to `norm_pow_le'`, new `norm_pow_le` assumes `[norm_one_class]` instead
  of `0 < n`;
* add a few supporting lemmas about `list`s and `finset`s.
  • Loading branch information
urkud committed Oct 1, 2020
1 parent d5834ee commit 4851857
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 50 deletions.
4 changes: 4 additions & 0 deletions src/algebra/big_operators/basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ namespace finset
of the finite set `s`."]
protected def prod [comm_monoid β] (s : finset α) (f : α → β) : β := (s.1.map f).prod

@[simp] lemma prod_mk [comm_monoid β] (s : multiset α) (hs) (f : α → β) :
(⟨s, hs⟩ : finset α).prod f = (s.map f).prod :=
rfl

end finset

/-
Expand Down
6 changes: 3 additions & 3 deletions src/analysis/asymptotics.lean
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ end zero_const
theorem is_O_with_const_one (c : E) (l : filter α) : is_O_with ∥c∥ (λ x : α, c) (λ x, (1 : 𝕜)) l :=
begin
refine (is_O_with_const_const c _ l).congr_const _,
{ rw [normed_field.norm_one, div_one] },
{ rw [norm_one, div_one] },
{ exact one_ne_zero }
end

Expand All @@ -714,8 +714,8 @@ theorem is_o_const_iff {c : F'} (hc : c ≠ 0) :
(is_o_const_iff_is_o_one ℝ hc).trans
begin
clear hc c,
simp only [is_o, is_O_with, normed_field.norm_one, mul_one,
metric.nhds_basis_closed_ball.tendsto_right_iff, metric.mem_closed_ball, dist_zero_right]
simp only [is_o, is_O_with, norm_one, mul_one, metric.nhds_basis_closed_ball.tendsto_right_iff,
metric.mem_closed_ball, dist_zero_right]
end

lemma is_o_id_const {c : F'} (hc : c ≠ 0) :
Expand Down
99 changes: 79 additions & 20 deletions src/analysis/normed_space/basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -457,41 +457,96 @@ the inequality `∥x y∥ ≤ ∥x∥ ∥y∥`. -/
class normed_comm_ring (α : Type*) extends normed_ring α :=
(mul_comm : ∀ x y : α, x * y = y * x)

/-- A mixin class with the axiom `∥1∥ = 1`. Many `normed_ring`s and all `normed_field`s satisfy this
axiom. -/
class norm_one_class (α : Type*) [has_norm α] [has_one α] : Prop :=
(norm_one : ∥(1:α)∥ = 1)

export norm_one_class (norm_one)

attribute [simp] norm_one

@[simp] lemma nnnorm_one [normed_group α] [has_one α] [norm_one_class α] : nnnorm (1:α) = 1 :=
nnreal.eq norm_one

@[priority 100]
instance normed_comm_ring.to_comm_ring [β : normed_comm_ring α] : comm_ring α := { ..β }

@[priority 100] -- see Note [lower instance priority]
instance normed_ring.to_normed_group [β : normed_ring α] : normed_group α := { ..β }

lemma norm_mul_le {α : Type*} [normed_ring α] (a b : α) : (∥a*b∥) ≤ (∥a∥) * (∥b∥) :=
instance prod.norm_one_class [normed_group α] [has_one α] [norm_one_class α]
[normed_group β] [has_one β] [norm_one_class β] :
norm_one_class (α × β) :=
by simp [prod.norm_def]⟩

variables [normed_ring α]

lemma norm_mul_le (a b : α) : (∥a*b∥) ≤ (∥a∥) * (∥b∥) :=
normed_ring.norm_mul _ _

lemma norm_pow_le {α : Type*} [normed_ring α] (a : α) : ∀ {n : ℕ}, 0 < n → ∥a^n∥ ≤ ∥a∥^n
lemma list.norm_prod_le' : ∀ {l : list α}, l ≠ [] → ∥l.prod∥ ≤ (l.map norm).prod
| [] h := (h rfl).elim
| [a] _ := by simp
| (a :: b :: l) _ :=
begin
rw [list.map_cons, list.prod_cons, @list.prod_cons _ _ _ ∥a∥],
refine le_trans (norm_mul_le _ _) (mul_le_mul_of_nonneg_left _ (norm_nonneg _)),
exact list.norm_prod_le' (list.cons_ne_nil b l)
end

lemma list.norm_prod_le [norm_one_class α] : ∀ l : list α, ∥l.prod∥ ≤ (l.map norm).prod
| [] := by simp
| (a::l) := list.norm_prod_le' (list.cons_ne_nil a l)

lemma finset.norm_prod_le' {α : Type*} [normed_comm_ring α] (s : finset ι) (hs : s.nonempty)
(f : ι → α) :
∥∏ i in s, f i∥ ≤ ∏ i in s, ∥f i∥ :=
begin
rcases s with ⟨⟨l⟩, hl⟩,
have : l.map f ≠ [], by simpa using hs,
simpa using list.norm_prod_le' this
end

lemma finset.norm_prod_le {α : Type*} [normed_comm_ring α] [norm_one_class α] (s : finset ι)
(f : ι → α) :
∥∏ i in s, f i∥ ≤ ∏ i in s, ∥f i∥ :=
begin
rcases s with ⟨⟨l⟩, hl⟩,
simpa using (l.map f).norm_prod_le
end

/-- If `α` is a normed ring, then `∥a^n∥≤ ∥a∥^n` for `n > 0`. See also `norm_pow_le`. -/
lemma norm_pow_le' (a : α) : ∀ {n : ℕ}, 0 < n → ∥a^n∥ ≤ ∥a∥^n
| 1 h := by simp
| (n+2) h :=
le_trans (norm_mul_le a (a^(n+1)))
(mul_le_mul (le_refl _)
(norm_pow_le (nat.succ_pos _)) (norm_nonneg _) (norm_nonneg _))
(norm_pow_le' (nat.succ_pos _)) (norm_nonneg _) (norm_nonneg _))

lemma eventually_norm_pow_le {α : Type*} [normed_ring α] (a : α) :
∀ᶠ (n:ℕ) in at_top, ∥a ^ n∥ ≤ ∥a∥ ^ n :=
eventually_at_top.mpr ⟨1, λ b h, norm_pow_le a (nat.succ_le_iff.mp h)⟩
/-- If `α` is a normed ring with `∥1∥=1`, then `∥a^n∥≤ ∥a∥^n`. See also `norm_pow_le'`. -/
lemma norm_pow_le [norm_one_class α] (a : α) : ∀ (n : ℕ), ∥a^n∥ ≤ ∥a∥^n
| 0 := by simp
| (n+1) := norm_pow_le' a n.zero_lt_succ

lemma units.norm_pos {α : Type*} [normed_ring α] [nontrivial α] (x : units α) : 0 < ∥(x:α)∥ :=
lemma eventually_norm_pow_le (a : α) : ∀ᶠ (n:ℕ) in at_top, ∥a ^ n∥ ≤ ∥a∥ ^ n :=
eventually_at_top.mpr ⟨1, λ b h, norm_pow_le' a (nat.succ_le_iff.mp h)⟩

lemma units.norm_pos [nontrivial α] (x : units α) : 0 < ∥(x:α)∥ :=
norm_pos_iff.mpr (units.ne_zero x)

/-- In a normed ring, the left-multiplication `add_monoid_hom` is bounded. -/
lemma mul_left_bound {α : Type*} [normed_ring α] (x : α) :
lemma mul_left_bound (x : α) :
∀ (y:α), ∥add_monoid_hom.mul_left x y∥ ≤ ∥x∥ * ∥y∥ :=
norm_mul_le x

/-- In a normed ring, the right-multiplication `add_monoid_hom` is bounded. -/
lemma mul_right_bound {α : Type*} [normed_ring α] (x : α) :
lemma mul_right_bound (x : α) :
∀ (y:α), ∥add_monoid_hom.mul_right x y∥ ≤ ∥x∥ * ∥y∥ :=
λ y, by {rw mul_comm, convert norm_mul_le y x}

/-- Normed ring structure on the product of two normed rings, using the sup norm. -/
instance prod.normed_ring [normed_ring α] [normed_ring β] : normed_ring (α × β) :=
instance prod.normed_ring [normed_ring β] : normed_ring (α × β) :=
{ norm_mul := assume x y,
calc
∥x * y∥ = ∥(x.1*y.1, x.2*y.2)∥ : rfl
Expand Down Expand Up @@ -567,13 +622,10 @@ normed_field.norm_mul' a b
instance to_normed_comm_ring : normed_comm_ring α :=
{ norm_mul := λ a b, (norm_mul a b).le, ..‹normed_field α› }

@[simp] lemma norm_one : ∥(1 : α)∥ = 1 :=
have ∥(1 : α)∥ * ∥(1 : α)∥ = ∥(1 : α)∥ * 1, by calc
∥(1 : α)∥ * ∥(1 : α)∥ = ∥(1 : α) * (1 : α)∥ : by rw normed_field.norm_mul'
... = ∥(1 : α)∥ * 1 : by simp,
mul_left_cancel' (ne_of_gt (norm_pos_iff.2 (by simp))) this

@[simp] lemma nnnorm_one : nnnorm (1:α) = 1 := nnreal.eq $ by simp
@[priority 900]
instance to_norm_one_class : norm_one_class α :=
⟨mul_left_cancel' (mt norm_eq_zero.1 (@one_ne_zero α _ _)) $
by rw [← norm_mul, mul_one, mul_one]⟩

/-- `norm` as a `monoid_hom`. -/
@[simps] def norm_hom : α →* ℝ := ⟨norm, norm_one, norm_mul⟩
Expand Down Expand Up @@ -757,13 +809,17 @@ by rw [real.norm_of_nonneg (norm_nonneg _)]
@[simp] lemma nnnorm_norm [normed_group α] (a : α) : nnnorm ∥a∥ = nnnorm a :=
by simp only [nnnorm, norm_norm]

instance : normed_ring ℤ :=
instance : normed_comm_ring ℤ :=
{ norm := λ n, ∥(n : ℝ)∥,
norm_mul := λ m n, le_of_eq $ by simp only [norm, int.cast_mul, abs_mul],
dist_eq := λ m n, by simp only [int.dist_eq, norm, int.cast_sub] }
dist_eq := λ m n, by simp only [int.dist_eq, norm, int.cast_sub],
mul_comm := mul_comm }

@[norm_cast] lemma int.norm_cast_real (m : ℤ) : ∥(m : ℝ)∥ = ∥m∥ := rfl

instance : norm_one_class ℤ :=
by simp [← int.norm_cast_real]⟩

instance : normed_field ℚ :=
{ norm := λ r, ∥(r : ℝ)∥,
norm_mul' := λ r₁ r₂, by simp only [norm, rat.cast_mul, abs_mul],
Expand Down Expand Up @@ -1007,13 +1063,16 @@ include 𝕜
@[simp] lemma normed_algebra.norm_one : ∥(1:𝕜')∥ = 1 :=
by simpa using (norm_algebra_map_eq 𝕜' (1:𝕜))

lemma normed_algebra.norm_one_class : norm_one_class 𝕜' :=
⟨normed_algebra.norm_one 𝕜⟩

lemma normed_algebra.zero_ne_one : (0:𝕜') ≠ 1 :=
begin
refine (norm_pos_iff.mp _).symm,
rw @normed_algebra.norm_one 𝕜, norm_num,
end

lemma normed_algebra.to_nonzero : nontrivial 𝕜' :=
lemma normed_algebra.nontrivial : nontrivial 𝕜' :=
⟨⟨0, 1, normed_algebra.zero_ne_one 𝕜⟩⟩

end normed_algebra
Expand Down
6 changes: 3 additions & 3 deletions src/analysis/normed_space/units.lean
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ begin
have ht' : ∥t∥ < 1,
{ have : (2:ℝ)⁻¹ < 1 := by cancel_denoms,
linarith },
simp only [inverse_one_sub t ht', normed_field.norm_one, mul_one, set.mem_set_of_eq],
simp only [inverse_one_sub t ht', norm_one, mul_one, set.mem_set_of_eq],
change ∥(∑' (n : ℕ), t ^ n)∥ ≤ _,
have := normed_ring.tsum_geometric_of_norm_lt_1 t ht',
have : (1 - ∥t∥)⁻¹ ≤ 2,
Expand All @@ -191,7 +191,7 @@ end
/-- The function `λ t, inverse (x + t)` is O(1) as `t → 0`. -/
lemma inverse_add_norm (x : units R) : is_O (λ t, inverse (↑x + t)) (λ t, (1:ℝ)) (𝓝 (0:R)) :=
begin
simp only [is_O_iff, normed_field.norm_one, mul_one],
simp only [is_O_iff, norm_one, mul_one],
cases subsingleton_or_nontrivial R; resetI,
{ refine ⟨1, eventually_of_forall (λ t, _)⟩,
have : ∥inverse (↑x + t)∥ = 0 := by simp,
Expand Down Expand Up @@ -235,7 +235,7 @@ begin
rw hLHS,
refine le_trans (norm_mul_le _ _ ) _,
have h' : ∥(-(↑x⁻¹ * t)) ^ n∥ ≤ ∥(↑x⁻¹ : R)∥ ^ n * ∥t∥ ^ n,
{ calc ∥(-(↑x⁻¹ * t)) ^ n∥ ≤ ∥(-(↑x⁻¹ * t))∥ ^ n : norm_pow_le _ hn
{ calc ∥(-(↑x⁻¹ * t)) ^ n∥ ≤ ∥(-(↑x⁻¹ * t))∥ ^ n : norm_pow_le' _ hn
... = ∥↑x⁻¹ * t∥ ^ n : by rw norm_neg
... ≤ (∥(↑x⁻¹ : R)∥ * ∥t∥) ^ n : _
... = ∥(↑x⁻¹ : R)∥ ^ n * ∥t∥ ^ n : mul_pow _ _ n,
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/specific_limits.lean
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ begin
simp only [pow_zero],
refine le_trans (norm_add_le _ _) _,
have : ∥(∑' (b : ℕ), (λ n, x ^ (n + 1)) b)∥ ≤ (1 - ∥x∥)⁻¹ - 1,
{ refine tsum_of_norm_bounded _ (λ b, norm_pow_le _ (nat.succ_pos b)),
{ refine tsum_of_norm_bounded _ (λ b, norm_pow_le' _ (nat.succ_pos b)),
convert (has_sum_nat_add_iff' 1).mpr (has_sum_geometric_of_lt_1 (norm_nonneg x) h),
simp },
linarith
Expand Down
18 changes: 17 additions & 1 deletion src/data/finset/basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ erase_dup_eq_self.2 s.2
instance has_decidable_eq [decidable_eq α] : decidable_eq (finset α)
| s₁ s₂ := decidable_of_iff _ val_inj

/- membership -/
/-! ### membership -/

instance : has_mem α (finset α) := ⟨λ a s, a ∈ s.1

Expand Down Expand Up @@ -172,6 +172,11 @@ instance : inhabited (finset α) := ⟨∅⟩

@[simp] theorem not_mem_empty (a : α) : a ∉ (∅ : finset α) := id

@[simp] theorem not_nonempty_empty : ¬(∅ : finset α).nonempty :=
λ ⟨x, hx⟩, not_mem_empty x hx

@[simp] theorem mk_zero : (⟨0, nodup_zero⟩ : finset α) = ∅ := rfl

theorem ne_empty_of_mem {a : α} {s : finset α} (h : a ∈ s) : s ≠ ∅ :=
λ e, not_mem_empty a $ e ▸ h

Expand Down Expand Up @@ -264,6 +269,17 @@ by rcases s with ⟨⟨s⟩⟩; apply list.mem_cons_iff

@[simp] theorem cons_val {a : α} {s : finset α} (h : a ∉ s) : (cons a s h).1 = a :: s.1 := rfl

@[simp] theorem mk_cons {a : α} {s : multiset α} (h : (a :: s).nodup) :
(⟨a :: s, h⟩ : finset α) = cons a ⟨s, (multiset.nodup_cons.1 h).2⟩ (multiset.nodup_cons.1 h).1 :=
rfl

@[simp] theorem nonempty_cons {a : α} {s : finset α} (h : a ∉ s) : (cons a s h).nonempty :=
⟨a, mem_cons.2 (or.inl rfl)⟩

@[simp] lemma nonempty_mk_coe : ∀ {l : list α} {hl}, (⟨↑l, hl⟩ : finset α).nonempty ↔ l ≠ []
| [] hl := by simp
| (a::l) hl := by simp [← multiset.cons_coe]

/-! ### disjoint union -/

/-- `disj_union s t h` is the set such that `a ∈ disj_union s t h` iff `a ∈ s` or `a ∈ t`.
Expand Down
40 changes: 18 additions & 22 deletions src/data/padics/padic_integers.lean
Original file line number Diff line number Diff line change
Expand Up @@ -201,22 +201,6 @@ instance : has_norm ℤ_[p] := ⟨λ z, ∥(z : ℚ_[p])∥⟩

variables {p}

lemma norm_def {z : ℤ_[p]} : ∥z∥ = ∥(z : ℚ_[p])∥ := rfl

variables (p)

instance : normed_ring ℤ_[p] :=
{ dist_eq := λ ⟨_, _⟩ ⟨_, _⟩, rfl,
norm_mul := λ ⟨_, _⟩ ⟨_, _⟩, norm_mul_le _ _ }

instance : is_absolute_value (λ z : ℤ_[p], ∥z∥) :=
{ abv_nonneg := norm_nonneg,
abv_eq_zero := λ ⟨_, _⟩, by simp [norm_eq_zero],
abv_add := λ ⟨_,_⟩ ⟨_, _⟩, norm_add_le _ _,
abv_mul := λ _ _, by simp only [norm_def, padic_norm_e.mul, padic_int.coe_mul]}

variables {p}

protected lemma mul_comm : ∀ z1 z2 : ℤ_[p], z1*z2 = z2*z1
| ⟨q1, h1⟩ ⟨q2, h2⟩ := show (⟨q1*q2, _⟩ : ℤ_[p]) = ⟨q2*q1, _⟩, by simp [_root_.mul_comm]

Expand All @@ -231,15 +215,29 @@ have a * b = 0, from subtype.ext_iff_val.1 h,
(λ h1, or.inl (by simp [h1]; refl))
(λ h2, or.inr (by simp [h2]; refl))

lemma norm_def {z : ℤ_[p]} : ∥z∥ = ∥(z : ℚ_[p])∥ := rfl

variables (p)

instance : normed_comm_ring ℤ_[p] :=
{ dist_eq := λ ⟨_, _⟩ ⟨_, _⟩, rfl,
norm_mul := λ ⟨_, _⟩ ⟨_, _⟩, norm_mul_le _ _,
mul_comm := padic_int.mul_comm }

instance : norm_one_class ℤ_[p] := ⟨norm_def.trans norm_one⟩

instance : is_absolute_value (λ z : ℤ_[p], ∥z∥) :=
{ abv_nonneg := norm_nonneg,
abv_eq_zero := λ ⟨_, _⟩, by simp [norm_eq_zero],
abv_add := λ ⟨_,_⟩ ⟨_, _⟩, norm_add_le _ _,
abv_mul := λ _ _, by simp only [norm_def, padic_norm_e.mul, padic_int.coe_mul]}

instance : comm_ring ℤ_[p] :=
{ mul_comm := padic_int.mul_comm,
..padic_int.ring }
variables {p}

instance : integral_domain ℤ_[p] :=
{ eq_zero_or_eq_zero_of_mul_eq_zero := λ x y, padic_int.eq_zero_or_eq_zero_of_mul_eq_zero x y,
exists_pair_ne := ⟨0, 1, padic_int.zero_ne_one⟩,
..padic_int.comm_ring }
.. padic_int.normed_comm_ring p }

end padic_int

Expand All @@ -250,8 +248,6 @@ variables {p : ℕ} [fact p.prime]
lemma norm_le_one : ∀ z : ℤ_[p], ∥z∥ ≤ 1
| ⟨_, h⟩ := h

@[simp] lemma norm_one : ∥(1 : ℤ_[p])∥ = 1 := normed_field.norm_one

@[simp] lemma norm_mul (z1 z2 : ℤ_[p]) : ∥z1 * z2∥ = ∥z1∥ * ∥z2∥ :=
by simp [norm_def]

Expand Down

0 comments on commit 4851857

Please sign in to comment.