MAT3253 Complex Variables

7. Chapter 7.3 Differentiation rules and differentiation at the point at infinity🔗

import Mathlib.Data.Complex.Basic
import Mathlib.Tactic

In this section we formulate three L'Hospital rules for complex functions

  1. The basic version of L'Hospital rule:

  • Assumptions: f(z₀)=g(z₀)=0, and g'(z₀) ≠ 0

  • Then, lim (f(z)/g(z)) = f'(z₀)/g'(z₀)

  1. Alternate form of L'Hospital rule

  • Assumptions: f(z₀)=0, and g(z) has a simple zero at z₀

  • Then, lim (f(z)/g(z)) = f'(z₀)/g'(z₀)

  1. L'Hospital rule at the point at infinity

  • Assumptions: f(∞)=g(∞)=0, and g'(∞) ≠ 0

  • Then, lim (f(z)/g(z)) = f'(∞)/g'(∞)

Open a noncomputable section Lhospital rule

noncomputable section Lhospital_rule

We will need functions from the namespaces Complex, Filter, and Topology.

open Complex Filter Topology

By deriative, we mean Frechet deriative:

f x' = f x + (x' - x) • f' + o(x' - x) where x' converges to x.

This is implemented in Mathlib API HasDerivAt f f' x

HasDerivAt.{u, v} {𝕜 : Type u} [NontriviallyNormedField 𝕜] {F : Type v} [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] [ContinuousSMul 𝕜 F] (f : 𝕜 F) (f' : F) (x : 𝕜) : Prop#check HasDerivAt

The first LHospital rule is similar as in the real case.

Note: We can comment out the line {f g : ℂ → ℂ} {z₀ f' g' : ℂ} and replace it with {f g : ℝ → ℝ} {z₀ f' g' : ℝ}, and the same proof will work.

/-- L'Hôpital's Rule for complex differentiable functions at a point where both vanish. If f(z₀) = 0, g(z₀) = 0, and g'(z₀) ≠ 0, then lim (f(z)/g(z)) = f'(z₀)/g'(z₀). -/ theorem complex_lhopital_zero_zero --{f g : ℝ → ℝ} {z₀ f' g' : ℝ} We can uncomment this line {f g : } {z₀ f' g' : } -- and comment this line (hf : HasDerivAt f f' z₀) (hg : HasDerivAt g g' z₀) (hf0 : f z₀ = 0) (hg0 : g z₀ = 0) (hg_ne : g' 0) : Tendsto (fun z f z / g z) (𝓝[≠] z₀) (𝓝 (f' / g')) := f: g: z₀:f':g':hf:HasDerivAt f f' z₀hg:HasDerivAt g g' z₀hf0:f z₀ = 0hg0:g z₀ = 0hg_ne:g' 0Tendsto (fun z => f z / g z) (𝓝[≠] z₀) (𝓝 (f' / g')) /- By definition of the derivative, we know that \lim_{z \to z_0} \frac{f(z) - f(z_0)}{z - z_0} = f'(z_0) \lim_{z \to z_0} \frac{g(z) - g(z_0)}{z - z_0} = g'(z_0). -/ have h_deriv : Filter.Tendsto (fun z => (f z - f z₀) / (z - z₀)) (nhdsWithin z₀ {z₀}) (nhds f') Filter.Tendsto (fun z => (g z - g z₀) / (z - z₀)) (nhdsWithin z₀ {z₀}) (nhds g') := f: g: z₀:f':g':hf:HasDerivAt f f' z₀hg:HasDerivAt g g' z₀hf0:f z₀ = 0hg0:g z₀ = 0hg_ne:g' 0Tendsto (fun z => f z / g z) (𝓝[≠] z₀) (𝓝 (f' / g')) -- By definition of HasDerivAt, we know that the limit -- of (f(z) - f(z₀)) / (z - z₀) as z approaches z₀ -- is f', and similarly for g. have h_deriv_f : Filter.Tendsto (fun z => (f z - f z₀) / (z - z₀)) (nhdsWithin z₀ {z₀}) (nhds f') := f: g: z₀:f':g':hf:HasDerivAt f f' z₀hg:HasDerivAt g g' z₀hf0:f z₀ = 0hg0:g z₀ = 0hg_ne:g' 0Tendsto (fun z => f z / g z) (𝓝[≠] z₀) (𝓝 (f' / g')) f: g: z₀:f':g':hf:Tendsto (slope f z₀) (𝓝[≠] z₀) (𝓝 f')hg:HasDerivAt g g' z₀hf0:f z₀ = 0hg0:g z₀ = 0hg_ne:g' 0Tendsto (fun z => (f z - f z₀) / (z - z₀)) (𝓝[≠] z₀) (𝓝 f') All goals completed! 🐙 have h_deriv_g : Filter.Tendsto (fun z => (g z - g z₀) / (z - z₀)) (nhdsWithin z₀ {z₀}) (nhds g') := f: g: z₀:f':g':hf:HasDerivAt f f' z₀hg:HasDerivAt g g' z₀hf0:f z₀ = 0hg0:g z₀ = 0hg_ne:g' 0Tendsto (fun z => f z / g z) (𝓝[≠] z₀) (𝓝 (f' / g')) f: g: z₀:f':g':hf:HasDerivAt f f' z₀hg:Tendsto (slope g z₀) (𝓝[≠] z₀) (𝓝 g')hf0:f z₀ = 0hg0:g z₀ = 0hg_ne:g' 0h_deriv_f:Tendsto (fun z => (f z - f z₀) / (z - z₀)) (𝓝[≠] z₀) (𝓝 f')Tendsto (fun z => (g z - g z₀) / (z - z₀)) (𝓝[≠] z₀) (𝓝 g') All goals completed! 🐙 All goals completed! 🐙 -- Since the denominator is non-zero, we can apply -- the fact that the limit of a quotient is -- the quotient of the limits. have h_quot : Filter.Tendsto (fun z => ((f z - f z₀) / (z - z₀)) / ((g z - g z₀) / (z - z₀))) (nhdsWithin z₀ {z₀}) (nhds (f' / g')) := f: g: z₀:f':g':hf:HasDerivAt f f' z₀hg:HasDerivAt g g' z₀hf0:f z₀ = 0hg0:g z₀ = 0hg_ne:g' 0Tendsto (fun z => f z / g z) (𝓝[≠] z₀) (𝓝 (f' / g')) All goals completed! 🐙 -- Apply the congruence rule. -- This allows us to prove the limits are the same -- if the functions are equal near z₀. f: g: z₀:f':g':hf:HasDerivAt f f' z₀hg:HasDerivAt g g' z₀hf0:f z₀ = 0hg0:g z₀ = 0hg_ne:g' 0h_deriv:Tendsto (fun z => (f z - f z₀) / (z - z₀)) (𝓝[≠] z₀) (𝓝 f') Tendsto (fun z => (g z - g z₀) / (z - z₀)) (𝓝[≠] z₀) (𝓝 g')h_quot:Tendsto (fun z => (f z - f z₀) / (z - z₀) / ((g z - g z₀) / (z - z₀))) (𝓝[≠] z₀) (𝓝 (f' / g'))(fun z => (f z - f z₀) / (z - z₀) / ((g z - g z₀) / (z - z₀))) =ᶠ[𝓝[≠] z₀] fun z => f z / g z -- Filter to the set of points where z ≠ z₀. -- The filter 𝓝[≠] z₀ guarantees -- we only care about z where z ≠ z₀. filter_upwards [self_mem_nhdsWithin] with z f: g: z₀:f':g':hf:HasDerivAt f f' z₀hg:HasDerivAt g g' z₀hf0:f z₀ = 0hg0:g z₀ = 0hg_ne:g' 0h_deriv:Tendsto (fun z => (f z - f z₀) / (z - z₀)) (𝓝[≠] z₀) (𝓝 f') Tendsto (fun z => (g z - g z₀) / (z - z₀)) (𝓝[≠] z₀) (𝓝 g')h_quot:Tendsto (fun z => (f z - f z₀) / (z - z₀) / ((g z - g z₀) / (z - z₀))) (𝓝[≠] z₀) (𝓝 (f' / g'))z:hz:z {z₀}(f z - f z₀) / (z - z₀) / ((g z - g z₀) / (z - z₀)) = f z / g z -- Substitute f(z₀) = 0 and g(z₀) = 0 and -- simplify "something - 0" f: g: z₀:f':g':hf:HasDerivAt f f' z₀hg:HasDerivAt g g' z₀hf0:f z₀ = 0hg0:g z₀ = 0hg_ne:g' 0h_deriv:Tendsto (fun z => (f z - f z₀) / (z - z₀)) (𝓝[≠] z₀) (𝓝 f') Tendsto (fun z => (g z - g z₀) / (z - z₀)) (𝓝[≠] z₀) (𝓝 g')h_quot:Tendsto (fun z => (f z - f z₀) / (z - z₀) / ((g z - g z₀) / (z - z₀))) (𝓝[≠] z₀) (𝓝 (f' / g'))z:hz:z {z₀}f z / (z - z₀) / (g z / (z - z₀)) = f z / g z -- Perform the algebraic cancellation of (z - z₀). -- We need to establish that the denominator -- (z - z₀) is not zero. f: g: z₀:f':g':hf:HasDerivAt f f' z₀hg:HasDerivAt g g' z₀hf0:f z₀ = 0hg0:g z₀ = 0hg_ne:g' 0h_deriv:Tendsto (fun z => (f z - f z₀) / (z - z₀)) (𝓝[≠] z₀) (𝓝 f') Tendsto (fun z => (g z - g z₀) / (z - z₀)) (𝓝[≠] z₀) (𝓝 g')h_quot:Tendsto (fun z => (f z - f z₀) / (z - z₀) / ((g z - g z₀) / (z - z₀))) (𝓝[≠] z₀) (𝓝 (f' / g'))z:hz:z {z₀}h_ne:z - z₀ 0f z / (z - z₀) / (g z / (z - z₀)) = f z / g z -- Use field_simp to cancel the common factor. -- Alternatively, you could use: -- rw [div_div_div_cancel_right _ _ h_ne] All goals completed! 🐙

We Will use deriv and iteratedDeriv in the next theorem. The API deriv f x returns the derivative of function f at the point x, iteratedDeriv n f x returns the n-th derivative of function f at the point x.

deriv.{u, v} {𝕜 : Type u} [NontriviallyNormedField 𝕜] {F : Type v} [AddCommGroup F] [Module 𝕜 F] [TopologicalSpace F] (f : 𝕜 F) (x : 𝕜) : F#check deriv iteratedDeriv.{u_1, u_2} {𝕜 : Type u_1} [NontriviallyNormedField 𝕜] {F : Type u_2} [NormedAddCommGroup F] [NormedSpace 𝕜 F] (n : ) (f : 𝕜 F) (x : 𝕜) : F#check iteratedDeriv

A function g has zero order m if the m-th deriative is not zero, but for all k<m, the k-th deriative vanishes.

def HasZeroOrder (g : ) (z₀ : ) (m : ) : Prop := ( k < m, iteratedDeriv k g z₀ = 0) (iteratedDeriv m g z₀ 0) /-- L'Hopital's rule for complex functions at a point where the denominator has a simple zero (order 1). The formula f'/g' is valid whe g has zero order m=1. -/ theorem complex_lhopital_zero_zero' {f g : } {z₀ f' g' : } (hf : HasDerivAt f f' z₀) (hg : HasDerivAt g g' z₀) (hf0 : f z₀ = 0) (hg0 : g z₀ = 0) (m : ) (hm : m = 1) (hg_zero_order : HasZeroOrder g z₀ m) : Tendsto (fun z f z / g z) (𝓝[≠] z₀) (𝓝 (f' / g')) := f: g: z₀:f':g':hf:HasDerivAt f f' z₀hg:HasDerivAt g g' z₀hf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mTendsto (fun z => f z / g z) (𝓝[≠] z₀) (𝓝 (f' / g')) f: g: z₀:f':g':hf:Tendsto (fun t => t⁻¹ (f (z₀ + t) - f z₀)) (𝓝[≠] 0) (𝓝 f')hg:Tendsto (fun t => t⁻¹ (g (z₀ + t) - g z₀)) (𝓝[≠] 0) (𝓝 g')hf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mTendsto (fun z => f z / g z) (𝓝[≠] z₀) (𝓝 (f' / g')); -- We'll use the fact that if the denominator is -- non-zero and the numerator tends to a limit, then -- the quotient tends to the quotient of the limits. have h_div : Filter.Tendsto (fun t => (f (z₀ + t) - f z₀) / (g (z₀ + t) - g z₀)) (nhdsWithin 0 {0}) (nhds (f' / g')) := f: g: z₀:f':g':hf:HasDerivAt f f' z₀hg:HasDerivAt g g' z₀hf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mTendsto (fun z => f z / g z) (𝓝[≠] z₀) (𝓝 (f' / g')) have h_div : Filter.Tendsto (fun t => (f (z₀ + t) - f z₀)/ t / ((g (z₀+t) - g z₀) / t)) (nhdsWithin 0 {0}) (nhds (f' / g')) := f: g: z₀:f':g':hf:HasDerivAt f f' z₀hg:HasDerivAt g g' z₀hf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mTendsto (fun z => f z / g z) (𝓝[≠] z₀) (𝓝 (f' / g')) f: g: z₀:f':g':hf:Tendsto (fun t => t⁻¹ (f (z₀ + t) - f z₀)) (𝓝[≠] 0) (𝓝 f')hg:Tendsto (fun t => t⁻¹ (g (z₀ + t) - g z₀)) (𝓝[≠] 0) (𝓝 g')hf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ m(fun t => (f (z₀ + t) - f z₀) / t / ((g (z₀ + t) - g z₀) / t)) = (fun t => t⁻¹ (f (z₀ + t) - f z₀)) / fun t => t⁻¹ (g (z₀ + t) - g z₀)f: g: z₀:f':g':hf:Tendsto (fun t => t⁻¹ (f (z₀ + t) - f z₀)) (𝓝[≠] 0) (𝓝 f')hg:Tendsto (fun t => t⁻¹ (g (z₀ + t) - g z₀)) (𝓝[≠] 0) (𝓝 g')hf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mg' 0; f: g: z₀:f':g':hf:Tendsto (fun t => t⁻¹ (f (z₀ + t) - f z₀)) (𝓝[≠] 0) (𝓝 f')hg:Tendsto (fun t => t⁻¹ (g (z₀ + t) - g z₀)) (𝓝[≠] 0) (𝓝 g')hf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ m(fun t => (f (z₀ + t) - f z₀) / t / ((g (z₀ + t) - g z₀) / t)) = (fun t => t⁻¹ (f (z₀ + t) - f z₀)) / fun t => t⁻¹ (g (z₀ + t) - g z₀) f: g: z₀:f':g':hf:Tendsto (fun t => t⁻¹ (f (z₀ + t) - f z₀)) (𝓝[≠] 0) (𝓝 f')hg:Tendsto (fun t => t⁻¹ (g (z₀ + t) - g z₀)) (𝓝[≠] 0) (𝓝 g')hf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mx✝:(f (z₀ + x✝) - f z₀) / x✝ / ((g (z₀ + x✝) - g z₀) / x✝) = ((fun t => t⁻¹ (f (z₀ + t) - f z₀)) / fun t => t⁻¹ (g (z₀ + t) - g z₀)) x✝; All goals completed! 🐙 f: g: z₀:f':g':hf:Tendsto (fun t => t⁻¹ (f (z₀ + t) - f z₀)) (𝓝[≠] 0) (𝓝 f')hg:Tendsto (fun t => t⁻¹ (g (z₀ + t) - g z₀)) (𝓝[≠] 0) (𝓝 g')hf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mg' 0 f: g: z₀:f':g':m:hf:Tendsto (fun t => t⁻¹ * f (z₀ + t)) (𝓝[≠] 0) (𝓝 f')hg:Tendsto (fun t => t⁻¹ * g (z₀ + t)) (𝓝[≠] 0) (𝓝 g')hf0:f z₀ = 0hg0:g z₀ = 0hm:m = 1hg_zero_order:¬deriv g z₀ = 0¬g' = 0; f: g: z₀:f':g':m:hf:Tendsto (fun t => t⁻¹ * f (z₀ + t)) (𝓝[≠] 0) (𝓝 f')hg:Tendsto (fun t => t⁻¹ * g (z₀ + t)) (𝓝[≠] 0) (𝓝 g')hf0:f z₀ = 0hg0:g z₀ = 0hm:m = 1hg_zero_order:g' = 0deriv g z₀ = 0 f: g: z₀:f':g':m:hf:Tendsto (fun t => t⁻¹ * f (z₀ + t)) (𝓝[≠] 0) (𝓝 f')hg:Tendsto (fun t => t⁻¹ * g (z₀ + t)) (𝓝[≠] 0) (𝓝 g')hf0:f z₀ = 0hg0:g z₀ = 0hm:m = 1hg_zero_order:g' = 0g' = 0; All goals completed! 🐙 refine' h_div.congr' ( f: g: z₀:f':g':hf:Tendsto (fun t => t⁻¹ (f (z₀ + t) - f z₀)) (𝓝[≠] 0) (𝓝 f')hg:Tendsto (fun t => t⁻¹ (g (z₀ + t) - g z₀)) (𝓝[≠] 0) (𝓝 g')hf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mh_div:Tendsto (fun t => (f (z₀ + t) - f z₀) / t / ((g (z₀ + t) - g z₀) / t)) (𝓝[≠] 0) (𝓝 (f' / g'))(fun t => (f (z₀ + t) - f z₀) / t / ((g (z₀ + t) - g z₀) / t)) =ᶠ[𝓝[≠] 0] fun t => (f (z₀ + t) - f z₀) / (g (z₀ + t) - g z₀) filter_upwards [ self_mem_nhdsWithin ] with t f: g: z₀:f':g':hf:Tendsto (fun t => t⁻¹ (f (z₀ + t) - f z₀)) (𝓝[≠] 0) (𝓝 f')hg:Tendsto (fun t => t⁻¹ (g (z₀ + t) - g z₀)) (𝓝[≠] 0) (𝓝 g')hf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mh_div:Tendsto (fun t => (f (z₀ + t) - f z₀) / t / ((g (z₀ + t) - g z₀) / t)) (𝓝[≠] 0) (𝓝 (f' / g'))t:ht:t {0}(f (z₀ + t) - f z₀) / t / ((g (z₀ + t) - g z₀) / t) = (f (z₀ + t) - f z₀) / (g (z₀ + t) - g z₀) using f: g: z₀:f':g':hf:Tendsto (fun t => t⁻¹ (f (z₀ + t) - f z₀)) (𝓝[≠] 0) (𝓝 f')hg:Tendsto (fun t => t⁻¹ (g (z₀ + t) - g z₀)) (𝓝[≠] 0) (𝓝 g')hf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mh_div:Tendsto (fun t => (f (z₀ + t) - f z₀) / t / ((g (z₀ + t) - g z₀) / t)) (𝓝[≠] 0) (𝓝 (f' / g'))t:ht:t {0}(f (z₀ + t) - f z₀) / t / ((g (z₀ + t) - g z₀) / t) = (f (z₀ + t) - f z₀) / (g (z₀ + t) - g z₀) f: g: z₀:f':g':hf:Tendsto (fun t => t⁻¹ (f (z₀ + t) - f z₀)) (𝓝[≠] 0) (𝓝 f')hg:Tendsto (fun t => t⁻¹ (g (z₀ + t) - g z₀)) (𝓝[≠] 0) (𝓝 g')hf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mh_div:Tendsto (fun t => (f (z₀ + t) - f z₀) / t / ((g (z₀ + t) - g z₀) / t)) (𝓝[≠] 0) (𝓝 (f' / g'))t:ht:t {0}(f (z₀ + t) - f z₀) / t / ((g (z₀ + t) - g z₀) / t) = (f (z₀ + t) - f z₀) / (g (z₀ + t) - g z₀)All goals completed! 🐙} ) f: g: z₀:f':g':hf: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist (x⁻¹ (f (z₀ + x) - f z₀)) f' < εhg: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist (x⁻¹ (g (z₀ + x) - g z₀)) g' < εhf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mh_div: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist ((f (z₀ + x) - f z₀) / (g (z₀ + x) - g z₀)) (f' / g') < ε ε > 0, δ > 0, x : ⦄, x {z₀} dist x z₀ < δ dist (f x / g x) (f' / g') < ε intro ε f: g: z₀:f':g':hf: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist (x⁻¹ (f (z₀ + x) - f z₀)) f' < εhg: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist (x⁻¹ (g (z₀ + x) - g z₀)) g' < εhf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mh_div: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist ((f (z₀ + x) - f z₀) / (g (z₀ + x) - g z₀)) (f' / g') < εε::ε > 0 δ > 0, x : ⦄, x {z₀} dist x z₀ < δ dist (f x / g x) (f' / g') < ε f: g: z₀:f':g':hf: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist (x⁻¹ (f (z₀ + x) - f z₀)) f' < εhg: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist (x⁻¹ (g (z₀ + x) - g z₀)) g' < εhf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mh_div: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist ((f (z₀ + x) - f z₀) / (g (z₀ + x) - g z₀)) (f' / g') < εε::ε > 0δ::δ > 0H: x : ⦄, x {0} dist x 0 < δ dist ((f (z₀ + x) - f z₀) / (g (z₀ + x) - g z₀)) (f' / g') < ε δ > 0, x : ⦄, x {z₀} dist x z₀ < δ dist (f x / g x) (f' / g') < ε exact δ, , fun { x } hx₁ hx₂ => f: g: z₀:f':g':hf: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist (x⁻¹ (f (z₀ + x) - f z₀)) f' < εhg: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist (x⁻¹ (g (z₀ + x) - g z₀)) g' < εhf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mh_div: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist ((f (z₀ + x) - f z₀) / (g (z₀ + x) - g z₀)) (f' / g') < εε::ε > 0δ::δ > 0H: x : ⦄, x {0} dist x 0 < δ dist ((f (z₀ + x) - f z₀) / (g (z₀ + x) - g z₀)) (f' / g') < εx:hx₁:x {z₀}hx₂:dist x z₀ < δdist (f x / g x) (f' / g') < ε simpa [ * ] using H ( sub_ne_zero_of_ne hx₁ ) <| f: g: z₀:f':g':hf: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist (x⁻¹ (f (z₀ + x) - f z₀)) f' < εhg: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist (x⁻¹ (g (z₀ + x) - g z₀)) g' < εhf0:f z₀ = 0hg0:g z₀ = 0m:hm:m = 1hg_zero_order:HasZeroOrder g z₀ mh_div: ε > 0, δ > 0, x : ⦄, x {0} dist x 0 < δ dist ((f (z₀ + x) - f z₀) / (g (z₀ + x) - g z₀)) (f' / g') < εε::ε > 0δ::δ > 0H: x : ⦄, x {0} dist x 0 < δ dist ((f (z₀ + x) - f z₀) / (g (z₀ + x) - g z₀)) (f' / g') < εx:hx₁:x {z₀}hx₂:dist x z₀ < δdist (x - z₀) 0 < δ All goals completed! 🐙

For the point at infinity, we define HasDerivAtInfinity f f' as

\lim_{z \to \infty} z f(z) = f'.

def HasDerivAtInfinity (f : ) (f' : ) := Filter.Tendsto (fun z z * f z) (Filter.cocompact ) (nhds f')

We show that if HasDerivAtInfinity f f' and HasDerivAtInfinity g g' with g' \neq 0, then

\lim_{z \to \infty} f(z)/g(z) = f'/g'.

/-- L'Hopital's rule for the form 0/0 at infinity. If f and g behave like f'/z and g'/z at infinity, then f/g tends to f'/g'. -/ theorem complex_lhopital_infinity_infinity {f g : } {f' g' : } (hf : HasDerivAtInfinity f f') (hg : HasDerivAtInfinity g g') (hg_ne : g' 0) : Filter.Tendsto (fun z f z / g z) (Filter.cocompact ) (nhds (f' / g')) := f: g: f':g':hf:HasDerivAtInfinity f f'hg:HasDerivAtInfinity g g'hg_ne:g' 0Tendsto (fun z => f z / g z) (cocompact ) (𝓝 (f' / g')) -- We have f(z)/g(z) = (zf(z)) / (zg(z)) for z ≠ 0. suffices h_eq : Filter.Tendsto (fun z => (z * f z) / (z * g z)) (Filter.cocompact ) (nhds (f' / g')) f: g: f':g':hf:HasDerivAtInfinity f f'hg:HasDerivAtInfinity g g'hg_ne:g' 0h_eq:Tendsto (fun z => z * f z / (z * g z)) (cocompact ) (𝓝 (f' / g'))Tendsto (fun z => f z / g z) (cocompact ) (𝓝 (f' / g')) f: g: f':g':hf:HasDerivAtInfinity f f'hg:HasDerivAtInfinity g g'hg_ne:g' 0h_eq:Tendsto (fun z => z * f z / (z * g z)) (cocompact ) (𝓝 (f' / g'))(fun z => z * f z / (z * g z)) =ᶠ[cocompact ] fun z => f z / g z ; filter_upwards [ ( Filter.mem_cocompact.mpr Metric.closedBall 0 1, ProperSpace.isCompact_closedBall _ _, f: g: f':g':hf:HasDerivAtInfinity f f'hg:HasDerivAtInfinity g g'hg_ne:g' 0h_eq:Tendsto (fun z => z * f z / (z * g z)) (cocompact ) (𝓝 (f' / g'))(Metric.closedBall 0 1) ?m.60 All goals completed! 🐙 ) ] with x f: g: f':g':hf:HasDerivAtInfinity f f'hg:HasDerivAtInfinity g g'hg_ne:g' 0h_eq:Tendsto (fun z => z * f z / (z * g z)) (cocompact ) (𝓝 (f' / g'))x:hx:x (Metric.closedBall 0 1)x * f x / (x * g x) = f x / g x ; f: g: f':g':hf:HasDerivAtInfinity f f'hg:HasDerivAtInfinity g g'hg_ne:g' 0h_eq:Tendsto (fun z => z * f z / (z * g z)) (cocompact ) (𝓝 (f' / g'))x:hx:x (Metric.closedBall 0 1)h:x = 0x * f x / (x * g x) = f x / g xf: g: f':g':hf:HasDerivAtInfinity f f'hg:HasDerivAtInfinity g g'hg_ne:g' 0h_eq:Tendsto (fun z => z * f z / (z * g z)) (cocompact ) (𝓝 (f' / g'))x:hx:x (Metric.closedBall 0 1)h:¬x = 0x * f x / (x * g x) = f x / g x f: g: f':g':hf:HasDerivAtInfinity f f'hg:HasDerivAtInfinity g g'hg_ne:g' 0h_eq:Tendsto (fun z => z * f z / (z * g z)) (cocompact ) (𝓝 (f' / g'))x:hx:x (Metric.closedBall 0 1)h:x = 0x * f x / (x * g x) = f x / g xf: g: f':g':hf:HasDerivAtInfinity f f'hg:HasDerivAtInfinity g g'hg_ne:g' 0h_eq:Tendsto (fun z => z * f z / (z * g z)) (cocompact ) (𝓝 (f' / g'))x:hx:x (Metric.closedBall 0 1)h:¬x = 0x * f x / (x * g x) = f x / g x All goals completed! 🐙 /- Since $z * f(z) \to f'$ and $z * g(z) \to g'$ as $z \to \infty$, we can use the fact that the ratio of two functions that tend to their respective limits also tends to the ratio of the limits. -/ have h_tendsto : Filter.Tendsto (fun z => z * f z) (Filter.cocompact ) (nhds f') Filter.Tendsto (fun z => z * g z) (Filter.cocompact ) (nhds g') := f: g: f':g':hf:HasDerivAtInfinity f f'hg:HasDerivAtInfinity g g'hg_ne:g' 0Tendsto (fun z => f z / g z) (cocompact ) (𝓝 (f' / g')) f: g: f':g':hf:Tendsto (fun z => z * f z) (cocompact ) (𝓝 f')hg:Tendsto (fun z => z * g z) (cocompact ) (𝓝 g')hg_ne:g' 0Tendsto (fun z => z * f z) (cocompact ) (𝓝 f') Tendsto (fun z => z * g z) (cocompact ) (𝓝 g') All goals completed! 🐙; All goals completed! 🐙 end Lhospital_rule