summaryrefslogtreecommitdiff
path: root/stdlib/complex.ml
diff options
context:
space:
mode:
authorJacques Garrigue <garrigue at math.nagoya-u.ac.jp>2002-04-18 07:00:34 +0000
committerJacques Garrigue <garrigue at math.nagoya-u.ac.jp>2002-04-18 07:00:34 +0000
commit3447e059f033e7d59b4262fe869115aae20bcb85 (patch)
treeec3442ebc0940aefd4d6ab0e67dd88c08d5f5496 /stdlib/complex.ml
parent059d9fc181595b6cf7d2d1a6472eb97fce1fe86a (diff)
downloadocaml-poly_meth2.tar.gz
merging poly_meth2poly_meth2
git-svn-id: http://caml.inria.fr/svn/ocaml/branches/poly_meth2@4692 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'stdlib/complex.ml')
-rw-r--r--stdlib/complex.ml25
1 files changed, 15 insertions, 10 deletions
diff --git a/stdlib/complex.ml b/stdlib/complex.ml
index fe2e0388d1..3095534bab 100644
--- a/stdlib/complex.ml
+++ b/stdlib/complex.ml
@@ -62,16 +62,21 @@ let arg x = atan2 x.im x.re
let polar n a = { re = cos a *. n; im = sin a *. n }
-let sqrt x =
- (* Avoid cancellation in computing norm x + x.re
- when x.re < 0 and x.im is small *)
- if x.re >= 0.0 then begin
- let r = sqrt(0.5 *. norm x +. 0.5 *. x.re) in
- { re = r; im = if r = 0.0 then 0.0 else 0.5 *. x.im /. r }
- end else begin
- let s = sqrt(0.5 *. norm x -. 0.5 *. x.re) in
- { re = if s = 0.0 then 0.0 else 0.5 *. abs_float x.im /. s;
- im = if x.im >= 0.0 then s else -. s }
+let sqrt x =
+ if x.re = 0.0 && x.im = 0.0 then { re = 0.0; im = 0.0 }
+ else begin
+ let r = abs_float x.re and i = abs_float x.im in
+ let w =
+ if r >= i then begin
+ let q = i /. r in
+ sqrt(r) *. sqrt(0.5 *. (1.0 +. sqrt(1.0 +. q *. q)))
+ end else begin
+ let q = r /. i in
+ sqrt(i) *. sqrt(0.5 *. (q +. sqrt(1.0 +. q *. q)))
+ end in
+ if x.re >= 0.0
+ then { re = w; im = 0.5 *. x.im /. w }
+ else { re = 0.5 *. i /. w; im = if x.im >= 0.0 then w else -. w }
end
let exp x =