Professional

Home
Learn Shen
Videos
Community Wiki
Community
OS Kernel
OS Library
Shen Professional


More Help

Concurrency
FTP
Graphics
Shilbert
Standard Extension
Web
 

 

The Complex Package

(v.1.1 25-06-16)
W O Riha

1. Introduction

It seems a fair assumption that anybody wishing to make use of a complex maths library, is actually familiar with complex numbers, complex functions and the general terminology.

As there are differences in both terminology and notation, I shall briefly remind the interested reader of the terminology I am using. This link, provides more detailed background information. Mathematical explanations make use of traditional infix notation (x + y); function values are quoted as f(x). For notational convenience, we shall write “sqrt”. We use π for the well known constant.

2. Complex Numbers

2.1 Complex Plane

A complex number z is of the form z = a + bi, where a is the real part, re(z) of z, and b the imaginary part, im(z). The quantity, i, is the imaginary unit, and satisfies the identity i2 = –1. It can therefore be interpreted as the square root of –1, i.e. i = sqrt(-1).

Complex numbers can be visualised as points <a, b> in the so-called complex or Gaussian plane. Here, a and b are the (Cartesian) coordinates of z. The two axes are called the real and imaginary axes (see diagram).

The reflection of z = a + bi about the real axis is called the complex conjugate

z* (or z’) = a – bi (2.1.1)

1. Introduction

2. Complex Numbers

2.1 Complex Plane
2.2 Polar Representation
2.3 Euler's Formula
2.4 Complex Arithmetic
2.5 Complex Functions
2.5.1 Exponential Function and Logarithm
2.5.2 General Powers
2.5.3 Integral Powers and Roots
2.6 Trigonometric Functions
2.7 Inverse Trigonometric Functions
2.8 Hyperbolic Functions
2.9 Inverse Hyperbolic Functions

3. The Complex Library

3.1 Representation
3.2 Constructors, Constants and Comparison
3.2.1 Constructors
3.3 Accessor Functions
3.4 Predicates
3.5 Various Functions
3.6 Arithmetic Operations
3.7 Exponential Function and Logarithm
3.8 Powers and Roots
3.8.1 General Powers
3.8.2 Integral Powers and Roots
3.9 Trigonometric Functions
3.10 Inverse Trigonometric Functions
3.11 Hyperbolic Functions
3.12 Inverse Hyerbolic Functions

2.2 Polar Representation

It is also possible, uniquely to specify a point in the plane by its distance from the origin <0, 0> and the angle at which its vector points away from the positive horizontal axis – except for the point <0, 0> itself, where the angle is undefined. This specification is called polar representation. In terms of the coordinates a and b, the distance from the origin, called the modulus, norm or absolute value of z, is

|z| = sqrt (a2 + b2) (2.2.1)

The angle θ (arg in the diagram) is given by arctan (b/a). arg is referred to as the phase or the argument, arg(z), of z.

Note: Since the tan function is periodic with period 2π, i.e. tan x = tan(x + (2kπ)), for k is a member of Z, arctan is a multi-valued function: if Arctan denotes the principal branch (with π/2 < Arctan (x) = π/2), as returned by atan, we have

arctan (x) = Arctan(x) + 2kπ.

In order to make the angle θ unique, one defines

Arg (z) = atan2(b, a) (2.2.2)

This ensures that –π < Arg(z) <= π. atan2 is described and implemented in the maths library. Clearly,

arg (z) = Arg (z) + (2π k), for k in Z (2.2.3)

A generalisation of the sign function for reals to complex numbers, is defined by

sign(z) = 0 if z = 0
and z / |z| otherwise

It is a complex number with arg(z) and unit modulus.

2.3 Euler’s Formula

There is a simple relationship between Cartesian and polar coordinates. It can be seen from the diagram above that a = |z|cos θ and b = |z|sin θ, or z = |z|(cos θ + i sin θ). Now, according to Euler’s formula

cos θ + i sin θ = e (2.3.1)

It follows that

z =|z|e =|z|eiθ(z) (2.3.2)

This representation of complex numbers makes it easy to compute, logarithms, exponential and powers of z.

The complex valued function θ --> cos θ + i sin θ, with real argument θ, is called “cis” (see library functions). Notice, for example, that cis(p) = –1 and cis(2π) = 1.

2.4. Complex Arithmetic

Just like the real numbers R, the complex numbers C form a field, that is addition, subtraction, multiplication and division (by non-zero divisor) are well defined.

Let X = a +bi and Y = c + di, then

X + Y = (a+c) + (b+d)i (2.4.1)
X – Y = (a–c) + (b–d)i (2.4.2)
X Y = (ac – bd) + (ad +bc)i (2.4.3)
X / Y = (ac – bd)/|Y| + (ad +bc)i/|Y|
where |Y| = sqrt(c2 + d2)
(division is not defined for Y = 0)
(2.4.4)

The additive inverse of X is

–X = –a – bi (2.4.5)

The multiplicative inverse (reciprocal) of X is

1/X = a /|X| + bi/|X| (2.4.6)

 

2.5 Complex Functions

Functions from R --> R, in particular the elementary transcendental functions, such as exp and log, can be extended to functions from C --> C. They are usually given the same name. This can be confusing, especially when deriving or explaining such function extensions. It is tempting to make use of a different name or symbol in order to clarify the distinction. I have decided not to do so, as it would probably make the situation even worse. Instead, I assume that the reader appreciates and understands the ideas of overloading. Many authors have done this in the past. Consider, for example, the definition of log z (2.5.1.2’):

log (z) = log|z| + i arg(z)

The log function on the left is being defined for complex arguments, assuming that the log function already exists for real arguments. There is no circular reasoning here, because |z| is a real number, for which log has already been defined.

Some function extensions turn out to be periodic or multi-valued. In particular, if a periodic function f has an inverse, then this inverse f-1 must be multi-valued; see arctan in section 2.2.

Indeed, if y = f(x) = f(x + p) = f(x + 2p) …, then f-1(y) = {x+kp | k in Z}. To each fixed k, there corresponds an inverse of f, called a branch. To define a unique inverse, one singles out a particular branch, called the principal branch which is usually denoted by capitalising the name of the function, for example, Arctan and Log. It is these single-valued functions that are implemented in the library. Since function names in Shen cannot start with a capital letter, we use names starting with a ‘c’ to denote them, for example, clog, csqrt, catan etc.

It can happen that a function is not defined for all arguments, for example, log z, for z = 0. But even if a function is defined at a certain point, it may fail to be continuous there. The set of all such branch points is referred to as the branch cut of the function. This is usually a line or, more generally, a section of the complex plane.

2.5.1 Exponential Function and Logarithm

To define the function exp(z) = ez for complex z = a + bi, we note that ez = ea+bi = eaebi = ea(cos b + i sin b). Hence

exp (z) = exp(a) cis (b) (2.5.1.1)

Now, since sin and cos are periodic with period 2π, exp (z) is periodic with period 2π. That is

exp (z) = exp (z + 2πki), for k in Z

exp (z) is an entire function – a function f with dom(f) = C, and range(f) = C , or range(f) = C – {p}, for one particular p in C. We have range(exp) = C – {0}, as exp(z) is never 0.

Referring to formula (2.3.2), the natural logarithm (inverse of ez) is defined by log (z) = log (|z|ei arg(z)). It follows that log (z) = log|z| + i log earg(z). Hence, for ~(z = 0)

log (z) = log|z| + i arg(z) (2.5.1.2')

The principal branch of this function is

Log (z) = log|z| + i Arg(z), ~(z = 0) (2.5.1.2)

and so, by (2.2.3)

log (z) = Log (z) + 2πki, ~(z = 0) and k in Z

We have dom(Log) = C – {0} range(Log) = R (–π π]. The branch cut is the negative real axis.

Logarithms with general base b are defined as in the real case

Logb(z) = Log z/Log b ~(z = 0), ~(b = 0)
Log0(z) = 0 if ~(z = 0)
(2.5.1.3)

2.5.2 General Powers

For real numbers x and y, the general power xy (= expt (x, y)) is defined by

expt (x, y) = exp (y log x), for x > 0

General complex powers zw are defined by the analogous formula

expt (z, w) = exp (w log z), ~(z = 0) (2.5.2.1)

The principal branch is given by

Expt (z, w) = exp (w Log z), ~(z = 0) (2.5.2.2)

Special cases not covered by the formula are

Expt (0, 0) = 1
Expt (0, w) = 0, if re(w) > 0 (undefined if re(w) = 0

zw as a function of w, with z fixed, has no branch cut.

Regarded as a function of z, with w fixed, the branch cut is the same as for Log

It can happen that a complex power is a real number, for example ii = eπ/2 as seen from (2.5.2.2)

2.5.3 Integral Powers and Roots

As mentioned above, some functions, such as integral powers or roots are easy to compute using the representation (2.3.2) z =|z|e . However, this is not always the most efficient method.

Squaring a complex number

There a several ways to compute the square z2 of a complex number z = a +bi.

(a) z =|z|e implies z2 =|z|2 e2iθ.

Since complex numbers are represented in terms of their real and imaginary parts, a and b, we need to compute (a2 + b2) and θ = atan2(b, a) and then (cis 2θ) – this is quite a lot of work!

(b) We could simply multiply z by z according to (2.4.3), which requires just 4 real mults and 2 adds.
(c) We can compute z2 as (a2 – b2) + 2abi = (a+b)(a–b) + 2abi, essentially 2 real mults and 3 adds.

Integral Powers

zm , for m in Z, can be computed by repeated squaring and/or multiplication, as in the real case (see maths lib). It can also be computed using de Moivre’s formula:

(cos θ + i sin θ)m = eiθm =
cos(mθ) + i sin(mθ)
(2.5.3.1)

Numerical experiments show that the first method is more accurate, but slower than the second. Unless you need to compute powers with large exponents 100000 times, the first method is preferred.

Integral roots are computed by a similar formula:

(cos θ + i sin θ)1/n = eiθ/n = cos ((θ + 2πk)/n) + i sin ((θ + 2πk)/n), 0 <= k < n (2.5.3.2)

This formula can be used to compute all n roots. The case k=0, produces the principal root, which is not always what one would expect! –2 is a cube root of –8, but it is not the principal root, which, in fact, is 1 + i*sqrt(3).

The two formulae can be combined to compute zm/n for m, n in Z, ~(n = 0).

(cos θ + i sin θ)m/n = eiθ/n = cos (m(θ + 2πk)/n) + i sin (m(θ + 2πk)/n), 0 <= k < n (2.5.3.3)

Note: In practice, this formula also works for any floating-point number x, as such numbers are all fractions of the form m/2d.

2.6 Trigonometric Functions

These are defined as follows

sin z = (eiz – e–iz)/(2i) (2.6.1)
cos z = (eiz + e–iz)/2 (2.6.2)
tan z = i(e–iz – eiz)/(e–iz + eiz) (2.6.3)

They are entire functions and are periodic with periods 2π (sin and cos), and π (tan).

2.7 Inverse Trigonometric Functions

These are defined in terms Log

Arcsin z = –i Log (iz + sqrt (1–z2)) (2.7.1)
Arccos z = –i Log (z + i sqrt (1–z2)) (2.7.2)
Arccos z = π/2 – Arcsin z  
Arctan z = iLog((1–iz)/(1+iz))/2 (2.7.3)

2.8 Hyperbolic Functions

Their definition is analogous to the trigonometric functions (see 2.6 above)

sinh z = (ez – e–z)/2 (2.8.1)
cosh z = (ez + ez)/2 (2.8.2)
tanh z = (e–z – ez)/(e–z + ez) (2.8.3)

They are entire functions and are periodic with periods 2π (sinh and cosh) and π (tanh).

There exist simple relationships between hyperbolic and trigonometric functions:

sinh z = –i sin iz sin z = –i sinh iz (2.8.4)
cosh z = cos iz cos z = cosh iz (2.8.5)
tanh z = –i tan iz tan z = –i tanh iz (2.8.6)

2.9 Inverse Hyperbolic Functions

These are, again, defined in terms Log

Arsinh z = Log (z + sqrt (z2+1)) (2.9.1)
Arcosh z = Log (z + sqrt (z2–1)) (2.9.2)
Artanh z = Log((1+z)/(1–z)) (2.9.3)

3. The Complex Library

3.1 Representation

Complex numbers in Shen inhabit the abstract data type complex whose elements are objects of the form (c# number number). The two numbers correspond to the real and imaginary parts of the complex number that the object represents.

(c# 3 4)
(c# 3 4) : complex \\ the number 3 + 4i

(c# 0 1)
(c# 0 1) : complex \\ the imaginary unit, i

(c# 1 0)
(c# 1 0) : complex \* the real number 1, written as
the complex number 1 + 0i *\

3.2 Constructors, Constants and Comparison

3.2.1 Constructors

To construct a complex number from its real and imaginary parts, we use the function

complex : number --> number --> complex \\ constructor
or the shorter alternative
c# : (no type) \\ constructor (short-hand)
Input: Two numbers A and B.
Output: The (representation of the) complex number A + Bi.

(complex 3 4)
(c# 3 4) : complex

(c# 3 4)
(c# 3 4) : complex

To make a real number into a complex number, we use the short-hand


c# : (no type) \\ constructor (short-hand)
Input: A number A.
Output: The (representation of the) complex number A + 0i.

(c# 12.3)
(c# 12.3 0) : complex

To construct a complex number from its modulus and argument, we use


cp# : number --> number --> complex \\ constructor from polar coords
Input: Two numbers M and A.
Output: The (representation of the) complex number MeiA = M (cos A + i sin A).

(cp# (sqrt 2) (pi/4)) \\ the polar coordinates of 1+i
(c# 1.0 1.0000000000000002) : complex

(cp# (sqrt 2) (+ (pi/4) (* 10 (pi)))) \\ also represents 1+i
(c# 1.000000000000004 0.9999999999999962) : complex

3.2.2 Constants

For the sake of convenience, the following constants are available

c0 : --> complex \\ complex 0
c1 : --> complex \\ complex 1
i : --> complex \\ imaginary unit i
-i : --> complex \\ -i

These are shorthand for (c# 0 0), (c# 1 0), (c# 0 1) and (c# 0 -1). They are useful in arithmetic expressions!

(c1)
(c# 1 0) : complex

(-i)
(c# 0 -1) : complex

3.2.3 Comparison

The only comparison operations defined on complex numbers are equality =, and its negation !=. Due to rounding errors, equality is a dangerous and unreliable operation, just as with real numbers.

In the following test, both numbers represent 1 + i (see above), but are deemed not to be equal.

(= (cp# (sqrt 2) (pi/4)) (c# 1 1))
false : boolean

I am introducing a new equality operator that takes into account rounding errors

=c : complex --> complex --> boolean \\ special equality test
Input: Two complex numbers X and Y.
Output: true or false depending on whether the absolute difference of X and Y is less than a fixed tolerance.

(=c (cp# (sqrt 2) (pi/4)) (c# 1 1))
true : boolean

(=c (cp# (sqrt 2) (+ (pi/4) (* 8 (pi)))) (c# 1 1))
true : boolean

(=c (cp# (sqrt 2) (+ (pi/4) (* 10 (pi)))) (c# 1 1))
false : boolean \\ should of course be true – but rounding error is too big!

3.3 Accessor Functions

re : complex --> number \\ get real part
im : complex --> number \\ get imaginary part

Input: A complex number Z.
Output: The real and imaginary parts of Z

(re (c# 3 4))
3 : number

(im (c# 3 4))
4 : number

(re (cp# (sqrt 2) (pi/4))) \\ see above!
1.0 : number


modulus : complex --> number \\ modulus (abs or norm)
cabs : complex --> number \\ modulus (abs or norm)

Input: A complex number Z.
Output: The modulus of Z – see (2.2.1 )

(modulus (c# 3 4))
5.0 : number

(cabs (c# 1 1)) \\ sqrt (2)
1.4142135623730951 : number


arg : complex --> number \\ argument (or phase)
Input: A complex number Z.
Output: The Argument of Z – see (2.2.2)
Note: (arg Z) is always returned as an angle θ satisfying – π < θ <= π.

(arg (c# 1 1)) \\ pi/4
0.7853981633974483 : number

(rad->degs (arg (c# 1 1))) \\ or 45 degs
45.0 : number


csign : complex --> complex \\ signum – see (2.2.4)
Input: A complex number Z.
Output: The signum of Z.

(csign (c0))
(c# 0 0) : complex

(csign (c# 1 1))
(c# 0.7071067811865475 0.7071067811865475) : complex

3.4 Predicates

complex? : A --> boolean \\ recogniser of complex numbers
Input: Any Shen object X.
Output: true if X is a complex number, false otherwise.

(complex? Mark)
false : boolean

(complex? (@p 1 2))
false : boolean

(complex? (i))
true : boolean


real? : complex --> boolean
imag? : complex --> boolean

Input: A complex number Z.
Output: true or false depending on whether Z represents a real or purely imaginary number.
Note: It can happen that due to rounding error in a computation, a real or imaginary part is very close to 0, whilst, theoretically, it should be exactly equal to 0. The predicates take account of this, as shown in the second example.

(real? (c# 1.2 0))
true : boolean

(real? (c# 1.2309157 -3.5901e-16))
true : boolean

(imag? (c# 1.2 1))
false : boolean

3.5 Various Functions

c’ : complex --> complex \\ complex conjugate
Input: A complex number Z.
Output: The complex conjugate of Z – see (2.1.1)

(c' (c# 1 2))
(c# 1 -2) : complex

(c' (i))
(c# 0 -1) : complex

(c' (c1))
(c# 1 0) : complex


cis : number --> complex \\ cosine + i sine
Input: A (real) number A.
Output: The complex number eiA = cos(A) + i sin(A)

(cis (pi/2)) \\ exp (i π/2) = i
(c# 0 1.0) : complex

(cis (pi)) \\ exp (i π) = –1
(c# -1.0 0) : complex

(cis (/(pi) 3)) \\ 1/2 + i sqrt(3)/2
(c# 0.5000000000000001 0.8660254037844386) : complex

3.6 Arithmetic Operations

+c : complex --> complex --> complex \\ complex addition
Input: Two complex numbers X and Y.
Output: The sum of X and Y – see (2.4.1).

(+c (c# 17 5) (c# 1 13))
(c# 18 18) : complex


-c : complex --> complex --> complex \\ complex subtraction
Input: Two complex numbers X and Y.
Output: The difference of X and Y – see (2.4.2).

(-c (c# 17 5) (c# 1 13))
(c# 16 -8) : complex


*c : complex --> complex --> complex \\ complex multiplication
Input: Two complex numbers X and Y.
Output: The product of X and Y – see (2.4.3).

(*c (c# 17 5) (c# 1 13))
(c# -48 226) : complex

(*c (~c (i)) (i)) \\ -i i = 1
(c# 1 0) : complex


/c : complex --> complex --> complex \\ complex division
Input: Two complex numbers X and Y /= 0
Output: The quotient of X and Y – see (2.4.4), or an error message.

(/c (c# 17 5) (c# 3 4))
(c# 2.84 -2.12) : complex

(/c (c# 17 5) (c0))
division by 0!


~c : complex --> complex \\ unary –
Input: A complex number Z.
Output: The number –Z – see (2.4.5).

(~c (c# 3 -4))
(c# -3 4) : complex


/1c : complex --> complex \\ reciprocal 1/z
Input: A complex number Z where ~(Z = 0).
Output: The number 1/Z, (see 2.1.6), or an error message when Z = (c0)

(/1c (c# 3 4))
(c# 0.12 -0.16) : complex \\ 3/25 – (4/25)i

(/1c (i))
(c# 0 -1) : complex \\ 1/i = -i

(/1c (c0))
divsion by 0 in fn. /cn!


*cn : complex --> number --> complex \\ product of complex & real
Input: A complex number Z and a real number X.
Output: The product of Z and X.

(*cn (c# 3 -4) 1.5)
(c# 4.5 -6.0) : complex


/cn : complex --> number --> complex \\ quotient of complex & real
Input: A complex number Z and a real number X where ~(X = 0).
Output: The quotient Z / N, or an error message if X = 0.

(/cn (c# 3 -4) 1.5)
(c# 2.0 -2.6666666666666665) : complex

(/cn (c# 3 -4) 0)
divsion by 0 in fn. /cn!


*ci : complex --> complex \\ zi
Input: A complex number Z.
Output: The product of Z and i.

(*ci (c# 3 4))
(c# -4 3) : complex

The functions described in the following sections have all been compared with the corresponding functions available on the SBCL platform. It was found that the values produced by the Shen implementation agree with those delivered by SBCL to within rounding error.

3.7 Exponential Function and Logarithm

cexp : complex --> complex \\ e to a complex power
Input: A complex number Z.
Output: The (complex) number eZ – see (2.5.1.1).

(cexp (c# 0 (pi*2))) \\ e2pi = 1
(c# 1.0 0) : complex

(cexp (c# 2 -1))
(c# 3.992324048441272 -6.217676312367968) : complex

(cexp (c# 2 (+ -1 (pi*2)))) \\ same!
(c# 3.99232404844127 -6.217676312367969) : complex


clog : complex --> complex \\ Log
Input: A complex number Z where ~(Z = 0).
Output: The complex number Log Z – see (2.5.1.2), or an error message.

(clog (cexp (c# 2 -1)))
(c# 2.0 -1.0) : complex

(clog (c# -1)) \\ log (-1) = ip
(c# 0 3.141592653589793) : complex

(clog (c0))
clog 0 - is not defined!

clog : complex --> complex --> complex \\ Log (b z)
Input: Two complex numbers B and Z.
Output: The value of Log (B Z) – see (2.5.1.3).

(clog (c# 2) (c# 1 1))
(c# 0.32596797216345985 -0.7387021222729508) : complex

(clog (c# 2 3) (c0))
(c# 0 0) : complex

(clog (-i) (i))
(c# -1.0 0) : complex

3.8 Powers and Roots

3.8.1 General Powers

cexpt : complex --> complex --> complex \\ complex powers
Input: Two complex numbers Z, W
Output: The (complex) number ZW – see (2.5.2.1).

(cexpt (c# 1 1) (c# 1 1)) \\ (1 + i) to the power (1 + i)
(c# 0.2739572538301211 0.5837007587586147) : complex

(cexpt (i) (i)) \\ = e–p/2
(c# 0.20787957635076196 0) : complex

(cexpt (c0) (c# -1 1))
cexpt - not defined!

(cexpt (c0) (c# 1 1))
(c# 0 0) : complex

(cexpt (c# 1 2) (c# 8)) \\ (1 + 2i)8 – see further down!
(c# -527.0000000000001 336.0000000000006) : complex

3.8.2 Integral Powers and Roots

csquare : complex --> complex \\ z squared
Input: A complex number Z.
Output: The complex number Z2.

(csquare (c# 2 3))
(c# -5 12) : complex

(csquare (i))
(c# -1 0) : complex

cpower : complex --> number --> complex \\ z to the power M, for integer M
cpowerMoivre : complex --> number --> complex \\ based on (2.5.3.1)

Input: A complex number Z and an integer N.
Output: The complex power ZN.

(cpower (c# 1 2) 8)
(c# -527 336) : complex
(cpowerMoivre (c# 1 2) 8) \\ less accurate
(c# -527.0000000000002 336.0000000000007) : complex

(cpower (c# 1 2) -8)
(c# -0.00134912 -8.6016e-4) : complex

(cpowerMoivre (c# 1 2) -8) \\ less accurate
(c# -0.0013491199999999981 -8.601600000000002e-4) : complex

Speed comparison (in secs): (for 100000 evaluations)

(cpower (c# 1 1) 10) 0.172 (cpower (c# 1 1) 101) 1.467
(cpowerMoivre (c# 1 1) 10) 0.237 (cpowerMoivre (c# 1 1) 101) 0.235
(cexpt (c# 1 1) (c# 10)) 0.262 (cexpt (c# 1 1) (c# 101)) 0.284

Note: As mentioned in 2.5.2, cpowerMoivre also works for general exponents:

(cpowerMoivre (c# 1.234 5.66) 2.312347)
(c# -58.08756282057958 0.3334082296434587) : complex


croot : complex --> number --> complex \\ n-th root
Input: A complex number Z and an integer N where ~(N = 0).
Output: The N-th (principal) root of Z – using (2.5.2.2)

(croot (c# 1 1) 5)
(c# 1.0585781527063765 0.16766230825618095) : complex

(croot (c# 1 1) -5)
(c# 0.9215458071315066 -0.14595851689594672) : complex


As a special case we have

csqrt : complex --> complex \\ complex sqrt
Input: A complex number Z.
Output: The (principal) square root of Z.

(csqrt (c# 3 -4))
(c# 2.0 -1.0) : complex

(csqrt (c# -1))
(c# 0 1.0) : complex \\ i

To work out all n roots of zm/n using formula (2.5.3.3) we use the function


all-roots : complex --> number --> number --> (list complex)
and to print them
print-roots : complex --> number --> number --> unit
Input: A complex number Z, two integers M and N, N > 0
Output: A list of the N roots of Z.

(all-roots (c# 3 -4) 2 3) \\ cube root of (c# 3 -4) squared
[(c# 2.382854712517302 -1.6946631383309103) (c# -2.6590486849102817 -1.2162811454019933) (c# 0.27619397239298155 2.910944283732904)] : (list complex)

(print-roots (c# 3 -4) 2 3)
(c# 2.382854712517302 -1.6946631383309103)
(c# -2.6590486849102817 -1.2162811454019933)
(c# 0.27619397239298155 2.910944283732904)
: unit

(print-roots (c1) 1 6) \\ the sixth roots of unity
(c# 1.0 0) \\ 1
(c# 0.5000000000000001 0.8660254037844386) \\ 1/2(1 + iv3)
(c# -0.4999999999999998 0.8660254037844387) \\ 1/2(–1 + iv3)
(c# -1.0 0) \\ -1
(c# -0.5000000000000004 -0.8660254037844384) \\ –1/2(1 + iv3)
(c# 0.49999999999999933 -0.866025403784439) \\ 1/2(1 – iv3)
: unit

3.9 Trigonometric Functions

csin : complex --> complex \\ complex sin
ccos : complex --> complex \\ complex cos
ctan : complex --> complex \\ complex tan

Input: A complex number Z.
Output: sin Z, cos Z or tanZ – see (2.6.1 – 2.6.3)

(csin (c# 12.67 -3.897))
(c# 2.5485896006073303 -24.48501678529392) : complex

(ccos (c# 12.67 -3.897))
(c# 24.505210595176475 2.546489405072857) : complex

Check accuracy, using the formula sin2 z + cos2 z = 1

(+c (csquare(csin (c# 12.67 -3.897))) (csquare(ccos (c# 12.67 -3.897))))
(c# 1.0 0) : complex \\ happens to be exactly correct!

But not in this case!

(+c (csquare(csin (c# 12.671 -3.89))) (csquare(ccos (c# 12.671 -3.89))))
(c# 0.9999999999998863 -2.842170943040401e-14) : complex

(ctan (c# 3.1 -6.2))
(c# -6.844165341309994e-7 -0.9999917913394022) : complex

Should be the same as

(/c (csin (c# 3.1 -6.2)) (ccos (c# 3.1 -6.2)))
(c# -6.844165341439968e-7 -0.9999917913394023) : complex \\ pretty good!

3.10 Inverse Trigonometric Functions

casin : complex --> complex \\ Arcsin
cacos : complex --> complex \\ Arccos
catan : complex --> complex \\ Arctan

Input: A complex number Z.
Output: Arcsin Z, Arccos Z or ArctanZ – see (2.7.1 – 2.7.3)

(casin (csin (c# 1.47 -3.89)))
(c# 1.4699999999999904 -3.890000000000057) : complex \\ absolute error 5.76e-14

(catan (ctan (c# 1.53 4.78)))
(c# 1.5299999999999812 4.780000000000188) : complex \\ absolute error 1.88e-13

3.11 Hyperbolic Functions

csinh : complex --> complex \\ complex sinh
ccosh : complex --> complex \\ complex cosh
ctanh : complex --> complex \\ complex tanh

Input: A complex number Z.
Output: sinh Z, cosh Z or tanh Z – see (2.8.1 – 2.8.3)

(csinh (c# 1.85 -0.34))
(c# 2.923756727357254 -1.0866771422516306) : complex

(ccosh (c# 1.85 -0.34))
(c# 3.071992799493883 -1.0342405768812373) : complex

Check, using the formula cosh2 z – sinh2 z = 1

(-c (csquare (ccosh (c# 1.85 -0.34))) (csquare (csinh (c# 1.85 -0.34))))
(c# 0.9999999999999991 0) : complex

(ccos (c# 1 -1))
(c# 0.833730025131149 0.9888977057628651) : complex

(ccosh (*ci(c# 1 -1))) \\ see 2.8.5
(c# 0.833730025131149 0.9888977057628651) : complex

3.12 Inverse Hyperbolic Functions

casinh : complex --> complex \\ complex arsinh
cacosh : complex --> complex \\ complex arcosh
catanh : complex --> complex \\ complex artanh

Input: A complex number Z.
Output: arsinh Z, arcosh Z or artanh Z – see (2.9.1 – 2.9.3)

(casinh(csinh (c# 1.85 -0.34)))
(c# 1.85 -0.3400000000000002) : complex

(catanh (c# 1 1))
(c# 0.402359478108525 1.0172219678978514) : complex

(ctanh(catanh (c# 1 1)))
(c# 1.0 1.0000000000000002) : complex \\ pretty good!