1- {-# LANGUAGE KindSignatures #-}
2- {-# LANGUAGE GeneralizedNewtypeDeriving #-}
3- {-# LANGUAGE DerivingVia #-}
4- {-# LANGUAGE DataKinds #-}
1+ {-# LANGUAGE AllowAmbiguousTypes #-}
52{-# LANGUAGE BangPatterns #-}
6- {-# LANGUAGE TypeApplications #-}
3+ {-# LANGUAGE DataKinds #-}
4+ {-# LANGUAGE DerivingVia #-}
75{-# LANGUAGE FlexibleContexts #-}
8- {-# LANGUAGE AllowAmbiguousTypes #-}
6+ {-# LANGUAGE GeneralizedNewtypeDeriving #-}
7+ {-# LANGUAGE KindSignatures #-}
98{-# LANGUAGE ScopedTypeVariables #-}
9+ {-# LANGUAGE TypeApplications #-}
1010
1111module Main (main ) where
1212
13+ import Control.DeepSeq
14+ import Criterion.Main
15+ import Data.Proxy
16+ import GHC.TypeLits
1317import LAoP.Dist.Internal
18+ import LAoP.Matrix.Type hiding (Countable , CountableN , FLN )
19+ import LAoP.Matrix.Type qualified as T (FLN )
1420import LAoP.Utils
15- import LAoP.Matrix.Type hiding (CountableN , Countable , FLN )
16- import qualified LAoP.Matrix.Type as T (FLN )
17- import Criterion.Main
18- import Control.DeepSeq
1921import Test.QuickCheck
20- import GHC.TypeLits
21- import Data.Proxy
2222import Prelude hiding (id , (.) )
2323
24- selectM2 ::
25- ( Num e ,
26- T. FLN b b ,
27- CountableN b
28- ) => Matrix e cols (Either a b ) -> Matrix e a b -> Matrix e cols b
24+ selectM2 ::
25+ ( Num e
26+ , T. FLN b b
27+ , CountableN b
28+ ) =>
29+ Matrix e cols (Either a b ) ->
30+ Matrix e a b ->
31+ Matrix e cols b
2932selectM2 m y = join y iden `comp` m
3033
31- selectD2 ::
32- ( FLN b b ,
33- CountableN b
34- ) => Dist (Either a b ) -> Matrix Prob a b -> Dist b
34+ selectD2 ::
35+ ( FLN b b
36+ , CountableN b
37+ ) =>
38+ Dist (Either a b ) ->
39+ Matrix Prob a b ->
40+ Dist b
3541selectD2 (D d) m = D (join m iden `comp` d)
3642
3743-- Composition with iden
38- compId m = comp iden m
44+ compId = comp iden
3945
40- randomDist :: forall a . (Countable a , FLN () a ) => Gen (Dist a )
46+ randomDist :: forall a . (Countable a , FLN () a ) => Gen (Dist a )
4147randomDist = do
4248 let size = fromInteger (natVal (Proxy :: Proxy (Count a )))
4349 l <- vectorOf size (arbitrary :: Gen Prob )
4450 let ln = normalize l
45- lr = map (: [] ) ln
46- m = fromLists lr
51+ lr = map (: [] ) ln
52+ m = fromLists lr
4753 return (D m)
4854
49- randomMatrix :: forall a b . (CountableDims a b , FLN a b ) => Gen (Matrix Prob a b )
55+ randomMatrix :: forall a b . (CountableDims a b , FLN a b ) => Gen (Matrix Prob a b )
5056randomMatrix = do
5157 let cols = fromInteger (natVal (Proxy :: Proxy (Count a )))
5258 rows = fromInteger (natVal (Proxy :: Proxy (Count b )))
5359 l <- vectorOf (cols * rows) arbitrary
5460 let lr = buildList l cols
55- m = fromLists lr
61+ m = fromLists lr
5662 return m
5763
5864buildList [] _ = []
59- buildList l r = take r l : buildList (drop r l) r
65+ buildList l r = take r l : buildList (drop r l) r
6066
6167normalize :: [Prob ] -> [Prob ]
62- normalize l = let l' = map abs l
63- s = sum l'
64- in map (/ s) l'
68+ normalize l =
69+ let l' = map abs l
70+ s = sum l'
71+ in map (/ s) l'
6572
6673-- Probability
6774newtype Probability = P Double
6875 deriving (Num , Show , Fractional , NFData ) via Double
69- newtype Dist' a = D' { unD :: [(a ,Probability )] }
76+ newtype Dist' a = D' { unD :: [(a , Probability )]}
7077 deriving (Show , NFData )
7178
7279instance Functor Dist' where
73- fmap f (D' d) = D' [(f x,p) | (x,p) <- d]
80+ fmap f (D' d) = D' [(f x, p) | (x, p) <- d]
7481
7582instance Applicative Dist' where
7683 pure x = D' [(x, 1 )]
77- fm <*> m = D' [(f x,q * p) | (f,p) <- unD fm, (x,q) <- unD m]
84+ fm <*> m = D' [(f x, q * p) | (f, p) <- unD fm, (x, q) <- unD m]
7885
79- class Applicative f => Selective f where
86+ class ( Applicative f ) => Selective f where
8087 select :: f (Either a b ) -> f (a -> b ) -> f b
8188
8289instance Selective Dist' where
8390 select x y = (\ e f -> either f id e) <$> x <*> y -- selectA
8491
8592instance Monad Dist' where
86- return = pure
87- (D' d) >>= f = D' [(y,q* p) | (x,p) <- d, (y,q) <- unD (f x)]
88-
89- normalize2 :: forall a . (Enum a , Bounded a ) => [Probability ] -> [(a , Probability )]
90- normalize2 l = let l' = map abs l
91- as = [minBound .. maxBound ]
92- s = sum l'
93- probs = map (/ s) l'
94- in zip as probs
95-
96- randomDist2 :: forall a . (Countable a , Enum a , Bounded a ) => Gen (Dist' a )
93+ return = pure
94+ (D' d) >>= f = D' [(y, q * p) | (x, p) <- d, (y, q) <- unD (f x)]
95+
96+ normalize2 :: forall a . (Enum a , Bounded a ) => [Probability ] -> [(a , Probability )]
97+ normalize2 l =
98+ let l' = map abs l
99+ as = [minBound .. maxBound ]
100+ s = sum l'
101+ probs = map (/ s) l'
102+ in zip as probs
103+
104+ randomDist2 :: forall a . (Countable a , Enum a , Bounded a ) => Gen (Dist' a )
97105randomDist2 = do
98106 let size = fromInteger (natVal (Proxy :: Proxy (Count a )))
99107 l <- vectorOf size (arbitrary :: Gen Prob )
100108 let ln = normalize2 @ a (map P l)
101109 return (D' ln)
102110
103- normalize3 :: forall a . [a ] -> [Probability ] -> [(a , Probability )]
104- normalize3 as l = let s = sum l
105- probs = map (/ s) l
106- in zip as probs
111+ normalize3 :: forall a . [a ] -> [Probability ] -> [(a , Probability )]
112+ normalize3 as l =
113+ let s = sum l
114+ probs = map (/ s) l
115+ in zip as probs
107116
108- randomDistF :: forall a b . (CountableDims a b , CoArbitrary a , Arbitrary b ) => Gen (Dist' (a -> b ))
117+ randomDistF :: forall a b . (CountableDims a b , CoArbitrary a , Arbitrary b ) => Gen (Dist' (a -> b ))
109118randomDistF = do
110119 let a = fromInteger (natVal (Proxy :: Proxy (Count a )))
111120 b = fromInteger (natVal (Proxy :: Proxy (Count b )))
@@ -117,59 +126,72 @@ randomDistF = do
117126
118127instance CoArbitrary (Natural a b )
119128
120- instance forall (a :: Nat ) (b :: Nat ). (KnownNat a , KnownNat b ) => Arbitrary (Natural a b )
121- where
129+ instance forall (a :: Nat ) (b :: Nat ). (KnownNat a , KnownNat b ) => Arbitrary (Natural a b ) where
122130 arbitrary =
123131 let bottom = fromInteger (natVal (Proxy :: Proxy a ))
124- top = fromInteger (natVal (Proxy :: Proxy b ))
132+ top = fromInteger (natVal (Proxy :: Proxy b ))
125133 in do
126- x <- arbitrary `suchThat` (\ n -> n >= bottom && n <= top)
127- return (nat x)
134+ x <- arbitrary `suchThat` (\ n -> n >= bottom && n <= top)
135+ return (nat x)
128136
129137setupEnv = do
130- m11 <- generate (resize 1 (randomMatrix @ (Natural 0 10 ) @ (Natural 0 10 ) ))
131- m12 <- generate (resize 1 (randomMatrix @ (Natural 0 10 ) @ (Natural 0 10 ) ))
132- m21 <- generate (resize 1 (randomMatrix @ (Natural 0 100 ) @ (Natural 0 100 ) ))
133- m22 <- generate (resize 1 (randomMatrix @ (Natural 0 100 ) @ (Natural 0 100 ) ))
134- m31 <- generate (resize 1 (randomMatrix @ (Natural 0 200 ) @ (Natural 0 200 ) ))
135- m32 <- generate (resize 1 (randomMatrix @ (Natural 0 200 ) @ (Natural 0 200 ) ))
138+ m11 <- generate (resize 1 (randomMatrix @ (Natural 0 10 ) @ (Natural 0 10 )))
139+ m12 <- generate (resize 1 (randomMatrix @ (Natural 0 10 ) @ (Natural 0 10 )))
140+ m21 <- generate (resize 1 (randomMatrix @ (Natural 0 100 ) @ (Natural 0 100 )))
141+ m22 <- generate (resize 1 (randomMatrix @ (Natural 0 100 ) @ (Natural 0 100 )))
142+ m31 <- generate (resize 1 (randomMatrix @ (Natural 0 200 ) @ (Natural 0 200 )))
143+ m32 <- generate (resize 1 (randomMatrix @ (Natural 0 200 ) @ (Natural 0 200 )))
136144 return (m11, m12, m21, m22, m31, m32)
137145
138146setupEnv2 = do
139- m21 <- generate (resize 1 (randomMatrix @ (Natural 0 100 ) @ (Natural 0 100 ) ))
140- m40 <- generate (resize 1 (randomMatrix @ (Natural 0 100 ) @ (Either (Natural 0 100 ) (Natural 0 100 ) )))
141- dist <- generate (resize 1 (randomDist @ (Either (Natural 0 100 ) (Natural 0 100 )) ))
142- dist2 <- generate (resize 1 (randomMatrix @ (Natural 0 100 ) @ (Natural 0 100 ) ))
147+ m21 <- generate (resize 1 (randomMatrix @ (Natural 0 100 ) @ (Natural 0 100 )))
148+ m40 <- generate (resize 1 (randomMatrix @ (Natural 0 100 ) @ (Either (Natural 0 100 ) (Natural 0 100 ))))
149+ dist <- generate (resize 1 (randomDist @ (Either (Natural 0 100 ) (Natural 0 100 ))))
150+ dist2 <- generate (resize 1 (randomMatrix @ (Natural 0 100 ) @ (Natural 0 100 )))
143151 distList1 <- generate (resize 1 (randomDist2 @ (Either (Natural 0 100 ) (Natural 0 100 ))))
144152 distList2 <- generate (resize 1 (randomDistF @ (Natural 0 100 ) @ (Natural 0 100 )))
145153 return (m21, m40, dist, dist2, distList1, distList2)
146154
147155main :: IO ()
148- main = defaultMain [
149- env setupEnv $ \ ~ (m11, m12, m21, m22, m31, m32) -> bgroup " Matrix Composition" [
150- bgroup " 10x10" [
151- bench " WHNF - 10x10" $ whnf (comp m11) m12
152- , bench " NF - 10x10" $ nf (comp m11) m12
153- ],
154- bgroup " 100x100" [
155- bench " WHNF - 100x100" $ whnf (comp m21) m22
156- , bench " NF - 100x100" $ nf (comp m21) m22
157- ],
158- bgroup " 200x200" [
159- bench " WHNF - 200x200" $ whnf (comp m31) m32
160- , bench " NF - 200x200" $ nf (comp m31) m32
161- ],
162- bgroup " 200x200 - RULES" [
163- bench " No rules - 200x200" $ nf (comp m21) iden
164- , bench " Rules - 200x200" $ nf compId m21
165- ] ],
166- env setupEnv2 $ \ ~ (m21, m40, dist, dist2, dl1, dl2) -> bgroup " Matrix vs List - `select`" [
167- bgroup " Distribution `select` - 100+100 / 100x100" [
168- bench " List Distribution - Applicative version" $ nf (select dl1) dl2
169- , bench " Matrix Distribution - Applicative version" $ nf (selectD2 dist) dist2
170- , bench " Matrix Distribution - Selective version" $ nf (selectD dist) dist2
171- ],
172- bgroup " Matrix `select` - 100x(100+100) / 100x100" [
173- bench " Applicative version" $ nf (selectM2 m40) m21
174- , bench " Selective version" $ nf (selectM m40) m21
175- ] ] ]
156+ main =
157+ defaultMain
158+ [ env setupEnv $ \ ~ (m11, m12, m21, m22, m31, m32) ->
159+ bgroup
160+ " Matrix Composition"
161+ [ bgroup
162+ " 10x10"
163+ [ bench " WHNF - 10x10" $ whnf (comp m11) m12
164+ , bench " NF - 10x10" $ nf (comp m11) m12
165+ ]
166+ , bgroup
167+ " 100x100"
168+ [ bench " WHNF - 100x100" $ whnf (comp m21) m22
169+ , bench " NF - 100x100" $ nf (comp m21) m22
170+ ]
171+ , bgroup
172+ " 200x200"
173+ [ bench " WHNF - 200x200" $ whnf (comp m31) m32
174+ , bench " NF - 200x200" $ nf (comp m31) m32
175+ ]
176+ , bgroup
177+ " 200x200 - RULES"
178+ [ bench " No rules - 200x200" $ nf (comp m21) iden
179+ , bench " Rules - 200x200" $ nf compId m21
180+ ]
181+ ]
182+ , env setupEnv2 $ \ ~ (m21, m40, dist, dist2, dl1, dl2) ->
183+ bgroup
184+ " Matrix vs List - `select`"
185+ [ bgroup
186+ " Distribution `select` - 100+100 / 100x100"
187+ [ bench " List Distribution - Applicative version" $ nf (select dl1) dl2
188+ , bench " Matrix Distribution - Applicative version" $ nf (selectD2 dist) dist2
189+ , bench " Matrix Distribution - Selective version" $ nf (selectD dist) dist2
190+ ]
191+ , bgroup
192+ " Matrix `select` - 100x(100+100) / 100x100"
193+ [ bench " Applicative version" $ nf (selectM2 m40) m21
194+ , bench " Selective version" $ nf (selectM m40) m21
195+ ]
196+ ]
197+ ]
0 commit comments