The latest versions of the Wolfram Language have builtin knowledge about singularities and branch cuts of mathematical functions. Here we show some examples of how this knowledge is used to solve univariate transcendental equations.
Suppose we would like to find all roots of a univariate function in a complex rectangle. We can start by finding root approximations using a numeric method. However, we would like to know for sure that each approximation represents an actual root and that we have found all the roots. This is where some knowledge of the function is required.
If we know that the function is holomorphic (complex differentiable) in the disk represented by an approximate number, we can use interval arithmetic (for elementary functions) or significance arithmetic (for nonelementary functions) and a criterion based on Rouché’s theorem to prove existence and the total multiplicity of roots in the disk.
To prove that we have found all the roots in a given complex rectangle, we compute the winding number of the function along the boundary of the rectangle (the total number of times that the value of the function travels around zero when its argument travels around the boundary of the rectangle) using interval arithmetic (for elementary functions) or numeric integration (for nonelementary functions). For this method to be valid, we need to know that the function is holomorphic in the rectangle or that the function is meromorphic (a ratio of holomorphic functions) in the rectangle, and we need to know the total multiplicity of poles of the function contained in the rectangle.
Holomorphic Function Example
Holomorphic Function Example
Using the builtin knowledge about mathematical functions, Solve can decide that is holomorphic in ( is given by ). Since the function is not elementary, numeric integration is used to compute the winding number—hence the warning message:
FresnelC[z]z1
2≤Re[z]≤2∧2≤Im[z]≤2
FresnelC[z]
∫cos(πt/2)dt
z
0
2
In[1]:=
sols=Solve[FresnelC[z]z1&&2≤Re[z]≤2&&2≤Im[z]≤2,z]
Out[1]=
{{zRoot[{1FresnelC[#1]+#1&,1.47187658130381999332185573786}]},{z
Root[{1FresnelC[#1]+#1&,
0.4977900906045427782901547619085811924580579929838065565970
1.2288479042170920570297427715537585547338160544064894797337}]},{z
Root[{1FresnelC[#1]+#1&,
0.4977900906045427782901547619085811924580579929838065565970+
1.2288479042170920570297427715537585547338160544064894797337}]},{z
Root[{1FresnelC[#1]+#1&,
0.99701104920390363530014302748685108318160770995138382725731
0.76819101638090424674595944289406300579269496443262030456307}]},{z
Root[{1FresnelC[#1]+#1&,
0.99701104920390363530014302748685108318160770995138382725731+
0.76819101638090424674595944289406300579269496443262030456307}]}}
The roots are represented as Root objects , where is a pure function and is an approximate real or complex number such that exactly one root of lies within the numerical region defined by its precision. represents an exact number. In particular, we can compute its approximation to arbitrarily many digits:
Root[{f,x}]
0
f
x
0
f[x]
Root[{f,x}]
0
In[2]:=
N[Root[{1FresnelC[#1]+#1&,1.47187658130381999332185573786}],100]
Out[2]=

1.4718765813038199933218557378584063453799226762721876729977021619725492
46163460789585462914716272079
This illustrates the fact that the roots are intersection points of the zero sets of the real part and the imaginary part of the function:
In[3]:=
f=FresnelC[x+Iy]xIy1;
In[4]:=
Show[{ContourPlot[{Re[f],Im[f]},{x,2,2},{y,2,2},Contours0,
PlotPoints50],Graphics[{Red,PointSize[Large],Point[{Re[z],Im[z]}/.
sols]}]}]
Out[4]=