
Class: Complex
Object

+Magnitude

+ArithmeticValue

+Number

+Complex
 Package:
 stx:libbasic
 Category:
 MagnitudeNumbers
 Version:
 rev:
1.35
date: 2019/05/26 08:58:32
 user: cg
 file: Complex.st directory: libbasic
 module: stx stcclassLibrary: libbasic
 Author:
 Kurt Hebel (hebel@uinova.cerl.uiuc.edu)
 minor changes and double dispatching code by cg.
 additions (trigonometric) and fixes by cg.
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 (from the original author):
Although Complex seems 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.
NOTE (from porter):
moved to Number hierarchy.
Makes live of users much easier (isNumber, reading, etc)
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):

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):

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)

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):

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

Answer the result of dividing receiver by aNumber

divideSecureBy: anObject

Answer the result of dividing receiver by aNumber

i

Answer the result of multiplying the receiver with pure imaginary.
^ self * 1 i
This is an obvious extension of method i implemented in Number.
usage example(s):

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

Answer the receiver transformed to a lower generality, if such a
transformation is possible without losing information.
If not, answer the receiver
comparing

< aNumber

raises an error  complex numbers are not well ordered
usage example(s):

= anObject

return true, if the argument represents the same numeric value
as the receiver, false otherwise.
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):
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.

raisedFromFloat: aNumber

2 raisedTo:(2 + 2i)
2 ** (2 + 2i)
2.0 raisedTo:(2 + 2i)
2.0 ** (2 + 2i)

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

Answer the argument of the receiver.

exp

Return the complex exponential of the receiver.
usage example(s):
(10+4i) exp > (14397.4588569459576816669.6842763244522i)


ln

Answer the natural log of the receiver.

log: base

Answer the log base aNumber of the receiver.

sqrt

Return the square root of the receiver

sqrt_bad

Return the square root of the receiver

squaredNorm

Answer the square of receiver's norm.
printing & storing

displayOn: aGCOrStream

what a kludge  Dolphin and Squeak mean: printOn: a stream;

printOn: aStream


printString


storeOn: aStream

private

setReal: u setImaginary: v

testing

isComplex

Answer whether the receiver has an imaginary part
(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):
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.7071067811865470.707106781186547i)
(Complex new setReal:0 setImaginary:1) sign > (0.01.0i)
(Complex new setReal:1 setImaginary:1) sign > (0.7071067811865470.707106781186547i)

trigonometric functions

arcCos

Answer the arc cosine of the receiver.
This is the inverse function of cos.
usage example(s):
(10+4i) cos (22.9135606820921410714.84629106966035727i)
(10+4i) cos arcCos


arcCosh

Answer the receiver's area hyperbolic cosine.
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):

arcSin

Answer the arc sine of the receiver.
This is the inverse function of sin.

arcSinh

Answer receiver's area hyperbolic sine.
That is the inverse function of sinh.
usage example(s):
(10 + 4i) sinh arcSinh > (10.00.8584073464102067614i)


arcTan

Answer the arc tangent of the receiver.
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

Answer the four quadrants arc tangent of receiver over denominator.
usage example(s):
shouldn't it be an error ? ^DomainError signal: '0 arcTan: 0'


arcTanh

Answer the receiver's area hyperbolic tangent.
That is the inverse function of tanh.
usage example(s):

cos

Answer the receiver's cosine.
usage example(s):
usage example(s):
(10+4i) cos > (22.91356068209214107+14.84629106966035727i)
(10+4i) i cosh (22.91356068209214107+14.84629106966035727i)


cosh

Answer the receiver's hyperbolic cosine.
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.7294433106660798334.842120982836036i)


sin

Answer the receiver's sine.
usage example(s):
usage example(s):
(10+4i) sin > (14.8562551638752549822.89819255096375875i)


sinh

Answer the receiver's hyperbolic sine.
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.7294136352916048334.842155341616165i)


tan

Answer the receiver's tangent.
usage example(s):
(10+4i) tan > (0.0006123503000121616919+0.9997260574022127583i)
(10+4i) sin > (14.8562551638752549822.89819255096375875i)
(10+4i) cos > (22.91356068209214107+14.84629106966035727i)


tanh

Answer the receiver's hyperbolic tangent.
usage example(s):
truncation & rounding

ceiling

blocked: complex numbers have no ceiling

floor

blocked: complex numbers have no floor
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
