------------------------------------------------------------------------
-- |
-- 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
/= :: Complex a -> Complex a -> Bool
$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
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
min :: Complex a -> Complex a -> Complex a
$cmin :: forall a. Ord a => Complex a -> Complex a -> Complex a
max :: Complex a -> Complex a -> Complex a
$cmax :: forall a. Ord a => Complex a -> Complex a -> Complex a
>= :: 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
$c< :: forall a. Ord a => Complex a -> Complex a -> Bool
compare :: Complex a -> Complex a -> Ordering
$ccompare :: forall a. Ord a => Complex a -> Complex a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (Complex a)
Ord, Complex a -> Bool
(a -> m) -> Complex a -> m
(a -> b -> b) -> b -> Complex a -> b
(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
product :: Complex a -> a
$cproduct :: forall a. Num a => Complex a -> a
sum :: Complex a -> a
$csum :: forall a. Num a => Complex a -> a
minimum :: Complex a -> a
$cminimum :: forall a. Ord a => Complex a -> a
maximum :: Complex a -> a
$cmaximum :: forall a. Ord a => Complex a -> a
elem :: a -> Complex a -> Bool
$celem :: forall a. Eq a => a -> Complex a -> Bool
length :: Complex a -> Int
$clength :: forall a. Complex a -> Int
null :: Complex a -> Bool
$cnull :: forall a. Complex a -> Bool
toList :: Complex a -> [a]
$ctoList :: forall a. Complex a -> [a]
foldl1 :: (a -> a -> a) -> Complex a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Complex a -> a
foldr1 :: (a -> a -> a) -> Complex a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Complex a -> a
foldl' :: (b -> a -> b) -> b -> Complex a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Complex a -> b
foldl :: (b -> a -> b) -> b -> Complex a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Complex a -> b
foldr' :: (a -> b -> b) -> b -> Complex a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Complex a -> b
foldr :: (a -> b -> b) -> b -> Complex a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Complex a -> b
foldMap' :: (a -> m) -> Complex a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Complex a -> m
foldMap :: (a -> m) -> Complex a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Complex a -> m
fold :: Complex m -> m
$cfold :: forall m. Monoid m => Complex m -> m
Foldable, a -> Complex b -> Complex a
(a -> b) -> Complex a -> Complex b
(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
<$ :: a -> Complex b -> Complex a
$c<$ :: forall a b. a -> Complex b -> Complex a
fmap :: (a -> b) -> Complex a -> Complex b
$cfmap :: forall a b. (a -> b) -> Complex a -> Complex b
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
$cto :: forall a x. Rep (Complex a) x -> Complex a
$cfrom :: forall a x. Complex a -> Rep (Complex a) x
Generic)

infix 6 :+

traverseComplex :: Applicative f => (a -> f b) -> Complex a -> f (Complex b)
traverseComplex :: (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 (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 :: (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
    x :~: y
Refl <- x -> y -> Maybe (x :~: y)
forall u v. PolyEq u v => u -> v -> Maybe (u :~: v)
polyEqF x
rx y
ry
    x :~: y
Refl <- x -> y -> Maybe (x :~: y)
forall u v. PolyEq u v => u -> v -> Maybe (u :~: v)
polyEqF x
ix y
iy
    (Complex x :~: Complex x) -> Maybe (Complex x :~: Complex x)
forall (m :: Type -> Type) a. Monad m => a -> m a
return Complex x :~: Complex x
forall k (a :: k). a :~: a
Refl

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

imagPart :: Complex a -> a
imagPart :: 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 :: 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 :: 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 :: 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 :: 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 :: 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 :: 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 :: 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 :: 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 :: 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 :: 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 :: (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 :: (a -> m a) -> Complex a -> m (Complex a)
tryComplexSqrt a -> m a
sqrtFn Complex a
c = do
  a
m <- a -> m a
sqrtFn (Complex a -> a
forall a. Num a => Complex a -> a
magnitudeSq Complex a
c)
  let r :: a
r = Complex a -> a
forall a. Complex a -> a
realPart Complex a
c
      i :: a
i = Complex a -> a
forall a. Complex a -> a
imagPart Complex a
c
  a
r' <- a -> m a
sqrtFn (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$ (a
m a -> a -> a
forall a. Num a => a -> a -> a
+ a
r) a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
2
  a
i' <- a -> m a
sqrtFn (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$ (a
m a -> a -> a
forall a. Num a => a -> a -> a
- a
r) a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
2
  let i'' :: a
i'' = if (a
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
0) then a
i' else -a
i'
  Complex a -> m (Complex a)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (a
r' a -> a -> Complex a
forall a. a -> a -> Complex a
:+ a
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