[Shootout-list] Fasta in OCaml

William Douglas Neumann wdnx@unm.edu
Mon, 20 Dec 2004 09:40:25 -0700 (MST)


Below is the fasta benchmark in OCaml.  I believe the output is correct (I 
can't really confirm it's working, as the sample output file doesn't jive 
with the benchmark program -- though the start of my output seems to match 
the first 50 lines of output shown for the Oberon version;

let length = 60;;
let s = String.create length;;

type freq = {c : char; mutable p : float};;

let makeCumulative arr =
   ignore (Array.fold_left
     (fun b v -> let cp = (b +. v.p) in v.p <- cp; cp)
     0.0 arr);
   arr;;

let gen_random =
   let last = ref 42 and im = 139968 and ia = 3877 and ic = 29573 in
   let fim = float im in
   fun () -> last := (!last * ia + ic) mod im; (float !last) /. fim;;

let makeFastaFragment id desc arr n =
   let selectRandom () =
     let rec afh r i =
       if r <= arr.(i).p then arr.(i).c else afh r (succ i) in
     afh (gen_random ()) 0 in
   let rec loop n =
     if n > 0 then
     begin
       let x = n < length in
       for i = 0 to pred (if x then n else length) do
         s.[i] <- (selectRandom ())
       done;
       if x then String.fill s n (length - n) ' ';
       print_endline s;
       loop (n - length)
     end in
   Printf.printf ">%s %s\n" id desc;
   loop n;;

let _ =
   let n = try int_of_string Sys.argv.(1) with _ -> 1 in
   let dna1 =
     makeCumulative
     [| {c = 'a'; p = 0.3029549426680}; {c = 'c'; p = 0.1979883004921};
        {c = 'g'; p = 0.1975473066391}; {c = 't'; p = 0.3015094502008} |]
   and dna2 =
     makeCumulative
     [| {c = 'a'; p = 0.250}; {c = 'c'; p = 0.125};
        {c = 'g'; p = 0.125}; {c = 't'; p = 0.250};
        {c = 'U'; p = 0.019230769231}; {c = 'R'; p = 0.019230769231};
        {c = 'Y'; p = 0.019230769231}; {c = 'K'; p = 0.019230769231};
        {c = 'M'; p = 0.019230769231}; {c = 'S'; p = 0.019230769231};
        {c = 'W'; p = 0.019230769231}; {c = 'B'; p = 0.019230769231};
        {c = 'D'; p = 0.019230769231}; {c = 'H'; p = 0.019230769231};
        {c = 'V'; p = 0.019230769231}; {c = 'N'; p = 0.019230769231};
        {c = '-'; p = 0.019230769231} |] in
   makeFastaFragment "TestOne" "test fragment" dna2 (n*1);
   makeFastaFragment "TestTwo" "test fragment" dna1 (n*2);
   makeFastaFragment "TestThree" "test fragment" dna2 (n*3);
   makeFastaFragment "TestFour" "test fragment" dna1 (n*4);
   makeFastaFragment "TestFive" "test fragment" dna2 (n*5);;


William D. Neumann
<wdnx@unm.edu>

FWO to the Nth degree!!!
---
Dear Lord, please make me the kind of person
my dog thinks I am.