calc: Branch Cuts

 
 9.4 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.  Recent versions of
 Calc 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.