packages feed

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

import Options.Applicative
import Control.Monad
import System.TimeIt
import Foreign.C.Types

import Data.Number.Flint

main = timeItNamed "binet"
     $ run =<< customExecParser (prefs showHelpOnEmpty) opts where
  desc = "This program computes the n-th Fibonacci number using Binet’s formula"
  opts = info (parameters <**> helper) (
         fullDesc
      <> progDesc desc
      <> header desc)

run params@(Parameters n limit) = do

  ctx <- newCaCtx

  [sqrt5, phi, psi, t, u] <- replicateM 5 (newCa ctx)

  withCaCtx ctx $  \ctx -> do
    case limit of
      Just prec -> ca_ctx_set_option ctx ca_opt_prec_limit prec
      _         -> return ()
    withCa sqrt5 $ \sqrt5 -> do
      withCa phi $ \phi -> do
        withCa psi $ \psi -> do
          withCa t $ \t -> do
            withCa u $ \u -> do
              ca_sqrt_ui sqrt5 5 ctx
              ca_add_ui phi sqrt5 1 ctx
              ca_div_ui phi phi 2 ctx
              ca_ui_sub psi 1 phi ctx
              withFmpz n $ \n -> do
                ca_pow_fmpz t phi n ctx
                ca_pow_fmpz u psi n ctx
              ca_sub t t u ctx
              ca_div t t sqrt5 ctx
              ca_print t ctx; putStr "\n"

-- Parser ----------------------------------------------------------------------

data Parameters = Parameters {
    n :: Fmpz
  , limit :: Maybe CLong
} deriving Show

parameters :: Parser Parameters
parameters = Parameters
  <$> argument auto (
      help "nth power"
   <> metavar "n")
  <*> optional optionLimit

optionLimit = option auto (
      help "limiting precision"
   <> long "limit"
   <> metavar "limit")