aboutsummaryrefslogtreecommitdiff
path: root/src/clojure/contrib/complex_numbers.clj
diff options
context:
space:
mode:
authorKonrad Hinsen <konrad.hinsen@laposte.net>2009-04-02 20:01:43 +0000
committerKonrad Hinsen <konrad.hinsen@laposte.net>2009-04-02 20:01:43 +0000
commiteaeb3c8450a8c5f185869a0ec8e83f157c61d995 (patch)
treea7b08056958764ab4b8199564c84c86cbbc506e3 /src/clojure/contrib/complex_numbers.clj
parentb006d0f4e371a16d37d5a8e78982dfb92deadef0 (diff)
complex-numbers: exp and better sqrt
Diffstat (limited to 'src/clojure/contrib/complex_numbers.clj')
-rw-r--r--src/clojure/contrib/complex_numbers.clj48
1 files changed, 40 insertions, 8 deletions
diff --git a/src/clojure/contrib/complex_numbers.clj b/src/clojure/contrib/complex_numbers.clj
index 1a05934a..942051da 100644
--- a/src/clojure/contrib/complex_numbers.clj
+++ b/src/clojure/contrib/complex_numbers.clj
@@ -1,7 +1,7 @@
;; Complex numbers
;; by Konrad Hinsen
-;; last updated March 23, 2009
+;; last updated April 2, 2009
;; Copyright (c) Konrad Hinsen, 2009. All rights reserved. The use
;; and distribution terms for this software are covered by the Eclipse
@@ -249,10 +249,42 @@
;
; Square root
;
-(defmethod gm/sqrt ::complex
- [{r :real i :imag}]
- (let [abs (gm/sqrt (ga/+ (ga/* r r) (ga/* i i)))
- p (gm/sqrt ((ga/qsym ga /) (ga/+ abs r) 2))
- q (ga/* (gm/sgn i)
- (gm/sqrt ((ga/qsym ga /) (ga/- abs r) 2)))]
- (complex p q)))
+(let [one-half (/ 1 2)
+ one-eighth (/ 1 8)]
+ (defmethod gm/sqrt ::complex
+ [x]
+ (let [[r i] (vals x)]
+ (if (and (gc/zero? r) (gc/zero? i))
+ 0
+ (let [; The basic formula would say
+ ; abs (gm/sqrt (ga/+ (ga/* r r) (ga/* i i)))
+ ; p (gm/sqrt (ga/* one-half (ga/+ abs r)))
+ ; but the slightly more complicated one below
+ ; avoids overflow for large r or i.
+ ar (gm/abs r)
+ ai (gm/abs i)
+ r8 (ga/* one-eighth ar)
+ i8 (ga/* one-eighth ai)
+ abs (gm/sqrt (ga/+ (ga/* r8 r8) (ga/* i8 i8)))
+ p (ga/* 2 (gm/sqrt (ga/+ abs r8)))
+ q ((ga/qsym ga /) ai (ga/* 2 p))
+ s (gm/sgn i)]
+ (if (gc/< r 0)
+ (complex q (ga/* s p))
+ (complex p (ga/* s q))))))))
+
+;
+; Exponential function
+;
+(defmethod gm/exp ::complex
+ [x]
+ (let [[r i] (vals x)
+ exp-r (gm/exp r)
+ cos-i (gm/cos i)
+ sin-i (gm/sin i)]
+ (complex (ga/* exp-r cos-i) (ga/* exp-r sin-i))))
+
+(defmethod gm/exp ::pure-imaginary
+ [x]
+ (let [i (imag x)]
+ (complex (gm/cos i) (gm/sin i))))