[Shootout-list] Improved Ocaml Mandlebrot
Brian Hurt
bhurt at spnz.org
Tue Aug 23 01:43:32 UTC 2005
Attached is a speed-improved version of Mandlebrot in Ocaml. It runs in
about 3/4th to 2/3rds the time on my machine. Humorously enough, the
changes make the program more functional in nature, as I changed a for
loop with references to a recursive function. Someone should probably
check to make sure the output is correct before including it.
Brian
-------------- next part --------------
let niter = 50
let limit = 2.
let limit2 = limit *. limit
type complex = { mutable r:float; mutable i:float }
let get_bit c z =
z.r <- 0.;
z.i <- 0.;
let rec loop i =
if i < niter then
begin
let zi = 2. *. z.r *. z.i +. c.i in
z.r <- z.r *. z.r -. z.i *. z.i +. c.r;
z.i <- zi;
if z.r *. z.r +. z.i *. z.i > limit2 then false else loop (i+1)
end
else
true
in
loop 0
let () =
let w = int_of_string(Array.get Sys.argv 1) in
let h = w in
let fw = float w
and fh = float h
and cplmt8 = 8 - w mod 8 in
Printf.printf "P4\n%i %i\n" w h;
let c = { r = 0.0; i = 0.0 } in
let tmp = { r = 0.0; i = 0.0 } in
let rec loop1 byte bit y x =
c.i <- 2. *. float y /. fh -. 1.;
c.r <- 2. *. float x /. fw -. 1.5;
let byte =
if get_bit c tmp then
(byte lsl 1) lor 1
else
byte lsl 1
in
loop2 byte (bit + 1) y x
and loop2 byte bit y x =
if bit == 8 then
begin
output_byte stdout byte;
loop3 0 0 y x
end
else
loop3 byte bit y x
and loop3 byte bit y x =
let x = x + 1 in
if (x == w) then
let y = y + 1 in
if (y == h) then
begin
output_byte stdout byte;
()
end
else
loop1 byte bit y 0
else
loop1 byte bit y x
in
loop1 0 0 0 0
More information about the Shootout-list
mailing list