packages feed

swish-0.2.1: Swish/HaskellRDF/Sort/DigitalSort.lhs

%-------------------------------=  --------------------------------------------
\chapter{Digital sorting}
%-------------------------------=  --------------------------------------------

%align

> module Swish.HaskellRDF.Sort.DigitalSort 
> where
> import Data.Array
> import Data.Bits
> import Data.Int

%align 33

> bucketSort			:: (Ix b) => (b, b) -> (a -> b) -> [a] -> [a]
> bucketSort bs key as		=  [ a | b <- elems buckets, a <- reverse b ]
>     where buckets		=  distribute bs [ (key a, a) | a <- as ]
>
> distribute			:: (Ix a) => (a, a) -> [(a, b)] -> Array a [b]
> distribute			=  accumArray (flip (:)) []
>
> radixSort			:: (Ix b) => (b, b) -> [a -> b] -> [a] -> [a]
> radixSort bs keys x		=  foldr (bucketSort bs) x keys

|keys| must satisfy the following property: let $a \leq_i b
\Longleftrightarrow |key|_i\;a \leq |key|_i\;b$ and $a(R\fatsemi S)b
\Longleftrightarrow aRb \vee (a=b \wedge aSb)$, then $(\leq)
\Longleftrightarrow (\leq_1)\fatsemi\ldots\fatsemi(\leq_n)$.

\NB |Word| should be used instead of |Int| since the sign bit is
ignored.

> int32Keys'			:: [Int32 -> Bool]
> int32Keys'			=  [ \i -> testBit i k | k <- [s - 1, s - 2 .. 0] ]
>     where s			=  bitSize (0 :: Int32)
>
> int32RadixSort'		:: [Int32] -> [Int32]
> int32RadixSort'		=  radixSort (False, True) int32Keys'

|shiftR| does not work properly, that's why |32 - 24| instead of |24|
is used below.

> int32Keys			:: [Int32 -> Int32]
> int32Keys			=  [ \i -> shiftR i (32 - 24) .&. 255
>				   , \i -> shiftR i (32 - 16) .&. 255
>				   , \i -> shiftR i (32 - 8) .&. 255
>				   , \i -> i .&. 255 ]
>
> int32RadixSort		:: [Int32] -> [Int32]
> int32RadixSort		=  radixSort (0, 255) int32Keys
>