packages feed

Flint2-Examples-0.1.0.0: app/keiper_li/Main.hs

import System.IO
import System.TimeIt

import Control.Monad 
import Options.Applicative

import Foreign.C.Types
import Foreign.C.String
import Foreign.Marshal.Alloc (free) 
import Foreign.Marshal.Array (advancePtr)

import Data.Number.Flint

main = timeItNamed "time"
     $ run =<< customExecParser (prefs showHelpOnEmpty) opts where
  desc = "Calculates keipers series."
  opts = info (parameters <**> helper) (
         fullDesc
      <> progDesc desc
      <> header desc)

run params@(Parameters n prec num_threads outFile) = do
  print params
  
  flint_set_num_threads num_threads
  
  let len = n + 1
      workingPrecision = case prec of
        Just p  -> p
        Nothing -> round (1.1 * fromIntegral len + 50)
  print workingPrecision
  z <- _arb_vec_init len

  keiper_li_series z len workingPrecision

  case outFile of
    Just fileName -> do
      mode <- newCString "w"
      out_file_name <- newCString fileName
      fp <- fopen out_file_name mode
      withNewFmpz $ \man -> do
        withNewFmpz $ \exp -> do
          withNewArf $ \t -> do
            forM_ [0 .. fromIntegral len - 1] $ \j -> do
            
              arf_get_fmpz_2exp man exp (arb_midref (z `advancePtr` j))
              
              withCString (show j ++ " ") $ \s -> do fputs s fp
              fmpz_fprint fp man
              withCString " " $ \s -> fputs s fp
              fmpz_fprint fp exp
              withCString " +/- " $ \s -> fputs s fp
              
              arf_set_mag t (arb_radref (z `advancePtr` j))
              arf_get_fmpz_2exp man exp t

              fmpz_fprint fp man
              withCString " " $ \s -> fputs s fp
              fmpz_fprint fp exp
              withCString "\n" $ \s -> fputs s fp
      fclose fp
      mapM_ free [mode, out_file_name]
      return ()
    Nothing -> do               
      forM_ [0 .. len - 1] $ \j -> do
        putStr $ show j ++ ": "
        arb_printd (z `advancePtr` (fromIntegral j)) 50
        putStr "\n"

-- c file ----------------------------------------------------------------------

foreign import ccall "stdio.h fopen"
  fopen :: CString -> CString -> IO (Ptr CFile)

foreign import ccall "stdio.h fclose"
  fclose :: Ptr CFile -> IO CInt

foreign import ccall "stdio.h fputs"
  fputs :: CString -> Ptr CFile -> IO CInt

data Parameters = Parameters {
    n :: CLong
  , prec :: Maybe CLong
  , num_threads :: CInt
  , outFile :: Maybe String
} deriving Show

parameters :: Parser Parameters
parameters = Parameters
  <$> argument auto (
      help "n"
   <> metavar "n")
  <*> optional optionPrecision
  <*> option auto (
      help "number of threads"
   <> long "threads"
   <> value 1
   <> metavar "threads")
  <*> optional optionOutput

optionPrecision = option auto  (
      help "precision"
   <> long "prec"
   <> short 'p'
   <> metavar "precision")

optionOutput = strOption (
      help "output file"
   <> short 'o'
   <> metavar "write output to file")

--------------------------------------------------------------------------------

keiper_li_series z len prec = do

  t <- _arb_vec_init len
  u <- _arb_vec_init len
  v <- _arb_vec_init len

  timeItNamed "zeta: " $ do 
    arb_zero t
    arb_one (next t)
    arb_one u
    _arb_poly_zeta_series v t 2 u 0 len prec
    _arb_vec_neg v v len

  timeItNamed "log: " $ do
    _arb_poly_log_series t v len len prec

  -- add log(gamma(1+s/2))
  timeItNamed "gamma: " $ do
    arb_one u
    arb_one (next u)
    arb_mul_2exp_si (next u) (next u) (-1)
    _arb_poly_lgamma_series v u 2 len prec
    _arb_vec_add t t v len prec

  -- subtract 0.5 s log(pi)
  arb_const_pi u prec
  arb_log u u prec
  arb_mul_2exp_si u u (-1)
  arb_sub (next t) (next t) u prec

  -- add log(1-s)
  arb_one u
  arb_set_si (next u) (-1)
  _arb_poly_log_series v u 2 len prec
  _arb_vec_add t t v len prec

  timeItNamed "binomial transform: " $ do
    arb_set z t
    _arb_vec_neg (next t) (next t) (len - 1)
    _arb_poly_binomial_transform (next z) (next t) (len - 1) (len - 1) prec
    
next x = x `advancePtr` 1