{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
module Number.Complex
(
T(real,imag),
imaginaryUnit,
fromReal,
(+:),
(-:),
scale,
exp,
quarterLeft,
quarterRight,
fromPolar,
cis,
signum,
signumNorm,
toPolar,
magnitude,
magnitudeSqr,
phase,
conjugate,
propPolar,
Power(power),
defltPow,
) where
import qualified Algebra.NormedSpace.Euclidean as NormedEuc
import qualified Algebra.NormedSpace.Sum as NormedSum
import qualified Algebra.NormedSpace.Maximum as NormedMax
import qualified Algebra.OccasionallyScalar as OccScalar
import qualified Algebra.VectorSpace as VectorSpace
import qualified Algebra.Module as Module
import qualified Algebra.Vector as Vector
import qualified Algebra.RealTranscendental as RealTrans
import qualified Algebra.Transcendental as Trans
import qualified Algebra.Algebraic as Algebraic
import qualified Algebra.Field as Field
import qualified Algebra.Units as Units
import qualified Algebra.PrincipalIdealDomain as PID
import qualified Algebra.IntegralDomain as Integral
import qualified Algebra.RealRing as RealRing
import qualified Algebra.Absolute as Absolute
import qualified Algebra.Ring as Ring
import qualified Algebra.Additive as Additive
import qualified Algebra.ZeroTestable as ZeroTestable
import qualified Algebra.Indexable as Indexable
import Algebra.Module((<*>.*>), )
import qualified NumericPrelude.Elementwise as Elem
import Algebra.Additive ((<*>.+), (<*>.-), (<*>.-$), )
import Foreign.Storable (Storable (..), )
import qualified Foreign.Storable.Record as Store
import Control.Applicative (liftA2, )
import Test.QuickCheck (Arbitrary, arbitrary, )
import Control.Monad (liftM2, guard, )
import qualified MathObj.Wrapper.Haskell98 as W98
import qualified Prelude as P
import NumericPrelude.Base
import NumericPrelude.Numeric hiding (signum, exp, )
import Text.Show.HT (showsInfixPrec, )
import Text.Read.HT (readsInfixPrec, )
infix 6 +:, `Cons`
data T a
= Cons {T a -> a
real :: !a
,T a -> a
imag :: !a
}
deriving (T a -> T a -> Bool
(T a -> T a -> Bool) -> (T a -> T a -> Bool) -> Eq (T a)
forall a. Eq a => T a -> T a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: T a -> T a -> Bool
$c/= :: forall a. Eq a => T a -> T a -> Bool
== :: T a -> T a -> Bool
$c== :: forall a. Eq a => T a -> T a -> Bool
Eq)
{-# INLINE imaginaryUnit #-}
imaginaryUnit :: Ring.C a => T a
imaginaryUnit :: T a
imaginaryUnit = a
forall a. C a => a
zero a -> a -> T a
forall a. a -> a -> T a
+: a
forall a. C a => a
one
{-# INLINE fromReal #-}
fromReal :: Additive.C a => a -> T a
fromReal :: a -> T a
fromReal a
x = a -> a -> T a
forall a. a -> a -> T a
Cons a
x a
forall a. C a => a
zero
{-# INLINE plusPrec #-}
plusPrec :: Int
plusPrec :: Int
plusPrec = Int
6
instance (Show a) => Show (T a) where
showsPrec :: Int -> T a -> ShowS
showsPrec Int
prec (Cons a
x a
y) = String -> Int -> Int -> a -> a -> ShowS
forall a b.
(Show a, Show b) =>
String -> Int -> Int -> a -> b -> ShowS
showsInfixPrec String
"+:" Int
plusPrec Int
prec a
x a
y
instance (Read a) => Read (T a) where
readsPrec :: Int -> ReadS (T a)
readsPrec Int
prec = String -> Int -> Int -> (a -> a -> T a) -> ReadS (T a)
forall a b c.
(Read a, Read b) =>
String -> Int -> Int -> (a -> b -> c) -> ReadS c
readsInfixPrec String
"+:" Int
plusPrec Int
prec a -> a -> T a
forall a. a -> a -> T a
(+:)
instance Functor T where
{-# INLINE fmap #-}
fmap :: (a -> b) -> T a -> T b
fmap a -> b
f (Cons a
x a
y) = b -> b -> T b
forall a. a -> a -> T a
Cons (a -> b
f a
x) (a -> b
f a
y)
instance (Arbitrary a) => Arbitrary (T a) where
{-# INLINE arbitrary #-}
arbitrary :: Gen (T a)
arbitrary = (a -> a -> T a) -> Gen a -> Gen a -> Gen (T a)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 a -> a -> T a
forall a. a -> a -> T a
Cons Gen a
forall a. Arbitrary a => Gen a
arbitrary Gen a
forall a. Arbitrary a => Gen a
arbitrary
instance (Storable a) => Storable (T a) where
sizeOf :: T a -> Int
sizeOf = Dictionary (T a) -> T a -> Int
forall r. Dictionary r -> r -> Int
Store.sizeOf Dictionary (T a)
forall a. Storable a => Dictionary (T a)
store
alignment :: T a -> Int
alignment = Dictionary (T a) -> T a -> Int
forall r. Dictionary r -> r -> Int
Store.alignment Dictionary (T a)
forall a. Storable a => Dictionary (T a)
store
peek :: Ptr (T a) -> IO (T a)
peek = Dictionary (T a) -> Ptr (T a) -> IO (T a)
forall r. Dictionary r -> Ptr r -> IO r
Store.peek Dictionary (T a)
forall a. Storable a => Dictionary (T a)
store
poke :: Ptr (T a) -> T a -> IO ()
poke = Dictionary (T a) -> Ptr (T a) -> T a -> IO ()
forall r. Dictionary r -> Ptr r -> r -> IO ()
Store.poke Dictionary (T a)
forall a. Storable a => Dictionary (T a)
store
store ::
(Storable a) =>
Store.Dictionary (T a)
store :: Dictionary (T a)
store =
Access (T a) (T a) -> Dictionary (T a)
forall r. Access r r -> Dictionary r
Store.run (Access (T a) (T a) -> Dictionary (T a))
-> Access (T a) (T a) -> Dictionary (T a)
forall a b. (a -> b) -> a -> b
$
(a -> a -> T a)
-> Access (T a) a -> Access (T a) a -> Access (T a) (T a)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> T a
forall a. a -> a -> T a
(+:)
((T a -> a) -> Access (T a) a
forall a r. Storable a => (r -> a) -> Access r a
Store.element T a -> a
forall a. T a -> a
real)
((T a -> a) -> Access (T a) a
forall a r. Storable a => (r -> a) -> Access r a
Store.element T a -> a
forall a. T a -> a
imag)
{-# INLINE (+:) #-}
(+:) :: a -> a -> T a
+: :: a -> a -> T a
(+:) = a -> a -> T a
forall a. a -> a -> T a
Cons
{-# INLINE (-:) #-}
(-:) :: Additive.C a => a -> a -> T a
-: :: a -> a -> T a
(-:) a
x a
y = a -> a -> T a
forall a. a -> a -> T a
Cons a
x (-a
y)
{-# INLINE conjugate #-}
conjugate :: (Additive.C a) => T a -> T a
conjugate :: T a -> T a
conjugate (Cons a
x a
y) = a -> a -> T a
forall a. a -> a -> T a
Cons a
x (-a
y)
{-# INLINE scale #-}
scale :: (Ring.C a) => a -> T a -> T a
scale :: a -> T a -> T a
scale a
r = (a -> a) -> T a -> T a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a
ra -> a -> a
forall a. C a => a -> a -> a
*)
{-# INLINE exp #-}
exp :: (Trans.C a) => T a -> T a
exp :: T a -> T a
exp (Cons a
x a
y) = a -> T a -> T a
forall a. C a => a -> T a -> T a
scale (a -> a
forall a. C a => a -> a
Trans.exp a
x) (a -> T a
forall a. C a => a -> T a
cis a
y)
{-# INLINE quarterRight #-}
{-# INLINE quarterLeft #-}
quarterRight, quarterLeft :: (Additive.C a) => T a -> T a
quarterRight :: T a -> T a
quarterRight (Cons a
x a
y) = a -> a -> T a
forall a. a -> a -> T a
Cons a
y (-a
x)
quarterLeft :: T a -> T a
quarterLeft (Cons a
x a
y) = a -> a -> T a
forall a. a -> a -> T a
Cons (-a
y) a
x
signum :: (Algebraic.C a, ZeroTestable.C a) => T a -> T a
signum :: T a -> T a
signum T a
z =
if T a -> Bool
forall a. C a => a -> Bool
isZero T a
z
then T a
forall a. C a => a
zero
else a -> T a -> T a
forall a. C a => a -> T a -> T a
scale (a -> a
forall a. C a => a -> a
recip (T a -> a
forall a. C a => T a -> a
magnitude T a
z)) T a
z
{-# INLINE signumNorm #-}
signumNorm :: (Algebraic.C a, NormedEuc.C a a, ZeroTestable.C a) => T a -> T a
signumNorm :: T a -> T a
signumNorm T a
z =
if T a -> Bool
forall a. C a => a -> Bool
isZero T a
z
then T a
forall a. C a => a
zero
else a -> T a -> T a
forall a. C a => a -> T a -> T a
scale (a -> a
forall a. C a => a -> a
recip (T a -> a
forall a v. C a v => v -> a
NormedEuc.norm T a
z)) T a
z
{-# INLINE fromPolar #-}
fromPolar :: (Trans.C a) => a -> a -> T a
fromPolar :: a -> a -> T a
fromPolar a
r a
theta = a -> T a -> T a
forall a. C a => a -> T a -> T a
scale a
r (a -> T a
forall a. C a => a -> T a
cis a
theta)
{-# INLINE cis #-}
cis :: (Trans.C a) => a -> T a
cis :: a -> T a
cis a
theta = a -> a -> T a
forall a. a -> a -> T a
Cons (a -> a
forall a. C a => a -> a
cos a
theta) (a -> a
forall a. C a => a -> a
sin a
theta)
propPolar :: (RealTrans.C a, ZeroTestable.C a) => T a -> Bool
propPolar :: T a -> Bool
propPolar T a
z = (a -> a -> T a) -> (a, a) -> T a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry a -> a -> T a
forall a. C a => a -> a -> T a
fromPolar (T a -> (a, a)
forall a. (C a, C a) => T a -> (a, a)
toPolar T a
z) T a -> T a -> Bool
forall a. Eq a => a -> a -> Bool
== T a
z
{-# INLINE floatMagnitude #-}
floatMagnitude :: (P.RealFloat a, Algebraic.C a) => T a -> a
floatMagnitude :: T a -> a
floatMagnitude (Cons a
x a
y) =
let k :: Int
k = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (a -> Int
forall a. RealFloat a => a -> Int
P.exponent a
x) (a -> Int
forall a. RealFloat a => a -> Int
P.exponent a
y)
mk :: Int
mk = - Int
k
in Int -> a -> a
forall a. RealFloat a => Int -> a -> a
P.scaleFloat Int
k
(a -> a
forall a. C a => a -> a
sqrt (Int -> a -> a
forall a. RealFloat a => Int -> a -> a
P.scaleFloat Int
mk a
x a -> Integer -> a
forall a. C a => a -> Integer -> a
^ Integer
2 a -> a -> a
forall a. C a => a -> a -> a
+
Int -> a -> a
forall a. RealFloat a => Int -> a -> a
P.scaleFloat Int
mk a
y a -> Integer -> a
forall a. C a => a -> Integer -> a
^ Integer
2))
{-# INLINE [1] magnitude #-}
magnitude :: (Algebraic.C a) => T a -> a
magnitude :: T a -> a
magnitude = a -> a
forall a. C a => a -> a
sqrt (a -> a) -> (T a -> a) -> T a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> a
forall a. C a => T a -> a
magnitudeSqr
{-# RULES
"Complex.magnitude :: Double"
magnitude = floatMagnitude :: T Double -> Double;
"Complex.magnitude :: Float"
magnitude = floatMagnitude :: T Float -> Float;
#-}
{-# INLINE magnitudeSqr #-}
magnitudeSqr :: (Ring.C a) => T a -> a
magnitudeSqr :: T a -> a
magnitudeSqr (Cons a
x a
y) = a
xa -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2 a -> a -> a
forall a. C a => a -> a -> a
+ a
ya -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
2
{-# INLINE phase #-}
phase :: (RealTrans.C a, ZeroTestable.C a) => T a -> a
phase :: T a -> a
phase T a
z =
if T a -> Bool
forall a. C a => a -> Bool
isZero T a
z
then a
forall a. C a => a
zero
else case T a
z of (Cons a
x a
y) -> a -> a -> a
forall a. C a => a -> a -> a
atan2 a
y a
x
toPolar :: (RealTrans.C a, ZeroTestable.C a) => T a -> (a,a)
toPolar :: T a -> (a, a)
toPolar T a
z = (T a -> a
forall a. C a => T a -> a
magnitude T a
z, T a -> a
forall a. (C a, C a) => T a -> a
phase T a
z)
instance (Indexable.C a) => Indexable.C (T a) where
{-# INLINE compare #-}
compare :: T a -> T a -> Ordering
compare (Cons a
x a
y) (Cons a
x' a
y') = (a, a) -> (a, a) -> Ordering
forall a. C a => a -> a -> Ordering
Indexable.compare (a
x,a
y) (a
x',a
y')
instance (ZeroTestable.C a) => ZeroTestable.C (T a) where
{-# INLINE isZero #-}
isZero :: T a -> Bool
isZero (Cons a
x a
y) = a -> Bool
forall a. C a => a -> Bool
isZero a
x Bool -> Bool -> Bool
&& a -> Bool
forall a. C a => a -> Bool
isZero a
y
instance (Additive.C a) => Additive.C (T a) where
{-# INLINE zero #-}
{-# INLINE negate #-}
{-# INLINE (+) #-}
{-# INLINE (-) #-}
zero :: T a
zero = a -> a -> T a
forall a. a -> a -> T a
Cons a
forall a. C a => a
zero a
forall a. C a => a
zero
+ :: T a -> T a -> T a
(+) = T (T a, T a) (T a) -> T a -> T a -> T a
forall x y a. T (x, y) a -> x -> y -> a
Elem.run2 (T (T a, T a) (T a) -> T a -> T a -> T a)
-> T (T a, T a) (T a) -> T a -> T a -> T a
forall a b. (a -> b) -> a -> b
$ (a -> a -> T a) -> T (T a, T a) (a -> a -> T a)
forall a v. a -> T v a
Elem.with a -> a -> T a
forall a. a -> a -> T a
Cons T (T a, T a) (a -> a -> T a)
-> (T a -> a) -> T (T a, T a) (a -> T a)
forall x v a. C x => T (v, v) (x -> a) -> (v -> x) -> T (v, v) a
<*>.+ T a -> a
forall a. T a -> a
real T (T a, T a) (a -> T a) -> (T a -> a) -> T (T a, T a) (T a)
forall x v a. C x => T (v, v) (x -> a) -> (v -> x) -> T (v, v) a
<*>.+ T a -> a
forall a. T a -> a
imag
(-) = T (T a, T a) (T a) -> T a -> T a -> T a
forall x y a. T (x, y) a -> x -> y -> a
Elem.run2 (T (T a, T a) (T a) -> T a -> T a -> T a)
-> T (T a, T a) (T a) -> T a -> T a -> T a
forall a b. (a -> b) -> a -> b
$ (a -> a -> T a) -> T (T a, T a) (a -> a -> T a)
forall a v. a -> T v a
Elem.with a -> a -> T a
forall a. a -> a -> T a
Cons T (T a, T a) (a -> a -> T a)
-> (T a -> a) -> T (T a, T a) (a -> T a)
forall x v a. C x => T (v, v) (x -> a) -> (v -> x) -> T (v, v) a
<*>.- T a -> a
forall a. T a -> a
real T (T a, T a) (a -> T a) -> (T a -> a) -> T (T a, T a) (T a)
forall x v a. C x => T (v, v) (x -> a) -> (v -> x) -> T (v, v) a
<*>.- T a -> a
forall a. T a -> a
imag
negate :: T a -> T a
negate = T (T a) (T a) -> T a -> T a
forall v a. T v a -> v -> a
Elem.run (T (T a) (T a) -> T a -> T a) -> T (T a) (T a) -> T a -> T a
forall a b. (a -> b) -> a -> b
$ (a -> a -> T a) -> T (T a) (a -> a -> T a)
forall a v. a -> T v a
Elem.with a -> a -> T a
forall a. a -> a -> T a
Cons T (T a) (a -> a -> T a) -> (T a -> a) -> T (T a) (a -> T a)
forall x v a. C x => T v (x -> a) -> (v -> x) -> T v a
<*>.-$ T a -> a
forall a. T a -> a
real T (T a) (a -> T a) -> (T a -> a) -> T (T a) (T a)
forall x v a. C x => T v (x -> a) -> (v -> x) -> T v a
<*>.-$ T a -> a
forall a. T a -> a
imag
instance (Ring.C a) => Ring.C (T a) where
{-# INLINE one #-}
one :: T a
one = a -> a -> T a
forall a. a -> a -> T a
Cons a
forall a. C a => a
one a
forall a. C a => a
zero
{-# INLINE (*) #-}
(Cons a
x a
y) * :: T a -> T a -> T a
* (Cons a
x' a
y') = a -> a -> T a
forall a. a -> a -> T a
Cons (a
xa -> a -> a
forall a. C a => a -> a -> a
*a
x'a -> a -> a
forall a. C a => a -> a -> a
-a
ya -> a -> a
forall a. C a => a -> a -> a
*a
y') (a
xa -> a -> a
forall a. C a => a -> a -> a
*a
y'a -> a -> a
forall a. C a => a -> a -> a
+a
ya -> a -> a
forall a. C a => a -> a -> a
*a
x')
{-# INLINE fromInteger #-}
fromInteger :: Integer -> T a
fromInteger = a -> T a
forall a. C a => a -> T a
fromReal (a -> T a) -> (Integer -> a) -> Integer -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> a
forall a. C a => Integer -> a
fromInteger
instance (Absolute.C a, Algebraic.C a, ZeroTestable.C a) => Absolute.C (T a) where
{-# INLINE abs #-}
{-# INLINE signum #-}
abs :: T a -> T a
abs T a
x = a -> a -> T a
forall a. a -> a -> T a
Cons (T a -> a
forall a. C a => T a -> a
magnitude T a
x) a
forall a. C a => a
zero
signum :: T a -> T a
signum = T a -> T a
forall a. (C a, C a) => T a -> T a
signum
instance Vector.C T where
{-# INLINE zero #-}
zero :: T a
zero = T a
forall a. C a => a
zero
{-# INLINE (<+>) #-}
<+> :: T a -> T a -> T a
(<+>) = T a -> T a -> T a
forall a. C a => a -> a -> a
(+)
{-# INLINE (*>) #-}
*> :: a -> T a -> T a
(*>) = a -> T a -> T a
forall a. C a => a -> T a -> T a
scale
instance (Module.C a b) => Module.C a (T b) where
{-# INLINE (*>) #-}
*> :: a -> T b -> T b
(*>) = T (a, T b) (T b) -> a -> T b -> T b
forall x y a. T (x, y) a -> x -> y -> a
Elem.run2 (T (a, T b) (T b) -> a -> T b -> T b)
-> T (a, T b) (T b) -> a -> T b -> T b
forall a b. (a -> b) -> a -> b
$ (b -> b -> T b) -> T (a, T b) (b -> b -> T b)
forall a v. a -> T v a
Elem.with b -> b -> T b
forall a. a -> a -> T a
Cons T (a, T b) (b -> b -> T b) -> (T b -> b) -> T (a, T b) (b -> T b)
forall a x v c.
C a x =>
T (a, v) (x -> c) -> (v -> x) -> T (a, v) c
<*>.*> T b -> b
forall a. T a -> a
real T (a, T b) (b -> T b) -> (T b -> b) -> T (a, T b) (T b)
forall a x v c.
C a x =>
T (a, v) (x -> c) -> (v -> x) -> T (a, v) c
<*>.*> T b -> b
forall a. T a -> a
imag
instance (VectorSpace.C a b) => VectorSpace.C a (T b)
instance (Additive.C a, NormedSum.C a v) => NormedSum.C a (T v) where
{-# INLINE norm #-}
norm :: T v -> a
norm T v
x = v -> a
forall a v. C a v => v -> a
NormedSum.norm (T v -> v
forall a. T a -> a
real T v
x) a -> a -> a
forall a. C a => a -> a -> a
+ v -> a
forall a v. C a v => v -> a
NormedSum.norm (T v -> v
forall a. T a -> a
imag T v
x)
instance (NormedEuc.Sqr a b) => NormedEuc.Sqr a (T b) where
{-# INLINE normSqr #-}
normSqr :: T b -> a
normSqr T b
x = b -> a
forall a v. Sqr a v => v -> a
NormedEuc.normSqr (T b -> b
forall a. T a -> a
real T b
x) a -> a -> a
forall a. C a => a -> a -> a
+ b -> a
forall a v. Sqr a v => v -> a
NormedEuc.normSqr (T b -> b
forall a. T a -> a
imag T b
x)
instance (Algebraic.C a, NormedEuc.Sqr a b) => NormedEuc.C a (T b) where
{-# INLINE norm #-}
norm :: T b -> a
norm = T b -> a
forall a v. (C a, Sqr a v) => v -> a
NormedEuc.defltNorm
instance (Ord a, NormedMax.C a v) => NormedMax.C a (T v) where
{-# INLINE norm #-}
norm :: T v -> a
norm T v
x = a -> a -> a
forall a. Ord a => a -> a -> a
max (v -> a
forall a v. C a v => v -> a
NormedMax.norm (T v -> v
forall a. T a -> a
real T v
x)) (v -> a
forall a v. C a v => v -> a
NormedMax.norm (T v -> v
forall a. T a -> a
imag T v
x))
instance (Show v, ZeroTestable.C v, Additive.C v, OccScalar.C a v) => OccScalar.C a (T v) where
toScalar :: T v -> a
toScalar = T v -> a
forall a v. (C a v, Show v) => v -> a
OccScalar.toScalarShow
toMaybeScalar :: T v -> Maybe a
toMaybeScalar T v
x =
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (v -> Bool
forall a. C a => a -> Bool
isZero (T v -> v
forall a. T a -> a
imag T v
x)) Maybe () -> Maybe a -> Maybe a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
v -> Maybe a
forall a v. C a v => v -> Maybe a
OccScalar.toMaybeScalar (T v -> v
forall a. T a -> a
real T v
x)
fromScalar :: a -> T v
fromScalar = v -> T v
forall a. C a => a -> T a
fromReal (v -> T v) -> (a -> v) -> a -> T v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> v
forall a v. C a v => a -> v
OccScalar.fromScalar
instance (Integral.C a) => Integral.C (T a) where
divMod :: T a -> T a -> (T a, T a)
divMod T a
z T a
z' =
let denom :: a
denom = T a -> a
forall a. C a => T a -> a
magnitudeSqr T a
z'
zBig :: T a
zBig = T a
z T a -> T a -> T a
forall a. C a => a -> a -> a
* T a -> T a
forall a. C a => T a -> T a
conjugate T a
z'
q :: T a
q = (a -> a) -> T a -> T a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> a -> a) -> a -> a -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> a -> a
forall a. C a => a -> a -> a
div a
denom) T a
zBig
in (T a
q, T a
zT a -> T a -> T a
forall a. C a => a -> a -> a
-T a
qT a -> T a -> T a
forall a. C a => a -> a -> a
*T a
z')
{-# INLINE divModCent #-}
divModCent :: (Ord a, Integral.C a) => T a -> T a -> (T a, T a)
divModCent :: T a -> T a -> (T a, T a)
divModCent T a
z T a
z' =
let denom :: a
denom = T a -> a
forall a. C a => T a -> a
magnitudeSqr T a
z'
zBig :: T a
zBig = T a
z T a -> T a -> T a
forall a. C a => a -> a -> a
* T a -> T a
forall a. C a => T a -> T a
conjugate T a
z'
re :: (a, a)
re = a -> a -> (a, a)
forall a. C a => a -> a -> (a, a)
divMod (T a -> a
forall a. T a -> a
real T a
zBig) a
denom
im :: (a, a)
im = a -> a -> (a, a)
forall a. C a => a -> a -> (a, a)
divMod (T a -> a
forall a. T a -> a
imag T a
zBig) a
denom
q :: T a
q = a -> a -> T a
forall a. a -> a -> T a
Cons ((a, a) -> a
forall a b. (a, b) -> a
fst (a, a)
re) ((a, a) -> a
forall a b. (a, b) -> a
fst (a, a)
im)
r :: T a
r = a -> a -> T a
forall a. a -> a -> T a
Cons ((a, a) -> a
forall a b. (a, b) -> b
snd (a, a)
re) ((a, a) -> a
forall a b. (a, b) -> b
snd (a, a)
im)
q' :: T a
q' = a -> a -> T a
forall a. a -> a -> T a
Cons
(T a -> a
forall a. T a -> a
real T a
q a -> a -> a
forall a. C a => a -> a -> a
+ if a
2 a -> a -> a
forall a. C a => a -> a -> a
* T a -> a
forall a. T a -> a
real T a
r a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
denom then a
forall a. C a => a
one else a
forall a. C a => a
zero)
(T a -> a
forall a. T a -> a
imag T a
q a -> a -> a
forall a. C a => a -> a -> a
+ if a
2 a -> a -> a
forall a. C a => a -> a -> a
* T a -> a
forall a. T a -> a
imag T a
r a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
denom then a
forall a. C a => a
one else a
forall a. C a => a
zero)
in (T a
q', T a
zT a -> T a -> T a
forall a. C a => a -> a -> a
-T a
q'T a -> T a -> T a
forall a. C a => a -> a -> a
*T a
z')
{-# INLINE modCent #-}
modCent :: (Ord a, Integral.C a) => T a -> T a -> T a
modCent :: T a -> T a -> T a
modCent T a
z T a
z' = (T a, T a) -> T a
forall a b. (a, b) -> b
snd (T a -> T a -> (T a, T a)
forall a. (Ord a, C a) => T a -> T a -> (T a, T a)
divModCent T a
z T a
z')
instance (Ord a, Units.C a) => Units.C (T a) where
{-# INLINE isUnit #-}
isUnit :: T a -> Bool
isUnit (Cons a
x a
y) =
a -> Bool
forall a. C a => a -> Bool
isUnit a
x Bool -> Bool -> Bool
&& a
ya -> a -> Bool
forall a. Eq a => a -> a -> Bool
==a
forall a. C a => a
zero Bool -> Bool -> Bool
||
a -> Bool
forall a. C a => a -> Bool
isUnit a
y Bool -> Bool -> Bool
&& a
xa -> a -> Bool
forall a. Eq a => a -> a -> Bool
==a
forall a. C a => a
zero
{-# INLINE stdAssociate #-}
stdAssociate :: T a -> T a
stdAssociate z :: T a
z@(Cons a
x a
y) =
let z' :: T a
z' = if a
ya -> a -> Bool
forall a. Ord a => a -> a -> Bool
<a
0 Bool -> Bool -> Bool
|| a
ya -> a -> Bool
forall a. Eq a => a -> a -> Bool
==a
0 Bool -> Bool -> Bool
&& a
xa -> a -> Bool
forall a. Ord a => a -> a -> Bool
<a
0 then T a -> T a
forall a. C a => a -> a
negate T a
z else T a
z
in if T a -> a
forall a. T a -> a
real T a
z'a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<=a
0 then T a -> T a
forall a. C a => T a -> T a
quarterRight T a
z' else T a
z'
{-# INLINE stdUnit #-}
stdUnit :: T a -> T a
stdUnit z :: T a
z@(Cons a
x a
y) =
if T a
zT a -> T a -> Bool
forall a. Eq a => a -> a -> Bool
==T a
forall a. C a => a
zero
then T a
1
else
let (a
x',T a
sgn') = if a
ya -> a -> Bool
forall a. Ord a => a -> a -> Bool
<a
0 Bool -> Bool -> Bool
|| a
ya -> a -> Bool
forall a. Eq a => a -> a -> Bool
==a
0 Bool -> Bool -> Bool
&& a
xa -> a -> Bool
forall a. Ord a => a -> a -> Bool
<a
0
then (a -> a
forall a. C a => a -> a
negate a
x, -T a
1)
else (a
x, T a
1)
in if a
x'a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<=a
0 then T a -> T a
forall a. C a => T a -> T a
quarterLeft T a
sgn' else T a
sgn'
instance (Ord a, ZeroTestable.C a, Units.C a) => PID.C (T a) where
{-# INLINE gcd #-}
gcd :: T a -> T a -> T a
gcd = (T a -> T a -> T a) -> T a -> T a -> T a
forall a. (C a, C a) => (a -> a -> a) -> a -> a -> a
euclid T a -> T a -> T a
forall a. (Ord a, C a) => T a -> T a -> T a
modCent
{-# INLINE extendedGCD #-}
extendedGCD :: T a -> T a -> (T a, (T a, T a))
extendedGCD = (T a -> T a -> (T a, T a)) -> T a -> T a -> (T a, (T a, T a))
forall a. (C a, C a) => (a -> a -> (a, a)) -> a -> a -> (a, (a, a))
extendedEuclid T a -> T a -> (T a, T a)
forall a. (Ord a, C a) => T a -> T a -> (T a, T a)
divModCent
{-# INLINE [1] divide #-}
divide :: (Field.C a) => T a -> T a -> T a
divide :: T a -> T a -> T a
divide (Cons a
x a
y) z' :: T a
z'@(Cons a
x' a
y') =
let d :: a
d = T a -> a
forall a. C a => T a -> a
magnitudeSqr T a
z'
in a -> a -> T a
forall a. a -> a -> T a
Cons ((a
xa -> a -> a
forall a. C a => a -> a -> a
*a
x'a -> a -> a
forall a. C a => a -> a -> a
+a
ya -> a -> a
forall a. C a => a -> a -> a
*a
y') a -> a -> a
forall a. C a => a -> a -> a
/ a
d) ((a
ya -> a -> a
forall a. C a => a -> a -> a
*a
x'a -> a -> a
forall a. C a => a -> a -> a
-a
xa -> a -> a
forall a. C a => a -> a -> a
*a
y') a -> a -> a
forall a. C a => a -> a -> a
/ a
d)
{-# INLINE floatDivide #-}
floatDivide :: (P.RealFloat a, Field.C a) => T a -> T a -> T a
floatDivide :: T a -> T a -> T a
floatDivide (Cons a
x a
y) (Cons a
x' a
y') =
let k :: Int
k = - Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (a -> Int
forall a. RealFloat a => a -> Int
P.exponent a
x') (a -> Int
forall a. RealFloat a => a -> Int
P.exponent a
y')
x'' :: a
x'' = Int -> a -> a
forall a. RealFloat a => Int -> a -> a
P.scaleFloat Int
k a
x'
y'' :: a
y'' = Int -> a -> a
forall a. RealFloat a => Int -> a -> a
P.scaleFloat Int
k a
y'
d :: a
d = a
x'a -> a -> a
forall a. C a => a -> a -> a
*a
x'' a -> a -> a
forall a. C a => a -> a -> a
+ a
y'a -> a -> a
forall a. C a => a -> a -> a
*a
y''
in a -> a -> T a
forall a. a -> a -> T a
Cons ((a
xa -> a -> a
forall a. C a => a -> a -> a
*a
x''a -> a -> a
forall a. C a => a -> a -> a
+a
ya -> a -> a
forall a. C a => a -> a -> a
*a
y'') a -> a -> a
forall a. C a => a -> a -> a
/ a
d) ((a
ya -> a -> a
forall a. C a => a -> a -> a
*a
x''a -> a -> a
forall a. C a => a -> a -> a
-a
xa -> a -> a
forall a. C a => a -> a -> a
*a
y'') a -> a -> a
forall a. C a => a -> a -> a
/ a
d)
{-# RULES
"Complex.divide :: Double"
divide = floatDivide :: T Double -> T Double -> T Double;
"Complex.divide :: Float"
divide = floatDivide :: T Float -> T Float -> T Float;
#-}
instance (Field.C a) => Field.C (T a) where
{-# INLINE (/) #-}
/ :: T a -> T a -> T a
(/) = T a -> T a -> T a
forall a. C a => T a -> T a -> T a
divide
{-# INLINE fromRational' #-}
fromRational' :: Rational -> T a
fromRational' = a -> T a
forall a. C a => a -> T a
fromReal (a -> T a) -> (Rational -> a) -> Rational -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> a
forall a. C a => Rational -> a
fromRational'
class (Algebraic.C a) => (Power a) where
power :: Rational -> T a -> T a
{-# INLINE defltPow #-}
defltPow :: (RealTrans.C a, ZeroTestable.C a) =>
Rational -> T a -> T a
defltPow :: Rational -> T a -> T a
defltPow Rational
r T a
x =
let (a
mag,a
arg) = T a -> (a, a)
forall a. (C a, C a) => T a -> (a, a)
toPolar T a
x
in a -> a -> T a
forall a. C a => a -> a -> T a
fromPolar (a
mag a -> Rational -> a
forall a. C a => a -> Rational -> a
^/ Rational
r)
(a
arg a -> a -> a
forall a. C a => a -> a -> a
* Rational -> a
forall a. C a => Rational -> a
fromRational' Rational
r)
instance Power Float where
{-# INLINE power #-}
power :: Rational -> T Float -> T Float
power = Rational -> T Float -> T Float
forall a. (C a, C a) => Rational -> T a -> T a
defltPow
instance Power Double where
{-# INLINE power #-}
power :: Rational -> T Double -> T Double
power = Rational -> T Double -> T Double
forall a. (C a, C a) => Rational -> T a -> T a
defltPow
instance (RealRing.C a, Algebraic.C a, Power a) =>
Algebraic.C (T a) where
{-# INLINE sqrt #-}
sqrt :: T a -> T a
sqrt z :: T a
z@(Cons a
x a
y) = if T a
z T a -> T a -> Bool
forall a. Eq a => a -> a -> Bool
== T a
forall a. C a => a
zero
then T a
forall a. C a => a
zero
else
let u' :: a
u' = a -> a
forall a. C a => a -> a
sqrt ((T a -> a
forall a. C a => T a -> a
magnitude T a
z a -> a -> a
forall a. C a => a -> a -> a
+ a -> a
forall a. C a => a -> a
abs a
x) a -> a -> a
forall a. C a => a -> a -> a
/ a
2)
v' :: a
v' = a -> a
forall a. C a => a -> a
abs a
y a -> a -> a
forall a. C a => a -> a -> a
/ (a
u'a -> a -> a
forall a. C a => a -> a -> a
*a
2)
(a
u,a
v) = if a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 then (a
v',a
u') else (a
u',a
v')
in a -> a -> T a
forall a. a -> a -> T a
Cons a
u (if a
y a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 then -a
v else a
v)
{-# INLINE (^/) #-}
^/ :: T a -> Rational -> T a
(^/) = (Rational -> T a -> T a) -> T a -> Rational -> T a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Rational -> T a -> T a
forall a. Power a => Rational -> T a -> T a
power
instance (RealRing.C a, RealTrans.C a, ZeroTestable.C a, Power a) =>
Trans.C (T a) where
{-# INLINE pi #-}
pi :: T a
pi = a -> T a
forall a. C a => a -> T a
fromReal a
forall a. C a => a
pi
{-# INLINE exp #-}
exp :: T a -> T a
exp = T a -> T a
forall a. C a => T a -> T a
exp
{-# INLINE log #-}
log :: T a -> T a
log T a
z = let (a
m,a
p) = T a -> (a, a)
forall a. (C a, C a) => T a -> (a, a)
toPolar T a
z in a -> a -> T a
forall a. a -> a -> T a
Cons (a -> a
forall a. C a => a -> a
log a
m) a
p
{-# INLINE sin #-}
sin :: T a -> T a
sin (Cons a
x a
y) = a -> a -> T a
forall a. a -> a -> T a
Cons (a -> a
forall a. C a => a -> a
sin a
x a -> a -> a
forall a. C a => a -> a -> a
* a -> a
forall a. C a => a -> a
cosh a
y) ( a -> a
forall a. C a => a -> a
cos a
x a -> a -> a
forall a. C a => a -> a -> a
* a -> a
forall a. C a => a -> a
sinh a
y)
{-# INLINE cos #-}
cos :: T a -> T a
cos (Cons a
x a
y) = a -> a -> T a
forall a. a -> a -> T a
Cons (a -> a
forall a. C a => a -> a
cos a
x a -> a -> a
forall a. C a => a -> a -> a
* a -> a
forall a. C a => a -> a
cosh a
y) (- a -> a
forall a. C a => a -> a
sin a
x a -> a -> a
forall a. C a => a -> a -> a
* a -> a
forall a. C a => a -> a
sinh a
y)
{-# INLINE sinh #-}
sinh :: T a -> T a
sinh (Cons a
x a
y) = a -> a -> T a
forall a. a -> a -> T a
Cons (a -> a
forall a. C a => a -> a
cos a
y a -> a -> a
forall a. C a => a -> a -> a
* a -> a
forall a. C a => a -> a
sinh a
x) (a -> a
forall a. C a => a -> a
sin a
y a -> a -> a
forall a. C a => a -> a -> a
* a -> a
forall a. C a => a -> a
cosh a
x)
{-# INLINE cosh #-}
cosh :: T a -> T a
cosh (Cons a
x a
y) = a -> a -> T a
forall a. a -> a -> T a
Cons (a -> a
forall a. C a => a -> a
cos a
y a -> a -> a
forall a. C a => a -> a -> a
* a -> a
forall a. C a => a -> a
cosh a
x) (a -> a
forall a. C a => a -> a
sin a
y a -> a -> a
forall a. C a => a -> a -> a
* a -> a
forall a. C a => a -> a
sinh a
x)
{-# INLINE asin #-}
asin :: T a -> T a
asin T a
z = T a -> T a
forall a. C a => T a -> T a
quarterRight (T a -> T a
forall a. C a => a -> a
log (T a -> T a
forall a. C a => T a -> T a
quarterLeft T a
z T a -> T a -> T a
forall a. C a => a -> a -> a
+ T a -> T a
forall a. C a => a -> a
sqrt (T a
1 T a -> T a -> T a
forall a. C a => a -> a -> a
- T a
zT a -> Integer -> T a
forall a. C a => a -> Integer -> a
^Integer
2)))
{-# INLINE acos #-}
acos :: T a -> T a
acos T a
z = T a -> T a
forall a. C a => T a -> T a
quarterRight (T a -> T a
forall a. C a => a -> a
log (T a
z T a -> T a -> T a
forall a. C a => a -> a -> a
+ T a -> T a
forall a. C a => T a -> T a
quarterLeft (T a -> T a
forall a. C a => a -> a
sqrt (T a
1 T a -> T a -> T a
forall a. C a => a -> a -> a
- T a
zT a -> Integer -> T a
forall a. C a => a -> Integer -> a
^Integer
2))))
{-# INLINE atan #-}
atan :: T a -> T a
atan z :: T a
z@(Cons a
x a
y) = T a -> T a
forall a. C a => T a -> T a
quarterRight (T a -> T a
forall a. C a => a -> a
log (a -> a -> T a
forall a. a -> a -> T a
Cons (a
1a -> a -> a
forall a. C a => a -> a -> a
-a
y) a
x T a -> T a -> T a
forall a. C a => a -> a -> a
/ T a -> T a
forall a. C a => a -> a
sqrt (T a
1T a -> T a -> T a
forall a. C a => a -> a -> a
+T a
zT a -> Integer -> T a
forall a. C a => a -> Integer -> a
^Integer
2)))
instance (P.Floating a, Eq a) => P.Num (T a) where
{-# INLINE fromInteger #-}
fromInteger :: Integer -> T a
fromInteger Integer
n = a -> a -> T a
forall a. a -> a -> T a
Cons (Integer -> a
forall a. Num a => Integer -> a
P.fromInteger Integer
n) (Integer -> a
forall a. Num a => Integer -> a
P.fromInteger Integer
0)
{-# INLINE negate #-}
negate :: T a -> T a
negate = (T (T a) -> T (T a)) -> T a -> T a
forall (f :: * -> *) a b.
Functor f =>
(f (T a) -> f (T b)) -> f a -> f b
W98.unliftF1 T (T a) -> T (T a)
forall a. C a => a -> a
Additive.negate
{-# INLINE (+) #-}
+ :: T a -> T a -> T a
(+) = (T (T a) -> T (T a) -> T (T a)) -> T a -> T a -> T a
forall (f :: * -> *) a b c.
Functor f =>
(f (T a) -> f (T b) -> f (T c)) -> f a -> f b -> f c
W98.unliftF2 T (T a) -> T (T a) -> T (T a)
forall a. C a => a -> a -> a
(Additive.+)
{-# INLINE (*) #-}
* :: T a -> T a -> T a
(*) = (T (T a) -> T (T a) -> T (T a)) -> T a -> T a -> T a
forall (f :: * -> *) a b c.
Functor f =>
(f (T a) -> f (T b) -> f (T c)) -> f a -> f b -> f c
W98.unliftF2 T (T a) -> T (T a) -> T (T a)
forall a. C a => a -> a -> a
(Ring.*)
{-# INLINE abs #-}
abs :: T a -> T a
abs = (T (T a) -> T (T a)) -> T a -> T a
forall (f :: * -> *) a b.
Functor f =>
(f (T a) -> f (T b)) -> f a -> f b
W98.unliftF1 T (T a) -> T (T a)
forall a. C a => a -> a
Absolute.abs
{-# INLINE signum #-}
signum :: T a -> T a
signum = (T (T a) -> T (T a)) -> T a -> T a
forall (f :: * -> *) a b.
Functor f =>
(f (T a) -> f (T b)) -> f a -> f b
W98.unliftF1 T (T a) -> T (T a)
forall a. C a => a -> a
Absolute.signum
instance (P.Floating a, Eq a) => P.Fractional (T a) where
{-# INLINE fromRational #-}
fromRational :: Rational -> T a
fromRational Rational
x = a -> a -> T a
forall a. a -> a -> T a
Cons (Rational -> a
forall a. Fractional a => Rational -> a
P.fromRational Rational
x) (Integer -> a
forall a. Num a => Integer -> a
P.fromInteger Integer
0)
{-# INLINE (/) #-}
/ :: T a -> T a -> T a
(/) = (T (T a) -> T (T a) -> T (T a)) -> T a -> T a -> T a
forall (f :: * -> *) a b c.
Functor f =>
(f (T a) -> f (T b) -> f (T c)) -> f a -> f b -> f c
W98.unliftF2 T (T a) -> T (T a) -> T (T a)
forall a. C a => a -> a -> a
(Field./)