{-# LANGUAGE FlexibleContexts #-}
module RandomCycle.Vector.Cycle where
import Control.Monad (when)
import Control.Monad.Primitive (PrimMonad, PrimState, liftPrim)
import Data.STRef
import qualified Data.Vector as V
import System.Random.MWC.Distributions (uniformPermutation, uniformShuffleM)
import System.Random.Stateful
uniformCyclePartitionThinM ::
(StatefulGen g m, PrimMonad m) =>
STRef (PrimState m) Bool ->
STRef (PrimState m) Int ->
((Int, Int) -> Bool) ->
V.MVector (PrimState m) Int ->
g ->
m ()
uniformCyclePartitionThinM :: forall g (m :: * -> *).
(StatefulGen g m, PrimMonad m) =>
STRef (PrimState m) Bool
-> STRef (PrimState m) Int
-> ((Int, Int) -> Bool)
-> MVector (PrimState m) Int
-> g
-> m ()
uniformCyclePartitionThinM STRef (PrimState m) Bool
chk STRef (PrimState m) Int
maxit (Int, Int) -> Bool
r MVector (PrimState m) Int
v g
gen = do
Int
maxitVal <- forall (m1 :: * -> *) (m2 :: * -> *) a.
(PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
m1 a -> m2 a
liftPrim forall a b. (a -> b) -> a -> b
$ forall s a. STRef s a -> ST s a
readSTRef STRef (PrimState m) Int
maxit
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
maxitVal forall a. Ord a => a -> a -> Bool
<= Int
0) (forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
forall g (m :: * -> *) (v :: * -> * -> *) a.
(StatefulGen g m, PrimMonad m, MVector v a) =>
v (PrimState m) a -> g -> m ()
uniformShuffleM MVector (PrimState m) Int
v g
gen
Vector Int
vVal <- forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> m (Vector a)
V.freeze MVector (PrimState m) Int
v
if forall a. (a -> Bool) -> Vector a -> Bool
V.all (Int, Int) -> Bool
r (forall a. Vector a -> Vector (Int, a)
V.indexed Vector Int
vVal)
then do
forall (m1 :: * -> *) (m2 :: * -> *) a.
(PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
m1 a -> m2 a
liftPrim forall a b. (a -> b) -> a -> b
$ forall s a. STRef s a -> (a -> a) -> ST s ()
modifySTRef' STRef (PrimState m) Bool
chk (forall a b. a -> b -> a
const Bool
True)
else do
forall (m1 :: * -> *) (m2 :: * -> *) a.
(PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
m1 a -> m2 a
liftPrim forall a b. (a -> b) -> a -> b
$ forall s a. STRef s a -> (a -> a) -> ST s ()
modifySTRef' STRef (PrimState m) Int
maxit (\Int
x -> Int
x forall a. Num a => a -> a -> a
- Int
1)
forall g (m :: * -> *).
(StatefulGen g m, PrimMonad m) =>
STRef (PrimState m) Bool
-> STRef (PrimState m) Int
-> ((Int, Int) -> Bool)
-> MVector (PrimState m) Int
-> g
-> m ()
uniformCyclePartitionThinM STRef (PrimState m) Bool
chk STRef (PrimState m) Int
maxit (Int, Int) -> Bool
r MVector (PrimState m) Int
v g
gen
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
uniformCyclePartition ::
(StatefulGen g m, PrimMonad m) =>
Int ->
g ->
m (V.Vector (Int, Int))
uniformCyclePartition :: forall g (m :: * -> *).
(StatefulGen g m, PrimMonad m) =>
Int -> g -> m (Vector (Int, Int))
uniformCyclePartition Int
n g
gen = forall a. Vector a -> Vector (Int, a)
V.indexed forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall g (m :: * -> *) (v :: * -> *).
(StatefulGen g m, PrimMonad m, Vector v Int) =>
Int -> g -> m (v Int)
uniformPermutation Int
n g
gen
uniformCyclePartitionThin ::
(StatefulGen g m, PrimMonad m) =>
Int ->
((Int, Int) -> Bool) ->
Int ->
g ->
m (Maybe (V.Vector (Int, Int)))
uniformCyclePartitionThin :: forall g (m :: * -> *).
(StatefulGen g m, PrimMonad m) =>
Int
-> ((Int, Int) -> Bool)
-> Int
-> g
-> m (Maybe (Vector (Int, Int)))
uniformCyclePartitionThin Int
maxit (Int, Int) -> Bool
_ Int
n g
_en | Int
maxit forall a. Ord a => a -> a -> Bool
<= Int
0 Bool -> Bool -> Bool
|| Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
uniformCyclePartitionThin Int
maxit (Int, Int) -> Bool
r Int
n g
gen = do
let v :: Vector Int
v = forall a. Int -> (Int -> a) -> Vector a
V.generate Int
n forall a. a -> a
id
MVector (PrimState m) Int
mv <- forall (m :: * -> *) a.
PrimMonad m =>
Vector a -> m (MVector (PrimState m) a)
V.thaw Vector Int
v
STRef (PrimState m) Bool
chk' <- forall (m1 :: * -> *) (m2 :: * -> *) a.
(PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
m1 a -> m2 a
liftPrim forall a b. (a -> b) -> a -> b
$ forall a s. a -> ST s (STRef s a)
newSTRef Bool
False
STRef (PrimState m) Int
maxit' <- forall (m1 :: * -> *) (m2 :: * -> *) a.
(PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
m1 a -> m2 a
liftPrim forall a b. (a -> b) -> a -> b
$ forall a s. a -> ST s (STRef s a)
newSTRef Int
maxit
forall g (m :: * -> *).
(StatefulGen g m, PrimMonad m) =>
STRef (PrimState m) Bool
-> STRef (PrimState m) Int
-> ((Int, Int) -> Bool)
-> MVector (PrimState m) Int
-> g
-> m ()
uniformCyclePartitionThinM STRef (PrimState m) Bool
chk' STRef (PrimState m) Int
maxit' (Int, Int) -> Bool
r MVector (PrimState m) Int
mv g
gen
Bool
chk <- forall (m1 :: * -> *) (m2 :: * -> *) a.
(PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
m1 a -> m2 a
liftPrim forall a b. (a -> b) -> a -> b
$ forall s a. STRef s a -> ST s a
readSTRef STRef (PrimState m) Bool
chk'
if Bool
chk
then do
forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> Vector (Int, a)
V.indexed forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> m (Vector a)
V.freeze MVector (PrimState m) Int
mv
else forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing