I tried to implement the bitonicsorter I wrote about in my masters thesis. The
result is the following code:
// BitonicSort
//
// http :// www . diku . dk / forskning / performance - engineering / Ramon / thesis . pdf
let inline isPow2 x =
match x with
| 0 -> false
| _ -> x &&& ( x - 1 ) = 0
let comparator x y =
match x with
| _ when x < y -> ( x , y )
| _ -> ( y , x )
let halfCleaner bs =
let n = bs |> Array . length
let m = n / 2
match isPow2 ( n ) with
| true -> ()
| false -> failwith "Input array %A, must be n=2^k" bs
Array . mapi ( fun i x ->
match i with
| _ when i < m -> fst ( comparator x bs . [ m + i ])
| _ -> snd ( comparator x bs . [ i - m ])) bs
let rec bitonicSorter bs =
let n = bs |> Array . length
let m = n / 2
match isPow2 ( n ) with
| true -> ()
| false -> failwith "Input array %A, must be n=2^k" bs
let bs' = halfCleaner bs
let bs1 = bs' . [ 0 .. ( m - 1 )]
let bs2 = bs' . [ m .. ( n - 1 )]
match n with
| _ when 2 < n ->
Array . append ( bitonicSorter bs1 ) ( bitonicSorter bs2 )
| _ -> bs'
let merger ss1 ss2 =
let m1 = ss1 |> Array . length
let m2 = ss2 |> Array . length
let n = m1 + m2
let m = n / 2
match ( m1 = m2 ) with
| true -> ()
| false -> failwith "Input arrays (%A,%A), must have the same length" ss1 ss2
match isPow2 ( n ) with
| true -> ()
| false -> failwith "Comibnation of (%A,%A) arrays, must be n=2^k" ss1 ss2
let ss2' = ss2 |> Array . rev
let ss1'' = Array . map2 ( fun x y -> fst ( comparator x y )) ss1 ss2'
let ss2'' = Array . map2 ( fun x y -> snd ( comparator x y )) ss1 ss2'
match n with
| _ when 2 < n -> Array . append ( bitonicSorter ss1'' ) ( bitonicSorter ss2'' )
| _ -> Array . append ss1'' ss2''
let rec sorter array =
let n = array |> Array . length
let m = n / 2
match isPow2 ( n ) with
| true -> ()
| false -> failwith "Input array %A, must be n=2^k" array
let as1 = array . [ 0 .. ( m - 1 )]
let as2 = array . [ m .. ( n - 1 )]
match n with
| _ when 2 < n -> merger ( sorter as1 ) ( sorter as2 )
| _ -> merger as1 as2
let n = 1 <<< 16
let a = Array . init n ( fun i -> i % 2 )
sorter a
It still lacks of speed, even with the use of the included libraries
Array.Parallel
or Async.Parallel
/
Async.RunSynchronously
(fork/join ) but it was fun to write as
usual.
REMARK: It’s much more readable than the code I wrote back in the days …