dph-examples-0.5.1.1: lib/Points2D/Generate.hs
{-# LANGUAGE TypeOperators #-}
module Points2D.Generate
( genPointsUniform
, genPointsUniformWithSeed
, genPointsDisc
, genPointsCombo
, pointsPArrayOfUArray )
where
import Points2D.Types
import Randomish
import qualified Data.Array.Parallel.Unlifted as U
import qualified Data.Array.Parallel as P
import qualified Data.Array.Parallel.PArray as P
import Data.Array.Parallel.PArray (PArray)
import Control.Exception
-- Random points generation
-- IMPORTANT: We use the same seed with the same random generator in all
-- quickhull codes. The asymptotic work complexity of quickhull
-- is between O (N) and O (N^2) depending on the input.
-- To compare benchmark results, they always need to use the same
-- input.
seed :: Int
seed = 42742
-- | Some uniformly distributed points
genPointsUniform
:: Int -- ^ number of points
-> Double -- ^ minimum coordinate
-> Double -- ^ maximum coordinate
-> U.Array (Double, Double)
genPointsUniform n pointMin pointMax
= let pts = randomishDoubles (n*2) pointMin pointMax seed
xs = U.extract pts 0 n
ys = U.extract pts n n
in U.zip xs ys
-- | Some uniformly distributed points
genPointsUniformWithSeed
:: Int -- ^ seed
-> Int -- ^ number of points
-> Double -- ^ minimum coordinate
-> Double -- ^ maximum coordinate
-> U.Array (Double, Double)
genPointsUniformWithSeed seed' n pointMin pointMax
= let pts = randomishDoubles (n*2) pointMin pointMax seed'
xs = U.extract pts 0 n
ys = U.extract pts n n
in U.zip xs ys
-- | Some points distributed as a disc
genPointsDisc
:: Int -- ^ number of points
-> (Double, Double) -- ^ center of disc
-> Double -- ^ radius of disc
-> U.Array (Double, Double)
genPointsDisc n (originX, originY) radiusMax
= let radius = randomishDoubles n 0 radiusMax seed
angle = randomishDoubles n (-pi) pi (seed + 1234)
makeXY r a
= ( originX + r * cos a
, originY + r * sin a)
in originX `seq` originY `seq` U.zipWith makeXY radius angle
-- | A point cloud with areas of high an low density
genPointsCombo
:: Int -- ^ number of points
-> U.Array (Double, Double)
genPointsCombo n
= genPointsDisc (n `div` 5) (250, 250) 200
U.+:+ genPointsDisc (n `div` 5) (100, 100) 80
U.+:+ genPointsDisc (n `div` 5) (150, 300) 30
U.+:+ genPointsDisc (n `div` 5) (500, 120) 30
U.+:+ genPointsDisc (n `div` 5) (300, 200) 150
-- | Convert a list of points to a PArray
pointsPArrayOfUArray
:: U.Array (Double, Double)
-> IO (PArray Point)
pointsPArrayOfUArray ps
= do
let pts = makePointsPA
(P.fromUArrPA' (U.fsts ps))
(P.fromUArrPA' (U.snds ps))
evaluate $ P.nf pts
return pts