MAT3253 Complex Variables

6. Chapter 6.2 Complex differentiability and Cauchy-Riemann condition🔗

import Mathlib.Tactic
import Mathlib.Data.Complex.Basic
section ComplexDifferentiability

Definition 6.2.1. Let f : ℂ → ℂ be a complex function defined in a domain D. Given a point z₀ ∈ D, we say that f is complex differentiable at z₀ if there exists a complex constant w₀ such that

f(z₀ + Δz) ≈ f(z₀) + w₀ · Δz

in the sense that the error is o(Δz) as Δz → 0. The constant w₀ is called the derivative of f at z₀.

In Mathlib, this is captured by HasDerivAt f w₀ z₀, which asserts that:

‖f(z₀ + h) - f(z₀) - w₀ • h‖ / ‖h‖ → 0 as h → 0.

open Complex Filter def IsComplexDiffAt (f : ) (w₀ : ) (z₀ : ) : Prop := HasDerivAt f w₀ z₀

We prove the equivalence with the classical limit definition:

Theorem 6.2.2. Complex function f is complex differentiable at z₀ with derivative w₀ if and only if

\lim_{h → 0} (f(z_0 + h) - f(z_0)) / h = w_0.

theorem isComplexDiffAt_iff_limit (f : ) (w₀ : ) (z₀ : ) : IsComplexDiffAt f w₀ z₀ Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀) := f: w₀:z₀:IsComplexDiffAt f w₀ z₀ Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀) f: w₀:z₀:Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀) Tendsto (fun t => t⁻¹ (f (z₀ + t) - f z₀)) (nhdsWithin 0 {0}) (nhds w₀); All goals completed! 🐙 /-- Theorem 6.2.2 A complex function `f` is complex differentiable at `z₀` if and only if the limit `lim_{h → 0} (f(z₀ + h) - f(z₀)) / h` exists -/ theorem complex_differentiableAt_iff_limit_exists (f : ) (z₀ : ) : DifferentiableAt f z₀ w₀ : , Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀) := f: z₀:DifferentiableAt f z₀ w₀, Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀) f: z₀:DifferentiableAt f z₀ w₀, Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀)f: z₀:(∃ w₀, Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀)) DifferentiableAt f z₀ f: z₀:DifferentiableAt f z₀ w₀, Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀)f: z₀:(∃ w₀, Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀)) DifferentiableAt f z₀ f: z₀:h: w₀, Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀)DifferentiableAt f z₀ f: z₀:h:DifferentiableAt f z₀ w₀, Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀) f: z₀:h:DifferentiableAt f z₀(∃ w₀, Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀)) Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds (deriv f z₀)); f: z₀:h:DifferentiableAt f z₀(∃ w₀, Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀)) Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds (deriv f z₀))f: z₀:h:DifferentiableAt f z₀Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds (deriv f z₀)) w₀, Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀); f: z₀:h:DifferentiableAt f z₀(∃ w₀, Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀)) Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds (deriv f z₀)) exact fun _ => hasDerivAt_iff_tendsto_slope_zero.mp h.hasDerivAt |> fun h => h.congr fun x => f: z₀:h✝:DifferentiableAt f z₀x✝: w₀, Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀)h:Tendsto (fun t => t⁻¹ (f (z₀ + t) - f z₀)) (nhdsWithin 0 {0}) (nhds (deriv f z₀))x:x⁻¹ (f (z₀ + x) - f z₀) = (f (z₀ + x) - f z₀) / x All goals completed! 🐙; f: z₀:h:DifferentiableAt f z₀Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds (deriv f z₀)) w₀, Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀) All goals completed! 🐙; f: z₀:h: w₀, Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀)DifferentiableAt f z₀ f: z₀:w₀:hw₀:Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀)DifferentiableAt f z₀; f: z₀:w₀:hw₀:Tendsto (fun h => (f (z₀ + h) - f z₀) / h) (nhdsWithin 0 {0}) (nhds w₀)DifferentiableAt f z₀; f: z₀:w₀:hw₀:Tendsto (fun h => h⁻¹ * (f (z₀ + h) - f z₀)) (nhdsWithin 0 {0}) (nhds w₀)DifferentiableAt f z₀ ; f: z₀:w₀:hw₀:Tendsto (fun h => h⁻¹ * (f (z₀ + h) - f z₀)) (nhdsWithin 0 {0}) (nhds w₀)f: z₀:w₀:hw₀:Tendsto (fun h => h⁻¹ * (f (z₀ + h) - f z₀)) (nhdsWithin 0 {0}) (nhds w₀)Tendsto (fun t => t⁻¹ (f (z₀ + t) - f z₀)) (nhdsWithin 0 {0}) (nhds ?mpr.refine'_1) All goals completed! 🐙

Next, we prove another equivalent condition for complex differentiability expressed in terms of Cauchy-Riemann equation.

The function defined by multiplying a complex constant c from the left is linear in two senses. It is both \mathbb{R}-linear and is \mathbb{C}-linear. We distinguish them by two different definitions. The Cauchy-Riemann condition is a consequence of studying complex differentiable function as a real-linear function.

/-- Multiplication by `c` is an ℝ-linear continuous map `ℂ →L[ℝ] ℂ`. -/ noncomputable def ContLinearMap.mulLeftReal (c : ) : →L[] where toFun z := c * z map_add' x y := c:x:y:c * (x + y) = c * x + c * y All goals completed! 🐙 map_smul' r x := c:r:x:c * r x = (RingHom.id ) r (c * x) All goals completed! 🐙 cont := continuous_const.mul continuous_id /-- Multiplication by `c` is a ℂ-linear continuous map `ℂ →L[ℂ] ℂ`. -/ noncomputable def ContLinearMap.mulLeftComplex (c : ) : →L[] where toFun z := c * z map_add' x y := c:x:y:c * (x + y) = c * x + c * y All goals completed! 🐙 map_smul' r x := c:r:x:c * r x = (RingHom.id ) r (c * x) c:r:x:c * (r * x) = r * (c * x); All goals completed! 🐙 cont := continuous_const.mul continuous_id

Two helper functions to be used in the proof of the main theorem.

@[simp] lemma ContLinearMap.mulLeftReal_apply (c z : ) : ContLinearMap.mulLeftReal c z = c * z := rfl @[simp] lemma ContLinearMap.mulLeftComplex_apply (c z : ) : ContLinearMap.mulLeftComplex c z = c * z := rfl

We need some lemmas about real-linear and complex-linear functions.

/-- Every ℂ-linear map ℂ → ℂ is multiplication by a constant -/ lemma ContLinearMap.complex_apply_eq_mul (L : →L[] ) (z : ) : L z = L 1 * z := L: →L[] z:L z = L 1 * z L: →L[] z:L z = L (z 1)L: →L[] z:L 1 * z = z L 1 L: →L[] z:L z = L (z 1)L: →L[] z:L 1 * z = z L 1 All goals completed! 🐙 /-- Suppose two functions are equal, and one of them is real linear and the other one is complex linear. Then if the first one has deriative, the second one also has derivative -/ lemma hasFDerivAt_complex_real {f : } {L₁ : →L[] } {L₂ : →L[] } {z₀ : } (h : HasFDerivAt f L₁ z₀) (heq : z, L₁ z = L₂ z) : HasFDerivAt f L₂ z₀ := f: L₁: →L[] L₂: →L[] z₀:h:HasFDerivAt f L₁ z₀heq: (z : ), L₁ z = L₂ zHasFDerivAt f L₂ z₀ f: L₁: →L[] L₂: →L[] z₀:h:(fun h => f (z₀ + h) - f z₀ - L₁ h) =o[nhds 0] fun h => hheq: (z : ), L₁ z = L₂ z(fun h => f (z₀ + h) - f z₀ - L₂ h) =o[nhds 0] fun h => h; All goals completed! 🐙 lemma hasFDerivAt_real_complex {f : } {L₁ : →L[] } {L₂ : →L[] } {z₀ : } (h : HasFDerivAt f L₁ z₀) (heq : z, L₁ z = L₂ z) : HasFDerivAt f L₂ z₀ := f: L₁: →L[] L₂: →L[] z₀:h:HasFDerivAt f L₁ z₀heq: (z : ), L₁ z = L₂ zHasFDerivAt f L₂ z₀ f: L₁: →L[] L₂: →L[] z₀:h:(fun h => f (z₀ + h) - f z₀ - L₁ h) =o[nhds 0] fun h => hheq: (z : ), L₁ z = L₂ z(fun h => f (z₀ + h) - f z₀ - L₂ h) =o[nhds 0] fun h => h; All goals completed! 🐙 /-- Helper lemmas for ℝ-linear maps on ℂ -/ lemma clm_real_apply_eq (L : →L[] ) (z : ) : L z = z.re L 1 + z.im L I := L: →L[] z:L z = z.re L 1 + z.im L I L: →L[] z:L z = L (z.re 1 + z.im I)L: →L[] z:z.re L 1 + z.im L I = L (z.re 1) + L (z.im I) L: →L[] z:L z = L (z.re 1 + z.im I) All goals completed! 🐙; L: →L[] z:z.re L 1 + z.im L I = L (z.re 1) + L (z.im I) All goals completed! 🐙 /-- Real continuous linear map is complex linear if CR -/ lemma clm_real_is_mul_of_CR (L : →L[] ) (h1 : (L 1).re = (L I).im) (h2: (L I).re = -(L 1).im) : z, L z = (L 1) * z := L: →L[] h1:(L 1).re = (L I).imh2:(L I).re = -(L 1).im (z : ), L z = L 1 * z L: →L[] h1:(L 1).re = (L I).imh2:(L I).re = -(L 1).imz:L z = L 1 * z; exact (L: →L[] h1:(L 1).re = (L I).imh2:(L I).re = -(L 1).imz:L z = L 1 * z L: →L[] h1:(L 1).re = (L I).imh2:(L I).re = -(L 1).imz:L 1 * z = z.re L 1 + z.im L I ; L: →L[] h1:(L 1).re = (L I).imh2:(L I).re = -(L 1).imz:z.re * (L I).im - z.im * (L 1).im = z.re * (L I).im + -(z.im * (L 1).im) ; All goals completed! 🐙;)

Theorem 6.2.4. Suppose f(z) = u(x, y)+iv(x, y) is a complex function defined on a domain which contains z_0 = x_0 + iy_0. Then, f is complex differentiable at z_0 = x_0+iy_0 if and only if

  • the vector function (u(x, y), v(x, y)) is real-differentiable at (x_0, y_0),

  • the partial derivatives satisfy the Cauchy-Riemann equations

u_x = v_y, u_y = -v_x at (x_0,y_0)

/-- An equivalent condition for complex differentiability -/ theorem complex_diff_iff_real_diff_and_CR (f : ) (z₀ : ) : DifferentiableAt f z₀ DifferentiableAt f z₀ let u_x := (fderiv f z₀ 1).re let v_x := (fderiv f z₀ 1).im let u_y := (fderiv f z₀ I).re let v_y := (fderiv f z₀ I).im u_x = v_y u_y = -v_x := f: z₀:DifferentiableAt f z₀ DifferentiableAt f z₀ let u_x := ((fderiv f z₀) 1).re; let v_x := ((fderiv f z₀) 1).im; let u_y := ((fderiv f z₀) I).re; let v_y := ((fderiv f z₀) I).im; u_x = v_y u_y = -v_x f: z₀:DifferentiableAt f z₀ DifferentiableAt f z₀ let u_x := ((fderiv f z₀) 1).re; let v_x := ((fderiv f z₀) 1).im; let u_y := ((fderiv f z₀) I).re; let v_y := ((fderiv f z₀) I).im; u_x = v_y u_y = -v_xf: z₀:(DifferentiableAt f z₀ let u_x := ((fderiv f z₀) 1).re; let v_x := ((fderiv f z₀) 1).im; let u_y := ((fderiv f z₀) I).re; let v_y := ((fderiv f z₀) I).im; u_x = v_y u_y = -v_x) DifferentiableAt f z₀ f: z₀:DifferentiableAt f z₀ DifferentiableAt f z₀ let u_x := ((fderiv f z₀) 1).re; let v_x := ((fderiv f z₀) 1).im; let u_y := ((fderiv f z₀) I).re; let v_y := ((fderiv f z₀) I).im; u_x = v_y u_y = -v_x -- Forward: ℂ-differentiable → ℝ-differentiable + CR f: z₀:hf:DifferentiableAt f z₀DifferentiableAt f z₀ let u_x := ((fderiv f z₀) 1).re; let v_x := ((fderiv f z₀) 1).im; let u_y := ((fderiv f z₀) I).re; let v_y := ((fderiv f z₀) I).im; u_x = v_y u_y = -v_x f: z₀:L: →L[] hL:HasFDerivAt f L z₀DifferentiableAt f z₀ let u_x := ((fderiv f z₀) 1).re; let v_x := ((fderiv f z₀) 1).im; let u_y := ((fderiv f z₀) I).re; let v_y := ((fderiv f z₀) I).im; u_x = v_y u_y = -v_x f: z₀:L: →L[] hL:HasFDerivAt f L z₀c: := L 1DifferentiableAt f z₀ let u_x := ((fderiv f z₀) 1).re; let v_x := ((fderiv f z₀) 1).im; let u_y := ((fderiv f z₀) I).re; let v_y := ((fderiv f z₀) I).im; u_x = v_y u_y = -v_x -- Transfer to ℝ-HasFDerivAt via mulLeftReal have hL_real : HasFDerivAt f (ContLinearMap.mulLeftReal c) z₀ := hasFDerivAt_complex_real hL (fun z => f: z₀:L: →L[] hL:HasFDerivAt f L z₀c: := L 1z:L z = (ContLinearMap.mulLeftReal c) z f: z₀:L: →L[] hL:HasFDerivAt f L z₀c: := L 1z:L z = c * z All goals completed! 🐙) f: z₀:L: →L[] hL:HasFDerivAt f L z₀c: := L 1hL_real:HasFDerivAt f (ContLinearMap.mulLeftReal c) z₀DifferentiableAt f z₀f: z₀:L: →L[] hL:HasFDerivAt f L z₀c: := L 1hL_real:HasFDerivAt f (ContLinearMap.mulLeftReal c) z₀let u_x := ((fderiv f z₀) 1).re; let v_x := ((fderiv f z₀) 1).im; let u_y := ((fderiv f z₀) I).re; let v_y := ((fderiv f z₀) I).im; u_x = v_y u_y = -v_x f: z₀:L: →L[] hL:HasFDerivAt f L z₀c: := L 1hL_real:HasFDerivAt f (ContLinearMap.mulLeftReal c) z₀DifferentiableAt f z₀ All goals completed! 🐙 f: z₀:L: →L[] hL:HasFDerivAt f L z₀c: := L 1hL_real:HasFDerivAt f (ContLinearMap.mulLeftReal c) z₀let u_x := ((fderiv f z₀) 1).re; let v_x := ((fderiv f z₀) 1).im; let u_y := ((fderiv f z₀) I).re; let v_y := ((fderiv f z₀) I).im; u_x = v_y u_y = -v_x -- CR equations f: z₀:L: →L[] hL:HasFDerivAt f L z₀c: := L 1hL_real:HasFDerivAt f (ContLinearMap.mulLeftReal c) z₀h_eq:fderiv f z₀ = ContLinearMap.mulLeftReal clet u_x := ((fderiv f z₀) 1).re; let v_x := ((fderiv f z₀) 1).im; let u_y := ((fderiv f z₀) I).re; let v_y := ((fderiv f z₀) I).im; u_x = v_y u_y = -v_x f: z₀:L: →L[] hL:HasFDerivAt f L z₀c: := L 1hL_real:HasFDerivAt f (ContLinearMap.mulLeftReal c) z₀h_eq:fderiv f z₀ = ContLinearMap.mulLeftReal c(c * 1).re = (c * I).im (c * I).re = -(c * 1).im f: z₀:L: →L[] hL:HasFDerivAt f L z₀c: := L 1hL_real:HasFDerivAt f (ContLinearMap.mulLeftReal c) z₀h_eq:fderiv f z₀ = ContLinearMap.mulLeftReal c(c * 1).re = (c * I).imf: z₀:L: →L[] hL:HasFDerivAt f L z₀c: := L 1hL_real:HasFDerivAt f (ContLinearMap.mulLeftReal c) z₀h_eq:fderiv f z₀ = ContLinearMap.mulLeftReal c(c * I).re = -(c * 1).im f: z₀:L: →L[] hL:HasFDerivAt f L z₀c: := L 1hL_real:HasFDerivAt f (ContLinearMap.mulLeftReal c) z₀h_eq:fderiv f z₀ = ContLinearMap.mulLeftReal c(c * 1).re = (c * I).imf: z₀:L: →L[] hL:HasFDerivAt f L z₀c: := L 1hL_real:HasFDerivAt f (ContLinearMap.mulLeftReal c) z₀h_eq:fderiv f z₀ = ContLinearMap.mulLeftReal c(c * I).re = -(c * 1).im All goals completed! 🐙 f: z₀:(DifferentiableAt f z₀ let u_x := ((fderiv f z₀) 1).re; let v_x := ((fderiv f z₀) 1).im; let u_y := ((fderiv f z₀) I).re; let v_y := ((fderiv f z₀) I).im; u_x = v_y u_y = -v_x) DifferentiableAt f z₀ -- Backward: ℝ-differentiable + CR → ℂ-differentiable f: z₀:hf_real:DifferentiableAt f z₀h1:((fderiv f z₀) 1).re = ((fderiv f z₀) I).imh2:((fderiv f z₀) I).re = -((fderiv f z₀) 1).imDifferentiableAt f z₀ f: z₀:hf_real:DifferentiableAt f z₀h1:((fderiv f z₀) 1).re = ((fderiv f z₀) I).imh2:((fderiv f z₀) I).re = -((fderiv f z₀) 1).imh_mul: (z : ), (fderiv f z₀) z = (fderiv f z₀) 1 * zDifferentiableAt f z₀ have h_complex : HasFDerivAt f (ContLinearMap.mulLeftComplex (fderiv f z₀ 1)) z₀ := hasFDerivAt_real_complex hf_real.hasFDerivAt (fun z => f: z₀:hf_real:DifferentiableAt f z₀h1:((fderiv f z₀) 1).re = ((fderiv f z₀) I).imh2:((fderiv f z₀) I).re = -((fderiv f z₀) 1).imh_mul: (z : ), (fderiv f z₀) z = (fderiv f z₀) 1 * zz:(fderiv f z₀) z = (ContLinearMap.mulLeftComplex ((fderiv f z₀) 1)) z All goals completed! 🐙) All goals completed! 🐙

As a corollary, we obtain a necessary condition for complex differentiability.

Theorem 6.2.3. If a complex function is complex differentiable at a point, then it satisfies Cauchy-Riemann equation.

theorem complex_diff_implies_CR (f : ) (z₀ : ) : DifferentiableAt f z₀ DifferentiableAt f z₀ let u_x := (fderiv f z₀ 1).re let v_x := (fderiv f z₀ 1).im let u_y := (fderiv f z₀ I).re let v_y := (fderiv f z₀ I).im u_x = v_y u_y = -v_x := f: z₀:DifferentiableAt f z₀ DifferentiableAt f z₀ let u_x := ((fderiv f z₀) 1).re; let v_x := ((fderiv f z₀) 1).im; let u_y := ((fderiv f z₀) I).re; let v_y := ((fderiv f z₀) I).im; u_x = v_y u_y = -v_x f: z₀:h:DifferentiableAt f z₀DifferentiableAt f z₀ let u_x := ((fderiv f z₀) 1).re; let v_x := ((fderiv f z₀) 1).im; let u_y := ((fderiv f z₀) I).re; let v_y := ((fderiv f z₀) I).im; u_x = v_y u_y = -v_x All goals completed! 🐙 end ComplexDifferentiability