**namespace import ::math::complexnumbers::*; set a [complex 1 0]; set b [complex 0 1]; set c [complex -1 0]**).

GPS: Arjen and Richard come up with interesting contraptions. I hadn't heard of complex numbers before this page, and I suspect many others have not as well. To that end I found this page useful: http://www.clarku.edu/~djoyce/complex/plane.htmlFor some reason this reminds me of Funge.

AM Fixed a small bug in [cos], noted by Oscar Andres Lopez] (26 october 2005)

# qcomplex.tcl -- # Small module for dealing with complex numbers # The design goal was to make the operations as fast # as possible, not to offer a nice interface. So: # - complex numbers are represented as lists of two elements # - there is hardly any error checking, all arguments are assumed # to be complex numbers already (with a few obvious exceptions) # Missing: # the inverse trigonometric functions and the hyperbolic functions # namespace eval ::math::complexnumbers { namespace export + - / * conj exp sin cos tan real imag mod arg log pow sqrt tostring } # complex -- # Create a new complex number # Arguments: # real The real part # imag The imaginary part # Result: # New complex number # proc ::math::complexnumbers::complex {real imag} { return [list $real $imag] } # binary operations -- # Implement the basic binary operations # Arguments: # z1 First argument # z2 Second argument # Result: # New complex number # proc ::math::complexnumbers::+ {z1 z2} { set result {} foreach c $z1 d $z2 { lappend result [expr {$c+$d}] } return $result } proc ::math::complexnumbers::- {z1 {z2 {}}} { if { $z2 == {} } { set z2 $z1 set z1 {0.0 0.0} } set result {} foreach c $z1 d $z2 { lappend result [expr {$c-$d}] } return $result } proc ::math::complexnumbers::* {z1 z2} { set result {} foreach {c1 d1} $z1 {break} foreach {c2 d2} $z2 {break} return [list [expr {$c1*$c2-$d1*$d2}] [expr {$c1*$d2+$c2*$d1}]] } proc ::math::complexnumbers::/ {z1 z2} { set result {} foreach {c1 d1} $z1 {break} foreach {c2 d2} $z2 {break} set denom [expr {$c2*$c2+$d2*$d2}] return [list [expr {($c1*$c2+$d1*$d2)/$denom}] \ [expr {(-$c1*$d2+$c2*$d1)/$denom}]] } # unary operations -- # Implement the basic unary operations # Arguments: # z1 Argument # Result: # New complex number # proc ::math::complexnumbers::conj {z1} { foreach {c d} $z1 {break} return [list $c [expr {-$d}]] } proc ::math::complexnumbers::real {z1} { foreach {c d} $z1 {break} return $c } proc ::math::complexnumbers::imag {z1} { foreach {c d} $z1 {break} return $d } proc ::math::complexnumbers::mod {z1} { foreach {c d} $z1 {break} return [expr {hypot($c,$d)}] } proc ::math::complexnumbers::arg {z1} { foreach {c d} $z1 {break} if { $c != 0.0 || $d != 0.0 } { return [expr {atan2($d,$c)}] } else { return 0.0 } } # elementary functions -- # Implement the elementary functions # Arguments: # z1 Argument # z2 Second argument (if any) # Result: # New complex number # proc ::math::complexnumbers::exp {z1} { foreach {c d} $z1 {break} return [list [expr {exp($c)*cos($d)}] [expr {exp($c)*sin($d)}]] } proc ::math::complexnumbers::cos {z1} { foreach {c d} $z1 {break} return [list [expr {cos($c)*cosh($d)}] [expr {-sin($c)*sinh($d)}]] } proc ::math::complexnumbers::sin {z1} { foreach {c d} $z1 {break} return [list [expr {sin($c)*cosh($d)}] [expr {cos($c)*sinh($d)}]] } proc ::math::complexnumbers::tan {z1} { return [/ [sin $z1] [cos $z1]] } proc ::math::complexnumbers::log {z1} { return [list [expr {log([mod $z1])}] [arg $z1]] } proc ::math::complexnumbers::sqrt {z1} { set argz [expr {0.5*[arg $z1]}] set modz [expr {sqrt([mod $z1])}] return [list [expr {$modz*cos($argz)}] [expr {$modz*sin($argz)}]] } proc ::math::complexnumbers::pow {z1 z2} { return [exp [* [log $z1] $z2]] } # transformational functions -- # Implement transformational functions # Arguments: # z1 Argument # Result: # String like 1+i # proc ::math::complexnumbers::tostring {z1} { foreach {c d} $z1 {break} if { $d == 0.0 } { return "$c" } else { if { $c == 0.0 } { if { $d == 1.0 } { return "i" } elseif { $d == -1.0 } { return "-i" } else { return "${d}i" } } else { if { $d > 0.0 } { if { $d == 1.0 } { return "$c+i" } else { return "$c+${d}i" } } else { if { $d == -1.0 } { return "$c-i" } else { return "$c${d}i" } } } } } # # Some tests # namespace import ::math::complexnumbers::* set a [complex 1 0] set b [complex 0 1] set c [complex -1 0] puts "a = [tostring $a]; b = [tostring $b]; c = [tostring c]" puts "a+b= [+ $a $b] (= 1 1)" puts "a-b= [- $a $b] (= 1 -1)" puts "-a = [- $a] (= -1 0)" puts "a*a = [* $a $a] (= 1 0)" puts "b*b = [* $b $b] (= -1 0)" puts "a/b = [/ $a $b] (= 0 -1)" puts "exp(a) = [exp $a] (= e 0)" puts "exp(b) = [exp $b] (= cos(1) sin(1))" puts "cos(b) = [cos $b]" puts "sin(b) = [sin $b]" puts "tan(b) = [tan $b]" puts "conj(b) = [conj $b] (= 0 -1)" puts "mod(b) = [mod $b] (= 1)" puts "arg(b) = [arg $b] (= pi/2)" puts "real(b) = [real $b] (= 0)" puts "imag(b) = [imag $b] (= 1)" puts "sqrt(c) = [sqrt $c] (= 0 1)" puts "log(c) = [log $c] (= 0 pi)" puts "tostring(0 1) = [tostring {0 1}] (= i)" puts "tostring(1 -1) = [tostring {1 -1}] (= 1-i)" puts "tostring(1 0) = [tostring {1 0}] (= 1)" puts "pow(1,10i) = [pow {1 0} {0 10}] (= 1)" puts "pow(i,i) = [pow {0 1} {0 1}] (= e**(-pi/2))" puts "exp(i*pi) = [exp [list 0 [expr {acos(-1)}]]] (= -1)"

See also Complex math made simple - Complex math with TOOT

AM Recent discussions regarding the possibility to expand [expr] to take more data types into account, complex numbers for instance or vector-valued variables have led me to create two new pages: On mathematical notation - a very nice overview by Lars Hellstrom, and as I was inspired by the solution he proposed, Vector spaces.