Complex Numbers

Complex numbers arise in algebra in the solution of quadratic equations. The equation x2 = 1
does not have any real solutions. However, if we define a new number, i as the square root of -1, then we
have two solutions: i and -i. This, in turn, gives rise to an entirely new class of numbers of the
form a + ib with a and b real, and i defined as above. These are the complex
numbers.

Constructing complex numbers

The first constructor takes two arguments: the real and imaginary parts of the complex number.

C#

Copy

DoubleComplex a = new DoubleComplex(2, 4);

Visual Basic

Copy

Dim a As DoubleComplex = New DoubleComplex(2, 4)

The second constructor takes one real argument. It constructs a complex number whose imaginary part is zero.

C#

Copy

DoubleComplex b = new DoubleComplex(-3);

Visual Basic

Copy

Dim b As DoubleComplex = New DoubleComplex(-3)

The third constructor takes three arguments: two real numbers and a boolean parameter named polar. If
polar is true, the first two arguments are treated as the modulus and argument of the
complex number. If polar is false, the first two arguments are treated as the real and
imaginary part of the complex number.

C#

Copy

DoubleComplex c = new DoubleComplex(2, Constants.Pi/3, true);

Visual Basic

Copy

Dim c As DoubleComplex = New DoubleComplex(2, Constants.Pi/3, True)

Finally, the static RootOfUnity(Int32, Int32) method
constructs a complex number that is one of the solutions to the equation xn = 1. The solutions to
this equation are n complex numbers spaced equally on the unit circle. The first parameter of the method is
the degree, n, of the root. The second parameter is the index of the root in the series, counting
counter-clockwise on the unit circle. An index of 0 corresponds to the root x = 1.

Complex constants

The complex structure provides several constants for commonly used and special complex numbers. These are listed
in the following table:

Two values in the above list deserve special attention. The Infinity field represents complex
infinity. It is the result of dividing any non-zero complex number by zero.DoubleComplexinfinity does not have a
sign. Because the complex numbers do not have a natural ordering, is does not make sense to speak of positive or
negative numbers. Directed infinities, where the modulus of the complex number is infinite, but its argument is not,
are not supported. The static IsInfinity(DoubleComplex) method
verifies whether a complex number equals DoubleComplex.Infinity .

The NaN field represents complex Not-a-Number. It is a
special value that is the result of dividing zero by zero.The static IsNaN(DoubleComplex) method verifies whether a complex number equals
DoubleComplex.NaN. You can not use the equality operator for this purpose, as it always returns
false.

Working with complex numbers

Working with complex numbers is easy. The Re property
gets the real component of the complex number, while Im gets
the imaginary part. The Modulus property returns the
square root of the sum of the squares of the real and imaginary components. The Argument property returns the angle between the positive real
axis and a line from the origin to the complex number, measured counter-clockwise.

The modulus is computed every time the Modulus property is called. The same is true for the
Argument property. If you use these values multiple times, you should consider caching them in a
variable.

Details of complex arithmetic

When performing binary operations, if one of the operands is a DoubleComplex, then the other operand
is required to be an integral type or a floating-point type (Double or
Single) or a complex type (DoubleComplex). Prior
to performing the operation, if the other operand is not a DoubleComplex, it is converted to
DoubleComplex, and the operation is performed using at least DoubleComplex range and
precision. If the operation produces a numerical result, the type of the result is DoubleComplex.
Exceptions to this are methods that return a real property of a number: Argument, Modulus, ModulusSquared and
Abs(DoubleComplex). In these cases, the return type is Double.

The Extreme Optimization Mathematics Library for .NET extends the IEEE-754 standard definition of NaN's
for real numbers to complex numbers as follows.

The floating-point operators, including the assignment operators, do not throw exceptions. Instead, in exceptional
situations, the result of a floating-point operation is zero, Infinity, or NaN, as
described below:

If the result of a complex floating-point operation is too small for the destination format, the result of the
operation is zero.

If the magnitude of the complex result of a floating-point operation is too large for the destination format,
the result of the operation is DoubleComplex.Infinity.

If a complex floating-point operation on complex numbers is invalid, the result of the operation is
DoubleComplex.NaN.

If one or both operands of a complex floating-point operation are NaN (real or complex), the
result of the operation is DoubleComplex.NaN.

Arithmetic operations

The Extreme Optimization Mathematics Library for .NET provides methods for all basic arithmetic operators
on complex numbers. Most contain special versions for cases where one of the operands is real. Overloaded versions of
the arithmetic operators are provided for languages that support them. For languages that don't support operator
overloading, equivalent static (Shared in Visual Basic) methods are supplied.

There is one other static method that does not have an operator equivalent. The ConjugateMultiply
method returns the product of the conjugate of the first argument and the second argument.

Because the complex numbers don't have a natural ordering, only equality and inequality operators are available.
No other comparison operators are available.

Functions of complex numbers

TheDoubleComplextype defines static methods for the most common mathematical functions of complex numbers,
including: logarithmic, exponential, trigonometric and hyperbolic functions.

Some functions of real numbers have a limited domain when the result is restricted to be real, but are defined for
all real numbers if the result can be complex. Examples of this are the inverse sine and cosine, which are real only
for arguments between -1 and +1. TheDoubleComplextype defines methods that extend these functions to return a
complex result.

These functions are often discontinuous along the part of the real axis where they are complex-valued. Which
of the two limit values is chosen is arbitrary. However, the most consistent choice is the one that preserves
any symmetry or anti-symmetry about the origin. For example, the function Arcsin(x) satisfies Arcsin(-x) = -Arcsin(x) when x is within [-1, 1]. The Arcsin method with real argument also satisfies this identity.

Most elementary functions have been extended to cover the entire complex plane. Once again, many of them are
multi-valued, and a suitable choice has to be made regarding which of the two possible limit values is returned. The
choice is made easier by the fact that the discontinuities lie along the real or imaginary axis. This makes it
possible to distinguish between the 'limit from above' and the 'limit from below' by using the value of negative zero
for the limit from below. The situation is somewhat simplified by the fact that any analytic function satisfies the
identity f(conj(z) = conj(f(z)).

The tables below summarize these methods, and their meaning. Special functions with complex argument may be
available from the Extreme.Mathematics.Special namespace.