{-# options_ghc -Wno-unused-imports #-}
module Data.RPTree.Internal.Testing where

import Control.Monad.IO.Class (MonadIO(..))
import GHC.Word (Word8, Word64)

-- conduit
import qualified Data.Conduit as C (ConduitT, runConduit, yield, await, transPipe)
import Data.Conduit ((.|))
import qualified Data.Conduit.Combinators as C (map, mapM, scanl, scanlM, last, print)
import qualified Data.Conduit.List as C (chunksOf, unfold, unfoldM)
-- splitmix
import System.Random.SplitMix (initSMGen, unseedSMGen)
-- splitmix-distributions
import System.Random.SplitMix.Distributions (GenT)

import Data.RPTree.Internal (SVector, fromListSv, DVector, fromListDv)
import Data.RPTree.Gen (dense, sparse, normal2, normalSparse2, normalDense2)
import Data.RPTree.Conduit (dataSource)

data BenchConfig = BenchConfig {
  BenchConfig -> String
bcDescription :: String
  , BenchConfig -> Int
bcMaxTreeDepth :: Int
  , BenchConfig -> Int
bcMinLeafSize :: Int
  , BenchConfig -> Int
bcNumTrees :: Int
  , BenchConfig -> Int
bcChunkSize :: Int
  , BenchConfig -> Double
bcNZDensity :: Double
  , BenchConfig -> Int
bcVectorDim :: Int
  , BenchConfig -> Int
bcDataSize :: Int
  , BenchConfig -> Int
bcNumQueryPoints :: Int
                               } deriving (Int -> BenchConfig -> ShowS
[BenchConfig] -> ShowS
BenchConfig -> String
(Int -> BenchConfig -> ShowS)
-> (BenchConfig -> String)
-> ([BenchConfig] -> ShowS)
-> Show BenchConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BenchConfig] -> ShowS
$cshowList :: [BenchConfig] -> ShowS
show :: BenchConfig -> String
$cshow :: BenchConfig -> String
showsPrec :: Int -> BenchConfig -> ShowS
$cshowsPrec :: Int -> BenchConfig -> ShowS
Show)

randSeed :: MonadIO m => m Word64
randSeed :: m Word64
randSeed = IO Word64 -> m Word64
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO ((Word64, Word64) -> Word64
forall a b. (a, b) -> a
fst ((Word64, Word64) -> Word64)
-> (SMGen -> (Word64, Word64)) -> SMGen -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SMGen -> (Word64, Word64)
unseedSMGen (SMGen -> Word64) -> IO SMGen -> IO Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO SMGen
initSMGen)


-- | binary mixture of isotropic Gaussian rvs
datD :: Monad m =>
        Int -- ^ number of data points
     -> Int -- ^ vector dimension
     -> C.ConduitT i (DVector Double) (GenT m) ()
datD :: Int -> Int -> ConduitT i (DVector Double) (GenT m) ()
datD Int
n Int
d = Int
-> GenT m (DVector Double)
-> ConduitT i (DVector Double) (GenT m) ()
forall (m :: * -> *) a i.
Monad m =>
Int -> GenT m a -> ConduitT i a (GenT m) ()
dataSource Int
n (GenT m (DVector Double)
 -> ConduitT i (DVector Double) (GenT m) ())
-> GenT m (DVector Double)
-> ConduitT i (DVector Double) (GenT m) ()
forall a b. (a -> b) -> a -> b
$ Int -> GenT m (DVector Double)
forall (m :: * -> *). Monad m => Int -> GenT m (DVector Double)
normalDense2 Int
d

-- | binary mixture of isotropic Gaussian rvs with sparse components
datS :: Monad m =>
        Int -- ^ number of data points
     -> Int -- ^ vector dimension
     -> Double -- ^ nonzero density
     -> C.ConduitT i (SVector Double) (GenT m) ()
datS :: Int -> Int -> Double -> ConduitT i (SVector Double) (GenT m) ()
datS Int
n Int
d Double
pnz = Int
-> GenT m (SVector Double)
-> ConduitT i (SVector Double) (GenT m) ()
forall (m :: * -> *) a i.
Monad m =>
Int -> GenT m a -> ConduitT i a (GenT m) ()
dataSource Int
n (GenT m (SVector Double)
 -> ConduitT i (SVector Double) (GenT m) ())
-> GenT m (SVector Double)
-> ConduitT i (SVector Double) (GenT m) ()
forall a b. (a -> b) -> a -> b
$ Double -> Int -> GenT m (SVector Double)
forall (m :: * -> *).
Monad m =>
Double -> Int -> GenT m (SVector Double)
normalSparse2 Double
pnz Int
d