Flint2-Examples-0.1.0.0: app/multi_crt/Main.hs
{-# language ScopedTypeVariables #-}
import Options.Applicative
import Control.Monad
import Foreign.C.Types
import Foreign.Ptr
import Foreign.Marshal.Array
import Foreign.Storable
import Data.Number.Flint
main = run =<< customExecParser (prefs showHelpOnEmpty) opts where
desc = "Reconstruct integer using the chinese remainder theorem."
hdesc = "Fast tree version of the integer Chinese Remainder code."
opts = info (parameters <**> helper) (
fullDesc
<> progDesc desc
<> header desc)
run params@(Parameters n num_primes) = do
print params
primes <- mapM n_nth_prime [1..fromIntegral num_primes]
withArray primes $ \primes -> do
comb <- newFmpzComb (castPtr primes) (fromIntegral num_primes)
withFmpzComb comb $ \comb -> do
comb_temp <- newFmpzCombTemp comb
withFmpzCombTemp comb_temp $ \comb_temp -> do
withFmpz n $ \x -> do
withNewFmpz $ \y -> do
allocaArray num_primes $ \(residues :: Ptr CLong) -> do
-- Reduce modulo all primes
fmpz_multi_mod_ui (castPtr residues) x comb comb_temp
-- Reconstruct
fmpz_multi_CRT_ui y (castPtr residues) comb comb_temp 1
forM_ [0 .. fromIntegral num_primes - 1] $ \i -> do
p <- peek (primes `advancePtr` i)
r <- peek (residues `advancePtr` i)
putStrLn $ "residue mod " ++ show p ++ " = " ++ show r
putStr "reconstruction = "
fmpz_print y
putStr "\n"
data Parameters = Parameters {
n :: Fmpz
, num_primes :: Int
} deriving Show
parameters :: Parser Parameters
parameters = Parameters
<$> argument auto (
help "n to be reconstructed"
<> metavar "n")
<*> option auto (
help "number of primes [2, 3, ...] to use"
<> long "np"
<> value 1
<> metavar "num_primes")