{-# 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
data Complex a = !a :+ !a
deriving (Complex a -> Complex a -> Bool
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, Complex a -> Complex a -> Bool
Complex a -> Complex a -> Ordering
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
Ord, 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 :: forall a. Num a => Complex a -> a
$cproduct :: forall a. Num a => Complex a -> a
sum :: forall a. Num a => Complex a -> a
$csum :: forall a. Num a => Complex a -> a
minimum :: forall a. Ord a => Complex a -> a
$cminimum :: forall a. Ord a => Complex a -> a
maximum :: forall a. Ord a => Complex a -> a
$cmaximum :: forall a. Ord a => Complex a -> a
elem :: forall a. Eq a => a -> Complex a -> Bool
$celem :: forall a. Eq a => a -> Complex a -> Bool
length :: forall a. Complex a -> Int
$clength :: forall a. Complex a -> Int
null :: forall a. Complex a -> Bool
$cnull :: forall a. Complex a -> Bool
toList :: forall a. Complex a -> [a]
$ctoList :: forall a. Complex a -> [a]
foldl1 :: forall a. (a -> a -> a) -> Complex a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Complex a -> a
foldr1 :: forall a. (a -> a -> a) -> Complex a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Complex a -> a
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
$cfoldl :: forall b a. (b -> a -> 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
$cfoldr :: forall a b. (a -> b -> b) -> b -> Complex a -> b
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
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Complex a -> m
fold :: forall m. Monoid m => Complex m -> m
$cfold :: forall m. Monoid m => Complex m -> m
Foldable, 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
<$ :: forall a b. a -> Complex b -> Complex a
$c<$ :: forall a b. a -> Complex b -> Complex a
fmap :: forall a b. (a -> b) -> Complex a -> Complex b
$cfmap :: forall a b. (a -> b) -> Complex a -> Complex b
Functor, 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 :: 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) -> forall a. a -> a -> Complex a
(:+) forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f b
f a
x 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 = 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 <- forall u v. PolyEq u v => u -> v -> Maybe (u :~: v)
polyEqF x
rx y
ry
x :~: y
Refl <- forall u v. PolyEq u v => u -> v -> Maybe (u :~: v)
polyEqF x
ix y
iy
forall (m :: Type -> Type) a. Monad m => a -> m a
return forall {k} (a :: k). a :~: a
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) = forall a. Show a => a -> String
show a
r
show (a
0 :+ a
i) = forall a. Show a => a -> String
show a
i forall a. [a] -> [a] -> [a]
++ String
"i"
show (a
r :+ a
i) = forall a. Show a => a -> String
show a
r forall a. [a] -> [a] -> [a]
++ String
" + " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
i 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) = forall a. Num a => a -> a
negate a
r forall a. a -> a -> Complex 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 forall a. Num a => a -> a -> a
+ a
ry) forall a. a -> a -> Complex a
:+ (a
ix 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 forall a. Num a => a -> a -> a
- a
ry) forall a. a -> a -> Complex a
:+ (a
ix 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 forall a. Num a => a -> a -> a
* a
ry forall a. Num a => a -> a -> a
- a
ix forall a. Num a => a -> a -> a
* a
iy) forall a. a -> a -> Complex a
:+ (a
ix forall a. Num a => a -> a -> a
* a
ry forall a. Num a => a -> a -> a
+ a
rx forall a. Num a => a -> a -> a
* a
iy)
instance Floating a => Num (Complex a) where
+ :: Complex a -> Complex a -> Complex a
(+) = forall a. Num a => Complex a -> Complex a -> Complex a
complexAdd
(-) = forall a. Num a => Complex a -> Complex a -> Complex a
complexSub
negate :: Complex a -> Complex a
negate = forall a. Num a => Complex a -> Complex a
complexNegate
* :: 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 = forall a. Floating a => Complex a -> a
magnitude Complex a
c forall a. a -> a -> Complex a
:+ a
0
signum :: Complex a -> Complex a
signum c :: Complex a
c@(a
r :+ a
i) = a
rforall a. Fractional a => a -> a -> a
/a
m forall a. a -> a -> Complex a
:+ a
iforall a. Fractional a => a -> a -> a
/a
m
where m :: a
m = forall a. Floating a => Complex a -> a
magnitude Complex a
c
fromInteger :: Integer -> Complex a
fromInteger Integer
x = forall a. Num a => Integer -> a
fromInteger Integer
x forall a. a -> a -> Complex a
:+ a
0
instance (Ord a, Floating a) => Real (Complex a) where
toRational :: Complex a -> Rational
toRational = 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 = forall a. Fractional a => Rational -> a
fromRational Rational
r forall a. a -> a -> Complex a
:+ a
0
recip :: Complex a -> Complex a
recip = forall a. Fractional a => Complex a -> Complex a
complexRecip
/ :: 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 = forall a. Num a => Complex a -> Complex a -> Complex a
complexMul Complex a
x (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
rforall a. Fractional a => a -> a -> a
/a
m) forall a. a -> a -> Complex a
:+ (forall a. Num a => a -> a
negate a
iforall a. Fractional a => a -> a -> a
/a
m)
where m :: a
m = a
rforall a. Num a => a -> a -> a
*a
r forall a. Num a => a -> a -> a
+ a
iforall a. Num a => a -> a -> a
*a
i
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) = forall a. RealFloat a => a -> a -> a
atan2 a
y a
x
instance (RealFloat a) => Floating (Complex a) where
pi :: Complex a
pi = forall a. Floating a => a
pi forall a. a -> a -> Complex a
:+ a
0
exp :: Complex a -> Complex a
exp (a
x:+a
y) = a
expx forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
cos a
y forall a. a -> a -> Complex a
:+ a
expx forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
sin a
y
where expx :: a
expx = forall a. Floating a => a -> a
exp a
x
log :: Complex a -> Complex a
log Complex a
z = forall a. Floating a => a -> a
log (forall a. Floating a => Complex a -> a
magnitude Complex a
z) forall a. a -> a -> Complex 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 forall a. Ord a => a -> a -> Bool
> a
0 = forall a. Floating a => a -> a
sqrt a
x forall a. a -> a -> Complex a
:+ a
0
| a
x forall a. Eq a => a -> a -> Bool
== a
0 = a
0 forall a. a -> a -> Complex a
:+ a
0
| a
x forall a. Ord a => a -> a -> Bool
< a
0 = a
0 forall a. a -> a -> Complex a
:+ forall a. Floating a => a -> a
sqrt (-a
x)
sqrt (a
0:+a
y) | a
y forall a. Ord a => a -> a -> Bool
> a
0 = let u :: a
u = forall a. Floating a => a -> a
sqrt (a
yforall a. Fractional a => a -> a -> a
/a
2) in (a
u forall a. a -> a -> Complex a
:+ a
u)
| a
y forall a. Ord a => a -> a -> Bool
< a
0 = let u :: a
u = forall a. Floating a => a -> a
sqrt (forall a. Num a => a -> a
negate a
yforall a. Fractional a => a -> a -> a
/a
2) in (a
u forall a. a -> a -> Complex a
:+ forall a. Num a => a -> a
negate a
u)
sqrt z :: Complex a
z@(a
x:+a
y) = a
u forall a. a -> a -> Complex a
:+ (if a
y forall a. Ord a => a -> a -> Bool
< a
0 then -a
v else a
v)
where m :: a
m = forall a. Floating a => Complex a -> a
magnitude Complex a
z
u :: a
u = forall a. Floating a => a -> a
sqrt ((a
m forall a. Num a => a -> a -> a
+ a
x) forall a. Fractional a => a -> a -> a
/ a
2)
v :: a
v = forall a. Floating a => a -> a
sqrt ((a
m forall a. Num a => a -> a -> a
- a
x) forall a. Fractional a => a -> a -> a
/ a
2)
sin :: Complex a -> Complex a
sin (a
x:+a
y) = (forall a. Floating a => a -> a
sin a
xforall a. Num a => a -> a -> a
*forall a. Floating a => a -> a
cosh a
y) forall a. a -> a -> Complex a
:+ (forall a. Floating a => a -> a
cos a
x forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
sinh a
y)
cos :: Complex a -> Complex a
cos (a
x:+a
y) = (forall a. Floating a => a -> a
cos a
xforall a. Num a => a -> a -> a
*forall a. Floating a => a -> a
cosh a
y) forall a. a -> a -> Complex a
:+ (- forall a. Floating a => a -> a
sin a
x forall a. Num 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_xforall a. Num a => a -> a -> a
*a
cos_xforall a. Fractional a => a -> a -> a
/a
m) forall a. a -> a -> Complex a
:+ (a
sinh_yforall a. Num a => a -> a -> a
*a
cosh_yforall a. Fractional a => a -> a -> a
/a
m)
where sin_x :: a
sin_x = forall a. Floating a => a -> a
sin a
x
cos_x :: a
cos_x = forall a. Floating a => a -> a
cos a
x
sinh_y :: a
sinh_y = forall a. Floating a => a -> a
sinh a
y
cosh_y :: a
cosh_y = forall a. Floating a => a -> a
cosh a
y
u :: a
u = a
cos_x forall a. Num a => a -> a -> a
* a
cosh_y
v :: a
v = a
sin_x forall a. Num a => a -> a -> a
* a
sinh_y
m :: a
m = a
uforall a. Num a => a -> a -> a
*a
u forall a. Num a => a -> a -> a
+ a
vforall a. Num a => a -> a -> a
*a
v
sinh :: Complex a -> Complex a
sinh (a
x:+a
y) = forall a. Floating a => a -> a
cos a
y forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
sinh a
x forall a. a -> a -> Complex a
:+ forall a. Floating a => a -> a
sin a
y forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
cosh a
x
cosh :: Complex a -> Complex a
cosh (a
x:+a
y) = forall a. Floating a => a -> a
cos a
y forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
cosh a
x forall a. a -> a -> Complex a
:+ forall a. Floating a => a -> a
sin a
y forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
sinh a
x
tanh :: Complex a -> Complex a
tanh (a
x:+a
y) = (a
cosyforall a. Num a => a -> a -> a
*a
sinhxforall a. a -> a -> Complex a
:+a
sinyforall a. Num a => a -> a -> a
*a
coshx)forall a. Fractional a => a -> a -> a
/(a
cosyforall a. Num a => a -> a -> a
*a
coshxforall a. a -> a -> Complex a
:+a
sinyforall a. Num a => a -> a -> a
*a
sinhx)
where siny :: a
siny = forall a. Floating a => a -> a
sin a
y
cosy :: a
cosy = forall a. Floating a => a -> a
cos a
y
sinhx :: a
sinhx = forall a. Floating a => a -> a
sinh a
x
coshx :: a
coshx = 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'forall a. a -> a -> Complex a
:+(-a
x')
where (a
x':+a
y') = forall a. Floating a => a -> a
log (((-a
y)forall a. a -> a -> Complex a
:+a
x) forall a. Num a => a -> a -> a
+ forall a. Floating a => a -> a
sqrt (Complex a
1 forall a. Num a => a -> a -> a
- Complex a
zforall a. Num a => a -> a -> a
*Complex a
z))
acos :: Complex a -> Complex a
acos Complex a
z = a
y''forall a. a -> a -> Complex a
:+(-a
x'')
where (a
x'':+a
y'') = forall a. Floating a => a -> a
log (Complex a
z forall a. Num a => a -> a -> a
+ ((-a
y')forall a. a -> a -> Complex a
:+a
x'))
(a
x':+a
y') = forall a. Floating a => a -> a
sqrt (Complex a
1 forall a. Num a => a -> a -> a
- Complex a
zforall 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'forall a. a -> a -> Complex a
:+(-a
x')
where (a
x':+a
y') = forall a. Floating a => a -> a
log (((a
1forall a. Num a => a -> a -> a
-a
y)forall a. a -> a -> Complex a
:+a
x) forall a. Fractional a => a -> a -> a
/ forall a. Floating a => a -> a
sqrt (Complex a
1forall a. Num a => a -> a -> a
+Complex a
zforall a. Num a => a -> a -> a
*Complex a
z))
asinh :: Complex a -> Complex a
asinh Complex a
z = forall a. Floating a => a -> a
log (Complex a
z forall a. Num a => a -> a -> a
+ forall a. Floating a => a -> a
sqrt (Complex a
1forall a. Num a => a -> a -> a
+Complex a
zforall a. Num a => a -> a -> a
*Complex a
z))
acosh :: Complex a -> Complex a
acosh Complex a
z = forall a. Floating a => a -> a
log (Complex a
z forall a. Num a => a -> a -> a
+ (Complex a
zforall a. Num a => a -> a -> a
+Complex a
1) forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
sqrt ((Complex a
zforall a. Num a => a -> a -> a
-Complex a
1)forall a. Fractional a => a -> a -> a
/(Complex a
zforall a. Num a => a -> a -> a
+Complex a
1)))
atanh :: Complex a -> Complex a
atanh Complex a
z = Complex a
0.5 forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
log ((Complex a
1.0forall a. Num a => a -> a -> a
+Complex a
z) forall a. Fractional a => a -> a -> a
/ (Complex a
1.0forall 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 = 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 = forall a. Floating a => a -> a
sqrt (forall a. Num a => Complex a -> a
magnitudeSq Complex a
c)
magnitudeSq :: Num a => Complex a -> a
magnitudeSq :: forall a. Num a => Complex a -> a
magnitudeSq (a
r :+ a
i) = a
rforall a. Num a => a -> a -> a
*a
rforall a. Num a => a -> a -> a
+a
iforall a. Num a => a -> a -> a
*a
i
tryMagnitude :: Num a
=> (a -> b)
-> Complex a
-> b
tryMagnitude :: forall a b. Num a => (a -> b) -> Complex a -> b
tryMagnitude a -> b
sqrtFn = a -> b
sqrtFn forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Num a => Complex a -> a
magnitudeSq
tryComplexSqrt :: (Ord a, Fractional a, Monad m)
=> (a -> m 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
a
m <- a -> m a
sqrtFn (forall a. Num a => Complex a -> a
magnitudeSq Complex a
c)
let r :: a
r = forall a. Complex a -> a
realPart Complex a
c
i :: a
i = forall a. Complex a -> a
imagPart Complex a
c
a
r' <- a -> m a
sqrtFn forall a b. (a -> b) -> a -> b
$ (a
m forall a. Num a => a -> a -> a
+ a
r) forall a. Fractional a => a -> a -> a
/ a
2
a
i' <- a -> m a
sqrtFn forall a b. (a -> b) -> a -> b
$ (a
m forall a. Num a => a -> a -> a
- a
r) forall a. Fractional a => a -> a -> a
/ a
2
let i'' :: a
i'' = if (a
i forall a. Ord a => a -> a -> Bool
>= a
0) then a
i' else -a
i'
forall (m :: Type -> Type) a. Monad m => a -> m a
return (a
r' 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 forall a. Eq a => a -> a -> Bool
== Rational
0 = forall a. a -> Maybe a
Just Rational
r
| Bool
otherwise = forall a. Maybe a
Nothing