Flint2-0.1.0.0: src/Data/Number/Flint/Acb/ComplexField.hs
module Data.Number.Flint.Acb.ComplexField (
CF(..)
, RF'(..)
, Special (..)
, realPart
, imagPart
-- * Polar form
, mkPolar
, cis
, polar
, magnitude
, phase
-- * Conjugate
, conjugate
) where
import GHC.TypeLits
import Data.Proxy
import Data.Ratio
import System.IO.Unsafe
import Control.Monad
import Foreign.C.String
import Foreign.C.Types
import Foreign.ForeignPtr
import Foreign.Ptr ( Ptr, FunPtr, castPtr )
import Foreign.Storable
import Foreign.Marshal ( free )
import Foreign.Marshal.Array ( advancePtr )
import Data.Number.Flint.Fmpz
import Data.Number.Flint.Fmpz.Instances
import Data.Number.Flint.Arb
import Data.Number.Flint.Arb.RealField
import Data.Number.Flint.Arb.Types
import Data.Number.Flint.Acb
import Data.Number.Flint.Acb.Acf
import Data.Number.Flint.Acb.Types
import Data.Number.Flint.Acb.Hypgeom
import Data.Number.Flint.Acb.Modular
import Data.Number.Flint.Acb.Elliptic
import Data.Number.Flint.Support.D.Interval
newtype CF (n :: Nat) = CF Acb
realPart :: forall n. KnownNat n => (CF n) -> (RF n)
realPart (CF z) = unsafePerformIO $ do
res <- newArb
withArb res $ \res -> do
withAcb z $ \z -> do
acb_get_real res z
return $ RF res
imagPart :: forall n. KnownNat n => (CF n) -> (RF n)
imagPart (CF z) = unsafePerformIO $ do
res <- newArb
withArb res $ \res -> do
withAcb z $ \z -> do
acb_get_imag res z
return $ RF res
mkPolar :: forall n. KnownNat n => (RF n) -> (RF n) -> (CF n)
mkPolar (RF r) (RF theta) = unsafePerformIO $ do
let prec = fromInteger $ natVal (Proxy :: Proxy n)
res <- newAcb
withAcb res $ \res -> do
withArb r $ \r -> do
withArb theta $ \theta -> do
withNewArb $ \x -> do
withNewArb $ \y -> do
arb_sin_cos y x theta prec
arb_mul x x r prec
arb_mul y y r prec
acb_set_arb_arb res x y
return $ CF res
cis :: forall n. KnownNat n => (RF n) -> (CF n)
cis (RF theta) = unsafePerformIO $ do
let prec = fromInteger $ natVal (Proxy :: Proxy n)
res <- newAcb
withAcb res $ \res -> do
withArb theta $ \theta -> do
withNewArb $ \x -> do
withNewArb $ \y -> do
arb_sin_cos y x theta prec
acb_set_arb_arb res x y
return $ CF res
polar :: forall n. KnownNat n => (CF n) -> (RF n, RF n)
polar z = (magnitude z, phase z)
magnitude :: forall n. KnownNat n => (CF n) -> (RF n)
magnitude (CF z) = unsafePerformIO $ do
let prec = fromInteger $ natVal (Proxy :: Proxy n)
res <- newArb
withArb res $ \res -> do
withAcb z $ \z -> do
acb_abs res z prec
return $ RF res
phase :: forall n. KnownNat n => (CF n) -> (RF n)
phase (CF z) = unsafePerformIO $ do
let prec = fromInteger $ natVal (Proxy :: Proxy n)
res <- newArb
withArb res $ \res -> do
withAcb z $ \z -> do
acb_arg res z prec
return $ RF res
conjugate :: forall n. KnownNat n => (CF n) -> (CF n)
conjugate (CF z) = unsafePerformIO $ do
res <- newAcb
withAcb res $ \res -> do
withAcb z $ \z -> do
acb_conj res z
return $ CF res
instance forall n. KnownNat n => Eq (CF n) where
{-# INLINE (==) #-}
(==) = liftCmp acb_eq
{-# INLINE (/=) #-}
(/=) = liftCmp acb_ne
instance forall n. KnownNat n => Ord (CF n) where
compare = undefined
instance forall n. KnownNat n => Num (CF n) where
{-# INLINE (+) #-}
(+) = lift2 acb_add
{-# INLINE (-) #-}
(-) = lift2 acb_sub
{-# INLINE (*) #-}
(*) = lift2 acb_mul
{-# INLINE negate #-}
negate = lift1 acb_neg
abs = undefined
{-# INLINE fromInteger #-}
fromInteger x = unsafePerformIO $ do
result <- newAcb
let prec = fromInteger $ natVal (Proxy :: Proxy n)
withAcb result $ \result -> do
acb_set_ui result (fromIntegral x)
return (CF result)
signum = undefined
instance forall n. KnownNat n => Fractional (CF n) where
{-# INLINE (/) #-}
(/) = lift2 acb_div
fromRational x = p / q where
p = fromIntegral (numerator x) :: CF n
q = fromIntegral (denominator x) :: CF n
instance forall n. KnownNat n => Real (CF n) where
toRational = undefined
instance forall n. KnownNat n => RealFrac (CF n) where
properFraction = undefined
instance forall n. KnownNat n => Floating (CF n) where
pi = liftConstant arb_const_pi
exp = liftF1 acb_exp
log = liftF1 acb_log
sqrt = liftF1 acb_sqrt
sin = liftF1 acb_sin
cos = liftF1 acb_cos
tan = liftF1 acb_tan
asin = liftF1 acb_asin
acos = liftF1 acb_acos
atan = liftF1 acb_atan
sinh = liftF1 acb_sinh
cosh = liftF1 acb_cosh
tanh = liftF1 acb_tanh
asinh = liftF1 acb_asinh
acosh = liftF1 acb_acosh
atanh = liftF1 acb_atanh
instance forall n. KnownNat n => Show (CF n) where
show (CF x) = unsafePerformIO $ do
let prec = fromInteger $ natVal (Proxy :: Proxy n)
digits = floor (fromIntegral prec * logBase 10 2)
(_, cstr) <- withAcb x $ \p ->
acb_get_strn p (fromIntegral digits) arb_str_no_radius
str <- peekCString cstr
return str
------------------------------------------------------------------------
instance forall n. KnownNat n => Special (CF n) where
gamma = liftF1 acb_gamma
digamma = liftF1 acb_digamma
lgamma = liftF1 acb_hypgeom_lgamma
zeta = liftF1 acb_zeta
erf = liftF1 acb_hypgeom_erf
airy (CF x) = unsafePerformIO $ do
let prec = fromInteger $ natVal (Proxy :: Proxy n)
ai <- newAcb
ai' <- newAcb
bi <- newAcb
bi' <- newAcb
withAcb x $ \x ->
withAcb ai $ \ai ->
withAcb ai' $ \ai' ->
withAcb bi $ \bi ->
withAcb bi' $ \bi' ->
acb_hypgeom_airy ai ai' bi bi' x prec
return $ (CF ai, CF ai', CF bi, CF bi')
airyZeros = undefined
besselJ = lift2 acb_hypgeom_bessel_j
besselY = lift2 acb_hypgeom_bessel_y
besselI = lift2 acb_hypgeom_bessel_i
besselK = lift2 acb_hypgeom_bessel_k
modj = liftF1 acb_modular_j
modjq = undefined
modeta = liftF1 acb_modular_eta
modetaq = undefined
modlambda = liftF1 acb_modular_lambda
modlambdaq = undefined
ellipp = lift2 acb_elliptic_p
ellipzeta = lift2 acb_elliptic_zeta
ellipsigma = lift2 acb_elliptic_sigma
barnesg = liftF1 acb_barnes_g
agm = lift2 acb_agm
fresnels = undefined
fresnelc = undefined
instance forall n. KnownNat n => RF' (CF n) where
euler = liftConstant arb_const_euler
glaisher = liftConstant arb_const_glaisher
catalan = liftConstant arb_const_catalan
khinchin = liftConstant arb_const_khinchin
polylog = lift2 acb_polylog
midPoint = lift1 acb_get_mid
-- lifting -------------------------------------------------------------
type Binary = Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CLong -> IO ()
type Cmp = Ptr CAcb -> Ptr CAcb -> IO CInt
type Function = Ptr CAcb -> Ptr CAcb -> IO ()
lift2 :: forall n. KnownNat n => Binary -> CF n -> CF n -> CF n
lift2 f (CF a) (CF b) = unsafePerformIO $ do
let prec = fromInteger $ natVal (Proxy :: Proxy n)
c <- newAcb
withAcb a $ \a ->
withAcb b $ \b ->
withAcb c $ \c ->
f c a b (CLong prec)
return (CF c)
lift1 :: forall n. KnownNat n => Function -> CF n -> CF n
lift1 f (CF x) = unsafePerformIO $ do
y <- newAcb
withAcb x $ \x -> withAcb y $ \y -> f y x
return (CF y)
lift0 f x = CF $ unsafePerformIO $ fst <$> withNewAcb (`f` x)
liftF1 :: forall n. KnownNat n =>
(Ptr CAcb -> Ptr CAcb -> CLong -> IO ()) -> CF n -> CF n
liftF1 f (CF x) = unsafePerformIO $ do
let prec = fromInteger $ natVal (Proxy :: Proxy n)
y <- newAcb
withAcb x $ \x -> withAcb y $ \y -> f y x (CLong prec)
return (CF y)
liftCmp :: forall n. KnownNat n => Cmp -> CF n -> CF n -> Bool
liftCmp f (CF x) (CF y) = unsafePerformIO $ do
(_, (_, cmp)) <- withAcb x $ \x -> withAcb y $ \y -> f x y
return (cmp == 1)
liftProp :: forall n. KnownNat n => (Ptr CAcb -> IO CInt) -> CF n -> Bool
liftProp f (CF x) = unsafePerformIO $ do
(_, prop) <- withAcb x $ \x -> f x
return (prop == 1)
liftConstant :: forall n. KnownNat n => (Ptr CArb -> CLong -> IO ()) -> CF n
liftConstant f = CF $ fst $ snd $ unsafePerformIO $ do
let prec = fromInteger $ natVal (Proxy :: Proxy n)
tmp <- newArb
withArb tmp $ \tmp -> do
f tmp prec
withNewAcb (`acb_set_arb` tmp)