Documentation
www.exept.de
Everywhere
for:

# Class: Complex

## Inheritance:

```   Object
|
+--Magnitude
|
+--ArithmeticValue
|
+--Complex
```

Package:
stx:libbasic
Category:
Magnitude-Numbers
Version:
rev: 1.30 date: 2018/05/15 16:16:00
user: cg
file: Complex.st directory: libbasic
module: stx stc-classLibrary: libbasic
Author:
Kurt Hebel (hebel@uinova.cerl.uiuc.edu)
minor changes and double dispatching code by cg.
additions (trigonometric) and fixes by cg.

## Description:

```This class implements complex numbers.
A complex number has real and imaginary parts which must be manipulated simultaneously
in any numeric processing.
Complex numbers can be used in many of the same places that regular numbers
can be used with one major exception of comparisons, since complex numbers cannot
be directly compared for size
(except through lengths of vectors (see absolute value)).

[Instance variables:]
real        <Number> the part of the number which can be expressed as a Real number
imaginary   <Number> the part of the number which, in terms of how the number behaves,
has been multiplied by 'i' (-1 sqrt)

[Constructors:]
5 i
6 + 7 i.
5.6 - 8 i.
Complex real: 10 imaginary: 5.
Complex abs: 5 arg: (Float pi / 4)

NOTE:
Although Complex something similiar to the Smalltalk''s Number class,
it would not be a good idea to make a Complex to be a subclass of a Number because:
- Number is subclass of Magnitude and Complex is certainly not a magnitude.
Complex does not behave very well as a Magnitude. Operations such as
<
>
<=
>=
do not make sense in case of complex numbers.
- Methods in the following Number methods'' categories do not make sense for a Complex numbers
truncation and round off
testing
intervals
comparing

However the following Number methods'' categories do have sense for a Complex number
arithmetic (with the exception of operation
//
\\
quo:
rem:
mathematical functions

Thus Complex is somewhat similar to a Number but it is not a subclass of it.
Some operations we would like to inherit (e.g. #abs, #negated, #reciprocal)
but some of the Number operations do not have sens to inherit or to overload.
Classes are not always neat mechanism.

!!! We had to COPY the implementation of some methods
abs
negated
reciprocal
log:
isZero
reciprocal
...
methods from the Number class to the Complex class.
Awful solution. Now I begin to appreciate Self.

```

## Class protocol:

coercing & converting
coerce: aNumber
convert the argument aNumber into an instance of the receiver's class and return it.

constants access
unity
Answer the value which allows, for any given arithmetic value, the following to be true:
aNumber * aNumber class unity = aNumber
This must be true regardless of how a given subclass chooses to define #*

zero
Answer the value which allows, for any given arithmetic value, the following to be true:
aNumber + aNumber class zero = aNumber
This must be true regardless of how a given subclass chooses to define #+

instance creation
abs: aNumber1 arg: aNumber2
self abs:10 arg:2 -> (-4.16146836547142387+9.092974268256816954i)

fromReal: aNumber
Create a new complex number from the given real number.
usage example(s):
 `````` Complex fromReal:1.0 ``````

imaginary: v
Create a new complex number with 0 as real and given imaginary parts.
If the imaginary part is zero, return the real part of the number.
usage example(s):
 `````` Complex imaginary:1.0 (0.0 % 1.0) ``````

real: aNumber
Create a new complex number from the given real number.
usage example(s):
 `````` Complex real:1.0 ``````

real: u imaginary: v
Create a new complex number with the given real and imaginary parts.
If the imaginary part is zero, return the real part of the number.
usage example(s):
 `````` Complex real:1.0 imaginary:2.0 (1.0 % 2.0) ``````

## Instance protocol:

accessing
imaginary
Return the imaginary part of the complex number.

imaginaryPart
Return the imaginary part of the complex number.
An alias for imaginary (for compatibility with other complex implementations)

real
Return the real part of the complex number.

realPart
Return the real part of the complex number.
An alias for real (for compatibility with other complex implementations)

arithmetic
* aNumber
Return the product of the receiver and the argument.
usage example(s):
 ``````r := (real * u) - (imaginary * v). ``````
usage example(s):
 ``````i := (real * v) + (imaginary * u). ``````

+ aNumber
Return the sum of the receiver and the argument.
usage example(s):
 ``````r := aNumber real + real. ``````
usage example(s):
 ``````i := aNumber imaginary + imaginary. ``````

- aNumber
Return the difference of the receiver and the argument.
usage example(s):
 ``````r := real - aNumber real. ``````
usage example(s):
 ``````i := imaginary - aNumber imaginary. ``````

/ aNumber
Return the quotient of the receiver and the argument.
usage example(s):
 ``````r := u * real + (v * imaginary) / denom. ``````
usage example(s):
 ``````i := u * imaginary - (v * real) / denom. ``````

abs
Return the magnitude (or absolute value) of the complex number
that's the distance from zero (the origin in the complex plane).
usage example(s):
 `````` (1 + 1i) abs ``````

absSecure
Answer the distance of the receiver from zero (0 + 0 i).
Try avoiding overflow and/or underflow
usage example(s):
 `````` (10 + 4i) abs -> 10.770329614269 (10 + 4i) absSecure -> 10.770329614269 ``````

conjugated
Return the complex conjugate of this complex number
(i.e. with imaginary part negated).

divideFastAndSecureBy: anObject

divideSecureBy: anObject

i
^ self * 1 i
This is an obvious extension of method i implemented in Number.
usage example(s):
 `````` (10+4i) i -> (-4+10i) ``````

modulus

negated
return a new complex with both real and imaginary parts negated

coercing & converting
asComplex
I am a complex - so return the receiver

asFloat

asInteger

asPoint
Return the complex number as a point.

coerce: aNumber
convert the argument aNumber into an instance of the receiver's class and return it.

generality

reduceGeneralityIfPossible
transformation is possible without losing information.

comparing
< aNumber
raises an error - complex numbers are not well ordered
usage example(s):
 `````` 1 < (2 % 2) (2 % 2) < 1 ``````

= aNumber
return true, if the argument represents the same numeric value
usage example(s):
 `````` (Complex real:1.0 imaginary:2.0) = (Complex real:1.0 imaginary:2.0) (Complex real:1.0 imaginary:0) = 1.0 ``````

hash
Hash is implemented because = is implemented.
usage example(s):
 `````` (1+0i) hash (1+1i) hash ``````

double dispatching
differenceFromComplex: aComplex
Return the difference of the argument, aComplex and the receiver.

differenceFromFixedPoint: aFixedPoint
Return the difference of the argument, aFixedPoint and the receiver.

differenceFromFloat: aFloat
Return the difference of the argument, aFloat and the receiver.

differenceFromFraction: aFraction
Return the difference of the argument, aFraction and the receiver.

differenceFromInteger: anInteger
Return the difference of the argument, anInteger and the receiver.

equalFromComplex: aComplex
return true if aComplex represents the same number as myself

equalFromFloat: aFloat
return true if aFloat represents the same number as myself

productFromComplex: aComplex
Return the product of the receiver and the argument, aComplex.

productFromFixedPoint: aFixedPoint
Return the product of the receiver and the argument, aFixedPoint.

productFromFloat: aFloat
Return the product of the receiver and the argument, aFloat.

productFromFraction: aFraction
Return the product of the receiver and the argument, aFraction.

productFromInteger: anInteger
sent when an integer does not know how to multiply the receiver, a complex.
Return the product of the receiver and the argument, anInteger.

quotientFromComplex: aComplex
Return the quotient of the argument, aComplex and the receiver.

quotientFromFixedPoint: aFixedPoint
Return the quotient of the argument, aFixedPoint and the receiver.

quotientFromFloat: aFloat
Return the quotient of the argument, aFloat and the receiver.

quotientFromFraction: aFraction
Return the quotient of the argument, aFraction and the receiver.

quotientFromInteger: anInteger
Return the quotient of the argument, anInteger and the receiver.

raisedFromNumber: aNumber
see http://www.math.toronto.edu/mathnet/questionCorner/complexexp.html

sumFromComplex: aComplex
Return the sum of the receiver and the argument, aComplex.

sumFromFixedPoint: aFixedPoint
Return the sum of the receiver and the argument, aFixedPoint.

sumFromFloat: aFloat
Return the sum of the receiver and the argument, aFloat.

sumFromFraction: aFraction
Return the sum of the receiver and the argument, aFraction.

sumFromInteger: anInteger
Return the sum of the receiver and the argument, anInteger.

mathematical functions
angle
Return the radian angle for this Complex number.
usage example(s):
 `````` (1 % 1) angle radiansToDegrees ``````

arg

exp
Return the complex exponential of the receiver.
usage example(s):
 `````` (10+4i) exp -> (-14397.45885694595768-16669.6842763244522i) ``````

ln

log: base

sqrt
Return the square root of the receiver

Return the square root of the receiver

squaredNorm

printing
displayOn: aGCOrStream
what a kludge - Dolphin and Squeak mean: printOn: a stream;

printOn: aStream

printString

storeOn: aStream

private
setReal: u setImaginary: v

testing
isComplex
(i.e. if it is a complex number). Always true here.

isReal
Return true if this Complex number has a zero imaginary part.

isZero
Answer whether 'self = self class zero'.
We can't use #= because #= is defined in terms of #isZero

sign
squeak does:
usage example(s):
 ``````^ real sign ``````
usage example(s):
 ``````return a new complex, consisting of the signs of the real and imaginary parts. ``````
usage example(s):
 ``````^ self class real:(real sign) imaginary:(imaginary sign) ``````
usage example(s):
 ``````this is consistent with Wolfram's output: (Complex new setReal:1 setImaginary:0) sign -> 1 (Complex new setReal:-1 setImaginary:0) sign -> -1 (Complex new setReal:0 setImaginary:0) sign -> 0 (Complex new setReal:1 setImaginary:1) sign -> (0.707106781186547+0.707106781186547i) (Complex new setReal:0 setImaginary:1) sign -> (0.0+1.0i) (Complex new setReal:-1 setImaginary:1) sign -> (-0.707106781186547+0.707106781186547i) (Complex new setReal:1 setImaginary:-1) sign -> (0.707106781186547-0.707106781186547i) (Complex new setReal:0 setImaginary:-1) sign -> (0.0-1.0i) (Complex new setReal:-1 setImaginary:-1) sign -> (-0.707106781186547-0.707106781186547i) ``````

trigonometric functions
arcCos
This is the inverse function of cos.
usage example(s):
 `````` (10+4i) cos (-22.91356068209214107-14.84629106966035727i) (10+4i) cos arcCos ``````

arcCosh
That is the inverse function of cosh.
Some possible implementations:
^imaginary > 0
ifTrue: [(self + (self * self - 1) sqrt) ln]
ifFalse: [(self + (self * self - 1) sqrt) ln negated]
^self arcCos i
This implementation provides an answer with a positive real part.
It also avoids creating intermediate Complex.
usage example(s):
 `````` (10 + 4i) arcCosh ``````

arcSin
This is the inverse function of sin.

arcSinh
That is the inverse function of sinh.
usage example(s):
 `````` (10 + 4i) sinh arcSinh -> (-10.0-0.8584073464102067614i) ``````

arcTan
This is the inverse function of tan.
usage example(s):
 `````` (1+4i) tan arcTan -> (1.000000000000000043+4.000000000000004772i) (10+4i) tan arcTan -> (0.5752220392306203171+4.00000000000000004i) ``````

arcTan: denominator
usage example(s):
 ``````shouldn't it be an error ? ^DomainError signal: '0 arcTan: 0' ``````

arcTanh
That is the inverse function of tanh.
usage example(s):
 `````` (10+4i) tanh arcTanh ``````

cos
usage example(s):
 ``````^ self i cosh ``````
usage example(s):
 `````` (10+4i) cos -> (-22.91356068209214107+14.84629106966035727i) (10+4i) i cosh (-22.91356068209214107+14.84629106966035727i) ``````

cosh
Hyperbolic cosine is defined by same power series expansion as for real numbers,
that is in term of exponential:
^ (self exp + self negated exp) / 2.
This implementation avoids creating intermediate objects.
usage example(s):
 `````` (10+4i) cosh -> (-7198.729443310666079-8334.842120982836036i) ``````

sin
usage example(s):
 ``````^ self i sinh i negated ``````
usage example(s):
 `````` (10+4i) sin -> (-14.85625516387525498-22.89819255096375875i) ``````

sinh
Hyperbolic sine is defined by same power series expansion as for real numbers,
that is in term of exponential:
^ (self exp - self negated exp) / 2.
This implementation avoids creating intermediate objects.
usage example(s):
 `````` 10 sinh -> 11013.23287470339338 (10+4i) sinh (-7198.729413635291604-8334.842155341616165i) ``````

tan
usage example(s):
 `````` (10+4i) tan -> (0.0006123503000121616919+0.9997260574022127583i) (10+4i) sin -> (-14.85625516387525498-22.89819255096375875i) (10+4i) cos -> (-22.91356068209214107+14.84629106966035727i) ``````

tanh
usage example(s):
 `````` (10+4i) tanh ``````

truncation & rounding
ceiling
blocked: complex numbers have no ceiling

floor
blocked: complex numbers have no floor

## Examples:

-25 sqrt -> error Complex trapImaginary:[ -25 sqrt ] -> 5i (0.0+5.0i) Complex trapImaginary:[ -25 integerSqrt ] -> 5i (0+5i) (Complex trapImaginary:[ -5397346292805549782720214077673687804022210808238353958670041357153884304 integerSqrt ]) squared 1 + 3i Number i + 1 1 + Number i 1i * 1i Number i * Number i (5 % 7) real (5 % 7) imaginary (5 % 7) = 5 (5 % 0) = 5 (5.0 % 0) = 5 (1 % 0) + (2 % 0) (1 % 0) + (0 % 2) (1 % 0) + (2 % 3) (1 % 0) * (2 % 0) (1 % 0) * (0 % 2) (1 % 0) * (2 % 3) (1 % 2) + 2 (1 % 2) * 2 2 + (1 % 2) 2 * (1 % 2) (Number i raisedTo:-3) -> Number i (Number i raisedTo:-2) -> -1 (Number i raisedTo:-1) -> Number i negated (Number i raisedTo:0) -> 1 (Number i raisedTo:1) -> Number i (Number i raisedTo:2) -> -1 (Number i raisedTo:3) -> Number i negated (Number i raisedTo:4) -> 1 (Number i raisedTo:6) -> -1 3 raisedTo:Number i 3 i raisedTo:Number i 5i * 5i -> -25 5i squared -> -25

ST/X 7.1.0.0; WebServer 1.663 at exept.de:8081; Mon, 20 Aug 2018 15:01:15 GMT