Flint2-Examples-0.1.0.0: app/real_roots/Main.hs
{-# language OverloadedStrings #-}
import Data.Typeable
import Options.Applicative
import Options.Applicative.Help.Pretty hiding (char)
import Text.ParserCombinators.ReadP hiding (option, between, optional)
import Control.Monad
import Control.Monad.State
import Foreign.Ptr
import Foreign.ForeignPtr
import Foreign.C.Types
import Foreign.Marshal.Array
import Foreign.Marshal.Alloc
import Foreign.Storable
import Data.Char
import Data.Number.Flint hiding (airy)
import Functions
import FFI
import Run
main :: IO ()
main = run =<< customExecParser (prefs showHelpOnEmpty) opts where
opts = info (parameters <**> helper)
( fullDesc
<> header "\nRoot finding (real roots).\n"
<> progDescDoc (Just desc))
desc = vcat funs
funs =
[ "Examples of root finding for some examples (0..7)."
, " 0 Z(x), Z-function (Riemann zeta or Dirichlet L-function)"
, " 1 sin(x)"
, " 2 sin(x^2)"
, " 3 sin(1/x)"
, " 4 Ai(x), Airy function"
, " 5 Ai'(x), Airy function"
, " 6 Bi(x), Airy function"
, " 7 Bi'(x), Airy function"
, "With 0, specify optional Dirichlet character with \
\[-character q n]"
]
-- Parser ----------------------------------------------------------------------
parameters :: Parser Parameters
parameters = Parameters
<$> argument (between 0 7) (
help "function"
<> metavar "FUNCTION")
<*> option auto (
help "a"
<> long "xa"
<> metavar "A")
<*> option auto (
help "b"
<> long "xb"
<> metavar "B")
<*> optional optionDC
<*> option auto (
help "refine "
<> long "refine"
<> value 0
<> metavar "DIGITS")
<*> option pos (
help "verbose"
<> long "verbose"
<> short 'v'
<> value 0
<> metavar "VERBOSE")
<*> option auto (
help "maximal depth"
<> long "maxdepth"
<> value 30
<> metavar "MAX-DEPTH")
<*> option auto (
help "maximal number of evaluations"
<> long "maxeval"
<> value 100000
<> metavar "MAX-EVAL")
<*> option auto (
help "maximal number of zeros to be found"
<> long "maxfound"
<> value 100000
<> metavar "MAX-FOUND")
<*> option auto (
help "precision"
<> long "precision"
<> short 'p'
<> value 64
<> metavar "PRECISION")
optionDC = option dc (
help "Dirichlet character for L-function. Specify in the form q.r, \
\e.g. 12.7"
<> long "character")
pos :: (Read a, Integral a) => ReadM a
pos = eitherReader $ \s -> do
let result = read s
if result >= 0 then
Right result
else
Left "expected positive number"
between a b = eitherReader $ \s -> do
let result = read s
if a <= result && result <= b then
Right result
else
Left $ "expected number in range [" ++ show a ++ " .. " ++ show b ++ "]."
-- read Dirichlet Character ----------------------------------------------------
dc :: ReadM DC
dc = eitherReader $ \s -> do
let chi@(DC p r) = read s
if p > 0 && r >= 0 then
Right chi
else
Left "expected Dirichlet character, specified as p.r"
instance Read DC where
readsPrec _ = readP_to_S parseChar
parseChar = do
p <- read <$> munch1 isNumber
char '.'
q <- read <$> munch1 isNumber
return $ DC p q
-- testing ---------------------------------------------------------------------
testZParam = do
g <- newDirichletGroup 12
c <- newDirichletChar g
withDirichletGroup g $ \g -> do
withDirichletChar c $ \c -> do
print g
print c
dirichlet_char_print g c
putStr "\n"
params <- malloc :: IO (Ptr CZParam)
poke params (CZParam g c)
putStrLn "alloc works."
let ptr = castPtr params :: Ptr ()
print ptr
CZParam u v <- peek (castPtr ptr :: Ptr CZParam)
putStrLn "new pointer."
print u
print v
dirichlet_char_print u v
putStr "\n"
poke params (CZParam nullPtr nullPtr)
CZParam u v <- peek (castPtr ptr :: Ptr CZParam)
putStrLn "new pointer."
print u
print v
putStr "\n"
free params
return ()