summaryrefslogtreecommitdiff
path: root/testsuite/tests/dph/nbody/Generate.hs
blob: 5b700ddec5d1428b9ae0f9b4a2cfccd5683fa124 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
{-# LANGUAGE TypeOperators #-}
module Generate 
        ( genPointsUniform
        , genPointsUniformWithSeed
        , genPointsDisc
        , genPointsCombo
        , pointsPArrayOfUArray )
where
import 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 and 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.fromUArray (U.fsts ps))
                        (P.fromUArray (U.snds ps))
      evaluate $ P.nf pts
      return pts