2 module TestData
3 ( genPointsUniform
4 , genPointsDisc
5 , genPointsCombo
6 , toPArrayPoints )
7 where
9 import qualified Types as QH
10 import qualified Data.Array.Parallel.Unlifted as U
11 import qualified Data.Array.Parallel.Prelude as P
12 import qualified Data.Array.Parallel.Prelude.Double as D
13 import qualified Data.Array.Parallel.PArray as P
14 import Data.Array.Parallel.PArray (PArray)
16 import System.Random
17 import Control.Exception
19 -- Random points generation
20 -- IMPORTANT: We use the same seed with the same random generator in all
21 -- quickhull codes. The asymptotic work complexity of quickhull
22 -- is between O (N) and O (N^2) depending on the input.
23 -- To compare benchmark results, they always need to use the same
24 -- input.
25 seed = 42742
27 -- | Some uniformly distributed points
28 genPointsUniform
29 :: Int -- ^ number of points
30 -> Double -- ^ minimum coordinate
31 -> Double -- ^ maximum coordinate
32 -> [(Double, Double)]
34 genPointsUniform n minXY maxXY
35 = let
36 pointMin = 10
37 pointMax = 510
38 gen = mkStdGen seed
39 in toPairs \$ take (2*n) \$ randomRs (pointMin, pointMax) gen
41 toPairs [] = []
42 toPairs (x:y:pts) = (x, y) : toPairs pts
45 -- | Some points distributed as a disc
46 genPointsDisc
47 :: Int -- ^ number of points
48 -> (Double, Double) -- ^ center of disc
49 -> Double -- ^ radius of disc
50 -> [(Double, Double)]
52 genPointsDisc n (originX, originY) radiusMax
54 = split \$ mkStdGen seed
57 angle = take n \$ randomRs (- pi, pi) genAngle
59 makeXY (r, a)
60 = ( originX + r * cos a
61 , originY + r * sin a)
63 in map makeXY \$ zip radius angle
66 -- | A point cloud with areas of high an low density
67 genPointsCombo
68 :: Int -- ^ number of points
69 -> [(Double, Double)]
71 genPointsCombo n
72 = genPointsDisc (n `div` 5) (250, 250) 200
73 ++ genPointsDisc (n `div` 5) (100, 100) 80
74 ++ genPointsDisc (n `div` 5) (150, 300) 30
75 ++ genPointsDisc (n `div` 5) (500, 120) 30
76 ++ genPointsDisc (n `div` 5) (300, 200) 150
79 -- | Convert a list of points to a PArray
80 toPArrayPoints :: [(Double, Double)] -> IO (PArray QH.Point)
81 toPArrayPoints ps
82 = do let pts = QH.points (P.fromList (map fst ps))
83 (P.fromList (map snd ps))
84 evaluate \$ force pts
85 return pts
87 -- | Force points to be evaluated
88 force pts
89 = U.index "TestData" (P.toUArray (QH.xsOf pts)) 0 D.+
90 U.index "TestData" (P.toUArray (QH.ysOf pts)) 0