### wta: Change --out-degree to --transitions

```It's now used to specify how many transitions you want instead of how many
transitions per state. This is strictly more powerful because you can always
just specify states*out-degree as transition count.```
parent cab34a04
 ... @@ -2,7 +2,7 @@ ... @@ -2,7 +2,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE LambdaCase #-} module Generator (genWTA, runGenerator, GeneratorConfig(..), ZeroFrequency(..)) where module Generator (genWTA, runGenerator, GeneratorConfig(..), EdgeConfig(..)) where import Data.Vector ( Vector ) import Data.Vector ( Vector ) import qualified Data.Vector as V import qualified Data.Vector as V ... @@ -21,18 +21,18 @@ import Probability ... @@ -21,18 +21,18 @@ import Probability import IndexedTransition import IndexedTransition import qualified IndexedTransition import qualified IndexedTransition data ZeroFrequency = Percentage Probability | OutDegree Int data EdgeConfig = ZeroFrequency Probability | NumTransitions Int data GeneratorConfig m = GeneratorConfig data GeneratorConfig m = GeneratorConfig { spec :: WTASpec m { spec :: WTASpec m , zeroPolicy :: ZeroFrequency , zeroPolicy :: EdgeConfig , differentValues :: Maybe Int , differentValues :: Maybe Int } } type Generator m = ReaderT (GeneratorConfig m) IO type Generator m = ReaderT (GeneratorConfig m) IO zeroFreq :: GeneratorConfig m -> Probability zeroFreq :: GeneratorConfig m -> Probability zeroFreq (GeneratorConfig { zeroPolicy = Percentage p }) = p zeroFreq (GeneratorConfig { zeroPolicy = ZeroFrequency p }) = p zeroFreq _ = error "zeroFreq: unexpected out degree" -- TODO Ugly as hell zeroFreq _ = error "zeroFreq: unexpected out degree" -- TODO Ugly as hell runGenerator :: GeneratorConfig m -> Generator m a -> IO a runGenerator :: GeneratorConfig m -> Generator m a -> IO a ... @@ -107,13 +107,12 @@ uniqueTransitions num (IndexedTransition.Index max) = helper S.empty num ... @@ -107,13 +107,12 @@ uniqueTransitions num (IndexedTransition.Index max) = helper S.empty num genTransitions' :: Int -> Generator m (Vector (Vector (Transition m))) genTransitions' :: Int -> Generator m (Vector (Vector (Transition m))) genTransitions' outDegree = do genTransitions' numTransitions = do wtaSpec <- asks spec wtaSpec <- asks spec let n = numStates wtaSpec let n = numStates wtaSpec m = IndexedTransition.maxIndex wtaSpec m = IndexedTransition.maxIndex wtaSpec desiredEdges = n * outDegree transitions <- lift \$ map (IndexedTransition.fromIndex wtaSpec) <\$> uniqueTransitions desiredEdges m transitions <- lift \$ map (IndexedTransition.fromIndex wtaSpec) <\$> uniqueTransitions numTransitions m weightedTransitions <- (traverse.traverse.traverse) (const genMonoidValue) transitions weightedTransitions <- (traverse.traverse.traverse) (const genMonoidValue) transitions let byState = foldl' (\m (State s, t) -> M.insertWith (++) s [t] m) M.empty weightedTransitions let byState = foldl' (\m (State s, t) -> M.insertWith (++) s [t] m) M.empty weightedTransitions ... @@ -126,5 +125,5 @@ genTransitions' outDegree = do ... @@ -126,5 +125,5 @@ genTransitions' outDegree = do genWTA :: Generator m (WTA m) genWTA :: Generator m (WTA m) genWTA = asks zeroPolicy >>= \case genWTA = asks zeroPolicy >>= \case OutDegree d -> WTA <\$> asks spec <*> genStates <*> (genTransitions' d) NumTransitions d -> WTA <\$> asks spec <*> genStates <*> (genTransitions' d) Percentage _ -> WTA <\$> asks spec <*> genStates <*> genTransitions ZeroFrequency _ -> WTA <\$> asks spec <*> genStates <*> genTransitions
 ... @@ -32,7 +32,7 @@ data Opts = Opts ... @@ -32,7 +32,7 @@ data Opts = Opts { optMonoid :: SomeMonoid { optMonoid :: SomeMonoid , optStates :: Int , optStates :: Int , optSymbols :: SymbolSpec , optSymbols :: SymbolSpec , optZeroFrequency :: ZeroFrequency , optEdgeConfig :: EdgeConfig , optRandomState :: Maybe StdGen , optRandomState :: Maybe StdGen , optDifferentValues :: Maybe Int , optDifferentValues :: Maybe Int } } ... @@ -104,9 +104,9 @@ parseOpts = ... @@ -104,9 +104,9 @@ parseOpts = ) ) ) ) parseZeroFreq :: Options.Parser ZeroFrequency parseZeroFreq :: Options.Parser EdgeConfig parseZeroFreq = parseZeroFreq = (Percentage <\$> Options.option (ZeroFrequency <\$> Options.option (Options.eitherReader readProbability) (Options.eitherReader readProbability) ( Options.long "zero-frequency" ( Options.long "zero-frequency" <> Options.showDefault <> Options.showDefault ... @@ -116,13 +116,12 @@ parseZeroFreq = ... @@ -116,13 +116,12 @@ parseZeroFreq = "Frequency of edges with zero weight as number between 0 and 1." "Frequency of edges with zero weight as number between 0 and 1." ) ) ) ) <|> (OutDegree <\$> Options.option <|> (NumTransitions <\$> Options.option Options.auto Options.auto ( Options.long "out-degree" ( Options.long "transitions" <> Options.metavar "NUM_TRANSITIONS" <> Options.metavar "NUM" <> Options.help <> Options.help ("Expected number of outgoing transitions per state." ("Number of transitions to generate. They will be distributed randomly over states." <> " This calculates the zero frequency from the number of states, symbols and this parameter." ) ) ) ) ) ) ... @@ -134,9 +133,9 @@ withSpec opts f = case optMonoid opts of ... @@ -134,9 +133,9 @@ withSpec opts f = case optMonoid opts of , numSymbols = optSymbols opts , numSymbols = optSymbols opts } } computeProbability :: WTASpec m -> ZeroFrequency -> Probability computeProbability :: WTASpec m -> EdgeConfig -> Probability computeProbability _ (Percentage p) = p computeProbability _ (ZeroFrequency p) = p computeProbability spec (OutDegree d) = computeProbability spec (NumTransitions d) = let n = numStates spec let n = numStates spec t = V.sum (V.imap (\i syms -> syms * n ^ i) (numSymbols spec)) t = V.sum (V.imap (\i syms -> syms * n ^ i) (numSymbols spec)) in fromRationalApprox (1 - fromIntegral d / fromIntegral t) in fromRationalApprox (1 - fromIntegral d / fromIntegral t) ... @@ -157,10 +156,10 @@ main = do ... @@ -157,10 +156,10 @@ main = do withSpec opts \$ \spec -> do withSpec opts \$ \spec -> do randGen <- getStdGen randGen <- getStdGen -- let zeroFreq = computeProbability spec (optZeroFrequency opts) -- let zeroFreq = computeProbability spec (optEdgeConfig opts) -- hPutStrLn stderr \$ "p hacking: " ++ show zeroFreq -- hPutStrLn stderr \$ "p hacking: " ++ show zeroFreq wta <- runGenerator wta <- runGenerator (GeneratorConfig spec (optZeroFrequency opts) (optDifferentValues opts)) (GeneratorConfig spec (optEdgeConfig opts) (optDifferentValues opts)) genWTA genWTA putStrLn \$ "# Random state for this automaton: '" <> show randGen <> "'" putStrLn \$ "# Random state for this automaton: '" <> show randGen <> "'" T.putStr (Build.toLazyText (buildWTA wta)) T.putStr (Build.toLazyText (buildWTA wta))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!