module Main where
import Control.Applicative
import Criterion.Main
import Test.QuickCheck
import qualified Data.Vector as G
import qualified Data.Vector.Unboxed as V
import qualified OldKMeans as K
import qualified Math.KMeans as K2
main :: IO ()
main = do
persons1 <- generate persons
persons2 <- generate persons
defaultMain
[
bgroup "ints" [ bench "v0.2" $ whnf kmeans1 ints1
, bench "v0.3" $ whnf kmeans2 ints2
]
, bgroup "persons" [ bench "v0.2" $ whnf kmeansP1 persons1
, bench "v0.3" $ whnf kmeansP2 persons2]
]
ints1, ints2 :: [Int]
ints1 = [1..10000]
ints2 = [1..10000]
data Person = Person
{ age :: Int
, weight :: Double
, name :: String
, salary :: Int
} deriving (Eq, Show)
instance Arbitrary Person where
arbitrary = do
Person <$> choose (2, 100)
<*> choose (5, 150)
<*> pure "francis"
<*> choose (500, 100000)
persons :: Gen [Person]
persons = vector 10000
-- kmeans of 'Int's in 3 clusters
kmeans1 = G.fromList . K.kmeans 3 . map (\i -> (extract i, i))
kmeans2 = K2.kmeans extract dist 3
-- kmeans of 'Person's in 4 clusters
kmeansP1 = G.fromList . K.kmeans 4 . map p2v
where p2v p = (personToVec p, p)
kmeansP2 = K2.kmeans personToVec eucl 4
personToVec :: Person -> V.Vector Double
personToVec p = V.fromList
[ fromIntegral $ age p
, weight p
, fromIntegral $ salary p
]
extract :: Int -> V.Vector Double
extract = V.singleton . fromIntegral
dist :: K2.Distance
dist v1 v2 = V.sum $ V.zipWith (\x1 x2 -> abs (x1 - x2)) v1 v2
eucl :: K2.Distance
eucl v1 v2 = V.sum $ V.zipWith (\x1 x2 -> (x1 - x2)^2) v1 v2