bollu/symengine.hs

View on GitHub
src/Symengine/NumberTheory.hs

Summary

Maintainability
Test Coverage

{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE FunctionalDependencies #-}

module Symengine.NumberTheory(
  Symengine.NumberTheory.gcd,
  Symengine.NumberTheory.lcm,
  gcd_extended,
  next_prime,
  Symengine.NumberTheory.mod,
  quotient,
  quotient_and_mod,
  mod_f,
  quotient_f,
  quotient_and_mod_f,
  mod_inverse,
  fibonacci,
  fibonacci2,
  lucas,
  -- I do not understand exactly what lucas2 does. Clarify and then
  -- export 
  -- lucas2,
  binomial,
  factorial
)
where

import Foreign.C.Types
import Foreign.Ptr
import Foreign.C.String
import Foreign.Storable
import Foreign.Marshal.Array
import Foreign.Marshal.Alloc
import Foreign.ForeignPtr
import Control.Applicative
import Control.Monad -- for foldM
import System.IO.Unsafe
import Control.Monad
import GHC.Real

import Symengine.Internal
import Symengine.BasicSym


gcd :: BasicSym -> BasicSym -> BasicSym
gcd = lift_basicsym_binaryop ntheory_gcd_ffi

lcm :: BasicSym -> BasicSym -> BasicSym
lcm = lift_basicsym_binaryop ntheory_lcm_ffi

gcd_extended :: BasicSym -> BasicSym -> (BasicSym, BasicSym, BasicSym)
gcd_extended a b = unsafePerformIO $ do
  g <- basicsym_new
  s <- basicsym_new
  t <- basicsym_new

  with4 g s t a (\g s t a ->
                    with b (\b ->
                              ntheory_gcd_ext_ffi g s t a b))
  return (g, s, t)
  
next_prime :: BasicSym -> BasicSym
next_prime = lift_basicsym_unaryop ntheory_nextprime_ffi

type Quotient = BasicSym
type Modulo = BasicSym

mod :: BasicSym -> BasicSym -> Quotient
mod = lift_basicsym_binaryop ntheory_mod_ffi

quotient :: BasicSym -> BasicSym -> BasicSym
quotient = lift_basicsym_binaryop ntheory_quotient_ffi

quotient_and_mod :: BasicSym -> BasicSym -> (Quotient, Modulo)
quotient_and_mod a b = unsafePerformIO $ do
  quotient <- basicsym_new
  modulo <- basicsym_new
  with4 quotient modulo a b ntheory_quotient_mod_ffi
  return $  (quotient, modulo)


mod_f :: BasicSym -> BasicSym -> Quotient
mod_f = lift_basicsym_binaryop ntheory_mod_f_ffi

quotient_f :: BasicSym -> BasicSym -> BasicSym
quotient_f = lift_basicsym_binaryop ntheory_quotient_f_ffi

quotient_and_mod_f :: BasicSym -> BasicSym -> (Quotient, Modulo)
quotient_and_mod_f a b = unsafePerformIO $ do
  quotient <- basicsym_new
  modulo <- basicsym_new
  with4 quotient modulo a b ntheory_quotient_mod_f_ffi
  return $  (quotient, modulo)


mod_inverse :: BasicSym -> BasicSym -> Quotient
mod_inverse = lift_basicsym_binaryop ntheory_mod_inverse_ffi


fibonacci ::  Int -> BasicSym
fibonacci i = unsafePerformIO $  do
  fib <- basicsym_new
  with fib (\fib -> ntheory_fibonacci_ffi fib (fromIntegral i))
  return fib

fibonacci2 :: Int -> (BasicSym, BasicSym)
fibonacci2 n  = unsafePerformIO $ do
  g <- basicsym_new
  s <- basicsym_new
  
  with2 g s (\g s -> ntheory_fibonacci2_ffi g s (fromIntegral n))
  
  return (g, s) 


lucas :: Int -> BasicSym
lucas n = unsafePerformIO $ do
  l <- basicsym_new
  with l (\l -> ntheory_lucas_ffi l (fromIntegral n))
  return l

{-
lucas2 :: BasicSym -> BasicSym -> (BasicSym, BasicSym)
lucas2 n n_prev = unsafePerformIO $ do
  g <- basicsym_new
  s <- basicsym_new

  with4 g s n n_prev ntheory_lucas2_ffi
  
  return (g, s) 
-}
binomial :: BasicSym -> Int -> BasicSym
binomial n r = unsafePerformIO $ do
  ncr <- basicsym_new
  with2 ncr n (\ncr n -> ntheory_binomial_ffi ncr n (fromIntegral r))
  return ncr


factorial :: Int -> BasicSym
factorial n = unsafePerformIO $ do
  fact <- basicsym_new
  with fact (\fact -> ntheory_factorial_ffi fact (fromIntegral n))
  return fact
-- FFI Bindings
-- gcd, lcm

foreign import ccall "symengine/cwrapper.h ntheory_gcd" ntheory_gcd_ffi :: 
  Ptr CBasicSym -> Ptr CBasicSym -> Ptr CBasicSym -> IO CInt

foreign import ccall "symengine/cwrapper.h ntheory_lcm" ntheory_lcm_ffi :: 
  Ptr CBasicSym -> Ptr CBasicSym -> Ptr CBasicSym -> IO CInt

foreign import ccall "symengine/cwrapper.h ntheory_gcd_ext" ntheory_gcd_ext_ffi 
  :: Ptr CBasicSym -> Ptr CBasicSym -> Ptr CBasicSym -> 
      Ptr CBasicSym -> Ptr CBasicSym -> IO CInt

-- prime

foreign import ccall "symengine/cwrapper.h ntheory_nextprime"
  ntheory_nextprime_ffi :: Ptr CBasicSym -> Ptr CBasicSym -> IO CInt

-- modulus

foreign import ccall "symengine/cwrapper.h ntheory_mod"
  ntheory_mod_ffi :: Ptr CBasicSym -> Ptr CBasicSym -> Ptr CBasicSym -> IO CInt


foreign import ccall "symengine/cwrapper.h ntheory_quotient"
  ntheory_quotient_ffi :: Ptr CBasicSym -> Ptr CBasicSym -> Ptr CBasicSym -> IO CInt

foreign import ccall "symengine/cwrapper.h ntheory_quotient_mod"
  ntheory_quotient_mod_ffi :: Ptr CBasicSym -> Ptr CBasicSym -> 
                          Ptr CBasicSym -> Ptr CBasicSym -> IO CInt


-- _f versions (round towards -inf)
foreign import ccall "symengine/cwrapper.h ntheory_mod_f"
  ntheory_mod_f_ffi :: Ptr CBasicSym -> Ptr CBasicSym -> Ptr CBasicSym -> IO CInt


foreign import ccall "symengine/cwrapper.h ntheory_quotient_f"
  ntheory_quotient_f_ffi :: Ptr CBasicSym -> Ptr CBasicSym -> Ptr CBasicSym -> IO CInt

foreign import ccall "symengine/cwrapper.h ntheory_quotient_mod_f"
  ntheory_quotient_mod_f_ffi :: Ptr CBasicSym -> Ptr CBasicSym -> 
                          Ptr CBasicSym -> Ptr CBasicSym -> IO CInt

-- mod inverse
foreign import ccall "symengine/cwrapper.h ntheory_mod_inverse"
  ntheory_mod_inverse_ffi :: Ptr CBasicSym -> Ptr CBasicSym -> Ptr CBasicSym -> IO CInt


-- fibonacci
foreign import ccall "symengine/cwrapper.h ntheory_fibonacci"
  ntheory_fibonacci_ffi :: Ptr CBasicSym -> 
    CULong -> IO CInt


foreign import ccall "symengine/cwrapper.h ntheory_fibonacci2"
  ntheory_fibonacci2_ffi :: Ptr CBasicSym -> Ptr CBasicSym ->  
    CULong -> IO CInt

-- lucas
foreign import ccall "symengine/cwrapper.h ntheory_lucas"
  ntheory_lucas_ffi :: Ptr CBasicSym ->
    CULong -> IO CInt


foreign import ccall "symengine/cwrapper.h ntheory_lucas2"
  ntheory_lucas2_ffi :: Ptr CBasicSym -> Ptr CBasicSym ->  
     CULong -> IO CInt


-- binomial
foreign import ccall "symengine/cwrapper.h ntheory_binomial"
  ntheory_binomial_ffi :: Ptr CBasicSym -> Ptr CBasicSym ->  
    CULong -> IO CInt

-- factorial
foreign import ccall "symengine/cwrapper.h ntheory_factorial"
  ntheory_factorial_ffi :: Ptr CBasicSym -> 
    CULong -> IO CInt