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

Commit f7e862f

Browse files
committed
feat(analysis/special_functions/pow): z ^ w is continuous in (z, w) at (0, w) if 0 < re w (#13288)
Also add a few supporting lemmas.
1 parent 57682ff commit f7e862f

File tree

1 file changed

+48
-16
lines changed

1 file changed

+48
-16
lines changed

src/analysis/special_functions/pow.lean

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ begin
180180
{ exact continuous_at_const_cpow ha, },
181181
end
182182

183+
/-- The function `z ^ w` is continuous in `(z, w)` provided that `z` does not belong to the interval
184+
`(-∞, 0]` on the real line. See also `complex.continuous_at_cpow_zero_of_re_pos` for a version that
185+
works for `z = 0` but assumes `0 < re w`. -/
183186
lemma continuous_at_cpow {p : ℂ × ℂ} (hp_fst : 0 < p.fst.re ∨ p.fst.im ≠ 0) :
184187
continuous_at (λ x : ℂ × ℂ, x.1 ^ x.2) p :=
185188
begin
@@ -384,33 +387,37 @@ namespace complex
384387
lemma of_real_cpow {x : ℝ} (hx : 0 ≤ x) (y : ℝ) : ((x ^ y : ℝ) : ℂ) = (x : ℂ) ^ (y : ℂ) :=
385388
by simp [real.rpow_def_of_nonneg hx, complex.cpow_def]; split_ifs; simp [complex.of_real_log hx]
386389

387-
@[simp] lemma abs_cpow_real (x : ℂ) (y : ℝ) : abs (x ^ (y : ℂ)) = x.abs ^ y :=
390+
lemma abs_cpow_of_ne_zero {z : ℂ} (hz : z ≠ 0) (w : ℂ) :
391+
abs (z ^ w) = abs z ^ w.re / real.exp (arg z * im w) :=
392+
by rw [cpow_def_of_ne_zero hz, abs_exp, mul_re, log_re, log_im, real.exp_sub,
393+
real.rpow_def_of_pos (abs_pos.2 hz)]
394+
395+
lemma abs_cpow_le (z w : ℂ) : abs (z ^ w) ≤ abs z ^ w.re / real.exp (arg z * im w) :=
388396
begin
389-
rw [real.rpow_def_of_nonneg (abs_nonneg _), complex.cpow_def],
390-
split_ifs;
391-
simp [*, abs_of_nonneg (le_of_lt (real.exp_pos _)), complex.log, complex.exp_add,
392-
add_mul, mul_right_comm _ I, exp_mul_I, abs_cos_add_sin_mul_I,
393-
(complex.of_real_mul _ _).symm, -complex.of_real_mul, -is_R_or_C.of_real_mul] at *
397+
rcases ne_or_eq z 0 with hz|rfl; [exact (abs_cpow_of_ne_zero hz w).le, rw abs_zero],
398+
rcases eq_or_ne w 0 with rfl|hw, { simp },
399+
rw [zero_cpow hw, abs_zero],
400+
exact div_nonneg (real.rpow_nonneg_of_nonneg le_rfl _) (real.exp_pos _).le
394401
end
395402

403+
@[simp] lemma abs_cpow_real (x : ℂ) (y : ℝ) : abs (x ^ (y : ℂ)) = x.abs ^ y :=
404+
by rcases eq_or_ne x 0 with rfl|hx; [rcases eq_or_ne y 0 with rfl|hy, skip];
405+
simp [*, abs_cpow_of_ne_zero]
406+
396407
@[simp] lemma abs_cpow_inv_nat (x : ℂ) (n : ℕ) : abs (x ^ (n⁻¹ : ℂ)) = x.abs ^ (n⁻¹ : ℝ) :=
397408
by rw ← abs_cpow_real; simp [-abs_cpow_real]
398409

399410
lemma abs_cpow_eq_rpow_re_of_pos {x : ℝ} (hx : 0 < x) (y : ℂ) : abs (x ^ y) = x ^ y.re :=
400-
begin
401-
rw [cpow_def_of_ne_zero (of_real_ne_zero.mpr hx.ne'), abs_exp, ←of_real_log hx.le,
402-
of_real_mul_re, real.exp_mul, real.exp_log hx],
403-
end
411+
by rw [abs_cpow_of_ne_zero (of_real_ne_zero.mpr hx.ne'), arg_of_real_of_nonneg hx.le, zero_mul,
412+
real.exp_zero, div_one, abs_of_nonneg hx.le]
404413

405414
lemma abs_cpow_eq_rpow_re_of_nonneg {x : ℝ} (hx : 0 ≤ x) {y : ℂ} (hy : re y ≠ 0) :
406415
abs (x ^ y) = x ^ y.re :=
407416
begin
408-
rw cpow_def, split_ifs with j1 j2,
409-
{ rw j2, simp, },
410-
{ rw of_real_eq_zero at j1, rw [j1, abs_zero, real.zero_rpow hy] },
411-
{ have : 0 < x := lt_of_le_of_ne hx (ne_comm.mp $ of_real_ne_zero.mp j1),
412-
have t := abs_cpow_eq_rpow_re_of_pos this y,
413-
rwa cpow_def_of_ne_zero (of_real_ne_zero.mpr this.ne') at t }
417+
rcases hx.eq_or_lt with rfl|hlt,
418+
{ rw [of_real_zero, zero_cpow, abs_zero, real.zero_rpow hy],
419+
exact ne_of_apply_ne re hy },
420+
{ exact abs_cpow_eq_rpow_re_of_pos hlt y }
414421
end
415422

416423
end complex
@@ -957,6 +964,31 @@ by simpa only [one_mul] using is_o_rpow_exp_pos_mul_at_top s one_pos
957964

958965
end limits
959966

967+
namespace complex
968+
969+
/-- See also `complex.continuous_at_cpow`. -/
970+
lemma continuous_at_cpow_zero_of_re_pos {z : ℂ} (hz : 0 < z.re) :
971+
continuous_at (λ x : ℂ × ℂ, x.1 ^ x.2) (0, z) :=
972+
begin
973+
have hz₀ : z ≠ 0, from ne_of_apply_ne re hz.ne',
974+
rw [continuous_at, zero_cpow hz₀, tendsto_zero_iff_norm_tendsto_zero],
975+
refine squeeze_zero (λ _, norm_nonneg _) (λ _, abs_cpow_le _ _) _,
976+
simp only [div_eq_mul_inv, ← real.exp_neg],
977+
refine tendsto.zero_mul_is_bounded_under_le _ _,
978+
{ convert (continuous_fst.norm.tendsto _).rpow ((continuous_re.comp continuous_snd).tendsto _) _;
979+
simp [hz, real.zero_rpow hz.ne'] },
980+
{ simp only [(∘), real.norm_eq_abs, abs_of_pos (real.exp_pos _)],
981+
rcases exists_gt (|im z|) with ⟨C, hC⟩,
982+
refine ⟨real.exp (π * C), eventually_map.2 _⟩,
983+
refine (((continuous_im.comp continuous_snd).abs.tendsto (_, z)).eventually
984+
(gt_mem_nhds hC)).mono (λ z hz, real.exp_le_exp.2 $ (neg_le_abs_self _).trans _),
985+
rw _root_.abs_mul,
986+
exact mul_le_mul (abs_le.2 ⟨(neg_pi_lt_arg _).le, arg_le_pi _⟩) hz.le
987+
(_root_.abs_nonneg _) real.pi_pos.le }
988+
end
989+
990+
end complex
991+
960992
namespace nnreal
961993

962994
/-- The nonnegative real power function `x^y`, defined for `x : ℝ≥0` and `y : ℝ ` as the

0 commit comments

Comments
 (0)