(* ========================================================================= *)
(* Complex analysis. *)
(* *)
(* (c) Copyright, John Harrison 1998-2008 *)
(* (c) Copyright, Marco Maggesi, Graziano Gentili and Gianni Ciolli, 2008. *)
(* (c) Copyright, Valentina Bruno 2010 *)
(* ========================================================================= *)
needs "Library/floor.ml";;
needs "Library/iter.ml";;
needs "Multivariate/complexes.ml";;
prioritize_complex();;
(* ------------------------------------------------------------------------- *)
(* Some toplogical facts formulated for the complex numbers. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Complex-specific uniform limit composition theorems. *)
(* ------------------------------------------------------------------------- *)
let UNIFORM_LIM_COMPLEX_INV = prove
(`!net:(A)net P f l b.
(!e. &0 < e
==>
eventually (\x. !n:B. P n ==>
norm(f n x - l n) < e) net) /\
&0 < b /\
eventually (\x. !n. P n ==> b <=
norm(l n)) net
==> !e. &0 < e
==>
eventually
(\x. !n. P n ==>
norm(inv(f n x) - inv(l n)) < e) net`,
REPEAT STRIP_TAC THEN MATCH_MP_TAC
EVENTUALLY_MONO THEN
EXISTS_TAC
`\x. !n. P n ==> b <=
norm(l n) /\
b / &2 <=
norm((f:B->A->
complex) n x) /\
norm(f n x - l n) < e * b pow 2 / &2` THEN
REWRITE_TAC[TAUT `(p ==> q /\ r) <=> (p ==> q) /\ (p ==> r)`] THEN
REWRITE_TAC[
FORALL_AND_THM] THEN CONJ_TAC THENL
[X_GEN_TAC `x:A` THEN STRIP_TAC THEN X_GEN_TAC `n:B` THEN DISCH_TAC THEN
REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `n:B`) THEN ASM_REWRITE_TAC[]) THEN
REPEAT DISCH_TAC THEN
SUBGOAL_THEN `~((f:B->A->
complex) n x = Cx(&0)) /\ ~(l n = Cx(&0))`
STRIP_ASSUME_TAC THENL
[CONJ_TAC THEN DISCH_THEN SUBST_ALL_TAC THEN
RULE_ASSUM_TAC(REWRITE_RULE[
COMPLEX_NORM_CX]) THEN ASM_REAL_ARITH_TAC;
ALL_TAC] THEN
ASM_SIMP_TAC[COMPLEX_FIELD
`~(x = Cx(&0)) /\ ~(y = Cx(&0))
==> inv x - inv y = (y - x) / (x * y)`] THEN
ASM_SIMP_TAC[
COMPLEX_NORM_DIV;
REAL_LT_LDIV_EQ;
COMPLEX_NORM_NZ;
COMPLEX_ENTIRE] THEN
ONCE_REWRITE_TAC[
NORM_SUB] THEN
FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[
IMP_CONJ]
REAL_LTE_TRANS)) THEN
ASM_SIMP_TAC[
REAL_LE_LMUL_EQ; REAL_ARITH `b pow 2 / &2 = b / &2 * b`] THEN
REWRITE_TAC[
COMPLEX_NORM_MUL] THEN MATCH_MP_TAC
REAL_LE_MUL2 THEN
ASM_REAL_ARITH_TAC;
ASM_REWRITE_TAC[
EVENTUALLY_AND] THEN CONJ_TAC THENL
[FIRST_X_ASSUM(MP_TAC o SPEC `b / &2`) THEN
ASM_REWRITE_TAC[
REAL_HALF] THEN
FIRST_X_ASSUM(fun
th -> MP_TAC
th THEN REWRITE_TAC[IMP_IMP] THEN
GEN_REWRITE_TAC LAND_CONV [GSYM
EVENTUALLY_AND]) THEN
MATCH_MP_TAC(REWRITE_RULE[
IMP_CONJ]
EVENTUALLY_MONO) THEN
REWRITE_TAC[] THEN
ASM_MESON_TAC[NORM_ARITH
`b <=
norm l /\
norm(f - l) < b / &2 ==> b / &2 <=
norm f`];
FIRST_X_ASSUM MATCH_MP_TAC THEN
ASM_SIMP_TAC[
REAL_HALF;
REAL_POW_LT;
REAL_LT_MUL]]]);;
(* ------------------------------------------------------------------------- *)
(* The usual non-uniform versions. *)
(* ------------------------------------------------------------------------- *)
let LIM_COMPLEX_MUL = prove
(`!net:(A)net f g l m.
(f --> l) net /\ (g --> m) net ==> ((\x. f x * g x) --> l * m) net`,
let LIM_COMPLEX_INV = prove
(`!net:(A)net f g l m.
(f --> l) net /\ ~(l = Cx(&0)) ==> ((\x. inv(f x)) --> inv(l)) net`,
let LIM_COMPLEX_DIV = prove
(`!net:(A)net f g l m.
(f --> l) net /\ (g --> m) net /\ ~(m = Cx(&0))
==> ((\x. f x / g x) --> l / m) net`,
(* ------------------------------------------------------------------------- *)
(* Special cases of null limits. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Bound results for real and imaginary components of limits. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Left and right multiplication of series. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Complex-specific continuity closures. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Write away the netlimit, which is otherwise a bit tedious. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Also prove "on" variants as needed. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* And also uniform versions. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Continuity prover (not just for complex numbers but with more for them). *)
(* ------------------------------------------------------------------------- *)
let CONTINUOUS_TAC =
(* ------------------------------------------------------------------------- *)
(* Hence a limit calculator *)
(* ------------------------------------------------------------------------- *)
let LIM_TAC =
MATCH_MP_TAC LIM_CONTINUOUS THEN CONJ_TAC THENL
[CONTINUOUS_TAC; REWRITE_TAC[NETLIMIT_AT; NETLIMIT_WITHIN]];;
(* ------------------------------------------------------------------------- *)
(* Continuity of the norm. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Continuity switching range between complex and real^1 *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Linearity and continuity of the components. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Complex differentiability. *)
(* ------------------------------------------------------------------------- *)
parse_as_infix ("has_complex_derivative",(12,"right"));;
parse_as_infix ("complex_differentiable",(12,"right"));;
parse_as_infix ("holomorphic_on",(12,"right"));;
(* ------------------------------------------------------------------------- *)
(* A more direct characterization. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Arithmetical combining theorems. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Same thing just for complex differentiability. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Same again for being holomorphic on a set. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Same again for the actual derivative function. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Caratheodory characterization. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* A slightly stronger, more traditional notion of analyticity on a set. *)
(* ------------------------------------------------------------------------- *)
parse_as_infix ("analytic_on",(12,"right"));;
(* ------------------------------------------------------------------------- *)
(* The case of analyticity at a point. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Combining theorems for derivative with analytic_at {z} hypotheses. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* A composition lemma for functions of mixed type. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Complex differentiation of sequences and series. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Bound theorem. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Inverse function theorem for complex derivatives. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Cauchy-Riemann condition and relation to conformal. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Differentiation conversion. *)
(* ------------------------------------------------------------------------- *)
let complex_differentiation_theorems = ref [];;
let add_complex_differentiation_theorems =
add_complex_differentiation_theorems
[HAS_COMPLEX_DERIVATIVE_LMUL_WITHIN; HAS_COMPLEX_DERIVATIVE_LMUL_AT;
HAS_COMPLEX_DERIVATIVE_RMUL_WITHIN; HAS_COMPLEX_DERIVATIVE_RMUL_AT;
HAS_COMPLEX_DERIVATIVE_CDIV_WITHIN; HAS_COMPLEX_DERIVATIVE_CDIV_AT;
HAS_COMPLEX_DERIVATIVE_ID;
HAS_COMPLEX_DERIVATIVE_CONST;
HAS_COMPLEX_DERIVATIVE_NEG;
HAS_COMPLEX_DERIVATIVE_ADD;
HAS_COMPLEX_DERIVATIVE_SUB;
HAS_COMPLEX_DERIVATIVE_MUL_WITHIN; HAS_COMPLEX_DERIVATIVE_MUL_AT;
HAS_COMPLEX_DERIVATIVE_DIV_WITHIN; HAS_COMPLEX_DERIVATIVE_DIV_AT;
HAS_COMPLEX_DERIVATIVE_POW_WITHIN; HAS_COMPLEX_DERIVATIVE_POW_AT;
HAS_COMPLEX_DERIVATIVE_INV_WITHIN; HAS_COMPLEX_DERIVATIVE_INV_AT];;
let rec COMPLEX_DIFF_CONV =
let partfn tm = let l,r = dest_comb tm in mk_pair(lhand l,r)
and is_deriv = can (term_match [] `(f has_complex_derivative f') net`) in
let rec COMPLEX_DIFF_CONV tm =
try tryfind (fun th -> PART_MATCH partfn th (partfn tm))
(!complex_differentiation_theorems)
with Failure _ ->
let ith = tryfind (fun th ->
PART_MATCH (partfn o repeat (snd o dest_imp)) th (partfn tm))
(!complex_differentiation_theorems) in
COMPLEX_DIFF_ELIM ith
and COMPLEX_DIFF_ELIM th =
let tm = concl th in
if not(is_imp tm) then th else
let t = lhand tm in
if not(is_deriv t) then UNDISCH th
else COMPLEX_DIFF_ELIM (MATCH_MP th (COMPLEX_DIFF_CONV t)) in
COMPLEX_DIFF_CONV;;
(* ------------------------------------------------------------------------- *)
(* Hence a tactic. *)
(* ------------------------------------------------------------------------- *)
let COMPLEX_DIFF_TAC =
let pth = MESON[]
`(f has_complex_derivative f') net
==> f' = g'
==> (f has_complex_derivative g') net` in
W(fun (asl,w) -> let th = MATCH_MP pth (COMPLEX_DIFF_CONV w) in
MATCH_MP_TAC(repeat (GEN_REWRITE_RULE I [IMP_IMP]) (DISCH_ALL th)));;
let COMPLEX_DIFFERENTIABLE_TAC =
let DISCH_FIRST th = DISCH (hd(hyp th)) th in
GEN_REWRITE_TAC I [complex_differentiable] THEN
W(fun (asl,w) ->
let th = COMPLEX_DIFF_CONV(snd(dest_exists w)) in
let f' = rand(rator(concl th)) in
EXISTS_TAC f' THEN
(if hyp th = [] then MATCH_ACCEPT_TAC th else
let th' = repeat (GEN_REWRITE_RULE I [IMP_IMP] o DISCH_FIRST)
(DISCH_FIRST th) in
MATCH_MP_TAC th'));;
(* ------------------------------------------------------------------------- *)
(* A kind of complex Taylor theorem. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* The simplest special case. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Something more like the traditional MVT for real components. *)
(* Could, perhaps should, sharpen this to derivatives inside the segment. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Further useful properties of complex conjugation. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Some limit theorems about real part of real series etc. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Often convenient to use comparison with real limit of complex type. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Complex-valued geometric series. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Complex version (the usual one) of Dirichlet convergence test. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Versions with explicit bounds are sometimes useful. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Relations among convergence and absolute convergence for power series. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Comparing sums and "integrals" via complex antiderivatives. *)
(* ------------------------------------------------------------------------- *)
let SUM_INTEGRAL_UBOUND_INCREASING = prove
(`!f g m n.
m <= n /\
(!x. x
IN segment[Cx(&m),Cx(&n + &1)]
==> (g
has_complex_derivative f(x)) (
at x)) /\
(!x y. &m <= x /\ x <= y /\ y <= &n + &1 ==> Re(f(Cx x)) <= Re(f(Cx y)))
==>
sum(m..n) (\k. Re(f(Cx(&k)))) <= Re(g(Cx(&n + &1)) - g(Cx(&m)))`,
REPEAT STRIP_TAC THEN MATCH_MP_TAC
REAL_LE_TRANS THEN
EXISTS_TAC `--sum(m..n) (\k. Re(g(Cx(&k))) - Re(g(Cx(&(k + 1)))))` THEN
CONJ_TAC THENL
[ALL_TAC;
ASM_REWRITE_TAC[
SUM_DIFFS;
RE_SUB;
REAL_NEG_SUB; REAL_OF_NUM_ADD] THEN
REWRITE_TAC[
REAL_LE_REFL]] THEN
REWRITE_TAC[GSYM
SUM_NEG] THEN MATCH_MP_TAC
SUM_LE_NUMSEG THEN
REWRITE_TAC[
REAL_NEG_SUB] THEN X_GEN_TAC `r:num` THEN STRIP_TAC THEN
MP_TAC(ISPECL [`g:complex->
complex`; `f:complex->
complex`;
`Cx(&r)`; `Cx(&r + &1)`]
COMPLEX_MVT_LINE) THEN
ANTS_TAC THENL
[X_GEN_TAC `u:complex` THEN STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
UNDISCH_TAC `u
IN segment[Cx(&r),Cx(&r + &1)]` THEN
REWRITE_TAC[
SEGMENT_CONVEX_HULL] THEN
SPEC_TAC(`u:complex`,`u:complex`) THEN REWRITE_TAC[GSYM
SUBSET] THEN
MATCH_MP_TAC
HULL_MINIMAL THEN REWRITE_TAC[
CONVEX_CONVEX_HULL] THEN
REWRITE_TAC[
SUBSET;
IN_INSERT;
NOT_IN_EMPTY; GSYM
SEGMENT_CONVEX_HULL] THEN
REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[
IN_SEGMENT_CX] THEN
REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE] THEN
ASM_ARITH_TAC;
REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN DISCH_THEN(X_CHOOSE_THEN `u:complex`
(CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN
REWRITE_TAC[
CX_ADD; COMPLEX_RING `y * ((x + Cx(&1)) - x) = y`] THEN
SUBGOAL_THEN `?y. u = Cx y` (CHOOSE_THEN SUBST_ALL_TAC) THENL
[ASM_MESON_TAC[
REAL_SEGMENT;
REAL_CX;
REAL]; ALL_TAC] THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
IN_SEGMENT_CX]) THEN
REPEAT(FIRST_X_ASSUM
(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_OF_NUM_LE])) THEN
REAL_ARITH_TAC]);;
let SUM_INTEGRAL_UBOUND_DECREASING = prove
(`!f g m n.
m <= n /\
(!x. x
IN segment[Cx(&m - &1),Cx(&n)]
==> (g
has_complex_derivative f(x)) (
at x)) /\
(!x y. &m - &1 <= x /\ x <= y /\ y <= &n ==> Re(f(Cx y)) <= Re(f(Cx x)))
==>
sum(m..n) (\k. Re(f(Cx(&k)))) <= Re(g(Cx(&n)) - g(Cx(&m - &1)))`,
REPEAT STRIP_TAC THEN MATCH_MP_TAC
REAL_LE_TRANS THEN EXISTS_TAC
`--sum(m..n) (\k. Re(g(Cx(&(k) - &1))) - Re(g(Cx(&(k+1) - &1))))` THEN
CONJ_TAC THENL
[ALL_TAC;
ASM_REWRITE_TAC[
SUM_DIFFS;
REAL_NEG_SUB] THEN
REWRITE_TAC[GSYM REAL_OF_NUM_ADD; GSYM
REAL_OF_NUM_SUB] THEN
REWRITE_TAC[
RE_SUB; REAL_ARITH `(x + &1) - &1 = x`;
REAL_LE_REFL]] THEN
REWRITE_TAC[GSYM
SUM_NEG] THEN MATCH_MP_TAC
SUM_LE_NUMSEG THEN
REWRITE_TAC[
REAL_NEG_SUB] THEN X_GEN_TAC `r:num` THEN STRIP_TAC THEN
REWRITE_TAC[GSYM REAL_OF_NUM_ADD; REAL_ARITH `(x + &1) - &1 = x`] THEN
MP_TAC(ISPECL [`g:complex->
complex`; `f:complex->
complex`;
`Cx(&r - &1)`; `Cx(&r)`]
COMPLEX_MVT_LINE) THEN
ANTS_TAC THENL
[X_GEN_TAC `u:complex` THEN STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
UNDISCH_TAC `u
IN segment[Cx(&r - &1),Cx(&r)]` THEN
REWRITE_TAC[
SEGMENT_CONVEX_HULL] THEN
SPEC_TAC(`u:complex`,`u:complex`) THEN REWRITE_TAC[GSYM
SUBSET] THEN
MATCH_MP_TAC
HULL_MINIMAL THEN REWRITE_TAC[
CONVEX_CONVEX_HULL] THEN
REWRITE_TAC[
SUBSET;
IN_INSERT;
NOT_IN_EMPTY; GSYM
SEGMENT_CONVEX_HULL] THEN
REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[
IN_SEGMENT_CX] THEN
REPEAT(POP_ASSUM MP_TAC) THEN
REWRITE_TAC[GSYM REAL_OF_NUM_LE] THEN REAL_ARITH_TAC;
REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN DISCH_THEN(X_CHOOSE_THEN `u:complex`
(CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN
REWRITE_TAC[
CX_SUB; COMPLEX_RING `y * (x - (x - Cx(&1))) = y`] THEN
SUBGOAL_THEN `?y. u = Cx y` (CHOOSE_THEN SUBST_ALL_TAC) THENL
[ASM_MESON_TAC[
REAL_SEGMENT;
REAL_CX;
REAL]; ALL_TAC] THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
IN_SEGMENT_CX]) THEN
REPEAT(FIRST_X_ASSUM
(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_OF_NUM_LE])) THEN
REAL_ARITH_TAC]);;
(* ------------------------------------------------------------------------- *)
(* Relating different kinds of complex limits. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Transforming complex limits to real ones. *)
(* ------------------------------------------------------------------------- *)
let LIM_COMPLEX_REAL = prove
(`!f g l m.
eventually (\n. Re(g n) = f n)
sequentially /\
Re m = l /\
(g --> m)
sequentially
==> !e. &0 < e ==> ?N. !n. N <= n ==> abs(f n - l) < e`,
REPEAT GEN_TAC THEN
REWRITE_TAC[
EVENTUALLY_SEQUENTIALLY;
LIM_SEQUENTIALLY] THEN
DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `N1:num`)
(CONJUNCTS_THEN2 (SUBST1_TAC o SYM) ASSUME_TAC)) THEN
X_GEN_TAC `e:real` THEN DISCH_TAC THEN
FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[
dist] THEN
DISCH_THEN(X_CHOOSE_TAC `N0:num`) THEN EXISTS_TAC `N0 + N1:num` THEN
X_GEN_TAC `n:num` THEN DISCH_THEN(STRIP_ASSUME_TAC o MATCH_MP (ARITH_RULE
`N0 + N1:num <= n ==> N0 <= n /\ N1 <= n`)) THEN
UNDISCH_THEN `!n. N0 <= n ==>
norm ((g:num->
complex) n - m) < e`
(MP_TAC o SPEC `n:num`) THEN
FIRST_X_ASSUM(MP_TAC o SPEC `n:num`) THEN ASM_REWRITE_TAC[] THEN
DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[GSYM
RE_SUB] THEN
MATCH_MP_TAC(REAL_ARITH `x <= y ==> y < e ==> x < e`) THEN
REWRITE_TAC[
COMPLEX_NORM_GE_RE_IM]);;
(* ------------------------------------------------------------------------- *)
(* Uniform convergence of power series in a "Stolz angle". *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Hence continuity and the Abel limit theorem. *)
(* ------------------------------------------------------------------------- *)