Analysis II (Tao, 2022) -- Chapter 04 -- Section 06

section Chap04section Section06

Definition 4.6.1 (Complex numbers): the set of complex numbers is , where Unknown identifier `i`i is a symbol satisfying Unknown identifier `i`sorry ^ 2 = -1 : Propi^2 = -1. In Lean, this is identified with the existing type : Type.

abbrev complexNumbers : Type :=

Every complex number can be written in the form Unknown identifier `a`sorry + sorry : ?m.5a + Unknown identifier `b`b i with .

theorem complexNumbers_exists_real_imag (z : ) : a b : , z = (a : ) + (b : ) * Complex.I := by refine z.re, z.im, ?_ try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa using (Complex.re_add_im z).symm

Helper for Lemma 4.6.2: every complex number admits a real-imaginary pair representation Unknown identifier `z`sorry = sorry + sorry : Propz = Unknown identifier `a`a + Unknown identifier `bi`bi.

lemma helperForLemma_4_6_2_canonicalDecompositionExists (z : ) : p : × , z = (p.1 : ) + (p.2 : ) * Complex.I := by refine (z.re, z.im), ?_ try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa using (Complex.re_add_im z).symm

Helper for Lemma 4.6.2: any representation Unknown identifier `z`sorry = sorry + sorry : Propz = Unknown identifier `a`a + Unknown identifier `bi`bi must use and .

lemma helperForLemma_4_6_2_coordinatesFromRepresentation {z : } {p : × } (h : z = (p.1 : ) + (p.2 : ) * Complex.I) : p.1 = z.re p.2 = z.im := by have hRe : z.re = p.1 := by exact (congrArg Complex.re h).trans (by simp) have hIm : z.im = p.2 := by exact (congrArg Complex.im h).trans (by simp) exact hRe.symm, hIm.symm

Helper for Lemma 4.6.2: the pair (sorry, sorry) : ?m.1 × ?m.2(Unknown identifier `Re`Re z, Unknown identifier `Im`Im z) is the unique coefficient pair in a decomposition Unknown identifier `z`sorry = sorry + sorry : Propz = Unknown identifier `a`a + Unknown identifier `bi`bi.

lemma helperForLemma_4_6_2_uniqueDecompositionPair (z : ) (p : × ) (h : z = (p.1 : ) + (p.2 : ) * Complex.I) : p = (z.re, z.im) := by rcases helperForLemma_4_6_2_coordinatesFromRepresentation h with h1, h2 exact Prod.ext h1 h2

Helper for Lemma 4.6.2: the imaginary unit squares to -1 : -1.

lemma helperForLemma_4_6_2_iSquared : Complex.I ^ 2 = (-1 : ) := by try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa using Complex.I_sq

Helper for Lemma 4.6.2: negation agrees with multiplication by -1 : -1.

lemma helperForLemma_4_6_2_negEqualsNegOneMul (z : ) : -z = ((-1 : ) * z) := by try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa using (neg_one_mul z).symm

Lemma 4.6.2: every has a unique decomposition Unknown identifier `z`sorry = sorry + sorry : Propz = Unknown identifier `a`a + Unknown identifier `b`b i with ; moreover Unknown identifier `i`sorry ^ 2 = -1 : Propi^2 = -1 and for all .

theorem complex_unique_decomposition_i_sq_and_neg_mul : ( z : , ∃! p : × , z = (p.1 : ) + (p.2 : ) * Complex.I) Complex.I ^ 2 = (-1 : ) ( z : , -z = ((-1 : ) * z)) := by constructor · intro z rcases helperForLemma_4_6_2_canonicalDecompositionExists z with p, hp refine p, hp, ?_ intro q hq have hp' : p = (z.re, z.im) := helperForLemma_4_6_2_uniqueDecompositionPair z p hp have hq' : q = (z.re, z.im) := helperForLemma_4_6_2_uniqueDecompositionPair z q hq exact hq'.trans hp'.symm constructor · exact helperForLemma_4_6_2_iSquared · intro z exact helperForLemma_4_6_2_negEqualsNegOneMul z

Definition 4.6.2 (Complex numbers): (i) a complex number is an ordered pair (sorry, sorry) : ?m.1 × ?m.2(Unknown identifier `a`a, Unknown identifier `b`b) with ; (ii) equality is componentwise, i.e. (sorry, sorry) = (sorry, sorry) : Prop(Unknown identifier `a`a, Unknown identifier `b`b) = (Unknown identifier `c`c, Unknown identifier `d`d) iff Unknown identifier `a`sorry = sorry : Propa = Unknown identifier `c`c and Unknown identifier `b`sorry = sorry : Propb = Unknown identifier `d`d; (iii) the set of all such complex numbers is × : Type × .

abbrev complexNumbersAsPairs : Type := ×

Componentwise addition on ordered pairs of real numbers.

abbrev complexPairAdd (z w : complexNumbersAsPairs) : complexNumbersAsPairs := (z.1 + w.1, z.2 + w.2)

Componentwise negation on ordered pairs of real numbers.

abbrev complexPairNeg (z : complexNumbersAsPairs) : complexNumbersAsPairs := (-z.1, -z.2)

The zero ordered pair (0, 0) : × (0, 0) in × : Type × .

abbrev complexPairZero : complexNumbersAsPairs := (0, 0)

Definition 4.6.3 (Complex addition, negation, and zero): let : Type be the set of ordered pairs of real numbers. For Unknown identifier `z`sorry = (sorry, sorry) : Propz = (Unknown identifier `a`a, Unknown identifier `b`b) and Unknown identifier `w`sorry = (sorry, sorry) : Propw = (Unknown identifier `c`c, Unknown identifier `d`d), define , , and .

def complexPairAddNegZeroData : (complexNumbersAsPairs complexNumbersAsPairs complexNumbersAsPairs) × (complexNumbersAsPairs complexNumbersAsPairs) × complexNumbersAsPairs := (complexPairAdd, complexPairNeg, complexPairZero)

Lemma 4.6.1 (Addition on : Type satisfies the abelian group axioms): for all , (i) Unknown identifier `z₁`sorry + sorry = sorry + sorry : Propz₁ + Unknown identifier `z₂`z₂ = Unknown identifier `z₂`z₂ + Unknown identifier `z₁`z₁, (ii) sorry + sorry + sorry = sorry + (sorry + sorry) : Prop(Unknown identifier `z₁`z₁ + Unknown identifier `z₂`z₂) + Unknown identifier `z₃`z₃ = Unknown identifier `z₁`z₁ + (Unknown identifier `z₂`z₂ + Unknown identifier `z₃`z₃), (iii) , and (iv) . In particular, is an abelian group with identity element 0 : 0.

theorem complex_addition_abelian_group_axioms : ( z₁ z₂ : , z₁ + z₂ = z₂ + z₁) ( z₁ z₂ z₃ : , (z₁ + z₂) + z₃ = z₁ + (z₂ + z₃)) ( z₁ : , z₁ + 0 = z₁ 0 + z₁ = z₁) ( z₁ : , z₁ + (-z₁) = 0 (-z₁) + z₁ = 0) := by constructor · intro z₁ z₂ simpa using add_comm z₁ z₂ constructor · intro z₁ z₂ z₃ simpa using add_assoc z₁ z₂ z₃ constructor · intro z₁ constructor · try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa using add_zero z₁ · try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa using zero_add z₁ · intro z₁ constructor · try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa using add_right_neg z₁ · try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa using add_left_neg z₁

Definition 4.6.4 (Complex multiplication): for complex numbers viewed as ordered pairs z = (a, b) and w = (c, d), their product is zw = (ac - bd, ad + bc), and the complex multiplicative identity is 1_C = (1, 0).

def complexPairMulOneData : (complexNumbersAsPairs complexNumbersAsPairs complexNumbersAsPairs) × complexNumbersAsPairs := (fun z w => (z.1 * w.1 - z.2 * w.2, z.1 * w.2 + z.2 * w.1), (1, 0))

Definition 4.6.5 (Embedding of real numbers into complex numbers): define by identifying with (sorry, 0) : ?m.1 × (Unknown identifier `x`x, 0) in : Type.

def realToComplexEmbedding : := fun x => (x : )

The embedding of real numbers into complex numbers preserves equality, addition, negation, and multiplication.

theorem realToComplexEmbedding_respects_operations : ( x y : , x = y realToComplexEmbedding x = realToComplexEmbedding y) ( x₁ x₂ : , realToComplexEmbedding (x₁ + x₂) = realToComplexEmbedding x₁ + realToComplexEmbedding x₂) ( x : , realToComplexEmbedding (-x) = -realToComplexEmbedding x) ( x₁ x₂ : , realToComplexEmbedding (x₁ * x₂) = realToComplexEmbedding x₁ * realToComplexEmbedding x₂) := by constructor · intro x y try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa [realToComplexEmbedding] constructor · intro x₁ x₂ try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa [realToComplexEmbedding] constructor · intro x try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa [realToComplexEmbedding] · intro x₁ x₂ try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa [realToComplexEmbedding]

Definition 4.6.6 (Imaginary unit): the imaginary unit is the complex number failed to synthesize Membership ?m.1 Type Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.Unknown identifier `i`i defined by .

def imaginaryUnit : := 0, 1

A complex number is real when its imaginary part vanishes.

def IsRealComplex (z : ) : Prop := z.im = 0

A complex number is purely imaginary when its real part vanishes.

def IsPurelyImaginaryComplex (z : ) : Prop := z.re = 0

Definition 4.6.7 (Real and imaginary parts; complex conjugate): for , , a number is real iff , a number is purely imaginary iff , and the complex conjugate is .

theorem complex_real_imaginary_parts_and_conjugate (z : ) : z = (z.re : ) + Complex.I * (z.im : ) (IsRealComplex z z.im = 0) (IsPurelyImaginaryComplex z z.re = 0) star z = (z.re : ) - Complex.I * (z.im : ) := by constructor · simpa [mul_comm] using (Complex.re_add_im z).symm constructor · simp [IsRealComplex] constructor · simp [IsPurelyImaginaryComplex] · simpa [sub_eq_add_neg, mul_comm] using (Complex.re_add_im (star z)).symm

Helper for Proposition 4.6.2: equals written with Star.star.{u} {R : Type u} [self : Star R] : R Rstar.

lemma helperForProposition_4_6_2_re_eq_add_star (z : ) : (z.re : ) = (z + star z) / (2 : ) := by simpa using (Complex.re_eq_add_conj z)

Helper for Proposition 4.6.2: equals written with Star.star.{u} {R : Type u} [self : Star R] : R Rstar.

lemma helperForProposition_4_6_2_im_eq_sub_star (z : ) : (z.im : ) = (z - star z) / ((2 : ) * Complex.I) := by simpa using (Complex.im_eq_sub_conj z)

Proposition 4.6.2: for every complex number failed to synthesize Membership ?m.1 Type Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.Unknown identifier `z`z , and .

theorem complex_re_and_im_eq_conjugate_formulas (z : ) : ((z.re : ) = (z + star z) / (2 : )) ((z.im : ) = (z - star z) / ((2 : ) * Complex.I)) := by constructor · exact helperForProposition_4_6_2_re_eq_add_star z · exact helperForProposition_4_6_2_im_eq_sub_star z

Helper for Lemma 4.6.3: complex conjugation preserves addition, negation, and multiplication.

lemma helperForLemma_4_6_3_conj_add_neg_mul (z w : ) : star (z + w) = star z + star w star (-z) = -star z star (z * w) = star z * star w := by constructor · try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa using (starRingEnd ).map_add z w constructor · try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa using (starRingEnd ).map_neg z · try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa using (starRingEnd ).map_mul z w

Helper for Lemma 4.6.3: complex conjugation is involutive.

lemma helperForLemma_4_6_3_conj_involutive (z : ) : star (star z) = z := by try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa using (star_star z)

Helper for Lemma 4.6.3: complex conjugation is injective.

lemma helperForLemma_4_6_3_conj_eq_iff_eq (z w : ) : star z = star w z = w := by simpa using (star_injective.eq_iff (a := z) (b := w))

Helper for Lemma 4.6.3: fixed points of conjugation are exactly the real complex numbers.

lemma helperForLemma_4_6_3_conj_fixed_iff_isReal (z : ) : star z = z IsRealComplex z := by simpa [IsRealComplex] using (Complex.conj_eq_iff_im (z := z))

Lemma 4.6.3 (Complex conjugation is an involution): for , complex conjugation satisfies \overline{z + w} = \bar z + \bar w, \overline{-z} = -\bar z, \overline{z w} = \bar z \, \bar w, \overline{\bar z} = z, ` and moreover iff Unknown identifier `z`sorry = sorry : Propz = Unknown identifier `w`w, while iff Unknown identifier `z`z is real.

theorem complex_conjugation_involution (z w : ) : star (z + w) = star z + star w star (-z) = -star z star (z * w) = star z * star w star (star z) = z (star z = star w z = w) (star z = z IsRealComplex z) := by rcases helperForLemma_4_6_3_conj_add_neg_mul z w with hAdd, hNeg, hMul constructor · exact hAdd constructor · exact hNeg constructor · exact hMul constructor · exact helperForLemma_4_6_3_conj_involutive z constructor · exact helperForLemma_4_6_3_conj_eq_iff_eq z w · exact helperForLemma_4_6_3_conj_fixed_iff_isReal z

Definition 4.6.8 (Complex absolute value): for Unknown identifier `z`sorry = sorry + sorry : Propz = Unknown identifier `a`a + Unknown identifier `bi`bi with , the complex absolute value is the nonnegative real number . In Lean this is represented by the complex norm sorry : Unknown identifier `z`z.

noncomputable abbrev complexAbsoluteValue (z : ) : := z

Lemma 4.6.4: for every failed to synthesize Membership ?m.1 Type Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.Unknown identifier `z`z , the complex absolute value |sorry| : ?m.1|Unknown identifier `z`z| is a non-negative real number.

theorem complexAbsoluteValue_nonnegative (z : ) : 0 complexAbsoluteValue z := by try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa [complexAbsoluteValue] using norm_nonneg z

Lemma 4.6.5: for every failed to synthesize Membership ?m.1 Type Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.Unknown identifier `z`z , we have failed to synthesize AddGroup Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.|sorry| = 0 : Prop|Unknown identifier `z`z| = 0 if and only if Unknown identifier `z`sorry = 0 : Propz = 0.

theorem complexAbsoluteValue_eq_zero_iff (z : ) : complexAbsoluteValue z = 0 z = 0 := by try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa [complexAbsoluteValue] using (norm_eq_zero : z = 0 z = 0)

Helper for Lemma 4.6.6: is the real scalar Complex.normSq sorry : Complex.normSq Unknown identifier `z`z, viewed in : Type.

lemma helperForLemma_4_6_6_mulConj_eq_normSqCast (z : ) : z * star z = (Complex.normSq z : ) := by simpa using (Complex.mul_conj z)

Helper for Lemma 4.6.6: the real part of is Complex.normSq sorry : Complex.normSq Unknown identifier `z`z.

lemma helperForLemma_4_6_6_mulConj_re_eq_normSq (z : ) : (z * star z).re = Complex.normSq z := by simpa using congrArg Complex.re (helperForLemma_4_6_6_mulConj_eq_normSqCast z)

Helper for Lemma 4.6.6: equals |sorry| ^ 2 : ?m.8|Unknown identifier `z`z|^2.

lemma helperForLemma_4_6_6_mulConj_re_eq_absSq (z : ) : (z * star z).re = (complexAbsoluteValue z) ^ 2 := by calc (z * star z).re = Complex.normSq z := helperForLemma_4_6_6_mulConj_re_eq_normSq z _ = (complexAbsoluteValue z) ^ 2 := by simpa [complexAbsoluteValue] using (Complex.normSq_eq_norm_sq z)

Helper for Lemma 4.6.6: (|sorry| ^ 2) = |sorry| : Prop(|Unknown identifier `z`z|^2) = |Unknown identifier `z`z|.

lemma helperForLemma_4_6_6_sqrt_absSq_eq_absValue (z : ) : Real.sqrt ((complexAbsoluteValue z) ^ 2) = complexAbsoluteValue z := by calc Real.sqrt ((complexAbsoluteValue z) ^ 2) = |complexAbsoluteValue z| := by try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa using (Real.sqrt_sq_eq_abs (complexAbsoluteValue z)) _ = complexAbsoluteValue z := by exact abs_of_nonneg (complexAbsoluteValue_nonnegative z)

Lemma 4.6.6: for every failed to synthesize Membership ?m.1 Type Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.Unknown identifier `z`z , we have . In particular, , interpreted in Lean as .

theorem complex_mul_conj_eq_abs_sq_and_abs_eq_sqrt (z : ) : z * star z = ((complexAbsoluteValue z) ^ 2 : ) complexAbsoluteValue z = Real.sqrt ((z * star z).re) := by constructor · calc z * star z = (Complex.normSq z : ) := helperForLemma_4_6_6_mulConj_eq_normSqCast z _ = ((complexAbsoluteValue z) ^ 2 : ) := by simpa [complexAbsoluteValue] using congrArg (fun x : => (x : )) (Complex.normSq_eq_norm_sq z) · calc complexAbsoluteValue z = Real.sqrt ((complexAbsoluteValue z) ^ 2) := (helperForLemma_4_6_6_sqrt_absSq_eq_absValue z).symm _ = Real.sqrt ((z * star z).re) := by rw [helperForLemma_4_6_6_mulConj_re_eq_absSq z]

Lemma 4.6.7: for all , the complex absolute value is multiplicative: |sorry| = sorry : Prop|Unknown identifier `zw`zw| = |Unknown identifier `z`z| |w|.

lemma complexAbsoluteValue_mul (z w : ) : complexAbsoluteValue (z * w) = complexAbsoluteValue z * complexAbsoluteValue w := by try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa [complexAbsoluteValue] using (norm_mul z w)

Lemma 4.6.8: for every failed to synthesize Membership ?m.1 Type Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.Unknown identifier `z`z , the complex absolute value is invariant under complex conjugation: .

lemma complexAbsoluteValue_conj (z : ) : complexAbsoluteValue (star z) = complexAbsoluteValue z := by try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa [complexAbsoluteValue] using (norm_star z)

Proposition 4.6.3: if and Unknown identifier `w`sorry 0 : Propw 0, then |sorry / sorry| = |sorry| / |sorry| : Prop|Unknown identifier `z`z / Unknown identifier `w`w| = |Unknown identifier `z`z| / |Unknown identifier `w`w|.

theorem complexAbsoluteValue_div_of_ne_zero (z w : ) : w 0 complexAbsoluteValue (z / w) = complexAbsoluteValue z / complexAbsoluteValue w := by intro _ try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa [complexAbsoluteValue] using (norm_div z w)

Definition 4.6.9 (Complex reciprocal and quotient): for , the reciprocal is undefined at 0 : 0 and is otherwise; for , the quotient Unknown identifier `z`sorry / sorry : ?m.5z / Unknown identifier `w`w is defined when Unknown identifier `w`sorry 0 : Propw 0 by Unknown identifier `z`sorry * sorry ^ {-1} : ?m.16z * Unknown identifier `w`w^{-1}.

noncomputable def complexReciprocalQuotientPartialData : ( Option ) × ( Option ) := let reciprocal : Option := fun z => if z = 0 then none else some (((((complexAbsoluteValue z) ^ (2 : ))⁻¹ : ) : ) * star z) (reciprocal, fun z w => (reciprocal w).map (fun wInv => z * wInv))

Partial complex reciprocal: undefined at 0 : 0, and otherwise given by .

noncomputable def complexReciprocalPartial (z : ) : Option := complexReciprocalQuotientPartialData.1 z

Partial complex quotient: for , this is defined by mapping Unknown identifier `w`w to its partial reciprocal and multiplying by Unknown identifier `z`z.

noncomputable def complexQuotientPartial (z w : ) : Option := complexReciprocalQuotientPartialData.2 z w

Definition 4.6.10 (Complex exponential): for each failed to synthesize Membership ?m.1 Type Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.Unknown identifier `z`z , the complex exponential is defined by the power series .

noncomputable def complexExponential (z : ) : := ∑' n : , z ^ n / (Nat.factorial n : )

Theorem 4.6.1: for all , one has .

theorem complex_exp_add (z w : ) : Complex.exp (z + w) = Complex.exp z * Complex.exp w := by simpa using (Complex.exp_add z w)

Proposition 4.6.1: for every failed to synthesize Membership ?m.1 Type Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.Unknown identifier `z`z , the complex exponential commutes with complex conjugation, i.e. .

theorem complex_exp_conj (z : ) : Complex.exp (star z) = star (Complex.exp z) := by try 'simp' instead of 'simpa' Note: This linter can be disabled with `set_option linter.unnecessarySimpa false`simpa using (Complex.exp_conj z)

Helper for Lemma 4.6.9: the absolute value of the real part is bounded by the complex absolute value.

lemma helperForLemma_4_6_9_absRe_le_complexAbs (z : ) : |z.re| complexAbsoluteValue z := by simpa [complexAbsoluteValue] using (Complex.abs_re_le_norm z)

Helper for Lemma 4.6.9: the real part is bounded below by the negated complex absolute value.

lemma helperForLemma_4_6_9_negComplexAbs_le_re (z : ) : -complexAbsoluteValue z z.re := by exact (abs_le.mp (helperForLemma_4_6_9_absRe_le_complexAbs z)).1

Helper for Lemma 4.6.9: the real part is bounded above by the complex absolute value.

lemma helperForLemma_4_6_9_re_le_complexAbs (z : ) : z.re complexAbsoluteValue z := by exact (abs_le.mp (helperForLemma_4_6_9_absRe_le_complexAbs z)).2

Lemma 4.6.9: for every complex number Unknown identifier `z`z, its real part is bounded by its complex absolute value: .

theorem realPart_le_complexAbsoluteValue (z : ) : -complexAbsoluteValue z z.re z.re complexAbsoluteValue z := by constructor · exact helperForLemma_4_6_9_negComplexAbs_le_re z · exact helperForLemma_4_6_9_re_le_complexAbs z

Helper for Lemma 4.6.10: the absolute value of the imaginary part is bounded by the complex absolute value.

lemma helperForLemma_4_6_10_absIm_le_complexAbs (z : ) : |z.im| complexAbsoluteValue z := by simpa [complexAbsoluteValue] using (Complex.abs_im_le_norm z)

Helper for Lemma 4.6.10: the imaginary part is bounded below by the negated complex absolute value.

lemma helperForLemma_4_6_10_negComplexAbs_le_im (z : ) : -complexAbsoluteValue z z.im := by exact (abs_le.mp (helperForLemma_4_6_10_absIm_le_complexAbs z)).1

Helper for Lemma 4.6.10: the imaginary part is bounded above by the complex absolute value.

lemma helperForLemma_4_6_10_im_le_complexAbs (z : ) : z.im complexAbsoluteValue z := by exact (abs_le.mp (helperForLemma_4_6_10_absIm_le_complexAbs z)).2

Lemma 4.6.10: for every failed to synthesize Membership ?m.1 Type Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.Unknown identifier `z`z , the imaginary part is bounded by the complex absolute value: .

lemma imagPart_le_complexAbsoluteValue (z : ) : -complexAbsoluteValue z z.im z.im complexAbsoluteValue z := by constructor · exact helperForLemma_4_6_10_negComplexAbs_le_im z · exact helperForLemma_4_6_10_im_le_complexAbs z

Lemma 4.6.11: for every failed to synthesize Membership ?m.1 Type Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.Unknown identifier `z`z , the complex absolute value is bounded by the sum of the absolute values of its real and imaginary parts: .

lemma complexAbsoluteValue_le_abs_re_add_abs_im (z : ) : complexAbsoluteValue z |z.re| + |z.im| := by simpa [complexAbsoluteValue] using (Complex.norm_le_abs_re_add_abs_im z)

Lemma 4.6.12: for all , the complex absolute value satisfies the triangle inequality |sorry + sorry| |sorry| + |sorry| : Prop|Unknown identifier `z`z + Unknown identifier `w`w| |Unknown identifier `z`z| + |Unknown identifier `w`w|.

lemma complexAbsoluteValue_add_le (z w : ) : complexAbsoluteValue (z + w) complexAbsoluteValue z + complexAbsoluteValue w := by simpa [complexAbsoluteValue] using (norm_add_le z w)

Helper for Proposition 4.6.4: equality in the triangle inequality for complex norm is equivalent to the two numbers lying on the same real ray.

lemma helperForProposition_4_6_4_normEq_iff_sameRay (z w : ) : complexAbsoluteValue (z + w) = complexAbsoluteValue z + complexAbsoluteValue w SameRay z w := by simpa [complexAbsoluteValue] using (sameRay_iff_norm_add (x := z) (y := w)).symm

Helper for Proposition 4.6.4: two nonzero complex numbers on the same real ray differ by multiplication by a positive real scalar.

lemma helperForProposition_4_6_4_sameRay_to_existsPosMul (z w : ) (hz : z 0) (hw : w 0) (hzw : SameRay z w) : c : , 0 < c z = (c : ) * w := by rcases hzw.exists_pos_right hz hw with c, hc, hcw refine c, hc, ?_ simpa [Algebra.smul_def] using hcw

Helper for Proposition 4.6.4: if one complex number is a positive real multiple of another, then equality holds in the triangle inequality.

lemma helperForProposition_4_6_4_existsPosMul_to_normEq (z w : ) : ( c : , 0 < c z = (c : ) * w) complexAbsoluteValue (z + w) = complexAbsoluteValue z + complexAbsoluteValue w := by intro h rcases h with c, hc, hz have hz' : z = c w := by simpa [Algebra.smul_def] using hz have hRay : SameRay z w := by rw [hz'] exact SameRay.sameRay_pos_smul_left w hc exact (helperForProposition_4_6_4_normEq_iff_sameRay z w).2 hRay

Proposition 4.6.4: for nonzero complex numbers Unknown identifier `z`z and Unknown identifier `w`w, |sorry + sorry| = |sorry| + |sorry| : Prop|Unknown identifier `z`z + Unknown identifier `w`w| = |Unknown identifier `z`z| + |Unknown identifier `w`w| if and only if there exists a real number Unknown identifier `c`sorry > 0 : Propc > 0 such that Unknown identifier `z`sorry = sorry : Propz = Unknown identifier `c`c w.

theorem complexAbsoluteValue_add_eq_add_iff_exists_pos_real_mul (z w : ) (hz : z 0) (hw : w 0) : complexAbsoluteValue (z + w) = complexAbsoluteValue z + complexAbsoluteValue w c : , 0 < c z = (c : ) * w := by constructor · intro hEq have hRay : SameRay z w := (helperForProposition_4_6_4_normEq_iff_sameRay z w).1 hEq exact helperForProposition_4_6_4_sameRay_to_existsPosMul z w hz hw hRay · intro hMul exact helperForProposition_4_6_4_existsPosMul_to_normEq z w hMul

Helper for Proposition 4.6.5: if Unknown identifier `i`i is positive and positivity is closed under multiplication, then -1 : -1 is positive.

lemma helperForProposition_4_6_5_posNegOne_from_posI (Pos : Prop) (hMulPos : z w : , Pos z Pos w Pos (z * w)) (hPosI : Pos Complex.I) : Pos (-(1 : )) := by have hPosISq : Pos (Complex.I * Complex.I) := hMulPos Complex.I Complex.I hPosI hPosI simpa [Complex.I_sq] using hPosISq

Helper for Proposition 4.6.5: if Unknown identifier `i`i is negative, negation sends negatives to positives, and positivity is multiplicatively closed, then -1 : -1 is positive.

lemma helperForProposition_4_6_5_posNegOne_from_negI (Pos Neg : Prop) (hNegToPos : z : , Neg z Pos (-z)) (hMulPos : z w : , Pos z Pos w Pos (z * w)) (hNegI : Neg Complex.I) : Pos (-(1 : )) := by have hPosNegI : Pos (-Complex.I) := hNegToPos Complex.I hNegI have hPosNegISq : Pos ((-Complex.I) * (-Complex.I)) := hMulPos (-Complex.I) (-Complex.I) hPosNegI hPosNegI simpa [Complex.I_sq] using hPosNegISq

Helper for Proposition 4.6.5: trichotomy at Unknown identifier `i`i, together with the negation rule Neg sorry sorry : Sort (imax (u_1 + 1) u_2)Neg Unknown identifier `z`z Unknown identifier `Pos`Pos (-z) and multiplicative closure of positivity, forces -1 : -1 to be positive.

lemma helperForProposition_4_6_5_posNegOne (Pos Neg : Prop) (hTrichotomy : z : , Pos z Neg z z = 0) (hNegToPos : z : , Neg z Pos (-z)) (hMulPos : z w : , Pos z Pos w Pos (z * w)) : Pos (-(1 : )) := by rcases hTrichotomy Complex.I with hPosI | hNegI | hIeqZero · exact helperForProposition_4_6_5_posNegOne_from_posI Pos hMulPos hPosI · exact helperForProposition_4_6_5_posNegOne_from_negI Pos Neg hNegToPos hMulPos hNegI · exact False.elim (Complex.I_ne_zero hIeqZero)

Helper for Proposition 4.6.5: if -1 : -1 is positive, positivity is closed under multiplication, and positives negate to negatives, then exclusivity of positive/negative classes yields a contradiction.

lemma helperForProposition_4_6_5_contradiction_from_posNegOne (Pos Neg : Prop) (hPosNegExclusive : z : , ¬ (Pos z Neg z)) (hPosToNeg : z : , Pos z Neg (-z)) (hMulPos : z w : , Pos z Pos w Pos (z * w)) (hPosNegOne : Pos (-(1 : ))) : False := by have hPosOneMul : Pos ((-(1 : )) * (-(1 : ))) := hMulPos (-(1 : )) (-(1 : )) hPosNegOne hPosNegOne have hPosOne : Pos (1 : ) := by simpa using hPosOneMul have hNegNegOne : Neg (-(1 : )) := by simpa using hPosToNeg (1 : ) hPosOne exact hPosNegExclusive (-(1 : )) hPosNegOne, hNegNegOne

Proposition 4.6.5: there does not exist a partition of : Type into positive, negative, and zero classes such that for every : (i) exactly one of Unknown identifier `Pos`Pos z, Neg sorry : Type u_1Neg Unknown identifier `z`z, or Unknown identifier `z`sorry = 0 : Propz = 0 holds, (ii) positivity/negativity are exchanged by negation, (iii) positive numbers are closed under addition, and (iv) positive numbers are closed under multiplication.

theorem no_complex_positive_negative_zero_partition : ¬ Pos Neg : Prop, ( z : , (Pos z Neg z z = 0) ¬ (Pos z Neg z) ¬ (Pos z z = 0) ¬ (Neg z z = 0)) ( z : , Pos z Neg (-z)) ( z : , Neg z Pos (-z)) ( z w : , Pos z Pos w Pos (z + w)) ( z w : , Pos z Pos w Pos (z * w)) := by intro hExists rcases hExists with Pos, Neg, hPartition, hPosToNeg, hNegToPos, hAddPos, hMulPos have hTrichotomy : z : , Pos z Neg z z = 0 := by intro z exact (hPartition z).1 have hPosNegExclusive : z : , ¬ (Pos z Neg z) := by intro z exact (hPartition z).2.1 have hPosNegOne : Pos (-(1 : )) := helperForProposition_4_6_5_posNegOne Pos Neg hTrichotomy hNegToPos hMulPos exact helperForProposition_4_6_5_contradiction_from_posNegOne Pos Neg hPosNegExclusive hPosToNeg hMulPos hPosNegOne

Lemma 4.6.13: with on : Type, this gives the usual metric on : Type; moreover, a sequence Unknown identifier `z_n`z_n converges to Unknown identifier `z`z in this metric iff both real and imaginary parts converge, i.e. and .

lemma complex_tendsto_iff_re_im_tendsto (zSeq : ) (z : ) : let d : := fun z₁ z₂ => z₁ - z₂; (( z₁ z₂ : , 0 d z₁ z₂) ( z₁ z₂ : , d z₁ z₂ = 0 z₁ = z₂) ( z₁ z₂ : , d z₁ z₂ = d z₂ z₁) ( z₁ z₂ z₃ : , d z₁ z₃ d z₁ z₂ + d z₂ z₃)) (( ε > 0, N : , n N, d (zSeq n) z < ε) Filter.Tendsto (fun n => (zSeq n).re) Filter.atTop (nhds z.re) Filter.Tendsto (fun n => (zSeq n).im) Filter.atTop (nhds z.im)) := by dsimp constructor · constructor · intro z₁ z₂ exact norm_nonneg (z₁ - z₂) · constructor · intro z₁ z₂ constructor · intro h exact sub_eq_zero.mp (norm_eq_zero.mp h) · intro h simp [h] · constructor · intro z₁ z₂ simpa [sub_eq_add_neg, add_comm, add_left_comm, add_assoc] using (norm_sub_rev z₁ z₂) · intro z₁ z₂ z₃ simpa [dist_eq_norm] using (dist_triangle z₁ z₂ z₃) · constructor · intro h have hz : Filter.Tendsto zSeq Filter.atTop (nhds z) := (Metric.tendsto_atTop.2 h) constructor · exact (Complex.continuous_re.tendsto z).comp hz · exact (Complex.continuous_im.tendsto z).comp hz · intro h rcases h with hre, him have hpair : Filter.Tendsto (fun n => ((zSeq n).re, (zSeq n).im)) Filter.atTop (nhds (z.re, z.im)) := by simpa [nhds_prod_eq] using hre.prodMk him have hsymm : Filter.Tendsto (fun p : × => Complex.equivRealProdCLM.symm p) (nhds (z.re, z.im)) (nhds (Complex.equivRealProdCLM.symm (z.re, z.im))) := (Complex.equivRealProdCLM.symm.continuous.tendsto (z.re, z.im)) have hz : Filter.Tendsto (fun n => Complex.equivRealProdCLM.symm ((zSeq n).re, (zSeq n).im)) Filter.atTop (nhds (Complex.equivRealProdCLM.symm (z.re, z.im))) := hsymm.comp hpair have hz' : Filter.Tendsto zSeq Filter.atTop (nhds z) := by simpa [Complex.equivRealProdCLM_symm_apply, Complex.re_add_im] using hz exact (Metric.tendsto_atTop.1 hz')

Helper for Lemma 4.6.14: bundled arithmetic limit laws in : Type for sum, difference, scalar multiplication, and product.

lemma helperForLemma_4_6_14_arith_tendsto_bundle (zSeq wSeq : ) (z w c : ) (hz : Filter.Tendsto zSeq Filter.atTop (nhds z)) (hw : Filter.Tendsto wSeq Filter.atTop (nhds w)) : Filter.Tendsto (fun n => zSeq n + wSeq n) Filter.atTop (nhds (z + w)) Filter.Tendsto (fun n => zSeq n - wSeq n) Filter.atTop (nhds (z - w)) Filter.Tendsto (fun n => c * zSeq n) Filter.atTop (nhds (c * z)) Filter.Tendsto (fun n => zSeq n * wSeq n) Filter.atTop (nhds (z * w)) := by constructor · exact hz.add hw constructor · exact hz.sub hw constructor · exact hz.const_mul c · exact hz.mul hw

Helper for Lemma 4.6.14: conjugation preserves sequence limits in : Type.

lemma helperForLemma_4_6_14_star_tendsto (zSeq : ) (z : ) (hz : Filter.Tendsto zSeq Filter.atTop (nhds z)) : Filter.Tendsto (fun n => star (zSeq n)) Filter.atTop (nhds (star z)) := by simpa using hz.star

Helper for Lemma 4.6.14: quotient limit law in : Type under nonzero limit.

lemma helperForLemma_4_6_14_div_tendsto (zSeq wSeq : ) (z w : ) (hz : Filter.Tendsto zSeq Filter.atTop (nhds z)) (hw : Filter.Tendsto wSeq Filter.atTop (nhds w)) : ( n : , wSeq n 0) w 0 Filter.Tendsto (fun n => zSeq n / wSeq n) Filter.atTop (nhds (z / w)) := by intro _ hw0 exact hz.div hw hw0

Lemma 4.6.14 (Complex limit laws): if Unknown identifier `zₙ`sorry sorry : Sort (imax u_1 u_2)zₙ Unknown identifier `z`z and Unknown identifier `wₙ`sorry sorry : Sort (imax u_1 u_2)wₙ Unknown identifier `w`w in : Type, then Unknown identifier `zₙ`sorry + sorry sorry + sorry : Sort (imax u_3 u_6)zₙ + Unknown identifier `wₙ`wₙ Unknown identifier `z`z + Unknown identifier `w`w, Unknown identifier `zₙ`sorry - sorry sorry - sorry : Sort (imax u_3 u_6)zₙ - Unknown identifier `wₙ`wₙ Unknown identifier `z`z - Unknown identifier `w`w, Unknown identifier `c`sorry sorry : Sort (imax u_1 u_2)c zₙ Unknown identifier `c`c z, Unknown identifier `zₙ`sorry sorry : Sort (imax u_1 u_2)zₙ wₙ Unknown identifier `z`z w, and Unknown identifier `conj`sorry sorry : Sort (imax u_1 u_2)conj zₙ Unknown identifier `conj`conj z; moreover, if Unknown identifier `wₙ`sorry 0 : Propwₙ 0 for all Unknown identifier `n`n and Unknown identifier `w`sorry 0 : Propw 0, then Unknown identifier `zₙ`sorry / sorry sorry / sorry : Sort (imax u_3 u_6)zₙ / Unknown identifier `wₙ`wₙ Unknown identifier `z`z / Unknown identifier `w`w.

lemma complex_limit_laws (zSeq wSeq : ) (z w c : ) (hz : Filter.Tendsto zSeq Filter.atTop (nhds z)) (hw : Filter.Tendsto wSeq Filter.atTop (nhds w)) : Filter.Tendsto (fun n => zSeq n + wSeq n) Filter.atTop (nhds (z + w)) Filter.Tendsto (fun n => zSeq n - wSeq n) Filter.atTop (nhds (z - w)) Filter.Tendsto (fun n => c * zSeq n) Filter.atTop (nhds (c * z)) Filter.Tendsto (fun n => zSeq n * wSeq n) Filter.atTop (nhds (z * w)) Filter.Tendsto (fun n => star (zSeq n)) Filter.atTop (nhds (star z)) (( n : , wSeq n 0) w 0 Filter.Tendsto (fun n => zSeq n / wSeq n) Filter.atTop (nhds (z / w))) := by rcases helperForLemma_4_6_14_arith_tendsto_bundle zSeq wSeq z w c hz hw with hAdd, hSub, hConstMul, hMul constructor · exact hAdd constructor · exact hSub constructor · exact hConstMul constructor · exact hMul constructor · exact helperForLemma_4_6_14_star_tendsto zSeq z hz · exact helperForLemma_4_6_14_div_tendsto zSeq wSeq z w hz hw
end Section06end Chap04