# How to verify that a certain point is a branch point for a complex function using Mathematica?

It is straightforward to verify that z=0 is a branch point for w[z]=Sqrt[z]:

Clear["Global*"];

expr1 = Sqrt[r  Exp[I  θ]] /. {θ -> α} // PowerExpand // Simplify

expr2 = Limit[Sqrt[r  Exp[I  θ]] /. {θ -> α + ε π}, ε -> 2, Direction -> "FromBelow"] // PowerExpand // Simplify

Simplify[expr1 - expr2]


(* 2 E^((I α)/2) Sqrt[r] *)

And z=0 is a branch point for w[z]=Log[z]:

Clear["Global*"];

expr1 = Log[r  Exp[I  θ]] /. {θ -> α} // PowerExpand // Simplify

expr2 = Limit[Log[r  Exp[ I  θ]] /. {θ -> α + ε π}, ε -> 2, Direction -> "FromBelow"] // PowerExpand // Simplify

Simplify[expr1 - expr2]


(* -2 I π *)

However, for some more complex functions, verification is not straightforward. For example, for z = (-1 + Sqrt[5])/2, it is challenging to confirm that it is a branch point of w[z] = Log[𝑧-1/𝑧+1], or that z = a is a branch point of Sqrt[(z-a) (z+b)].

How can we write Mathematica (MMA) code to determine, for any given complex function w[z], how w[z] changes when z encircles any point in the z-plane counterclockwise along a small circle of infinitesimal radius, say, by one revolution (2 Pi)? This would help identify whether the point is a branch point.

EDIT I am aware that the function ComplexAnalysis'BranchPoints can be used to find branch points, but sometimes the branch points obtained by this function are incorrect( https://mathematica.stackexchange.com/a/289606/69835 ). Moreover, it is not the case that branch points cannot be found outside of this function. One approach is to first find the zeros and singular points (using specialized functions and code), and then systematically check whether these zeros and singular points satisfy the definition of branch points ( https://mathworld.wolfram.com/BranchPoint.html ) through a program. My question is how to programmatically check whether these zeros and singular points meet the definition of branch points, in order to make decisions and ultimately obtain all branch points.

The approach to finding the branch points of a complex function w[z] using MMA programming is as follows: first, determine all the zeros and singular points of w[z]. Then, for each of these points, compare whether the following two complex numbers are equal: the complex numbers centered at the point (e.g., point A)), denoted as z1-A and z2-A, with equal magnitudes and infinitesimally small, and where the argument of z1-A is 0, and the argument of z2-A is 2 Pi (Limit->2 Pi). If these two complex numbers are not equal, the point A is identified as a branch point.

• It is not a good practice to subststantially change the question (Log[(z - 1)/(z + 1)], is replaced by Log[𝑧-1/𝑧+1]), not indicating the change. Jan 21 at 12:52
• Please provide a few cases for which ComplexAnalysis BranchPoints gives incorrect results. Thanks. Jan 22 at 14:29
• Jan 23 at 2:38
• You wrote in your EDIT "and then systematically check whether these zeros and singular points satisfy the definition of branch points through a program". Can you kindly elaborate that statement, especially the definition of a branch point? How from Simplify[expr1 - expr2] do you derive that z==0 is a branch point? TIA. Jan 23 at 5:58
• @user64494 mathworld.wolfram.com/BranchPoint.html Jan 23 at 11:37

An undocumented command ComplexAnalysisBranchPoints works here:

ComplexAnalysisBranchPoints[Sqrt[(z - a)*(z - b)], z]


{a, b, ComplexInfinity}

ComplexAnalysisBranchPoints[Log[(z - 1)/(z + 1)], z]


{-1, 1}

despite your suggestion about a branch point at  z == (-1 + Sqrt[5])/2.

Addition. The following can be done, making use of of the integral from Wiki.

ContourIntegrate[D[Log[z - 1/z + 1], z]/Log[z - 1/z + 1],
z \[Element] Disk[{(-1 + Sqrt[5])/2, 0}, 1/10]]/(2*Pi*I)


-(ArcTan[\[Pi]/Log[890/(244 + 55 Sqrt[5])]]/\[Pi])

and

ContourIntegrate[D[Log[z - 1/z + 1], z]/Log[z - 1/z + 1],
z \[Element] Disk[{a, b}, 1/10],
Assumptions -> {a, b} \[Element] Reals && a != (-1 + Sqrt[5])/2 ||
a != (-1 - Sqrt[5])/2 &&
Point[{(-1 + Sqrt[5])/2, 0}] \[NotElement] Disk[{a, b}, 1/10] &&
Point[{(-1 - Sqrt[5])/2, 0}] \[NotElement] Disk[{a, b}, 1/10]]/(2*Pi*I)


0

One may ask why -(ArcTan[\[Pi]/Log[890/(244 + 55 Sqrt[5])]]/\[Pi]) is not an integer number. My explanation is that the branch cuts of Log[z - 1/z + 1] from z==(-1 +/- Sqrt[5])/2 to ComplexInfinity cause it. The branch cut may be taken from z==(-1 - Sqrt[5])/2 to z==(-1 + Sqrt[5])/2 (This is done in Сидоров Ю.В.,Федорюк М.В.,Шабунин М.И.Лекции по теории функций комплексного переменного (in Russian)). In this case the integral would be an integer. More complicated case can be handled too, e.g.

FullSimplify[ ContourIntegrate[D[Sqrt[(z - a - b*I)*(z - c - d*I)], z]/
Sqrt[(z - a - b*I)*(z - c - d*I)],
z \[Element] Disk[{a, b}, Abs[a + I b - c - I d]/2],
Assumptions ->   Abs[a + I b - c - I d] > 0 && {a, b, c, d} \[Element] Reals], Assumptions -> Abs[a + I b - c - I d] > 0]/(2*I*Pi)


1/2

• Concening branch points at infinity see Encyclopedia of Mathematics and Wiki. Jan 21 at 8:59
• The typographical errors in the formula w[z] = Log[𝑧-1/𝑧+1] have been corrected. I am aware of ComplexAnalysisBranchPoints, but it often yield incorrect results, and I have also reviewed your previous related answer mathematica.stackexchange.com/a/289606/69835. Since branch points belong to singularities and zeros, but not vice versa, I intend to first identify singularities and zeros, and then utilize the definition of branch points to exclude non-branch points. Jan 21 at 10:24
• ComplexAnalysis'BranchPoints[Log[z - 1/z + 1], z] performs {0, 1/2 (-1 - Sqrt[5]), 1/2 (-1 + Sqrt[5]), ComplexInfinity} in accordance with the result of the Maple command FunctionAdvisor(branch_cuts, log(z-1/z+1), plot = 2.). Jan 21 at 11:41
• Perhaps you didn't understand the purpose of my question. I am aware that the function ComplexAnalysis'BranchPoints can be used to find branch points, but sometimes the branch points obtained by this function are incorrect. Moreover, it is not the case that branch points cannot be found outside of this function. Jan 22 at 12:10
• One approach is to first find the zeros and singular points (using specialized functions and code), and then systematically check whether these zeros and singular points satisfy the definition of branch points through a program. My question is how to programmatically check whether these zeros and singular points meet the definition of branch points, in order to make decisions and ultimately obtain all branch points. Jan 22 at 12:11