-
Notifications
You must be signed in to change notification settings - Fork 273
/
RealDeriv.lean
188 lines (152 loc) · 9.44 KB
/
RealDeriv.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/-
Copyright (c) Sébastien Gouëzel. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Sébastien Gouëzel, Yourong Zang
-/
import Mathlib.Analysis.Calculus.ContDiff.Basic
import Mathlib.Analysis.Calculus.Deriv.Linear
import Mathlib.Analysis.Complex.Conformal
import Mathlib.Analysis.Calculus.Conformal.NormedSpace
#align_import analysis.complex.real_deriv from "leanprover-community/mathlib"@"3bce8d800a6f2b8f63fe1e588fd76a9ff4adcebe"
/-! # Real differentiability of complex-differentiable functions
`HasDerivAt.real_of_complex` expresses that, if a function on `ℂ` is differentiable (over `ℂ`),
then its restriction to `ℝ` is differentiable over `ℝ`, with derivative the real part of the
complex derivative.
`DifferentiableAt.conformalAt` states that a real-differentiable function with a nonvanishing
differential from the complex plane into an arbitrary complex-normed space is conformal at a point
if it's holomorphic at that point. This is a version of Cauchy-Riemann equations.
`conformalAt_iff_differentiableAt_or_differentiableAt_comp_conj` proves that a real-differential
function with a nonvanishing differential between the complex plane is conformal at a point if and
only if it's holomorphic or antiholomorphic at that point.
## TODO
* The classical form of Cauchy-Riemann equations
* On a connected open set `u`, a function which is `ConformalAt` each point is either holomorphic
throughout or antiholomorphic throughout.
## Warning
We do NOT require conformal functions to be orientation-preserving in this file.
-/
section RealDerivOfComplex
/-! ### Differentiability of the restriction to `ℝ` of complex functions -/
open Complex
variable {e : ℂ → ℂ} {e' : ℂ} {z : ℝ}
/-- If a complex function is differentiable at a real point, then the induced real function is also
differentiable at this point, with a derivative equal to the real part of the complex derivative. -/
theorem HasStrictDerivAt.real_of_complex (h : HasStrictDerivAt e e' z) :
HasStrictDerivAt (fun x : ℝ => (e x).re) e'.re z := by
have A : HasStrictFDerivAt ((↑) : ℝ → ℂ) ofRealCLM z := ofRealCLM.hasStrictFDerivAt
have B :
HasStrictFDerivAt e ((ContinuousLinearMap.smulRight 1 e' : ℂ →L[ℂ] ℂ).restrictScalars ℝ)
(ofRealCLM z) :=
h.hasStrictFDerivAt.restrictScalars ℝ
have C : HasStrictFDerivAt re reCLM (e (ofRealCLM z)) := reCLM.hasStrictFDerivAt
-- Porting note: this should be by:
-- simpa using (C.comp z (B.comp z A)).hasStrictDerivAt
-- but for some reason simp can not use `ContinuousLinearMap.comp_apply`
convert (C.comp z (B.comp z A)).hasStrictDerivAt
rw [ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply]
simp
#align has_strict_deriv_at.real_of_complex HasStrictDerivAt.real_of_complex
/-- If a complex function `e` is differentiable at a real point, then the function `ℝ → ℝ` given by
the real part of `e` is also differentiable at this point, with a derivative equal to the real part
of the complex derivative. -/
theorem HasDerivAt.real_of_complex (h : HasDerivAt e e' z) :
HasDerivAt (fun x : ℝ => (e x).re) e'.re z := by
have A : HasFDerivAt ((↑) : ℝ → ℂ) ofRealCLM z := ofRealCLM.hasFDerivAt
have B :
HasFDerivAt e ((ContinuousLinearMap.smulRight 1 e' : ℂ →L[ℂ] ℂ).restrictScalars ℝ)
(ofRealCLM z) :=
h.hasFDerivAt.restrictScalars ℝ
have C : HasFDerivAt re reCLM (e (ofRealCLM z)) := reCLM.hasFDerivAt
-- Porting note: this should be by:
-- simpa using (C.comp z (B.comp z A)).hasStrictDerivAt
-- but for some reason simp can not use `ContinuousLinearMap.comp_apply`
convert (C.comp z (B.comp z A)).hasDerivAt
rw [ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply]
simp
#align has_deriv_at.real_of_complex HasDerivAt.real_of_complex
theorem ContDiffAt.real_of_complex {n : ℕ∞} (h : ContDiffAt ℂ n e z) :
ContDiffAt ℝ n (fun x : ℝ => (e x).re) z := by
have A : ContDiffAt ℝ n ((↑) : ℝ → ℂ) z := ofRealCLM.contDiff.contDiffAt
have B : ContDiffAt ℝ n e z := h.restrict_scalars ℝ
have C : ContDiffAt ℝ n re (e z) := reCLM.contDiff.contDiffAt
exact C.comp z (B.comp z A)
#align cont_diff_at.real_of_complex ContDiffAt.real_of_complex
theorem ContDiff.real_of_complex {n : ℕ∞} (h : ContDiff ℂ n e) :
ContDiff ℝ n fun x : ℝ => (e x).re :=
contDiff_iff_contDiffAt.2 fun _ => h.contDiffAt.real_of_complex
#align cont_diff.real_of_complex ContDiff.real_of_complex
variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℂ E]
theorem HasStrictDerivAt.complexToReal_fderiv' {f : ℂ → E} {x : ℂ} {f' : E}
(h : HasStrictDerivAt f f' x) :
HasStrictFDerivAt f (reCLM.smulRight f' + I • imCLM.smulRight f') x := by
simpa only [Complex.restrictScalars_one_smulRight'] using
h.hasStrictFDerivAt.restrictScalars ℝ
#align has_strict_deriv_at.complex_to_real_fderiv' HasStrictDerivAt.complexToReal_fderiv'
theorem HasDerivAt.complexToReal_fderiv' {f : ℂ → E} {x : ℂ} {f' : E} (h : HasDerivAt f f' x) :
HasFDerivAt f (reCLM.smulRight f' + I • imCLM.smulRight f') x := by
simpa only [Complex.restrictScalars_one_smulRight'] using h.hasFDerivAt.restrictScalars ℝ
#align has_deriv_at.complex_to_real_fderiv' HasDerivAt.complexToReal_fderiv'
theorem HasDerivWithinAt.complexToReal_fderiv' {f : ℂ → E} {s : Set ℂ} {x : ℂ} {f' : E}
(h : HasDerivWithinAt f f' s x) :
HasFDerivWithinAt f (reCLM.smulRight f' + I • imCLM.smulRight f') s x := by
simpa only [Complex.restrictScalars_one_smulRight'] using
h.hasFDerivWithinAt.restrictScalars ℝ
#align has_deriv_within_at.complex_to_real_fderiv' HasDerivWithinAt.complexToReal_fderiv'
theorem HasStrictDerivAt.complexToReal_fderiv {f : ℂ → ℂ} {f' x : ℂ} (h : HasStrictDerivAt f f' x) :
HasStrictFDerivAt f (f' • (1 : ℂ →L[ℝ] ℂ)) x := by
simpa only [Complex.restrictScalars_one_smulRight] using h.hasStrictFDerivAt.restrictScalars ℝ
#align has_strict_deriv_at.complex_to_real_fderiv HasStrictDerivAt.complexToReal_fderiv
theorem HasDerivAt.complexToReal_fderiv {f : ℂ → ℂ} {f' x : ℂ} (h : HasDerivAt f f' x) :
HasFDerivAt f (f' • (1 : ℂ →L[ℝ] ℂ)) x := by
simpa only [Complex.restrictScalars_one_smulRight] using h.hasFDerivAt.restrictScalars ℝ
#align has_deriv_at.complex_to_real_fderiv HasDerivAt.complexToReal_fderiv
theorem HasDerivWithinAt.complexToReal_fderiv {f : ℂ → ℂ} {s : Set ℂ} {f' x : ℂ}
(h : HasDerivWithinAt f f' s x) : HasFDerivWithinAt f (f' • (1 : ℂ →L[ℝ] ℂ)) s x := by
simpa only [Complex.restrictScalars_one_smulRight] using h.hasFDerivWithinAt.restrictScalars ℝ
#align has_deriv_within_at.complex_to_real_fderiv HasDerivWithinAt.complexToReal_fderiv
/-- If a complex function `e` is differentiable at a real point, then its restriction to `ℝ` is
differentiable there as a function `ℝ → ℂ`, with the same derivative. -/
theorem HasDerivAt.comp_ofReal (hf : HasDerivAt e e' ↑z) : HasDerivAt (fun y : ℝ => e ↑y) e' z :=
by simpa only [ofRealCLM_apply, ofReal_one, mul_one] using hf.comp z ofRealCLM.hasDerivAt
#align has_deriv_at.comp_of_real HasDerivAt.comp_ofReal
/-- If a function `f : ℝ → ℝ` is differentiable at a (real) point `x`, then it is also
differentiable as a function `ℝ → ℂ`. -/
theorem HasDerivAt.ofReal_comp {f : ℝ → ℝ} {u : ℝ} (hf : HasDerivAt f u z) :
HasDerivAt (fun y : ℝ => ↑(f y) : ℝ → ℂ) u z := by
simpa only [ofRealCLM_apply, ofReal_one, real_smul, mul_one] using
ofRealCLM.hasDerivAt.scomp z hf
#align has_deriv_at.of_real_comp HasDerivAt.ofReal_comp
end RealDerivOfComplex
section Conformality
/-! ### Conformality of real-differentiable complex maps -/
open Complex ContinuousLinearMap
open scoped ComplexConjugate
variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℂ E] {z : ℂ} {f : ℂ → E}
/-- A real differentiable function of the complex plane into some complex normed space `E` is
conformal at a point `z` if it is holomorphic at that point with a nonvanishing differential.
This is a version of the Cauchy-Riemann equations. -/
theorem DifferentiableAt.conformalAt (h : DifferentiableAt ℂ f z) (hf' : deriv f z ≠ 0) :
ConformalAt f z := by
rw [conformalAt_iff_isConformalMap_fderiv, (h.hasFDerivAt.restrictScalars ℝ).fderiv]
apply isConformalMap_complex_linear
simpa only [Ne.def, ext_ring_iff]
#align differentiable_at.conformal_at DifferentiableAt.conformalAt
/-- A complex function is conformal if and only if the function is holomorphic or antiholomorphic
with a nonvanishing differential. -/
theorem conformalAt_iff_differentiableAt_or_differentiableAt_comp_conj {f : ℂ → ℂ} {z : ℂ} :
ConformalAt f z ↔
(DifferentiableAt ℂ f z ∨ DifferentiableAt ℂ (f ∘ conj) (conj z)) ∧ fderiv ℝ f z ≠ 0 := by
rw [conformalAt_iff_isConformalMap_fderiv]
rw [isConformalMap_iff_is_complex_or_conj_linear]
apply and_congr_left
intro h
have h_diff := h.imp_symm fderiv_zero_of_not_differentiableAt
apply or_congr
· rw [differentiableAt_iff_restrictScalars ℝ h_diff]
rw [← conj_conj z] at h_diff
rw [differentiableAt_iff_restrictScalars ℝ (h_diff.comp _ conjCLE.differentiableAt)]
refine' exists_congr fun g => rfl.congr _
have : fderiv ℝ conj (conj z) = _ := conjCLE.fderiv
simp [fderiv.comp _ h_diff conjCLE.differentiableAt, this, conj_conj]
#align conformal_at_iff_differentiable_at_or_differentiable_at_comp_conj conformalAt_iff_differentiableAt_or_differentiableAt_comp_conj
end Conformality