{-# LANGUAGE CPP                   #-}
{-# LANGUAGE ConstraintKinds       #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE GADTs                 #-}
{-# LANGUAGE MagicHash             #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms       #-}
{-# LANGUAGE RebindableSyntax      #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TypeApplications      #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE TypeOperators         #-}
{-# LANGUAGE TypeSynonymInstances  #-}
{-# LANGUAGE UndecidableInstances  #-}
{-# LANGUAGE ViewPatterns          #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
-- |
-- Module      : Data.Array.Accelerate.Data.Complex
-- Copyright   : [2015..2020] The Accelerate Team
-- License     : BSD3
--
-- Maintainer  : Trevor L. McDonell <trevor.mcdonell@gmail.com>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)
--
-- Complex numbers, stored in the usual C-style array-of-struct representation,
-- for easy interoperability.
--
module Data.Array.Accelerate.Data.Complex (

  -- * Rectangular from
  Complex(..), pattern (::+),
  real,
  imag,

  -- * Polar form
  mkPolar,
  cis,
  polar,
  magnitude, magnitude',
  phase,

  -- * Conjugate
  conjugate,

) where

import Data.Array.Accelerate.Classes.Eq
import Data.Array.Accelerate.Classes.Floating
import Data.Array.Accelerate.Classes.Fractional
import Data.Array.Accelerate.Classes.FromIntegral
import Data.Array.Accelerate.Classes.Num
import Data.Array.Accelerate.Classes.Ord
import Data.Array.Accelerate.Classes.RealFloat
import Data.Array.Accelerate.Data.Functor
import Data.Array.Accelerate.Pattern
import Data.Array.Accelerate.Prelude
import Data.Array.Accelerate.Representation.Tag
import Data.Array.Accelerate.Representation.Type
import Data.Array.Accelerate.Representation.Vec
import Data.Array.Accelerate.Smart
import Data.Array.Accelerate.Sugar.Elt
import Data.Array.Accelerate.Sugar.Vec
import Data.Array.Accelerate.Type
import Data.Primitive.Vec

import Data.Complex                                                 ( Complex(..) )
import Prelude                                                      ( ($) )
import qualified Data.Complex                                       as C
import qualified Prelude                                            as P
#if __GLASGOW_HASKELL__ >= 904
import Data.Type.Equality
#endif


infix 6 ::+
pattern (::+) :: Elt a => Exp a -> Exp a -> Exp (Complex a)
pattern r $m::+ :: forall {r} {a}.
Elt a =>
Exp (Complex a) -> (Exp a -> Exp a -> r) -> ((# #) -> r) -> r
$b::+ :: forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ i <- (deconstructComplex -> (r, i))
  where (::+) = Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
constructComplex
{-# COMPLETE (::+) #-}


-- Use an array-of-structs representation for complex numbers if possible.
-- This matches the standard C-style layout, but we can use this representation only at
-- specific types (not for any type 'a') as we can only have vectors of primitive type.
-- For other types, we use a structure-of-arrays representation. This is handled by the
-- ComplexR. We use the GADT ComplexR and function complexR to reconstruct
-- information on how the elements are represented.
--
instance Elt a => Elt (Complex a) where
  type EltR (Complex a) = ComplexR (EltR a)
  eltR :: TypeR (EltR (Complex a))
eltR = let tR :: TypeR (EltR a)
tR = forall a. Elt a => TypeR (EltR a)
eltR @a
          in case TypeR (EltR a) -> ComplexType (EltR a) (ComplexR (EltR a))
forall a. TypeR a -> ComplexType a (ComplexR a)
complexR TypeR (EltR a)
tR of
               ComplexVec SingleType (EltR a)
s -> ScalarType (EltR (Complex a)) -> TypeR (EltR (Complex a))
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ScalarType (EltR (Complex a)) -> TypeR (EltR (Complex a)))
-> ScalarType (EltR (Complex a)) -> TypeR (EltR (Complex a))
forall a b. (a -> b) -> a -> b
$ VectorType (Vec 2 (EltR a)) -> ScalarType (Vec 2 (EltR a))
forall (n :: Nat) a1.
VectorType (Vec n a1) -> ScalarType (Vec n a1)
VectorScalarType (VectorType (Vec 2 (EltR a)) -> ScalarType (Vec 2 (EltR a)))
-> VectorType (Vec 2 (EltR a)) -> ScalarType (Vec 2 (EltR a))
forall a b. (a -> b) -> a -> b
$ Int -> SingleType (EltR a) -> VectorType (Vec 2 (EltR a))
forall (n :: Nat) a1.
KnownNat n =>
Int -> SingleType a1 -> VectorType (Vec n a1)
VectorType Int
2 SingleType (EltR a)
s
               ComplexType (EltR a) (ComplexR (EltR a))
ComplexTup   -> TupR ScalarType ()
forall (s :: * -> *). TupR s ()
TupRunit TupR ScalarType ()
-> TypeR (EltR a) -> TupR ScalarType ((), EltR a)
forall (s :: * -> *) a1 b. TupR s a1 -> TupR s b -> TupR s (a1, b)
`TupRpair` TypeR (EltR a)
tR TupR ScalarType ((), EltR a)
-> TypeR (EltR a) -> TupR ScalarType (((), EltR a), EltR a)
forall (s :: * -> *) a1 b. TupR s a1 -> TupR s b -> TupR s (a1, b)
`TupRpair` TypeR (EltR a)
tR

  tagsR :: [TagR (EltR (Complex a))]
tagsR = let tR :: TypeR (EltR a)
tR = forall a. Elt a => TypeR (EltR a)
eltR @a
           in case TypeR (EltR a) -> ComplexType (EltR a) (ComplexR (EltR a))
forall a. TypeR a -> ComplexType a (ComplexR a)
complexR TypeR (EltR a)
tR of
               ComplexVec SingleType (EltR a)
s -> [ ScalarType (Vec 2 (EltR a)) -> TagR (Vec 2 (EltR a))
forall a. ScalarType a -> TagR a
TagRsingle (VectorType (Vec 2 (EltR a)) -> ScalarType (Vec 2 (EltR a))
forall (n :: Nat) a1.
VectorType (Vec n a1) -> ScalarType (Vec n a1)
VectorScalarType (Int -> SingleType (EltR a) -> VectorType (Vec 2 (EltR a))
forall (n :: Nat) a1.
KnownNat n =>
Int -> SingleType a1 -> VectorType (Vec n a1)
VectorType Int
2 SingleType (EltR a)
s)) ]
               ComplexType (EltR a) (ComplexR (EltR a))
ComplexTup   -> let go :: TypeR t -> [TagR t]
                                   go :: forall t. TypeR t -> [TagR t]
go TupR ScalarType t
TupRunit         = [TagR t
TagR ()
TagRunit]
                                   go (TupRsingle ScalarType t
s)   = [ScalarType t -> TagR t
forall a. ScalarType a -> TagR a
TagRsingle ScalarType t
s]
                                   go (TupRpair TupR ScalarType a1
ta TupR ScalarType b
tb) = [TagR a1 -> TagR b -> TagR (a1, b)
forall a1 b. TagR a1 -> TagR b -> TagR (a1, b)
TagRpair TagR a1
a TagR b
b | TagR a1
a <- TupR ScalarType a1 -> [TagR a1]
forall t. TypeR t -> [TagR t]
go TupR ScalarType a1
ta, TagR b
b <- TupR ScalarType b -> [TagR b]
forall t. TypeR t -> [TagR t]
go TupR ScalarType b
tb]
                                in
                                [ TagR ()
TagRunit TagR () -> TagR (EltR a) -> TagR ((), EltR a)
forall a1 b. TagR a1 -> TagR b -> TagR (a1, b)
`TagRpair` TagR (EltR a)
ta TagR ((), EltR a) -> TagR (EltR a) -> TagR (((), EltR a), EltR a)
forall a1 b. TagR a1 -> TagR b -> TagR (a1, b)
`TagRpair` TagR (EltR a)
tb | TagR (EltR a)
ta <- TypeR (EltR a) -> [TagR (EltR a)]
forall t. TypeR t -> [TagR t]
go TypeR (EltR a)
tR, TagR (EltR a)
tb <- TypeR (EltR a) -> [TagR (EltR a)]
forall t. TypeR t -> [TagR t]
go TypeR (EltR a)
tR ]

  toElt :: EltR (Complex a) -> Complex a
toElt = case TypeR (EltR a) -> ComplexType (EltR a) (ComplexR (EltR a))
forall a. TypeR a -> ComplexType a (ComplexR a)
complexR (TypeR (EltR a) -> ComplexType (EltR a) (ComplexR (EltR a)))
-> TypeR (EltR a) -> ComplexType (EltR a) (ComplexR (EltR a))
forall a b. (a -> b) -> a -> b
$ forall a. Elt a => TypeR (EltR a)
eltR @a of
    ComplexVec SingleType (EltR a)
_ -> \(Vec2 EltR a
r EltR a
i)   -> EltR a -> a
forall a. Elt a => EltR a -> a
toElt EltR a
r a -> a -> Complex a
forall a. a -> a -> Complex a
:+ EltR a -> a
forall a. Elt a => EltR a -> a
toElt EltR a
i
    ComplexType (EltR a) (ComplexR (EltR a))
ComplexTup   -> \(((), EltR a
r), EltR a
i) -> EltR a -> a
forall a. Elt a => EltR a -> a
toElt EltR a
r a -> a -> Complex a
forall a. a -> a -> Complex a
:+ EltR a -> a
forall a. Elt a => EltR a -> a
toElt EltR a
i

  fromElt :: Complex a -> EltR (Complex a)
fromElt (a
r :+ a
i) = case TypeR (EltR a) -> ComplexType (EltR a) (ComplexR (EltR a))
forall a. TypeR a -> ComplexType a (ComplexR a)
complexR (TypeR (EltR a) -> ComplexType (EltR a) (ComplexR (EltR a)))
-> TypeR (EltR a) -> ComplexType (EltR a) (ComplexR (EltR a))
forall a b. (a -> b) -> a -> b
$ forall a. Elt a => TypeR (EltR a)
eltR @a of
    ComplexVec SingleType (EltR a)
_ -> EltR a -> EltR a -> Vec 2 (EltR a)
forall a. Prim a => a -> a -> Vec2 a
Vec2 (a -> EltR a
forall a. Elt a => a -> EltR a
fromElt a
r) (a -> EltR a
forall a. Elt a => a -> EltR a
fromElt a
i)
    ComplexType (EltR a) (ComplexR (EltR a))
ComplexTup   -> (((), a -> EltR a
forall a. Elt a => a -> EltR a
fromElt a
r), a -> EltR a
forall a. Elt a => a -> EltR a
fromElt a
i)

type family ComplexR a where
  ComplexR Half   = Vec2 Half
  ComplexR Float  = Vec2 Float
  ComplexR Double = Vec2 Double
  ComplexR Int    = Vec2 Int
  ComplexR Int8   = Vec2 Int8
  ComplexR Int16  = Vec2 Int16
  ComplexR Int32  = Vec2 Int32
  ComplexR Int64  = Vec2 Int64
  ComplexR Word   = Vec2 Word
  ComplexR Word8  = Vec2 Word8
  ComplexR Word16 = Vec2 Word16
  ComplexR Word32 = Vec2 Word32
  ComplexR Word64 = Vec2 Word64
  ComplexR a      = (((), a), a)

-- This isn't ideal because we gather the evidence based on the
-- representation type, so we really get the evidence (VecElt (EltR a)),
-- which is not very useful...
--    - TLM 2020-07-16
data ComplexType a c where
  ComplexVec :: VecElt a => SingleType a -> ComplexType a (Vec2 a)
  ComplexTup ::                             ComplexType a (((), a), a)

complexR :: TypeR a -> ComplexType a (ComplexR a)
complexR :: forall a. TypeR a -> ComplexType a (ComplexR a)
complexR = TypeR a -> ComplexType a (ComplexR a)
forall a. TypeR a -> ComplexType a (ComplexR a)
tuple
  where
    tuple :: TypeR a -> ComplexType a (ComplexR a)
    tuple :: forall a. TypeR a -> ComplexType a (ComplexR a)
tuple TupR ScalarType a
TupRunit       = ComplexType a (((), a), a)
ComplexType a (ComplexR a)
forall a. ComplexType a (((), a), a)
ComplexTup
    tuple TupRpair{}     = ComplexType a (((), a), a)
ComplexType a (ComplexR a)
forall a. ComplexType a (((), a), a)
ComplexTup
    tuple (TupRsingle ScalarType a
s) = ScalarType a -> ComplexType a (ComplexR a)
forall a. ScalarType a -> ComplexType a (ComplexR a)
scalar ScalarType a
s

    scalar :: ScalarType a -> ComplexType a (ComplexR a)
    scalar :: forall a. ScalarType a -> ComplexType a (ComplexR a)
scalar (SingleScalarType SingleType a
t) = SingleType a -> ComplexType a (ComplexR a)
forall a. SingleType a -> ComplexType a (ComplexR a)
single SingleType a
t
    scalar VectorScalarType{}   = ComplexType a (((), a), a)
ComplexType a (ComplexR a)
forall a. ComplexType a (((), a), a)
ComplexTup

    single :: SingleType a -> ComplexType a (ComplexR a)
    single :: forall a. SingleType a -> ComplexType a (ComplexR a)
single (NumSingleType NumType a
t) = NumType a -> ComplexType a (ComplexR a)
forall a. NumType a -> ComplexType a (ComplexR a)
num NumType a
t

    num :: NumType a -> ComplexType a (ComplexR a)
    num :: forall a. NumType a -> ComplexType a (ComplexR a)
num (IntegralNumType IntegralType a
t) = IntegralType a -> ComplexType a (ComplexR a)
forall a. IntegralType a -> ComplexType a (ComplexR a)
integral IntegralType a
t
    num (FloatingNumType FloatingType a
t) = FloatingType a -> ComplexType a (ComplexR a)
forall a. FloatingType a -> ComplexType a (ComplexR a)
floating FloatingType a
t

    integral :: IntegralType a -> ComplexType a (ComplexR a)
    integral :: forall a. IntegralType a -> ComplexType a (ComplexR a)
integral IntegralType a
TypeInt    = SingleType a -> ComplexType a (Vec2 a)
forall a. VecElt a => SingleType a -> ComplexType a (Vec2 a)
ComplexVec SingleType a
forall a. IsSingle a => SingleType a
singleType
    integral IntegralType a
TypeInt8   = SingleType a -> ComplexType a (Vec2 a)
forall a. VecElt a => SingleType a -> ComplexType a (Vec2 a)
ComplexVec SingleType a
forall a. IsSingle a => SingleType a
singleType
    integral IntegralType a
TypeInt16  = SingleType a -> ComplexType a (Vec2 a)
forall a. VecElt a => SingleType a -> ComplexType a (Vec2 a)
ComplexVec SingleType a
forall a. IsSingle a => SingleType a
singleType
    integral IntegralType a
TypeInt32  = SingleType a -> ComplexType a (Vec2 a)
forall a. VecElt a => SingleType a -> ComplexType a (Vec2 a)
ComplexVec SingleType a
forall a. IsSingle a => SingleType a
singleType
    integral IntegralType a
TypeInt64  = SingleType a -> ComplexType a (Vec2 a)
forall a. VecElt a => SingleType a -> ComplexType a (Vec2 a)
ComplexVec SingleType a
forall a. IsSingle a => SingleType a
singleType
    integral IntegralType a
TypeWord   = SingleType a -> ComplexType a (Vec2 a)
forall a. VecElt a => SingleType a -> ComplexType a (Vec2 a)
ComplexVec SingleType a
forall a. IsSingle a => SingleType a
singleType
    integral IntegralType a
TypeWord8  = SingleType a -> ComplexType a (Vec2 a)
forall a. VecElt a => SingleType a -> ComplexType a (Vec2 a)
ComplexVec SingleType a
forall a. IsSingle a => SingleType a
singleType
    integral IntegralType a
TypeWord16 = SingleType a -> ComplexType a (Vec2 a)
forall a. VecElt a => SingleType a -> ComplexType a (Vec2 a)
ComplexVec SingleType a
forall a. IsSingle a => SingleType a
singleType
    integral IntegralType a
TypeWord32 = SingleType a -> ComplexType a (Vec2 a)
forall a. VecElt a => SingleType a -> ComplexType a (Vec2 a)
ComplexVec SingleType a
forall a. IsSingle a => SingleType a
singleType
    integral IntegralType a
TypeWord64 = SingleType a -> ComplexType a (Vec2 a)
forall a. VecElt a => SingleType a -> ComplexType a (Vec2 a)
ComplexVec SingleType a
forall a. IsSingle a => SingleType a
singleType

    floating :: FloatingType a -> ComplexType a (ComplexR a)
    floating :: forall a. FloatingType a -> ComplexType a (ComplexR a)
floating FloatingType a
TypeHalf   = SingleType a -> ComplexType a (Vec2 a)
forall a. VecElt a => SingleType a -> ComplexType a (Vec2 a)
ComplexVec SingleType a
forall a. IsSingle a => SingleType a
singleType
    floating FloatingType a
TypeFloat  = SingleType a -> ComplexType a (Vec2 a)
forall a. VecElt a => SingleType a -> ComplexType a (Vec2 a)
ComplexVec SingleType a
forall a. IsSingle a => SingleType a
singleType
    floating FloatingType a
TypeDouble = SingleType a -> ComplexType a (Vec2 a)
forall a. VecElt a => SingleType a -> ComplexType a (Vec2 a)
ComplexVec SingleType a
forall a. IsSingle a => SingleType a
singleType


constructComplex :: forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
constructComplex :: forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
constructComplex Exp a
r Exp a
i =
  case TypeR (EltR a) -> ComplexType (EltR a) (ComplexR (EltR a))
forall a. TypeR a -> ComplexType a (ComplexR a)
complexR (forall a. Elt a => TypeR (EltR a)
eltR @a) of
    ComplexType (EltR a) (ComplexR (EltR a))
ComplexTup   -> Exp (a, a) -> Exp (Complex a)
forall a b. (EltR a ~ EltR b) => Exp a -> Exp b
coerce (Exp (a, a) -> Exp (Complex a)) -> Exp (a, a) -> Exp (Complex a)
forall a b. (a -> b) -> a -> b
$ Exp a -> Exp a -> Exp (a, a)
forall (con :: * -> *) x0 x1.
IsPattern con (x0, x1) (con x0, con x1) =>
con x0 -> con x1 -> con (x0, x1)
T2 Exp a
r Exp a
i
    ComplexVec SingleType (EltR a)
_ -> Exp (EltR a) -> Exp (EltR a) -> Exp (Complex a)
forall (con :: * -> *) vec x0 x1.
IsVector con vec (con x0, con x1) =>
con x0 -> con x1 -> con vec
V2 (forall a b. (EltR a ~ EltR b) => Exp a -> Exp b
coerce @a @(EltR a) Exp a
r) (forall a b. (EltR a ~ EltR b) => Exp a -> Exp b
coerce @a @(EltR a) Exp a
i)

deconstructComplex :: forall a. Elt a => Exp (Complex a) -> (Exp a, Exp a)
deconstructComplex :: forall a. Elt a => Exp (Complex a) -> (Exp a, Exp a)
deconstructComplex c :: Exp (Complex a)
c@(Exp SmartExp (EltR (Complex a))
c') =
  case TypeR (EltR a) -> ComplexType (EltR a) (ComplexR (EltR a))
forall a. TypeR a -> ComplexType a (ComplexR a)
complexR (forall a. Elt a => TypeR (EltR a)
eltR @a) of
    ComplexType (EltR a) (ComplexR (EltR a))
ComplexTup   -> let T2 Exp a
r Exp a
i = Exp (Complex a) -> Exp (a, a)
forall a b. (EltR a ~ EltR b) => Exp a -> Exp b
coerce Exp (Complex a)
c in (Exp a
r, Exp a
i)
    ComplexVec SingleType (EltR a)
t -> let T2 Exp a
r Exp a
i = SmartExp (EltR (a, a)) -> Exp (a, a)
forall t. SmartExp (EltR t) -> Exp t
Exp (PreSmartExp SmartAcc SmartExp (((), EltR a), EltR a)
-> SmartExp (((), EltR a), EltR a)
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (VecR (1 + 1) (EltR a) (((), EltR a), EltR a)
-> SmartExp (Vec (1 + 1) (EltR a))
-> PreSmartExp SmartAcc SmartExp (((), EltR a), EltR a)
forall (n :: Nat) s t (exp :: * -> *) (acc :: * -> *).
KnownNat n =>
VecR n s t -> exp (Vec n s) -> PreSmartExp acc exp t
VecUnpack (VecR 1 (EltR a) ((), EltR a)
-> VecR (1 + 1) (EltR a) (((), EltR a), EltR a)
forall (n1 :: Nat) single t.
VecR n1 single t -> VecR (n1 + 1) single (t, single)
VecRsucc (VecR 0 (EltR a) () -> VecR (0 + 1) (EltR a) ((), EltR a)
forall (n1 :: Nat) single t.
VecR n1 single t -> VecR (n1 + 1) single (t, single)
VecRsucc (SingleType (EltR a) -> VecR 0 (EltR a) ()
forall single. SingleType single -> VecR 0 single ()
VecRnil SingleType (EltR a)
t))) SmartExp (Vec (1 + 1) (EltR a))
SmartExp (EltR (Complex a))
c'))
                     in (Exp a
r, Exp a
i)

coerce :: EltR a ~ EltR b => Exp a -> Exp b
coerce :: forall a b. (EltR a ~ EltR b) => Exp a -> Exp b
coerce (Exp SmartExp (EltR a)
e) = SmartExp (EltR b) -> Exp b
forall t. SmartExp (EltR t) -> Exp t
Exp SmartExp (EltR a)
SmartExp (EltR b)
e

instance (Lift Exp a, Elt (Plain a)) => Lift Exp (Complex a) where
  type Plain (Complex a) = Complex (Plain a)
  lift :: Complex a -> Exp (Plain (Complex a))
lift (a
r :+ a
i) = a -> Exp (Plain a)
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift a
r Exp (Plain a) -> Exp (Plain a) -> Exp (Complex (Plain a))
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ a -> Exp (Plain a)
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift a
i

instance Elt a => Unlift Exp (Complex (Exp a)) where
  unlift :: Exp (Plain (Complex (Exp a))) -> Complex (Exp a)
unlift (Exp a
r ::+ Exp a
i) = Exp a
r Exp a -> Exp a -> Complex (Exp a)
forall a. a -> a -> Complex a
:+ Exp a
i


instance Eq a => Eq (Complex a) where
  Exp a
r1 ::+ Exp a
c1 == :: Exp (Complex a) -> Exp (Complex a) -> Exp Bool
== Exp a
r2 ::+ Exp a
c2 = Exp a
r1 Exp a -> Exp a -> Exp Bool
forall a. Eq a => Exp a -> Exp a -> Exp Bool
== Exp a
r2 Exp Bool -> Exp Bool -> Exp Bool
&& Exp a
c1 Exp a -> Exp a -> Exp Bool
forall a. Eq a => Exp a -> Exp a -> Exp Bool
== Exp a
c2
  Exp a
r1 ::+ Exp a
c1 /= :: Exp (Complex a) -> Exp (Complex a) -> Exp Bool
/= Exp a
r2 ::+ Exp a
c2 = Exp a
r1 Exp a -> Exp a -> Exp Bool
forall a. Eq a => Exp a -> Exp a -> Exp Bool
/= Exp a
r2 Exp Bool -> Exp Bool -> Exp Bool
|| Exp a
c1 Exp a -> Exp a -> Exp Bool
forall a. Eq a => Exp a -> Exp a -> Exp Bool
/= Exp a
c2

instance RealFloat a => P.Num (Exp (Complex a)) where
  + :: Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
(+)    = (Complex (Exp a) -> Complex (Exp a) -> Complex (Exp a))
-> Exp (Plain (Complex (Exp a)))
-> Exp (Plain (Complex (Exp a)))
-> Exp (Plain (Complex (Exp a)))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Complex (Exp a) -> Complex (Exp a) -> Complex (Exp a)
forall a. Num a => a -> a -> a
(+) :: Complex (Exp a) -> Complex (Exp a) -> Complex (Exp a))
  (-)    = (Complex (Exp a) -> Complex (Exp a) -> Complex (Exp a))
-> Exp (Plain (Complex (Exp a)))
-> Exp (Plain (Complex (Exp a)))
-> Exp (Plain (Complex (Exp a)))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 ((-) :: Complex (Exp a) -> Complex (Exp a) -> Complex (Exp a))
  * :: Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
(*)    = (Complex (Exp a) -> Complex (Exp a) -> Complex (Exp a))
-> Exp (Plain (Complex (Exp a)))
-> Exp (Plain (Complex (Exp a)))
-> Exp (Plain (Complex (Exp a)))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Complex (Exp a) -> Complex (Exp a) -> Complex (Exp a)
forall a. Num a => a -> a -> a
(*) :: Complex (Exp a) -> Complex (Exp a) -> Complex (Exp a))
  negate :: Exp (Complex a) -> Exp (Complex a)
negate = (Complex (Exp a) -> Complex (Exp a))
-> Exp (Plain (Complex (Exp a))) -> Exp (Plain (Complex (Exp a)))
forall a b.
(Unlift Exp a, Lift Exp b) =>
(a -> b) -> Exp (Plain a) -> Exp (Plain b)
lift1 (Complex (Exp a) -> Complex (Exp a)
forall a. Num a => a -> a
negate :: Complex (Exp a) -> Complex (Exp a))
  signum :: Exp (Complex a) -> Exp (Complex a)
signum z :: Exp (Complex a)
z@(Exp a
x ::+ Exp a
y) =
    if Exp (Complex a)
z Exp (Complex a) -> Exp (Complex a) -> Exp Bool
forall a. Eq a => Exp a -> Exp a -> Exp Bool
== Exp (Complex a)
0
       then Exp (Complex a)
z
       else let r :: Exp a
r = Exp (Complex a) -> Exp a
forall a. RealFloat a => Exp (Complex a) -> Exp a
magnitude Exp (Complex a)
z
             in Exp a
xExp a -> Exp a -> Exp a
forall a. Fractional a => a -> a -> a
/Exp a
r Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
yExp a -> Exp a -> Exp a
forall a. Fractional a => a -> a -> a
/Exp a
r
  abs :: Exp (Complex a) -> Exp (Complex a)
abs Exp (Complex a)
z         = Exp (Complex a) -> Exp a
forall a. RealFloat a => Exp (Complex a) -> Exp a
magnitude Exp (Complex a)
z Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
0
  fromInteger :: Integer -> Exp (Complex a)
fromInteger Integer
n = Integer -> Exp a
forall a. Num a => Integer -> a
fromInteger Integer
n Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
0

instance RealFloat a => P.Fractional (Exp (Complex a)) where
  fromRational :: Rational -> Exp (Complex a)
fromRational Rational
x  = Rational -> Exp a
forall a. Fractional a => Rational -> a
fromRational Rational
x Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
0
  Exp (Complex a)
z / :: Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
/ Exp (Complex a)
z'          = (Exp a
xExp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
x''Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
+Exp a
yExp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
y'') Exp a -> Exp a -> Exp a
forall a. Fractional a => a -> a -> a
/ Exp a
d Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ (Exp a
yExp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
x''Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
-Exp a
xExp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
y'') Exp a -> Exp a -> Exp a
forall a. Fractional a => a -> a -> a
/ Exp a
d
    where
      Exp a
x  :+ Exp a
y   = Exp (Plain (Complex (Exp a))) -> Complex (Exp a)
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift Exp (Complex a)
Exp (Plain (Complex (Exp a)))
z
      Exp a
x' :+ Exp a
y'  = Exp (Plain (Complex (Exp a))) -> Complex (Exp a)
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift Exp (Complex a)
Exp (Plain (Complex (Exp a)))
z'
      --
      x'' :: Exp a
x'' = Exp Int -> Exp a -> Exp a
forall a. RealFloat a => Exp Int -> Exp a -> Exp a
scaleFloat Exp Int
k Exp a
x'
      y'' :: Exp a
y'' = Exp Int -> Exp a -> Exp a
forall a. RealFloat a => Exp Int -> Exp a -> Exp a
scaleFloat Exp Int
k Exp a
y'
      k :: Exp Int
k   = - Exp Int -> Exp Int -> Exp Int
forall a. Ord a => Exp a -> Exp a -> Exp a
max (Exp a -> Exp Int
forall a. RealFloat a => Exp a -> Exp Int
exponent Exp a
x') (Exp a -> Exp Int
forall a. RealFloat a => Exp a -> Exp Int
exponent Exp a
y')
      d :: Exp a
d   = Exp a
x'Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
x'' Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
+ Exp a
y'Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
y''

instance RealFloat a => P.Floating (Exp (Complex a)) where
  pi :: Exp (Complex a)
pi                = Exp a
forall a. Floating a => a
pi Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
0
  exp :: Exp (Complex a) -> Exp (Complex a)
exp (Exp a
x ::+ Exp a
y)     = let expx :: Exp a
expx = Exp a -> Exp a
forall a. Floating a => a -> a
exp Exp a
x
                       in Exp a
expx Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
* Exp a -> Exp a
forall a. Floating a => a -> a
cos Exp a
y Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
expx Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
* Exp a -> Exp a
forall a. Floating a => a -> a
sin Exp a
y
  log :: Exp (Complex a) -> Exp (Complex a)
log Exp (Complex a)
z             = Exp a -> Exp a
forall a. Floating a => a -> a
log (Exp (Complex a) -> Exp a
forall a. RealFloat a => Exp (Complex a) -> Exp a
magnitude Exp (Complex a)
z) Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp (Complex a) -> Exp a
forall a. RealFloat a => Exp (Complex a) -> Exp a
phase Exp (Complex a)
z
  sqrt :: Exp (Complex a) -> Exp (Complex a)
sqrt z :: Exp (Complex a)
z@(Exp a
x ::+ Exp a
y)  =
    if Exp (Complex a)
z Exp (Complex a) -> Exp (Complex a) -> Exp Bool
forall a. Eq a => Exp a -> Exp a -> Exp Bool
== Exp (Complex a)
0
      then Exp (Complex a)
0
      else Exp a
u Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ (Exp a
y Exp a -> Exp a -> Exp Bool
forall a. Ord a => Exp a -> Exp a -> Exp Bool
< Exp a
0 Exp Bool -> (Exp a, Exp a) -> Exp a
forall t. Elt t => Exp Bool -> (Exp t, Exp t) -> Exp t
? (-Exp a
v, Exp a
v))
    where
      T2 Exp a
u Exp a
v = Exp a
x Exp a -> Exp a -> Exp Bool
forall a. Ord a => Exp a -> Exp a -> Exp Bool
< Exp a
0 Exp Bool -> (Exp (a, a), Exp (a, a)) -> Exp (a, a)
forall t. Elt t => Exp Bool -> (Exp t, Exp t) -> Exp t
? (Exp a -> Exp a -> Exp (a, a)
forall (con :: * -> *) x0 x1.
IsPattern con (x0, x1) (con x0, con x1) =>
con x0 -> con x1 -> con (x0, x1)
T2 Exp a
v' Exp a
u', Exp a -> Exp a -> Exp (a, a)
forall (con :: * -> *) x0 x1.
IsPattern con (x0, x1) (con x0, con x1) =>
con x0 -> con x1 -> con (x0, x1)
T2 Exp a
u' Exp a
v')
      v' :: Exp a
v'     = Exp a -> Exp a
forall a. Num a => a -> a
abs Exp a
y Exp a -> Exp a -> Exp a
forall a. Fractional a => a -> a -> a
/ (Exp a
u'Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
2)
      u' :: Exp a
u'     = Exp a -> Exp a
forall a. Floating a => a -> a
sqrt ((Exp (Complex a) -> Exp a
forall a. RealFloat a => Exp (Complex a) -> Exp a
magnitude Exp (Complex a)
z Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
+ Exp a -> Exp a
forall a. Num a => a -> a
abs Exp a
x) Exp a -> Exp a -> Exp a
forall a. Fractional a => a -> a -> a
/ Exp a
2)

  Exp (Complex a)
x ** :: Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
** Exp (Complex a)
y =
    if Exp (Complex a)
y Exp (Complex a) -> Exp (Complex a) -> Exp Bool
forall a. Eq a => Exp a -> Exp a -> Exp Bool
== Exp (Complex a)
0 then Exp (Complex a)
1 else
    if Exp (Complex a)
x Exp (Complex a) -> Exp (Complex a) -> Exp Bool
forall a. Eq a => Exp a -> Exp a -> Exp Bool
== Exp (Complex a)
0 then if Exp a
exp_r Exp a -> Exp a -> Exp Bool
forall a. Ord a => Exp a -> Exp a -> Exp Bool
> Exp a
0 then Exp (Complex a)
0 else
                   if Exp a
exp_r Exp a -> Exp a -> Exp Bool
forall a. Ord a => Exp a -> Exp a -> Exp Bool
< Exp a
0 then Exp a
inf Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
0
                                else Exp a
nan Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
nan
              else if Exp a -> Exp Bool
forall a. RealFloat a => Exp a -> Exp Bool
isInfinite Exp a
r Exp Bool -> Exp Bool -> Exp Bool
|| Exp a -> Exp Bool
forall a. RealFloat a => Exp a -> Exp Bool
isInfinite Exp a
i
                     then if Exp a
exp_r Exp a -> Exp a -> Exp Bool
forall a. Ord a => Exp a -> Exp a -> Exp Bool
> Exp a
0 then Exp a
inf Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
0 else
                          if Exp a
exp_r Exp a -> Exp a -> Exp Bool
forall a. Ord a => Exp a -> Exp a -> Exp Bool
< Exp a
0 then Exp (Complex a)
0
                                       else Exp a
nan Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
nan
                     else Exp (Complex a) -> Exp (Complex a)
forall a. Floating a => a -> a
exp (Exp (Complex a) -> Exp (Complex a)
forall a. Floating a => a -> a
log Exp (Complex a)
x Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
* Exp (Complex a)
y)
    where
      Exp a
r     ::+ Exp a
i  = Exp (Complex a)
x
      Exp a
exp_r ::+ Exp a
_  = Exp (Complex a)
y
      --
      inf :: Exp a
inf = Exp a
1 Exp a -> Exp a -> Exp a
forall a. Fractional a => a -> a -> a
/ Exp a
0
      nan :: Exp a
nan = Exp a
0 Exp a -> Exp a -> Exp a
forall a. Fractional a => a -> a -> a
/ Exp a
0

  sin :: Exp (Complex a) -> Exp (Complex a)
sin (Exp a
x ::+ Exp a
y)  = Exp a -> Exp a
forall a. Floating a => a -> a
sin Exp a
x Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
* Exp a -> Exp a
forall a. Floating a => a -> a
cosh Exp a
y Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a -> Exp a
forall a. Floating a => a -> a
cos Exp a
x Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
* Exp a -> Exp a
forall a. Floating a => a -> a
sinh Exp a
y
  cos :: Exp (Complex a) -> Exp (Complex a)
cos (Exp a
x ::+ Exp a
y)  = Exp a -> Exp a
forall a. Floating a => a -> a
cos Exp a
x Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
* Exp a -> Exp a
forall a. Floating a => a -> a
cosh Exp a
y Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ (- Exp a -> Exp a
forall a. Floating a => a -> a
sin Exp a
x Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
* Exp a -> Exp a
forall a. Floating a => a -> a
sinh Exp a
y)
  tan :: Exp (Complex a) -> Exp (Complex a)
tan (Exp a
x ::+ Exp a
y)  = (Exp a
sinxExp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
coshy Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
cosxExp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
sinhy) Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Fractional a => a -> a -> a
/ (Exp a
cosxExp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
coshy Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ (-Exp a
sinxExp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
sinhy))
    where
      sinx :: Exp a
sinx  = Exp a -> Exp a
forall a. Floating a => a -> a
sin Exp a
x
      cosx :: Exp a
cosx  = Exp a -> Exp a
forall a. Floating a => a -> a
cos Exp a
x
      sinhy :: Exp a
sinhy = Exp a -> Exp a
forall a. Floating a => a -> a
sinh Exp a
y
      coshy :: Exp a
coshy = Exp a -> Exp a
forall a. Floating a => a -> a
cosh Exp a
y

  sinh :: Exp (Complex a) -> Exp (Complex a)
sinh (Exp a
x ::+ Exp a
y) = Exp a -> Exp a
forall a. Floating a => a -> a
cos Exp a
y Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
* Exp a -> Exp a
forall a. Floating a => a -> a
sinh Exp a
x Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a -> Exp a
forall a. Floating a => a -> a
sin  Exp a
y Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
* Exp a -> Exp a
forall a. Floating a => a -> a
cosh Exp a
x
  cosh :: Exp (Complex a) -> Exp (Complex a)
cosh (Exp a
x ::+ Exp a
y) = Exp a -> Exp a
forall a. Floating a => a -> a
cos Exp a
y Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
* Exp a -> Exp a
forall a. Floating a => a -> a
cosh Exp a
x Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a -> Exp a
forall a. Floating a => a -> a
sin Exp a
y Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
* Exp a -> Exp a
forall a. Floating a => a -> a
sinh Exp a
x
  tanh :: Exp (Complex a) -> Exp (Complex a)
tanh (Exp a
x ::+ Exp a
y) = (Exp a
cosyExp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
sinhx Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
sinyExp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
coshx) Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Fractional a => a -> a -> a
/ (Exp a
cosyExp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
coshx Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
sinyExp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
sinhx)
    where
      siny :: Exp a
siny  = Exp a -> Exp a
forall a. Floating a => a -> a
sin Exp a
y
      cosy :: Exp a
cosy  = Exp a -> Exp a
forall a. Floating a => a -> a
cos Exp a
y
      sinhx :: Exp a
sinhx = Exp a -> Exp a
forall a. Floating a => a -> a
sinh Exp a
x
      coshx :: Exp a
coshx = Exp a -> Exp a
forall a. Floating a => a -> a
cosh Exp a
x

  asin :: Exp (Complex a) -> Exp (Complex a)
asin z :: Exp (Complex a)
z@(Exp a
x ::+ Exp a
y) = Exp a
y' Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ (-Exp a
x')
    where
      Exp a
x' ::+ Exp a
y' = Exp (Complex a) -> Exp (Complex a)
forall a. Floating a => a -> a
log (((-Exp a
y) Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
x) Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
+ Exp (Complex a) -> Exp (Complex a)
forall a. Floating a => a -> a
sqrt (Exp (Complex a)
1 Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
- Exp (Complex a)
zExp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
*Exp (Complex a)
z))

  acos :: Exp (Complex a) -> Exp (Complex a)
acos Exp (Complex a)
z                    = Exp a
y'' Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ (-Exp a
x'')
    where
      Exp a
x'' ::+ Exp a
y''  = Exp (Complex a) -> Exp (Complex a)
forall a. Floating a => a -> a
log (Exp (Complex a)
z Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
+ ((-Exp a
y') Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
x'))
      Exp a
x'  ::+ Exp a
y'   = Exp (Complex a) -> Exp (Complex a)
forall a. Floating a => a -> a
sqrt (Exp (Complex a)
1 Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
- Exp (Complex a)
zExp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
*Exp (Complex a)
z)

  atan :: Exp (Complex a) -> Exp (Complex a)
atan z :: Exp (Complex a)
z@(Exp a
x ::+ Exp a
y) = Exp a
y' Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ (-Exp a
x')
    where
      Exp a
x' ::+ Exp a
y' = Exp (Complex a) -> Exp (Complex a)
forall a. Floating a => a -> a
log (((Exp a
1Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
-Exp a
y) Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a
x) Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Fractional a => a -> a -> a
/ Exp (Complex a) -> Exp (Complex a)
forall a. Floating a => a -> a
sqrt (Exp (Complex a)
1Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
+Exp (Complex a)
zExp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
*Exp (Complex a)
z))

  asinh :: Exp (Complex a) -> Exp (Complex a)
asinh Exp (Complex a)
z =  Exp (Complex a) -> Exp (Complex a)
forall a. Floating a => a -> a
log (Exp (Complex a)
z Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
+ Exp (Complex a) -> Exp (Complex a)
forall a. Floating a => a -> a
sqrt (Exp (Complex a)
1Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
+Exp (Complex a)
zExp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
*Exp (Complex a)
z))
  acosh :: Exp (Complex a) -> Exp (Complex a)
acosh Exp (Complex a)
z =  Exp (Complex a) -> Exp (Complex a)
forall a. Floating a => a -> a
log (Exp (Complex a)
z Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
+ (Exp (Complex a)
zExp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
+Exp (Complex a)
1) Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
* Exp (Complex a) -> Exp (Complex a)
forall a. Floating a => a -> a
sqrt ((Exp (Complex a)
zExp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
-Exp (Complex a)
1)Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Fractional a => a -> a -> a
/(Exp (Complex a)
zExp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
+Exp (Complex a)
1)))
  atanh :: Exp (Complex a) -> Exp (Complex a)
atanh Exp (Complex a)
z =  Exp (Complex a)
0.5 Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
* Exp (Complex a) -> Exp (Complex a)
forall a. Floating a => a -> a
log ((Exp (Complex a)
1.0Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
+Exp (Complex a)
z) Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Fractional a => a -> a -> a
/ (Exp (Complex a)
1.0Exp (Complex a) -> Exp (Complex a) -> Exp (Complex a)
forall a. Num a => a -> a -> a
-Exp (Complex a)
z))


instance (FromIntegral a b, Num b, Elt (Complex b)) => FromIntegral a (Complex b) where
  fromIntegral :: Integral a => Exp a -> Exp (Complex b)
fromIntegral Exp a
x = Exp a -> Exp b
forall a b. (FromIntegral a b, Integral a) => Exp a -> Exp b
fromIntegral Exp a
x Exp b -> Exp b -> Exp (Complex b)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp b
0

-- | @since 1.2.0.0
--
instance Functor Complex where
  fmap :: forall a b.
(Elt a, Elt b, Elt (Complex a), Elt (Complex b)) =>
(Exp a -> Exp b) -> Exp (Complex a) -> Exp (Complex b)
fmap Exp a -> Exp b
f (Exp a
r ::+ Exp a
i) = Exp a -> Exp b
f Exp a
r Exp b -> Exp b -> Exp (Complex b)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ Exp a -> Exp b
f Exp a
i


-- | The non-negative magnitude of a complex number
--
magnitude :: RealFloat a => Exp (Complex a) -> Exp a
magnitude :: forall a. RealFloat a => Exp (Complex a) -> Exp a
magnitude (Exp a
r ::+ Exp a
i) = Exp Int -> Exp a -> Exp a
forall a. RealFloat a => Exp Int -> Exp a -> Exp a
scaleFloat Exp Int
k (Exp a -> Exp a
forall a. Floating a => a -> a
sqrt (Exp a -> Exp a
forall a. Num a => a -> a
sqr (Exp Int -> Exp a -> Exp a
forall a. RealFloat a => Exp Int -> Exp a -> Exp a
scaleFloat Exp Int
mk Exp a
r) Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
+ Exp a -> Exp a
forall a. Num a => a -> a
sqr (Exp Int -> Exp a -> Exp a
forall a. RealFloat a => Exp Int -> Exp a -> Exp a
scaleFloat Exp Int
mk Exp a
i)))
  where
    k :: Exp Int
k     = Exp Int -> Exp Int -> Exp Int
forall a. Ord a => Exp a -> Exp a -> Exp a
max (Exp a -> Exp Int
forall a. RealFloat a => Exp a -> Exp Int
exponent Exp a
r) (Exp a -> Exp Int
forall a. RealFloat a => Exp a -> Exp Int
exponent Exp a
i)
    mk :: Exp Int
mk    = -Exp Int
k
    sqr :: a -> a
sqr a
z = a
z a -> a -> a
forall a. Num a => a -> a -> a
* a
z

-- | As 'magnitude', but ignore floating point rounding and use the traditional
-- (simpler to evaluate) definition.
--
-- @since 1.3.0.0
--
magnitude' :: RealFloat a => Exp (Complex a) -> Exp a
magnitude' :: forall a. RealFloat a => Exp (Complex a) -> Exp a
magnitude' (Exp a
r ::+ Exp a
i) = Exp a -> Exp a
forall a. Floating a => a -> a
sqrt (Exp a
rExp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
r Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
+ Exp a
iExp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
*Exp a
i)

-- | The phase of a complex number, in the range @(-'pi', 'pi']@. If the
-- magnitude is zero, then so is the phase.
--
phase :: RealFloat a => Exp (Complex a) -> Exp a
phase :: forall a. RealFloat a => Exp (Complex a) -> Exp a
phase z :: Exp (Complex a)
z@(Exp a
r ::+ Exp a
i) =
  if Exp (Complex a)
z Exp (Complex a) -> Exp (Complex a) -> Exp Bool
forall a. Eq a => Exp a -> Exp a -> Exp Bool
== Exp (Complex a)
0
    then Exp a
0
    else Exp a -> Exp a -> Exp a
forall a. RealFloat a => Exp a -> Exp a -> Exp a
atan2 Exp a
i Exp a
r

-- | The function 'polar' takes a complex number and returns a (magnitude,
-- phase) pair in canonical form: the magnitude is non-negative, and the phase
-- in the range @(-'pi', 'pi']@; if the magnitude is zero, then so is the phase.
--
polar :: RealFloat a => Exp (Complex a) -> Exp (a,a)
polar :: forall a. RealFloat a => Exp (Complex a) -> Exp (a, a)
polar Exp (Complex a)
z =  Exp a -> Exp a -> Exp (a, a)
forall (con :: * -> *) x0 x1.
IsPattern con (x0, x1) (con x0, con x1) =>
con x0 -> con x1 -> con (x0, x1)
T2 (Exp (Complex a) -> Exp a
forall a. RealFloat a => Exp (Complex a) -> Exp a
magnitude Exp (Complex a)
z) (Exp (Complex a) -> Exp a
forall a. RealFloat a => Exp (Complex a) -> Exp a
phase Exp (Complex a)
z)

-- | Form a complex number from polar components of magnitude and phase.
--
mkPolar :: forall a. Floating a => Exp a -> Exp a -> Exp (Complex a)
mkPolar :: forall a. Floating a => Exp a -> Exp a -> Exp (Complex a)
mkPolar = (Exp a -> Exp a -> Complex (Exp a))
-> Exp (Plain (Exp a))
-> Exp (Plain (Exp a))
-> Exp (Plain (Complex (Exp a)))
forall a b c.
(Unlift Exp a, Unlift Exp b, Lift Exp c) =>
(a -> b -> c) -> Exp (Plain a) -> Exp (Plain b) -> Exp (Plain c)
lift2 (Exp a -> Exp a -> Complex (Exp a)
forall a. Floating a => a -> a -> Complex a
C.mkPolar :: Exp a -> Exp a -> Complex (Exp a))

-- | @'cis' t@ is a complex value with magnitude @1@ and phase @t@ (modulo
-- @2*'pi'@).
--
cis :: forall a. Floating a => Exp a -> Exp (Complex a)
cis :: forall a. Floating a => Exp a -> Exp (Complex a)
cis = (Exp a -> Complex (Exp a))
-> Exp (Plain (Exp a)) -> Exp (Plain (Complex (Exp a)))
forall a b.
(Unlift Exp a, Lift Exp b) =>
(a -> b) -> Exp (Plain a) -> Exp (Plain b)
lift1 (Exp a -> Complex (Exp a)
forall a. Floating a => a -> Complex a
C.cis :: Exp a -> Complex (Exp a))

-- | Return the real part of a complex number
--
real :: Elt a => Exp (Complex a) -> Exp a
real :: forall a. Elt a => Exp (Complex a) -> Exp a
real (Exp a
r ::+ Exp a
_) = Exp a
r

-- | Return the imaginary part of a complex number
--
imag :: Elt a => Exp (Complex a) -> Exp a
imag :: forall a. Elt a => Exp (Complex a) -> Exp a
imag (Exp a
_ ::+ Exp a
i) = Exp a
i

-- | Return the complex conjugate of a complex number, defined as
--
-- > conjugate(Z) = X - iY
--
conjugate :: Num a => Exp (Complex a) -> Exp (Complex a)
conjugate :: forall a. Num a => Exp (Complex a) -> Exp (Complex a)
conjugate Exp (Complex a)
z = Exp (Complex a) -> Exp a
forall a. Elt a => Exp (Complex a) -> Exp a
real Exp (Complex a)
z Exp a -> Exp a -> Exp (Complex a)
forall a. Elt a => Exp a -> Exp a -> Exp (Complex a)
::+ (- Exp (Complex a) -> Exp a
forall a. Elt a => Exp (Complex a) -> Exp a
imag Exp (Complex a)
z)