ComplexNumbers

Overview

This topic details the design of complex numbers in CommonLisp. Wikipedia defines a complex number to be "a number of the for a + bi where a and b are real numbers and i is the imaginary unit, with the property i^2 = -1." The implementation of complex numbers in CLforJava requires a new data type, complex, changes to the Reader and Printer, augmentation of existing arithmetic functions, and creation of new math functions.

#Tree

Inheritance Tree

The following is the hierarchical portion of the TypeSystem that contains the type Complex:
  • T
    • Atom
      • Number
        • Complex

Implementation

This section contains the implementation details of the type, augmentation of existing arithmetic functions, creation of new arithmetic functions, and changes to the Reader and Writer in order to provide for the addition of the complex number type.

Analysis of Implementation Candidates

Grading Scale

Categories A B C F
License Free to use and redistribute with no permissions needed Free to use and redistribute, but written permission required first GNU Royalty fees
Clarity Code is well documented, uses javadoc, has descriptive variable names, solution is simple Has good documentation, doesn't use javadoc, has descriptive variable names,solution is simple Has documentation but isn't good, uses javadoc, poor variable names, solution is simple Has no documentation, doesn't use javadoc, poor variable names, stylistic issues
Completeness Missing 1 function at the most Missing 2-4 functions Missing 4-6 functions Missing more than 6 functions
Correctness All functions and work All functions work but a bug was found and easily fixed in code Only 1 function implemented incorrectly More than 1 function has errors
Speed N/A N/A N/A N/A

Analysis

Candidates Clarity Completeness Licensure Correctness Speed* Comments
1 B C A B A Doesn't have overloaded functions
2 C F A A A Bad variable names, doesn't have "equals", and doesn't have overloaded functions
3 C C A A A Doesn't use javadoc, hard to read, doesn't have overloaded functions
4 F B A A A bad variable names, real and image variables are public, bad documentation, no overloaded functions, tough to read
5 F A C N/A N/A doesn't have overloaded functions, no javadoc, no comments, need to import their package, GNU license
6 A A A A A good documentation, uses javadoc, has overloaded functions, complete
* Speed test consisted of 1,000,000 calls to each of the functions in each of the candidate implementations that we have considered, except candidate implementation 5 as it would have been extremely time consuming to write a test for that particular implementation. As such, the team decided that we would not conduct a speed test on that specific implementation. The results of the speed tests can be found here.

Function Checklist

* - Indicates that this function is included in this implementation.
X - Indicates that this is the implementation we have chosen to incorporate into CLforJava.
Function 6 1 2 3 4 5 Comments HyperSpec
abs *     X * * Completed *
acos X           Completed *
acosh X           Completed *
asin X           Completed *
asinh X           Completed *
atan X       *   Completed *
atanh X       *   Completed *
conjugate X   * * *   Completed *
cos *   X   *   Completed *
cosh *   X       Completed *
equal X *   * * * Completed *
exp X   * * *   Completed *
imagpart X * *   * * Completed *
Zerop             Completed *
log X   * * *   Completed *
minus X * * * * * Completed *
negative X   *   *   Completed *
div X * * * * * Completed *
plus X * * * * * Completed *
expt X     * *   Completed *
realpart X * * * * * Completed *
sin *   X * *   Completed *
sinh *   X * *   Completed *
sqrt X   * * *   Completed *
tan X   *   *   Completed *
tanh X       *   Completed *
mult X * * * * * Completed *
toString * * *   * * Completed *
oneplus           * Completed *
oneminus           * Completed *
Complexp             Completed *
complex             Completed *
cis             Completed *
phase             Completed *

Type Specification (lisp.common.type.Complex)

The type specification must contain the following:
  • An instance of the symbol COMPLEX.
  • An implementing class with the following:
    • A real number representing the real part of a complex number.
    • A number representing the imaginary part of a complex number.
  • A nested Factory Class.
  • Method signatures for new arithmetic functions.

Type Promotion / Demotion

"If all the arguments are the same type of number (rational, floating point, or complex), the result will be the same type except in the case where the result of an operation on complex numbers with rational components yields a number with a zero imaginary part, in which case the result will be a rational. However, floating-point and complex numbers are contagious--if all the arguments are reals but one or more are floating-point numbers, the other arguments are converted to the nearest floating-point arguments. Floating-point numbers in a "smaller" representation are also converted to the larger representation. Similarly, if any of the arguments are complex, any real arguments are converted to the complex arguments." --Practical Common Lisp by Peter Seibel

Arithmetic Functions

Plus (lisp.common.function.Plus)

public Number Plus(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: If only one argument is given, then the complex number is added to 0 and then returned. Type Promotion / Demotion applies here.
>(+ #C(1 2))
#C(1 2)

public Number Plus(Complex arg1, Complex arg2) (More Info)
Input: Complex, Complex
Output: Number
Synopsis: When two complex numbers are passed, the real parts and the imaginary parts are added. Type promotion/demotion applies here.

>(+ #C(1 2) #C(3 4))
#C(4 6)

public Number Plus(Complex arg1, Real arg2) (More Info)
Input: Complex, Real
Output: Number
Synopsis: If the Complex number and a Real number are passed as parameters, then the real is added to the real part of the Complex. Type promotion/demotion applies here.

>(+ #C(1 2) 3)
#C(4 2)

Minus (lisp.common.function.Minus)

public Number Minus(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: If only a Complex number passed then it is subtract from 0. Type promotion/demotion applies here.
>(- #C(1 2))
#C(-1 2)

public Number Minus(Complex arg1, Complex arg2) (More Info)
Input: Complex, Complex
Output: Number
Synopsis: If a complex is passed, the real parts and the imaginary parts are resolved. Type promotion/demotion applies here.

>(- #C(1 2) #C(3 4))
#C(-2 -2)

public Number Minus(Complex arg1, Real arg2) (More Info)
Input: Complex, Real
Output: Number
Synopsis: If a Complex number and a Real number are passed, the then real part of the Complex number is subtracted by the real argument. Type promotion/demotion applies here.

>(- #C(1 2) 3)
#C(-2 2)

Mult (lisp.common.function.Mult)

public Number Mult(Complex arg1, Complex arg2) (More Info)
Input: Complex, Complex
Output: Number
Synopsis: When two Complex numbers are inputted, the foil method is applied to the real and imaginary parts of both Complex numbers.
>(* #C(1 2) #C(3 4))
#C(-5 10)

public Number Mult(Complex arg1, Real arg2) (More Info)
Input: Complex, Real
Output: Number
Synopsis: When a Complex and a Real are inputted, both the real and imaginary parts of the Complex number are multiplied by the Real number.

>(* #C(3.0 2.0) 3)
#C(9.0 6.0)

Div (lisp.common.function.Div)

public Complex Div(Complex arg1, Complex arg2) (More Info)
Input: Complex, Complex
Output: Number
Synopsis: Returns a new Complex number with the real part being equal to the sum of the multiplication of the two real parts and the multiplication of the two imaginary parts all over the sum of arg2's real part squared and arg2's imaginary part squared.
>(/ #C(3.0 1.0) #C(2.0 1.0))
#C(1.4 -0.2)

public Complex Div(Complex arg1, Real arg2) (More Info)
Input: Complex, Real
Output: Number
Synopsis: Divides the real and imaginary parts of the Complex number by the real number.

>(/ #C(3.0 1.0) 2)
#C(0.6 0.2)

Oneplus (lisp.common.function.Oneplus)

public Complex Oneplus(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Increments the real number by 1.
>(1+ #C(3.0 1.0))
#C(4.0 1.0)

Oneminus (lisp.common.function.Oneminus)

public Complex Oneminus(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Decrements the real number by 1.
>(1- #C(3.0 1.0))
#C(2.0 1.0)

Exponential, Logarithmic, and Trigonometric functions

Abs (lisp.common.function.Abs)

public Number Abs(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the absolute value of number.
>(abs #C(3.0 1.0))
3.1622777

Acos (lisp.common.function.Acos)

public Number Acos(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the arc cosine of the input in radians.
>(acos #C(3.0 1.0))
#C(0.3377011 -1.8241987))

Acosh (lisp.common.function.Acosh)

public Number Acosh(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the hyperbolic arc cosine of the input in radians.
>(acosh #C(3.0 1.0))
#C(1.8241987 0.3377011)

Asin (lisp.common.function.Asin)

public Number Asin(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the arc sine of the input in radians.
>(asin #C(3.0 1.0))
#C(1.2330952 1.8241987)

Asinh (lisp.common.function.Asinh)

public Number Asinh(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the hyperbolic arc sine of the input in radians.
>(asinh #C(3.0 1.0))
#C(1.8641615 0.30760366)

Atan (lisp.common.function.Atan)

public Number Atan(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the arc tangent of the input in radians.
>(atan #C(3.0 1.0))
#C(1.276795 0.091931194)

Atanh (lisp.common.function.Atanh)

public Number Atanh(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the hyperbolic arc tangent of the input in radians.
>(atanh #C(3.0 1.0))
#C(0.30594385 1.4614619)

Cis (lisp.common.function.Cis)

public Complex Cis(Number arg) (More Info)
Input: Number
Output: Number
Synopsis: Returns a complex with the value of e^i* radians. The real part is equal to the cosine of radians, and the imaginary part is equal to the sine of radians.
>(cis 0)
#C(1.0 0.0)
>(cis 3.14)
#C(-0.99999875 0.001592548)

Cos (lisp.common.function.Cos)

public Number Cos(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the cosine of the input in radians.
>(cos #C(3.0 1.0))
#C(-1.5276383 -0.1658444)

Cosh (lisp.common.function.Cosh)

public Number Cosh(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the hyperbolic cosine of the input in radians.
>(cosh #C(3.0 1.0))
#C(5.439581 8.42975)

Exp (lisp.common.function.Exp)

public Number Exp(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the constant e raised to a power.
>(exp #c(3.0 1.0))
#C(10.852262 16.901396)

Expt (lisp.common.function.Expt)

public Number Expt(Number arg1, Number arg2) (More Info)
Input: Number, Number
Output: Complex
Synopsis: Returns arg1 raised to the power arg2 where expt is defined as b^x = e^{x log b\/}.
>(expt #c(3.0 1.0) 3)
#C(18.0 26.0) 

Log (lisp.common.function.Log)

public Number Log(Number number, [Number base]) (More Info)
Input: A non-zero Number and an optional base (Number)
Output: A number
Synopsis: Returns the log of the number
>(log #c(1 2))
#C(0.804719 1.1071488) 

Phase (lisp.common.function.Phase)

public Number Phase(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the phase (the angle part of its polar representation) of the input in radians.
>(expt #c(3.0 1.0) 3)
#C(18.0 26.0)

Signum (lisp.common.function.Signum)

public Complex Signum(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns a numerical value that indicates whether number is negative, zero, or positive.
>(signum #c(3.0 1.0))
#C(0.94868327 0.31622776)
>(signum #c(-3.0 1.0))
#C(-0.94868327 0.31622776)
>(signum #c(-3.0 -1.0))
#C(-0.94868327 -0.31622776)
>(signum #c(3.0 -1.0))
#C(0.94868327 -0.31622776)

Sin (lisp.common.function.Sin)

public Number Sin(Complex arg)(More Info)
Input: Complex
Output: Number
Synopsis: Returns the sine of the input in radians.
>(sin #C(3.0 1.0))
#C(0.21775955162215221 -1.1634403637032504)

Sinh (lisp.common.function.Sinh)

public Number Sinh(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the hyperbolic sine of the input in radians.
>(sinh #C(3.0 1.0))
#C(5.412680923178194 8.47164545430015)

Sqrt (lisp.common.function.Sqrt)

public Number Sqrt(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the square root of the input.
>(sqrt #c(0 2))
#C(1.0 1.0)

Tan (lisp.common.function.Tan)

public Number Tan(Complex arg)(More Info)
Input: Complex
Output: Number
Synopsis: Returns the tangent of the input in radians.
>(tan #C(3.0 1.0))
#C(-0.05916853956605075 0.7680176472869111)

Tanh (lisp.common.function.Tanh)

public Number Tanh(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the hyperbolic tangent of the input in radians.
>(tanh #C(3.0 1.0))
#C(1.0020549882458119 0.00451713737276658315)

Comparison and Predication Functions

Equal (lisp.common.function.Equal)

public Boolean Equal(Complex arg) (More Info)
Checks for the equality of multiple complex numbers by comparing the real and imaginaries parts.
Input: Number
Output: Boolean
>(= #C(1.0 2) #C(1 2))
NIL
>(= #C(1 0) #C(1 0.0))
T
>(= #C(1 2) #C(1 2))
T
>(= (* #C(2 1) 3) #C(6 3))
T

Zerop (lisp.common.function.Zerop)

public Boolean Zerop(Complex arg) (More Info)
Input: Complex
Output: Boolean
Synopsis: Returns true if number is zero (integer, float, or complex); otherwise, returns false.
>(zerop #C(3.0 1.0))
NIL
>(zerop #C(0.0 0.0))
T

Complex Specific Functions

Complex (lisp.common.type.Complex)

public Number Complex(Real arg) (More Info)
Input: Real
Output: Number
Synopsis: Receives one number as a parameter and returns a complex number type.
>(complex 3.0)
#C(3.0 0.0)

Complex (lisp.common.type.Complex)

public Number Complex(Real arg1, Real arg2) (More Info)
Input: Real, Real
Output: Number
Synopsis: Receives two numbers as parameters and returns a complex number type.
>(complex 1 1)
#C(1 1)

Complexp (lisp.common.function.Complexp)

public Boolean Complexp(Number arg) (More Info)
Input: Number
Output: Boolean
Synopsis: Returns T if a number is of complex type and NIL if otherwise.
>(complexp #C(1 1))
T
>(complexp 1)
NIL
>

RealPart? (lisp.common.function.RealPart)

public Real RealPart? (Number arg) (More Info)
Input: Number
Output: Real
Synopsis: Receives a number as a parameter and returns the real part if the arg is of type Complex, or returns the number if the arg is of type Real.
>(realpart #C(1 2))
1
>(realpart 1)
1

ImagPart? (lisp.common.function.ImagPart)

public Real ImagPart? (Number arg) (More Info)
Input: Number
Output: Real
Synopsis: Receives a number as a parameter and returns the imaginary part if the arg is of type Complex, or returns ZERO if the arg is of type Real.
>(imagpart #C(1 2))
2
>(imagpart 1)
0

Conjugate (lisp.common.function.Conjugate)

public Number Conjugate(Complex arg) (More Info)
Input: Complex
Output: Number
Synopsis: Returns the complex conjugate of number. The conjugate of a real number is itself.
>(conjugate #C(3.0 1.0))
#C(3.0 -1.0)

Augmentation to the Reader

The Reader will import the lisp.common.type.Complex. A Read Macro will be created called SharpCeeMacro? .java. These classes will allow CLforJava to recognize complex numbers. Complex numbers are notated with a #C followed by a list of two arguments whose type is Real.
>#c(1 1)
#C(1 1)

Augmentation to the Printer

The Printer will print complex numbers as a list of two numbers whose type is Real preceded by the #C. Promotion/demotion applies where necessary.
>#c(1 1)
#C(1 1)

Core Java Classes Javadoc Links
complex.java  

Current Status of ComplexNumbers

Current Status: Complex numbers were successfully implemented in Spring 2007. This implementation includes the type, functions, augmentation to the reader and to the printer. The test suite still needs to have tests written for each of the functions that support complex numbers.

Status History: See Complex Numbers Group

Test Suites

Links to JUnit results

References

HyperSpec CLtL
Complex Numbers Complex Numbers

-- JerryBoetje - 12 Jul 2003

Topic attachments
I Attachment Action Size Date Who Comment
Microsoft Excel Spreadsheetxls 462spreadsheet.xls manage 42.0 K 2007-02-15 - 22:34 CharliePhillips This is a list of functions and which implementation(s) have them
Microsoft Word filedoc CandidateImplementationLicenses.doc manage 79.5 K 2007-02-14 - 00:11 DavidWilliams Candidate Implementation Licenses
PDFpdf CandidateImplementationSpeedTest.pdf manage 42.6 K 2007-02-03 - 20:42 DavidWilliams Contains the results of the speed test conducted on the candidate implementations.
PDFpdf ComplexPrinter.pdf manage 72.8 K 2007-03-19 - 21:54 BryanPeterson printer for complex numbers
Texttxt Implementation6.txt manage 35.5 K 2007-04-12 - 14:25 DavidWilliams Implementation6
Java source code filejava TestPrinterForComplex.java manage 2.8 K 2007-03-27 - 03:25 BryanPeterson current state of test file for printer
Java source code filejava functions.java manage 21.7 K 2007-02-27 - 00:57 TonyMalatanos All of the chosen functions from the various implementations in one single file.
Topic revision: r95 - 2009-03-11 - 20:26:21 - MadelineWilliams
 
Home
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback