# Check for holomorphy of a function

Given a (rather complicated) function H(z), what is the best approach to check symbolically whether it is holomorphic?

What I tried is checking explicitly the Cauchy-Riemann equations(*):

z = a + I b

H = E^-Sqrt[z^2] / (Sqrt[z^2] + Sqrt[z^2] Cosh[Sqrt[z^2]] + Sqrt[z^2] Sinh[Sqrt[z^2]])

HRe = FullSimplify[ComplexExpand[Re[H]], (a | b) ∈ Reals]
HIm = FullSimplify[ComplexExpand[Im[H]], (a | b) ∈ Reals]
HReA = Assuming[(a | b) ∈ Reals, D[HRe, a]]
HReA = Simplify[HReA, (a | b) ∈ Reals]
HImB = Assuming[(a | b) ∈ Reals, D[HIm, b]]
HImB = Simplify[HImB, (a | b) ∈ Reals]
Simplify[HReA == HImB, (a | b) ∈ Reals]


What I would expect as a result is either just True or some equation that a and b need to satisfy in order for the CR equations to be fulfilled. This would mean that my function is not holomorphic everywhere in the complex plane.

The problem that I encounter is that the call to Simplify does not complete computation in a reasonable amount of time (> 1 hour, then I aborted it).

Checking whether HRe and HIm are harmonic (which is a necessary condition for H to be holomorphic) did not seem to be any easier, with the second derivatives of H being even longer.

Is there a way to speed this up, or even a completely different approach? The derivatives are so long that a manual inspection is not an option.

(*) Note that as correctly pointed out by murray below, the Cauchy-Riemann DEs being fulfilled alone does not already imply holomorphy. Additional properties need to be given, e.g. continuity of H or continuity of its derivatives.

-
Do you mean one that completes or one that doesn't complete? –  jhin Jul 28 '14 at 14:07
I'll try and see if I can find something... –  jhin Jul 28 '14 at 14:14
Satisfying the Cauchy-Riemann equations does not suffice to make a function holomorphic! Simple example: f[z_] := Conjugate[z]^2/z, f[0] = 0; this is not differentiable at the origin, although it does satisfy the C-R equations there. –  murray Jul 28 '14 at 19:00
@Öskå Coming up with a really minimal example that gives the same issues is difficult for me, as the problem seems to lie in the complexity of the equation. At least I removed all unnecessary parameters and provided copyable example code, hope that already helps. I'll still ponder over a more minimal example, though. –  jhin Jul 28 '14 at 20:30
@murray Of course you're right, thanks for the hint! My function would also need to be continuous. Would give +1 if I could. –  jhin Jul 28 '14 at 20:32

The problem is the ByteCount of H is ~630 KB, so Simplify will run forever.

ComplexExpand[
With[{z = x + I y},
E^-Sqrt[z^2]/(Sqrt[z^2]+Sqrt[z^2] Cosh[Sqrt[z^2]]+Sqrt[z^2] Sinh[Sqrt[z^2]])
]
] // ByteCount

(* 629392 *)


Here are two partial workarounds. I call these workarounds because it proves H is not analytic, but it doesn't derive it i.e. we need to supply guesses for where we think it's not analytic.

## Series

We can easily show H has a pole at the origin:

Series[E^-Sqrt[z^2]/(Sqrt[z^2]+Sqrt[z^2] Cosh[Sqrt[z^2]]+Sqrt[z^2] Sinh[Sqrt[z^2]]),{z,0,0}]

(* 1/(2z) - 3/4 + O[z] *)


## Plotting

We can visually see H has a branch cut along on the imaginary axis.

Code

Here is code to plot $\mathbb{C}$ to $\mathbb{C}$, dumped from my init.m file.

ComplexColorPlot[f_, x_List] := ComplexColorPlot[f, x, x, .5];
ComplexColorPlot[f_, x_List, y_List] := ComplexColorPlot[f, x, y, .5];
ComplexColorPlot[f_, x_List, b_] := ComplexColorPlot[f, x, x, b];

ComplexColorPlot[f_, {xmn_, xmx_, xdel_}, {ymn_, ymx_, ydel_}, b_] := Block[{myArg, myAbs},

myArg[ComplexInfinity] = 0;
myArg[z_] := Mod[Arg[N@z], 2Pi]/(2Pi);

myAbs[ComplexInfinity] = Infinity;
myAbs[z_] := Abs[N@z];

Image[Monitor[

Table[
With[{tb = f[σ + I*t]},
With[{hue = Round[{myArg[tb], 1/(1 + .3*#), 1/(1.1 + b*#)}&[Log[myAbs@tb + 1]], .000001]},
List @@ ToColor[Hue @@ hue, RGBColor]
]
],
{t, ymx, ymn, -ydel}, {σ, xmn, xmx, xdel}
],

Row[{ProgressIndicator[#, {0., 1.}], "  ", Round[#, .0001], "%  σ + I*t \[LongEqual] ", σ + I*t}]&[1-(t-ymn)/(ymx-ymn)]

]]//Image[#, "Byte"]&
]


Explanation of plotter

Given $(x, y)$ in the Cartesian plane, this plots $f(x + iy)$. Looking at $f$ in polar coordinates, write $f(x + iy) = r e^{i \theta}$, where the phase angle $\theta$ is represented by color of the pixel at $(x, y)$ and the magniture $r$ is represented by the darkness of the pixel at $(x, y)$.

Red corresponds to $\theta = 0$, very light blue corresponds to $\theta = \pi$, colors between red and very light blue have $0 < \theta < \pi$, and colors between very light blue and dark red have $-\pi < \theta < 0$.

The darker the pixel, the larger the magnitude $r$. Pure white is a zero and pure black is a pole.

Now plot H for -2 < x < 2 and -2 < y < 2:

H = Function[z,
E^-Sqrt[z^2]/(Sqrt[z^2] + Sqrt[z^2] Cosh[Sqrt[z^2]] + Sqrt[z^2] Sinh[Sqrt[z^2]])];

ComplexColorPlot[H, {-2, 2, .01}]


So you can see the function's argument 'jumps' crossing the imaginary axis and probably has a singularity at the origin.

To see this jump, we can take a horizontal cross section of the above image:

Plot[Arg[H[z + 2I]], {z, -1, 1}]


Since you're looking for symbolic methods, we can prove this is a jump:

Limit[H[ε + 2I], ε -> 0, Direction -> 1] == Limit[H[ε + 2I], ε -> 0, Direction -> -1]

(* False *)

-
Could you elaborate a bit on that ByteCount thing? H would not seem extremely complicated to me on first sight, how could I know it is too tough for Simplify? That ComplexColorPlot is really neat as well as the limit calculation, thanks! (Of course it makes perfect sense that the branch cut along the negative real axis is transformed into one along the imaginary axis by the square.) –  jhin Jul 30 '14 at 9:33
Anyway I'd still be interested in methods to check holomorphy for regions without branch cuts, i.e. Re(z) > 0... –  jhin Jul 30 '14 at 9:38