import System.CPUTime import Foreign.Marshal.Alloc import Foreign.Marshal.Array import Foreign.C.Types import Foreign.Storable import Control.Monad import Text.Printf import Data.Number.Flint main = do let n = 12376 n_poly = (fromIntegral n) `div` 26 m = 17^26 :: Fmpz state <- newFRandState ctx <- newFmpzModCtx m r <- newFmpzModPoly ctx t <- newFmpzModPoly ctx makePolynomials n m state r t ctx radixInfo n m r t ctx radix <- timeItNamed "precomputation" $ do newFmpzModPolyRadix r (n + 1) ctx b <- _fmpz_mod_poly_vec_init (fromIntegral n + 1) ctx timeItNamed "conversion" $ do withFmpzModPoly t $ \t -> do withFmpzModCtx ctx $ \ctx -> do withFmpzModPolyRadix radix $ \radix -> do fmpz_mod_poly_radix b t radix ctx -- forM_ [0..10] $ \j -> do -- p <- peek (b `advancePtr` j) -- fmpz_mod_poly_print p ctx -- putStr "\n" _fmpz_mod_poly_vec_clear b (n_poly + 1) ctx radixInfo n m r t ctx = do withFmpzModPoly r $ \r -> do withFmpzModPoly t $ \t -> do withFmpzModCtx ctx $ \ctx -> do deg <- fmpz_mod_poly_degree r ctx polDeg <- fmpz_mod_poly_degree t ctx (_, bits) <- withFmpz m fmpz_bits putStrLn "Radix conversion\n\ \-----------------" putStrLn $ " Degree of the radix: " ++ show deg putStrLn $ " Bit size of the modulus: " ++ show bits putStrLn $ " Degree of the input: " ++ show polDeg putStr "\n" return () makePolynomials n m state r t ctx = do withFmpzModPoly r $ \r -> do withFmpzModPoly t $ \t -> do withNewFmpzModPoly ctx $ \u -> do withNewFmpzModPoly ctx $ \v -> do withFmpzModCtx ctx $ \ctx -> do fmpz_mod_poly_set_coeff_ui u 3 5 ctx fmpz_mod_poly_set_coeff_ui u 4 4 ctx fmpz_mod_poly_set_coeff_ui v 0 1 ctx fmpz_mod_poly_set_coeff_ui v 2 1 ctx fmpz_mod_poly_set_coeff_ui v 3 5 ctx fmpz_mod_poly_set_coeff_ui v 4 1 ctx fmpz_mod_poly_set_coeff_ui v 5 5 ctx fmpz_mod_poly_set_coeff_ui v 8 8 ctx fmpz_mod_poly_set_coeff_ui v 9 8 ctx fmpz_mod_poly_set_coeff_ui v 10 5 ctx fmpz_mod_poly_set_coeff_ui v 12 6 ctx fmpz_mod_poly_set_coeff_ui v 13 1 ctx fmpz_mod_poly_pow r u 3 ctx withNewFmpz $ \a -> do fmpz_set_ui a 4 fmpz_mod_poly_scalar_mul_fmpz r r a ctx fmpz_set_ui a 27 fmpz_mod_poly_scalar_mul_fmpz t t a ctx fmpz_mod_poly_add r r t ctx withFRandState state $ \state -> do fmpz_mod_poly_randtest t state (fromIntegral n + 1) ctx return () timeItNamed :: String -> IO a -> IO a timeItNamed s f = do t0 <- getCPUTime result <- f t1 <- getCPUTime let dt = fromIntegral (t1 - t0) / 10^9 :: Double printf "%s: %.6f ms\n" s dt return result _fmpz_mod_poly_vec_init :: Int -> FmpzModCtx -> IO (Ptr (Ptr CFmpzModPoly)) _fmpz_mod_poly_vec_init n ctx = do vec <- mallocArray n :: IO (Ptr (Ptr CFmpzModPoly)) result <- forM [0 .. fromIntegral n - 1] $ \j -> do poly <- malloc :: IO (Ptr CFmpzModPoly) withFmpzModCtx ctx $ \ctx -> do fmpz_mod_poly_init poly ctx return poly pokeArray vec result return vec _fmpz_mod_poly_vec_clear :: (Ptr (Ptr CFmpzModPoly)) -> Int -> FmpzModCtx -> IO () _fmpz_mod_poly_vec_clear vec n ctx = do withFmpzModCtx ctx $ \ctx -> do forM [0 .. fromIntegral n - 1] $ \j -> do p <- peek (vec `advancePtr` j) fmpz_mod_poly_clear p ctx return ()