    ------------------------------------------------------------------------
    -- |
    -- Module           : What4.Utils.Complex
    -- Description      : Provides a complex representation that is more generic
    --                    than Data.Complex.
    -- Copyright        : (c) Galois, Inc 2014-2020
    -- License          : BSD3
    -- Maintainer       : Joe Hendrix <jhendrix@galois.com>
    -- Stability        : provisional
    --
    -- This module provides complex numbers without the RealFloat constraints
    -- that Data.Complex has.  This is useful for representing various
    -- intermediate symbolic representations of complex numbers that are not
    -- literally number representations.
    ------------------------------------------------------------------------
    {-# LANGUAGE CPP #-}
    {-# LANGUAGE DeriveFunctor #-}
    {-# LANGUAGE DeriveFoldable #-}
    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE DeriveTraversable #-}
    {-# LANGUAGE GADTs #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    module What4.Utils.Complex
      ( Complex((:+))
      , realPart
      , imagPart
      , magnitude
      , magnitudeSq
      , complexNegate
      , complexAdd
      , complexSub
      , complexMul
      , complexDiv
      , complexRecip
      , tryComplexSqrt
      , tryMagnitude
      , complexAsRational
      ) where

    import Data.Hashable
    import GHC.Generics (Generic)

    import Data.Parameterized.Classes

    -- | A complex pair over an arbitrary type.
    data Complex a = !a :+ !a
      deriving (Complex a -> Complex a -> Bool
    (Complex a -> Complex a -> Bool)
    -> (Complex a -> Complex a -> Bool) -> Eq (Complex a)
    forall a. Eq a => Complex a -> Complex a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a. Eq a => Complex a -> Complex a -> Bool
    == :: Complex a -> Complex a -> Bool
    $c/= :: forall a. Eq a => Complex a -> Complex a -> Bool
    /= :: Complex a -> Complex a -> Bool
    Eq, Eq (Complex a)
    Eq (Complex a) =>
    (Complex a -> Complex a -> Ordering)
    -> (Complex a -> Complex a -> Bool)
    -> (Complex a -> Complex a -> Bool)
    -> (Complex a -> Complex a -> Bool)
    -> (Complex a -> Complex a -> Bool)
    -> (Complex a -> Complex a -> Complex a)
    -> (Complex a -> Complex a -> Complex a)
    -> Ord (Complex a)
    Complex a -> Complex a -> Bool
    Complex a -> Complex a -> Ordering
    Complex a -> Complex a -> Complex a
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    forall a. Ord a => Eq (Complex a)
    forall a. Ord a => Complex a -> Complex a -> Bool
    forall a. Ord a => Complex a -> Complex a -> Ordering
    forall a. Ord a => Complex a -> Complex a -> Complex a
    $ccompare :: forall a. Ord a => Complex a -> Complex a -> Ordering
    compare :: Complex a -> Complex a -> Ordering
    $c< :: forall a. Ord a => Complex a -> Complex a -> Bool
    < :: Complex a -> Complex a -> Bool
    $c<= :: forall a. Ord a => Complex a -> Complex a -> Bool
    <= :: Complex a -> Complex a -> Bool
    $c> :: forall a. Ord a => Complex a -> Complex a -> Bool
    > :: Complex a -> Complex a -> Bool
    $c>= :: forall a. Ord a => Complex a -> Complex a -> Bool
    >= :: Complex a -> Complex a -> Bool
    $cmax :: forall a. Ord a => Complex a -> Complex a -> Complex a
    max :: Complex a -> Complex a -> Complex a
    $cmin :: forall a. Ord a => Complex a -> Complex a -> Complex a
    min :: Complex a -> Complex a -> Complex a
    Ord, (forall m. Monoid m => Complex m -> m)
    -> (forall m a. Monoid m => (a -> m) -> Complex a -> m)
    -> (forall m a. Monoid m => (a -> m) -> Complex a -> m)
    -> (forall a b. (a -> b -> b) -> b -> Complex a -> b)
    -> (forall a b. (a -> b -> b) -> b -> Complex a -> b)
    -> (forall b a. (b -> a -> b) -> b -> Complex a -> b)
    -> (forall b a. (b -> a -> b) -> b -> Complex a -> b)
    -> (forall a. (a -> a -> a) -> Complex a -> a)
    -> (forall a. (a -> a -> a) -> Complex a -> a)
    -> (forall a. Complex a -> [a])
    -> (forall a. Complex a -> Bool)
    -> (forall a. Complex a -> Int)
    -> (forall a. Eq a => a -> Complex a -> Bool)
    -> (forall a. Ord a => Complex a -> a)
    -> (forall a. Ord a => Complex a -> a)
    -> (forall a. Num a => Complex a -> a)
    -> (forall a. Num a => Complex a -> a)
    -> Foldable Complex
    forall a. Eq a => a -> Complex a -> Bool
    forall a. Num a => Complex a -> a
    forall a. Ord a => Complex a -> a
    forall m. Monoid m => Complex m -> m
    forall a. Complex a -> Bool
    forall a. Complex a -> Int
    forall a. Complex a -> [a]
    forall a. (a -> a -> a) -> Complex a -> a
    forall m a. Monoid m => (a -> m) -> Complex a -> m
    forall b a. (b -> a -> b) -> b -> Complex a -> b
    forall a b. (a -> b -> b) -> b -> Complex a -> b
    forall (t :: Type -> Type).
    (forall m. Monoid m => t m -> m)
    -> (forall m a. Monoid m => (a -> m) -> t a -> m)
    -> (forall m a. Monoid m => (a -> m) -> t a -> m)
    -> (forall a b. (a -> b -> b) -> b -> t a -> b)
    -> (forall a b. (a -> b -> b) -> b -> t a -> b)
    -> (forall b a. (b -> a -> b) -> b -> t a -> b)
    -> (forall b a. (b -> a -> b) -> b -> t a -> b)
    -> (forall a. (a -> a -> a) -> t a -> a)
    -> (forall a. (a -> a -> a) -> t a -> a)
    -> (forall a. t a -> [a])
    -> (forall a. t a -> Bool)
    -> (forall a. t a -> Int)
    -> (forall a. Eq a => a -> t a -> Bool)
    -> (forall a. Ord a => t a -> a)
    -> (forall a. Ord a => t a -> a)
    -> (forall a. Num a => t a -> a)
    -> (forall a. Num a => t a -> a)
    -> Foldable t
    $cfold :: forall m. Monoid m => Complex m -> m
    fold :: forall m. Monoid m => Complex m -> m
    $cfoldMap :: forall m a. Monoid m => (a -> m) -> Complex a -> m
    foldMap :: forall m a. Monoid m => (a -> m) -> Complex a -> m
    $cfoldMap' :: forall m a. Monoid m => (a -> m) -> Complex a -> m
    foldMap' :: forall m a. Monoid m => (a -> m) -> Complex a -> m
    $cfoldr :: forall a b. (a -> b -> b) -> b -> Complex a -> b
    foldr :: forall a b. (a -> b -> b) -> b -> Complex a -> b
    $cfoldr' :: forall a b. (a -> b -> b) -> b -> Complex a -> b
    foldr' :: forall a b. (a -> b -> b) -> b -> Complex a -> b
    $cfoldl :: forall b a. (b -> a -> b) -> b -> Complex a -> b
    foldl :: forall b a. (b -> a -> b) -> b -> Complex a -> b
    $cfoldl' :: forall b a. (b -> a -> b) -> b -> Complex a -> b
    foldl' :: forall b a. (b -> a -> b) -> b -> Complex a -> b
    $cfoldr1 :: forall a. (a -> a -> a) -> Complex a -> a
    foldr1 :: forall a. (a -> a -> a) -> Complex a -> a
    $cfoldl1 :: forall a. (a -> a -> a) -> Complex a -> a
    foldl1 :: forall a. (a -> a -> a) -> Complex a -> a
    $ctoList :: forall a. Complex a -> [a]
    toList :: forall a. Complex a -> [a]
    $cnull :: forall a. Complex a -> Bool
    null :: forall a. Complex a -> Bool
    $clength :: forall a. Complex a -> Int
    length :: forall a. Complex a -> Int
    $celem :: forall a. Eq a => a -> Complex a -> Bool
    elem :: forall a. Eq a => a -> Complex a -> Bool
    $cmaximum :: forall a. Ord a => Complex a -> a
    maximum :: forall a. Ord a => Complex a -> a
    $cminimum :: forall a. Ord a => Complex a -> a
    minimum :: forall a. Ord a => Complex a -> a
    $csum :: forall a. Num a => Complex a -> a
    sum :: forall a. Num a => Complex a -> a
    $cproduct :: forall a. Num a => Complex a -> a
    product :: forall a. Num a => Complex a -> a
    Foldable, (forall a b. (a -> b) -> Complex a -> Complex b)
    -> (forall a b. a -> Complex b -> Complex a) -> Functor Complex
    forall a b. a -> Complex b -> Complex a
    forall a b. (a -> b) -> Complex a -> Complex b
    forall (f :: Type -> Type).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall a b. (a -> b) -> Complex a -> Complex b
    fmap :: forall a b. (a -> b) -> Complex a -> Complex b
    $c<$ :: forall a b. a -> Complex b -> Complex a
    <$ :: forall a b. a -> Complex b -> Complex a
    Functor, (forall x. Complex a -> Rep (Complex a) x)
    -> (forall x. Rep (Complex a) x -> Complex a)
    -> Generic (Complex a)
    forall x. Rep (Complex a) x -> Complex a
    forall x. Complex a -> Rep (Complex a) x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    forall a x. Rep (Complex a) x -> Complex a
    forall a x. Complex a -> Rep (Complex a) x
    $cfrom :: forall a x. Complex a -> Rep (Complex a) x
    from :: forall x. Complex a -> Rep (Complex a) x
    $cto :: forall a x. Rep (Complex a) x -> Complex a
    to :: forall x. Rep (Complex a) x -> Complex a
    Generic)

    infix 6 :+

    traverseComplex :: Applicative f => (a -> f b) -> Complex a -> f (Complex b)
    traverseComplex :: forall (f :: Type -> Type) a b.
    Applicative f =>
    (a -> f b) -> Complex a -> f (Complex b)
    traverseComplex = \a -> f b
    f (a
    x :+ a
    y) -> b -> b -> Complex b
    forall a. a -> a -> Complex a
    (:+) (b -> b -> Complex b) -> f b -> f (b -> Complex b)
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    <$> a -> f b
    f a
    x f (b -> Complex b) -> f b -> f (Complex b)
    forall a b. f (a -> b) -> f a -> f b
    forall (f :: Type -> Type) a b.
    Applicative f =>
    f (a -> b) -> f a -> f b
    <*> a -> f b
    f a
    y
    {-# INLINE traverseComplex #-}

    instance Traversable Complex where
      traverse :: forall (f :: Type -> Type) a b.
    Applicative f =>
    (a -> f b) -> Complex a -> f (Complex b)
    traverse = (a -> f b) -> Complex a -> f (Complex b)
    forall (f :: Type -> Type) a b.
    Applicative f =>
    (a -> f b) -> Complex a -> f (Complex b)
    traverseComplex

    instance Hashable a => Hashable (Complex a) where

    instance PolyEq x y => PolyEq (Complex x) (Complex y) where
      polyEqF :: Complex x -> Complex y -> Maybe (Complex x :~: Complex y)
    polyEqF (x
    rx :+ x
    ix) (y
    ry :+ y
    iy) = do
        Refl <- x -> y -> Maybe (x :~: y)
    forall u v. PolyEq u v => u -> v -> Maybe (u :~: v)
    polyEqF x
    rx y
    ry
        Refl <- polyEqF ix iy
        return Refl

    realPart :: Complex a -> a
    realPart :: forall a. Complex a -> a
    realPart (a
    a :+ a
    _) = a
    a

    imagPart :: Complex a -> a
    imagPart :: forall a. Complex a -> a
    imagPart (a
    _ :+ a
    b) = a
    b

    instance (Eq a, Num a, Show a) => Show (Complex a) where
      show :: Complex a -> String
    show (a
    r :+ a
    0) = a -> String
    forall a. Show a => a -> String
    show a
    r
      show (a
    0 :+ a
    i) = a -> String
    forall a. Show a => a -> String
    show a
    i String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "i"
      show (a
    r :+ a
    i) = a -> String
    forall a. Show a => a -> String
    show a
    r String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " + " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ a -> String
    forall a. Show a => a -> String
    show a
    i String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "i"

    complexNegate :: Num a => Complex a -> Complex a
    complexNegate :: forall a. Num a => Complex a -> Complex a
    complexNegate (a
    r :+ a
    i) = a -> a
    forall a. Num a => a -> a
    negate a
    r a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ a -> a
    forall a. Num a => a -> a
    negate a
    i

    complexAdd :: Num a => Complex a -> Complex a -> Complex a
    complexAdd :: forall a. Num a => Complex a -> Complex a -> Complex a
    complexAdd (a
    rx :+ a
    ix) (a
    ry :+ a
    iy) = (a
    rx a -> a -> a
    forall a. Num a => a -> a -> a
    + a
    ry) a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ (a
    ix a -> a -> a
    forall a. Num a => a -> a -> a
    + a
    iy)

    complexSub :: Num a => Complex a -> Complex a -> Complex a
    complexSub :: forall a. Num a => Complex a -> Complex a -> Complex a
    complexSub (a
    rx :+ a
    ix) (a
    ry :+ a
    iy) = (a
    rx a -> a -> a
    forall a. Num a => a -> a -> a
    - a
    ry) a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ (a
    ix a -> a -> a
    forall a. Num a => a -> a -> a
    - a
    iy)

    {-# SPECIALIZE complexMul :: Complex Rational -> Complex Rational -> Complex Rational #-}
    complexMul :: Num a => Complex a -> Complex a -> Complex a
    complexMul :: forall a. Num a => Complex a -> Complex a -> Complex a
    complexMul (a
    rx :+ a
    ix) (a
    ry :+ a
    iy) = (a
    rx a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    ry a -> a -> a
    forall a. Num a => a -> a -> a
    - a
    ix a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    iy) a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ (a
    ix a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    ry a -> a -> a
    forall a. Num a => a -> a -> a
    + a
    rx a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    iy)

    instance Floating a => Num (Complex a) where
      + :: Complex a -> Complex a -> Complex a
    (+) = Complex a -> Complex a -> Complex a
    forall a. Num a => Complex a -> Complex a -> Complex a
    complexAdd
      (-) = Complex a -> Complex a -> Complex a
    forall a. Num a => Complex a -> Complex a -> Complex a
    complexSub
      negate :: Complex a -> Complex a
    negate = Complex a -> Complex a
    forall a. Num a => Complex a -> Complex a
    complexNegate
      * :: Complex a -> Complex a -> Complex a
    (*) = Complex a -> Complex a -> Complex a
    forall a. Num a => Complex a -> Complex a -> Complex a
    complexMul
      abs :: Complex a -> Complex a
    abs Complex a
    c = Complex a -> a
    forall a. Floating a => Complex a -> a
    magnitude Complex a
    c a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ a
    0
      signum :: Complex a -> Complex a
    signum c :: Complex a
    c@(a
    r :+ a
    i) = a
    ra -> a -> a
    forall a. Fractional a => a -> a -> a
    /a
    m a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ a
    ia -> a -> a
    forall a. Fractional a => a -> a -> a
    /a
    m
        where m :: a
    m = Complex a -> a
    forall a. Floating a => Complex a -> a
    magnitude Complex a
    c
      fromInteger :: Integer -> Complex a
    fromInteger Integer
    x = Integer -> a
    forall a. Num a => Integer -> a
    fromInteger Integer
    x a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ a
    0

    instance (Ord a, Floating a) => Real (Complex a) where
      toRational :: Complex a -> Rational
    toRational = String -> Complex a -> Rational
    forall a. HasCallStack => String -> a
    error String
    "toRational undefined on complex numbers"

    instance Floating a => Fractional (Complex a) where
      fromRational :: Rational -> Complex a
    fromRational Rational
    r = Rational -> a
    forall a. Fractional a => Rational -> a
    fromRational Rational
    r a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ a
    0
      recip :: Complex a -> Complex a
    recip = Complex a -> Complex a
    forall a. Fractional a => Complex a -> Complex a
    complexRecip
      / :: Complex a -> Complex a -> Complex a
    (/) = Complex a -> Complex a -> Complex a
    forall a. Fractional a => Complex a -> Complex a -> Complex a
    complexDiv

    complexDiv :: Fractional a => Complex a -> Complex a -> Complex a
    complexDiv :: forall a. Fractional a => Complex a -> Complex a -> Complex a
    complexDiv Complex a
    x Complex a
    y = Complex a -> Complex a -> Complex a
    forall a. Num a => Complex a -> Complex a -> Complex a
    complexMul Complex a
    x (Complex a -> Complex a
    forall a. Fractional a => Complex a -> Complex a
    complexRecip Complex a
    y)

    complexRecip :: Fractional a => Complex a -> Complex a
    complexRecip :: forall a. Fractional a => Complex a -> Complex a
    complexRecip (a
    r :+ a
    i) = (a
    ra -> a -> a
    forall a. Fractional a => a -> a -> a
    /a
    m) a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ (a -> a
    forall a. Num a => a -> a
    negate a
    ia -> a -> a
    forall a. Fractional a => a -> a -> a
    /a
    m)
      where m :: a
    m = a
    ra -> a -> a
    forall a. Num a => a -> a -> a
    *a
    r a -> a -> a
    forall a. Num a => a -> a -> a
    + a
    ia -> a -> a
    forall a. Num a => a -> a -> a
    *a
    i

    -- | Returns the "complex argument" of the complex number.
    phase :: RealFloat a => Complex a -> a
    phase :: forall a. RealFloat a => Complex a -> a
    phase (a
    0 :+ a
    0)   = a
    0
    phase (a
    x:+a
    y)     = a -> a -> a
    forall a. RealFloat a => a -> a -> a
    atan2 a
    y a
    x

    instance (RealFloat a) => Floating (Complex a) where
      pi :: Complex a
    pi             =  a
    forall a. Floating a => a
    pi a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ a
    0
      exp :: Complex a -> Complex a
    exp (a
    x:+a
    y)     =  a
    expx a -> a -> a
    forall a. Num a => a -> a -> a
    * a -> a
    forall a. Floating a => a -> a
    cos a
    y a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ a
    expx a -> a -> a
    forall a. Num a => a -> a -> a
    * a -> a
    forall a. Floating a => a -> a
    sin a
    y
        where expx :: a
    expx = a -> a
    forall a. Floating a => a -> a
    exp a
    x
      log :: Complex a -> Complex a
    log Complex a
    z          =  a -> a
    forall a. Floating a => a -> a
    log (Complex a -> a
    forall a. Floating a => Complex a -> a
    magnitude Complex a
    z) a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ Complex a -> a
    forall a. RealFloat a => Complex a -> a
    phase Complex a
    z

      sqrt :: Complex a -> Complex a
    sqrt (a
    0:+a
    0)    =  Complex a
    0
      sqrt (a
    x:+a
    0) | a
    x a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    > a
    0  = a -> a
    forall a. Floating a => a -> a
    sqrt a
    x a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ a
    0
                  | a
    x a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    0 = a
    0 a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ a
    0
                  | a
    x a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    0  = a
    0 a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ a -> a
    forall a. Floating a => a -> a
    sqrt (-a
    x)
      sqrt (a
    0:+a
    y) | a
    y a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    > a
    0 = let u :: a
    u = a -> a
    forall a. Floating a => a -> a
    sqrt (a
    ya -> a -> a
    forall a. Fractional a => a -> a -> a
    /a
    2) in (a
    u a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ a
    u)
                  | a
    y a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    0 = let u :: a
    u = a -> a
    forall a. Floating a => a -> a
    sqrt (a -> a
    forall a. Num a => a -> a
    negate a
    ya -> a -> a
    forall a. Fractional a => a -> a -> a
    /a
    2) in (a
    u a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ a -> a
    forall a. Num a => a -> a
    negate a
    u)
      sqrt z :: Complex a
    z@(a
    x:+a
    y)  =  a
    u a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ (if a
    y a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    0 then -a
    v else a
    v)
                          where m :: a
    m = Complex a -> a
    forall a. Floating a => Complex a -> a
    magnitude Complex a
    z
                                u :: a
    u    = a -> a
    forall a. Floating a => a -> a
    sqrt ((a
    m a -> a -> a
    forall a. Num a => a -> a -> a
    + a
    x) a -> a -> a
    forall a. Fractional a => a -> a -> a
    / a
    2)
                                v :: a
    v    = a -> a
    forall a. Floating a => a -> a
    sqrt ((a
    m a -> a -> a
    forall a. Num a => a -> a -> a
    - a
    x) a -> a -> a
    forall a. Fractional a => a -> a -> a
    / a
    2)

      sin :: Complex a -> Complex a
    sin (a
    x:+a
    y) = (a -> a
    forall a. Floating a => a -> a
    sin a
    xa -> a -> a
    forall a. Num a => a -> a -> a
    *a -> a
    forall a. Floating a => a -> a
    cosh a
    y) a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ (a -> a
    forall a. Floating a => a -> a
    cos a
    x a -> a -> a
    forall a. Num a => a -> a -> a
    * a -> a
    forall a. Floating a => a -> a
    sinh a
    y)
      cos :: Complex a -> Complex a
    cos (a
    x:+a
    y) = (a -> a
    forall a. Floating a => a -> a
    cos a
    xa -> a -> a
    forall a. Num a => a -> a -> a
    *a -> a
    forall a. Floating a => a -> a
    cosh a
    y) a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ (- a -> a
    forall a. Floating a => a -> a
    sin a
    x a -> a -> a
    forall a. Num a => a -> a -> a
    * a -> a
    forall a. Floating a => a -> a
    sinh a
    y)
      tan :: Complex a -> Complex a
    tan (a
    x:+a
    y) = (a
    sin_xa -> a -> a
    forall a. Num a => a -> a -> a
    *a
    cos_xa -> a -> a
    forall a. Fractional a => a -> a -> a
    /a
    m) a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ (a
    sinh_ya -> a -> a
    forall a. Num a => a -> a -> a
    *a
    cosh_ya -> a -> a
    forall a. Fractional a => a -> a -> a
    /a
    m)
        where sin_x :: a
    sin_x  = a -> a
    forall a. Floating a => a -> a
    sin a
    x
              cos_x :: a
    cos_x  = a -> a
    forall a. Floating a => a -> a
    cos a
    x
              sinh_y :: a
    sinh_y = a -> a
    forall a. Floating a => a -> a
    sinh a
    y
              cosh_y :: a
    cosh_y = a -> a
    forall a. Floating a => a -> a
    cosh a
    y
              u :: a
    u = a
    cos_x a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    cosh_y
              v :: a
    v = a
    sin_x a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    sinh_y
              m :: a
    m = a
    ua -> a -> a
    forall a. Num a => a -> a -> a
    *a
    u a -> a -> a
    forall a. Num a => a -> a -> a
    + a
    va -> a -> a
    forall a. Num a => a -> a -> a
    *a
    v

      sinh :: Complex a -> Complex a
    sinh (a
    x:+a
    y)    =  a -> a
    forall a. Floating a => a -> a
    cos a
    y a -> a -> a
    forall a. Num a => a -> a -> a
    * a -> a
    forall a. Floating a => a -> a
    sinh a
    x a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ a -> a
    forall a. Floating a => a -> a
    sin a
    y a -> a -> a
    forall a. Num a => a -> a -> a
    * a -> a
    forall a. Floating a => a -> a
    cosh a
    x
      cosh :: Complex a -> Complex a
    cosh (a
    x:+a
    y)    =  a -> a
    forall a. Floating a => a -> a
    cos a
    y a -> a -> a
    forall a. Num a => a -> a -> a
    * a -> a
    forall a. Floating a => a -> a
    cosh a
    x a -> a -> Complex a
    forall a. a -> a -> Complex a
    :+ a -> a
    forall a. Floating a => a -> a
    sin a
    y a -> a -> a
    forall a. Num a => a -> a -> a
    * a -> a
    forall a. Floating a => a -> a
    sinh a
    x
      tanh :: Complex a -> Complex a
    tanh (a
    x:+a
    y)    =  (a
    cosya -> a -> a
    forall a. Num a => a -> a -> a
    *a
    sinhxa -> a -> Complex a
    forall a. a -> a -> Complex a
    :+a
    sinya -> a -> a
    forall a. Num a => a -> a -> a
    *a
    coshx)Complex a -> Complex a -> Complex a
    forall a. Fractional a => a -> a -> a
    /(a
    cosya -> a -> a
    forall a. Num a => a -> a -> a
    *a
    coshxa -> a -> Complex a
    forall a. a -> a -> Complex a
    :+a
    sinya -> a -> a
    forall a. Num a => a -> a -> a
    *a
    sinhx)
        where siny :: a
    siny  = a -> a
    forall a. Floating a => a -> a
    sin a
    y
              cosy :: a
    cosy  = a -> a
    forall a. Floating a => a -> a
    cos a
    y
              sinhx :: a
    sinhx = a -> a
    forall a. Floating a => a -> a
    sinh a
    x
              coshx :: a
    coshx = a -> a
    forall a. Floating a => a -> a
    cosh a
    x

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

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

    instance (Ord a, Floating a) => RealFrac (Complex a) where
      properFraction :: forall b. Integral b => Complex a -> (b, Complex a)
    properFraction = String -> Complex a -> (b, Complex a)
    forall a. HasCallStack => String -> a
    error String
    "properFraction undefined on complex numbers"

    magnitude :: Floating a => Complex a -> a
    magnitude :: forall a. Floating a => Complex a -> a
    magnitude Complex a
    c = a -> a
    forall a. Floating a => a -> a
    sqrt (Complex a -> a
    forall a. Num a => Complex a -> a
    magnitudeSq Complex a
    c)

    -- | Returns square of magnitude.
    magnitudeSq :: Num a => Complex a -> a
    magnitudeSq :: forall a. Num a => Complex a -> a
    magnitudeSq (a
    r :+ a
    i) = a
    ra -> a -> a
    forall a. Num a => a -> a -> a
    *a
    ra -> a -> a
    forall a. Num a => a -> a -> a
    +a
    ia -> a -> a
    forall a. Num a => a -> a -> a
    *a
    i

    tryMagnitude :: Num a
                 => (a -> b) -- ^ Sqrt function
                 -> Complex a
                 -> b
    tryMagnitude :: forall a b. Num a => (a -> b) -> Complex a -> b
    tryMagnitude a -> b
    sqrtFn = a -> b
    sqrtFn (a -> b) -> (Complex a -> a) -> Complex a -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Complex a -> a
    forall a. Num a => Complex a -> a
    magnitudeSq

    tryComplexSqrt :: (Ord a, Fractional a, Monad m)
                   => (a -> m a) -- ^ Square-root function defined for non-negative values a.
                   -> Complex a
                   -> m (Complex a)
    tryComplexSqrt :: forall a (m :: Type -> Type).
    (Ord a, Fractional a, Monad m) =>
    (a -> m a) -> Complex a -> m (Complex a)
    tryComplexSqrt a -> m a
    sqrtFn Complex a
    c = do
      m <- a -> m a
    sqrtFn (Complex a -> a
    forall a. Num a => Complex a -> a
    magnitudeSq Complex a
    c)
      let r = Complex a -> a
    forall a. Complex a -> a
    realPart Complex a
    c
          i = Complex a -> a
    forall a. Complex a -> a
    imagPart Complex a
    c
      r' <- sqrtFn $ (m + r) / 2
      i' <- sqrtFn $ (m - r) / 2
      let i'' = if (a
    i a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    >= a
    0) then a
    i' else -a
    i'
      return (r' :+ i'')

    complexAsRational :: Complex Rational -> Maybe Rational
    complexAsRational :: Complex Rational -> Maybe Rational
    complexAsRational (Rational
    r :+ Rational
    i) | Rational
    i Rational -> Rational -> Bool
    forall a. Eq a => a -> a -> Bool
    == Rational
    0 = Rational -> Maybe Rational
    forall a. a -> Maybe a
    Just Rational
    r
                               | Bool
    otherwise = Maybe Rational
    forall a. Maybe a
    Nothing