Go to the first, previous, next, last section, table of contents.

Branch Cuts and Principal Values

All of the logarithmic, trigonometric, and other scientific functions are defined for complex numbers as well as for reals. This section describes the values returned in cases where the general result is a family of possible values. Calc follows section 12.5.3 of Steele's Common Lisp, the Language, second edition, in these matters. This section will describe each function briefly; for a more detailed discussion (including some nifty diagrams), consult Steele's book.

Note that the branch cuts for arctan and arctanh were changed between the first and second editions of Steele. Versions of Calc starting with 2.00 follow the second edition.

The new branch cuts exactly match those of the HP-28/48 calculators. They also match those of Mathematica 1.2, except that Mathematica's arctan cut is always in the right half of the complex plane, and its arctanh cut is always in the top half of the plane. Calc's cuts are continuous with quadrants I and III for arctan, or II and IV for arctanh.

Note: The current implementations of these functions with complex arguments are designed with proper behavior around the branch cuts in mind, not efficiency or accuracy. You may need to increase the floating precision and wait a while to get suitable answers from them.

For `sqrt(a+bi)': When a<0 and b is small but positive or zero, the result is close to the +i axis. For b small and negative, the result is close to the -i axis. The result always lies in the right half of the complex plane.

For `ln(a+bi)': The real part is defined as `ln(abs(a+bi))'. The imaginary part is defined as `arg(a+bi) = arctan2(b,a)'. Thus the branch cuts for sqrt and ln both lie on the negative real axis.

The following table describes these branch cuts in another way. If the real and imaginary parts of z are as shown, then the real and imaginary parts of f(z) will be as shown. Here eps stands for a small positive value; each occurrence of eps may stand for a different small value.

     z           sqrt(z)       ln(z)
----------------------------------------
   +,   0         +,  0       any, 0
   -,   0         0,  +       any, pi
   -, +eps      +eps, +      +eps, +
   -, -eps      +eps, -      +eps, -

For `z1^z2': This is defined by `exp(ln(z1)*z2)'. One interesting consequence of this is that `(-8)^1:3' does not evaluate to -2 as you might expect, but to the complex number (1., 1.732). Both of these are valid cube roots of -8 (as is (1., -1.732)); Calc chooses a perhaps less-obvious root for the sake of mathematical consistency.

For `arcsin(z)': This is defined by `-i*ln(i*z + sqrt(1-z^2))'. The branch cuts are on the real axis, less than -1 and greater than 1.

For `arccos(z)': This is defined by `-i*ln(z + i*sqrt(1-z^2))', or equivalently by `pi/2 - arcsin(z)'. The branch cuts are on the real axis, less than -1 and greater than 1.

For `arctan(z)': This is defined by `(ln(1+i*z) - ln(1-i*z)) / (2*i)'. The branch cuts are on the imaginary axis, below -i and above i.

For `arcsinh(z)': This is defined by `ln(z + sqrt(1+z^2))'. The branch cuts are on the imaginary axis, below -i and above i.

For `arccosh(z)': This is defined by `ln(z + (z+1)*sqrt((z-1)/(z+1)))'. The branch cut is on the real axis less than 1.

For `arctanh(z)': This is defined by `(ln(1+z) - ln(1-z)) / 2'. The branch cuts are on the real axis, less than -1 and greater than 1.

The following tables for arcsin, arccos, and arctan assume the current angular mode is radians. The hyperbolic functions operate independently of the angular mode.

       z             arcsin(z)            arccos(z)
-------------------------------------------------------
 (-1..1),  0      (-pi/2..pi/2), 0       (0..pi), 0
 (-1..1), +eps    (-pi/2..pi/2), +eps    (0..pi), -eps
 (-1..1), -eps    (-pi/2..pi/2), -eps    (0..pi), +eps
   <-1,    0          -pi/2,     +         pi,    -
   <-1,  +eps      -pi/2 + eps,  +      pi - eps, -
   <-1,  -eps      -pi/2 + eps,  -      pi - eps, +
    >1,    0           pi/2,     -          0,    +
    >1,  +eps       pi/2 - eps,  +        +eps,   -
    >1,  -eps       pi/2 - eps,  -        +eps,   +
       z            arccosh(z)         arctanh(z)
-----------------------------------------------------
 (-1..1),  0        0,  (0..pi)       any,     0
 (-1..1), +eps    +eps, (0..pi)       any,    +eps
 (-1..1), -eps    +eps, (-pi..0)      any,    -eps
   <-1,    0        +,    pi           -,     pi/2
   <-1,  +eps       +,  pi - eps       -,  pi/2 - eps
   <-1,  -eps       +, -pi + eps       -, -pi/2 + eps
    >1,    0        +,     0           +,    -pi/2
    >1,  +eps       +,   +eps          +,  pi/2 - eps
    >1,  -eps       +,   -eps          +, -pi/2 + eps
       z           arcsinh(z)           arctan(z)
-----------------------------------------------------
   0, (-1..1)    0, (-pi/2..pi/2)         0,     any
   0,   <-1      -,    -pi/2            -pi/2,    -
 +eps,  <-1      +, -pi/2 + eps       pi/2 - eps, -
 -eps,  <-1      -, -pi/2 + eps      -pi/2 + eps, -
   0,    >1      +,     pi/2             pi/2,    +
 +eps,   >1      +,  pi/2 - eps       pi/2 - eps, +
 -eps,   >1      -,  pi/2 - eps      -pi/2 + eps, +

Finally, the following identities help to illustrate the relationship between the complex trigonometric and hyperbolic functions. They are valid everywhere, including on the branch cuts.

sin(i*z)  = i*sinh(z)       arcsin(i*z)  = i*arcsinh(z)
cos(i*z)  =   cosh(z)       arcsinh(i*z) = i*arcsin(z)
tan(i*z)  = i*tanh(z)       arctan(i*z)  = i*arctanh(z)
sinh(i*z) = i*sin(z)        cosh(i*z)    =   cos(z)

The "advanced math" functions (gamma, Bessel, etc.) are also defined for general complex arguments, but their branch cuts and principal values are not rigorously specified at present.


Go to the first, previous, next, last section, table of contents.