Paralleles Rabin-Miller
This is -*- Literate Haskell -*-
Autor: Oleg Lobachev
\begin{code}
module Main where
import RabinMiller
import FarmUntil
import System.IO.Unsafe (unsafePerformIO)
import System (getArgs)
import Debug.Trace (trace)
import Text.Printf (printf)
\end{code}
\begin{code}
import Parallel.Skel.EdenSkel (map_par, map_farm)
import Parallel.Eden (noPe)
\end{code}
\begin{seqcode}
module RabinMiller where
-- Autor: Kent Kwee
-- [...]
-- | Rabin-Miller
-- | Fuehre 20 Iterationen durch für Fehlerwahrscheinlichkeit < 0.25 ^ 20
listRabinMiller :: Integer -- ^ n ist der Primzahlkandidat
-> [Integer] -- ^ die Liste mit den Basen fuer RabinMiller
-> Maybe Integer -- ^ Die Ausgabe (Nothing: keine Primzahl, Just n: Moegliche Primzahl)
listRabinMiller n as
| (n<3) = error "N must be greater than 3."
| (n `mod` 2 == 0) = error "N must be odd."
| otherwise = listRabinMiller2 n as 20
\end{seqcode}
\begin{code}
listRabinMillerP :: Int
-> Integer
-> [Integer]
-> Maybe Integer
listRabinMillerP k n as
| (n<3) = error "N must be greater than 3."
| (n `mod` 2 == 0) = error "N must be odd."
| otherwise = listRabinMillerP2 n as k
\end{code}
\begin{seqcode}
-- | RabinMiller für feste Basen a aus einer Integerliste
listRabinMiller2 :: Integer -- ^ n ist der Primzahlkandidat
-> [Integer] -- ^ die Liste mit den Basen fuer RabinMiller
-> Integer -- ^ Restliche Durchlaeufe
-> Maybe Integer -- ^ Die Ausgabe (Nothing: keine Primzahl, Just n: Moegliche Primzahl)
listRabinMiller2 n (a:as) c
| (c==0) = Just n
| (singleRabinMillerBool n t 0 b) = listRabinMiller2 n as (c-1)
| otherwise = Nothing
where ((q,t),b) = (zerlege(n-1,0) , powermod a q n)
\end{seqcode}
\begin{code}
listRabinMillerP2 :: Integer
-> [Integer]
-> Int
-> Maybe Integer
listRabinMillerP2 n as k = let f :: (Integer, Integer) -> Bool
f (n, a) = singleRabinMillerBool n t 0 b
where ((q,t),b) = (zerlege(n1,0) , powermod a q n)
tasks = take k $ [(n, a) | a<-as]
res = trace ("Need to do " ++ (show k) ++ " iterations, "
++ "have data for " ++ (show $ length tasks) ) $
farmUntilBool f tasks
in case res of
True -> Just n
False -> Nothing
\end{code}
Sequentielles Code.
\begin{code}
rabinMillerPIO :: Integer
-> IO (Maybe Integer)
rabinMillerPIO n = do
ls <- randomBaseList n
let s = listRabinMillerP 20 n ls
return s
rabinMillerP :: Integer
-> Maybe Integer
rabinMillerP n = unsafePerformIO $ rabinMillerPIO n
\end{code}
Testen.
\begin{code}
createCandidate k = 2^k1
doIt = rabinMillerP
main = do
args <- getArgs
let k = read $ head args
n = createCandidate k
res = doIt n
putStrLn $ "Testing " ++ show n
putStrLn $ "Working " ++ " at " ++ show noPe ++ " PEs."
print res
putStrLn "done"
\end{code}