qcomplex.tcl

Go to the documentation of this file.
00001 /*  qcomplex.tcl --*/
00002 /*     Small module for dealing with complex numbers*/
00003 /*     The design goal was to make the operations as fast*/
00004 /*     as possible, not to offer a nice interface. So:*/
00005 /*     - complex numbers are represented as lists of two elements*/
00006 /*     - there is hardly any error checking, all arguments are assumed*/
00007 /*       to be complex numbers already (with a few obvious exceptions)*/
00008 /*     Missing:*/
00009 /*     the inverse trigonometric functions and the hyperbolic functions*/
00010 /* */
00011 
00012 namespace ::math::complexnumbers {
00013     namespace export + - / * conj exp sin cos tan real imag mod arg log pow sqrt tostring
00014 }
00015 
00016 /*  complex --*/
00017 /*     Create a new complex number*/
00018 /*  Arguments:*/
00019 /*     real      The real part*/
00020 /*     imag      The imaginary part*/
00021 /*  Result:*/
00022 /*     New complex number*/
00023 /* */
00024 ret  ::math::complexnumbers::complex (type real , type imag) {
00025     return [list $real $imag]
00026 }
00027 
00028 /*  binary operations --*/
00029 /*     Implement the basic binary operations*/
00030 /*  Arguments:*/
00031 /*     z1        First argument*/
00032 /*     z2        Second argument*/
00033 /*  Result:*/
00034 /*     New complex number*/
00035 /* */
00036 ret  ::math::complexnumbers::+ (type z1 , type z2) {
00037     set result {}
00038     foreach c $z1 d $z2 {
00039         lappend result [expr {$c+$d}]
00040     }
00041     return $result
00042 }
00043 ret  ::math::complexnumbers::- (type z1 , optional z2 ={)} {
00044     if { $z2 == {} } {
00045          z2 =  $z1
00046          z1 =  {0.0 0.0}
00047     }
00048      result =  {}
00049     foreach c $z1 d $z2 {
00050         lappend result [expr {$c-$d}]
00051     }
00052     return $result
00053 }
00054 ret  ::math::complexnumbers::* (type z1 , type z2) {
00055     set result {}
00056     foreach {c1 d1} $z1 {break}
00057     foreach {c2 d2} $z2 {break}
00058 
00059     return [list [expr {$c1*$c2-$d1*$d2}] [expr {$c1*$d2+$c2*$d1}]]
00060 }
00061 ret  ::math::complexnumbers::/ (type z1 , type z2) {
00062     set result {}
00063     foreach {c1 d1} $z1 {break}
00064     foreach {c2 d2} $z2 {break}
00065 
00066     set denom [expr {$c2*$c2+$d2*$d2}]
00067     return [list [expr {($c1*$c2+$d1*$d2)/$denom}] \
00068                  [expr {(-$c1*$d2+$c2*$d1)/$denom}]]
00069 }
00070 
00071 /*  unary operations --*/
00072 /*     Implement the basic unary operations*/
00073 /*  Arguments:*/
00074 /*     z1        Argument*/
00075 /*  Result:*/
00076 /*     New complex number*/
00077 /* */
00078 ret  ::math::complexnumbers::conj (type z1) {
00079     foreach {c d} $z1 {break}
00080     return [list $c [expr {-$d}]]
00081 }
00082 ret  ::math::complexnumbers::real (type z1) {
00083     foreach {c d} $z1 {break}
00084     return $c
00085 }
00086 ret  ::math::complexnumbers::imag (type z1) {
00087     foreach {c d} $z1 {break}
00088     return $d
00089 }
00090 ret  ::math::complexnumbers::mod (type z1) {
00091     foreach {c d} $z1 {break}
00092     return [expr {hypot($c,$d)}]
00093 }
00094 ret  ::math::complexnumbers::arg (type z1) {
00095     foreach {c d} $z1 {break}
00096     if { $c != 0.0 || $d != 0.0 } {
00097         return [expr {atan2($d,$c)}]
00098     } else {
00099         return 0.0
00100     }
00101 }
00102 
00103 /*  elementary functions --*/
00104 /*     Implement the elementary functions*/
00105 /*  Arguments:*/
00106 /*     z1        Argument*/
00107 /*     z2        Second argument (if any)*/
00108 /*  Result:*/
00109 /*     New complex number*/
00110 /* */
00111 ret  ::math::complexnumbers::exp (type z1) {
00112     foreach {c d} $z1 {break}
00113     return [list [expr {exp($c)*cos($d)}] [expr {exp($c)*sin($d)}]]
00114 }
00115 ret  ::math::complexnumbers::cos (type z1) {
00116     foreach {c d} $z1 {break}
00117     return [list [expr {cos($c)*cosh($d)}] [expr {-sin($c)*sinh($d)}]]
00118 }
00119 ret  ::math::complexnumbers::sin (type z1) {
00120     foreach {c d} $z1 {break}
00121     return [list [expr {sin($c)*cosh($d)}] [expr {cos($c)*sinh($d)}]]
00122 }
00123 ret  ::math::complexnumbers::tan (type z1) {
00124     return [/ [sin $z1] [cos $z1]]
00125 }
00126 ret  ::math::complexnumbers::log (type z1) {
00127     return [list [expr {log([mod $z1])}] [arg $z1]]
00128 }
00129 ret  ::math::complexnumbers::sqrt (type z1) {
00130     set argz [expr {0.5*[arg $z1]}]
00131     set modz [expr {sqrt([mod $z1])}]
00132     return [list [expr {$modz*cos($argz)}] [expr {$modz*sin($argz)}]]
00133 }
00134 ret  ::math::complexnumbers::pow (type z1 , type z2) {
00135     return [exp [* [log $z1] $z2]]
00136 }
00137 /*  transformational functions --*/
00138 /*     Implement transformational functions*/
00139 /*  Arguments:*/
00140 /*     z1        Argument*/
00141 /*  Result:*/
00142 /*     String like 1+i*/
00143 /* */
00144 ret  ::math::complexnumbers::tostring (type z1) {
00145     foreach {c d} $z1 {break}
00146     if { $d == 0.0 } {
00147         return "$c"
00148     } else {
00149         if { $c == 0.0 } {
00150             if { $d == 1.0 } {
00151                 return "i"
00152             } elseif { $d == -1.0 } {
00153                 return "-i"
00154             } else {
00155                 return "${d}i"
00156             }
00157         } else {
00158             if { $d > 0.0 } {
00159                 if { $d == 1.0 } {
00160                     return "$c+i"
00161                 } else {
00162                     return "$c+${d}i"
00163                 }
00164             } else {
00165                 if { $d == -1.0 } {
00166                     return "$c-i"
00167                 } else {
00168                     return "$c${d}i"
00169                 }
00170             }
00171         }
00172     }
00173 }
00174 
00175 /* */
00176 /*  Announce our presence*/
00177 /* */
00178 package provide math::complexnumbers 1.0.2
00179 

Generated on 21 Sep 2010 for Gui by  doxygen 1.6.1