module Numeric.VariablePrecision.Complex
( VComplex()
, (.+)
, (.*)
, (*.)
, toComplex
, fromComplex
, withComplex
, mapComplex
, recodeComplex
, scaleComplex
, realPart
, imagPart
, conjugate
, magnitude
, magnitude2
, sqr
, phase
, polar
, cis
, mkPolar
, scaleComplex'
, magnitude2'
, sqr'
, DComplex(..)
, toDComplex
, fromDComplex
, withDComplex
) where
import Data.Data (Data())
import Data.Typeable (Typeable())
import qualified Data.Complex as X
import Numeric.VariablePrecision.Float
import Numeric.VariablePrecision.Precision
import Numeric.VariablePrecision.Algorithms (recodeFloat)
newtype VComplex p = FromComplex
{
toComplex :: X.Complex (VFloat p)
}
deriving (Eq, Num, Fractional, Floating, Data, Typeable)
fromComplex :: X.Complex (VFloat p) -> VComplex p
fromComplex = FromComplex
(.+) :: NaturalNumber p => VFloat p -> VFloat p -> VComplex p
x .+ y = fromComplex (x X.:+ y)
infix 6 .+
instance HasPrecision VComplex
instance VariablePrecision VComplex where
adjustPrecision = withComplex (mapComplex adjustPrecision)
instance Normed VComplex where
norm1 z = abs (realPart z) + abs (imagPart z)
norm2 = magnitude
norm2Squared = magnitude2
normInfinity z = abs (realPart z) `max` abs (imagPart z)
withComplex :: (X.Complex (VFloat p) -> X.Complex (VFloat q)) -> (VComplex p -> VComplex q)
withComplex f = fromComplex . f . toComplex
instance NaturalNumber p => Show (VComplex p) where
showsPrec p = showsPrec p . toComplex
instance NaturalNumber p => Read (VComplex p) where
readsPrec p = map (first fromComplex) . readsPrec p
where first f (a, b) = (f a, b)
cis :: NaturalNumber p => VFloat p -> VComplex p
cis = fromComplex . X.cis
mkPolar :: NaturalNumber p => VFloat p -> VFloat p -> VComplex p
mkPolar r t = fromComplex (X.mkPolar r t)
conjugate :: NaturalNumber p => VComplex p -> VComplex p
conjugate = withComplex X.conjugate
imagPart :: NaturalNumber p => VComplex p -> VFloat p
imagPart = X.imagPart . toComplex
realPart :: NaturalNumber p => VComplex p -> VFloat p
realPart = X.realPart . toComplex
phase :: NaturalNumber p => VComplex p -> VFloat p
phase = X.phase . toComplex
polar :: NaturalNumber p => VComplex p -> (VFloat p, VFloat p)
polar = X.polar . toComplex
magnitude :: NaturalNumber p => VComplex p -> VFloat p
magnitude = X.magnitude . toComplex
magnitude2 :: NaturalNumber p => VComplex p -> VFloat p
magnitude2 = magnitude2' . toComplex
mapComplex :: (RealFloat a, RealFloat b) => (a -> b) -> X.Complex a -> X.Complex b
mapComplex f (x X.:+ y) = f x X.:+ f y
recodeComplex :: (RealFloat a, RealFloat b) => X.Complex a -> X.Complex b
recodeComplex = mapComplex recodeFloat
magnitude2' :: RealFloat r => X.Complex r -> r
magnitude2' (x X.:+ y) = x * x + y * y
sqr :: NaturalNumber p => VComplex p -> VComplex p
sqr = withComplex sqr'
sqr' :: RealFloat r => X.Complex r -> X.Complex r
sqr' (x X.:+ y) = (x + y) * (x y) X.:+ scaleFloat 1 (x * y)
scaleComplex :: NaturalNumber p => Int -> VComplex p -> VComplex p
scaleComplex = withComplex . scaleComplex'
scaleComplex' :: RealFloat r => Int -> X.Complex r -> X.Complex r
scaleComplex' = mapComplex . scaleFloat
(.*) :: NaturalNumber p => VFloat p -> VComplex p -> VComplex p
x .* y = withComplex (mapComplex (x *)) y
infixl 7 .*
(*.) :: NaturalNumber p => VComplex p -> VFloat p -> VComplex p
x *. y = withComplex (mapComplex (* y)) x
infixl 7 *.
data DComplex = DComplex{ dRealPart :: !DFloat, dImagPart :: !DFloat }
deriving (Eq, Ord, Read, Show, Data, Typeable)
toDComplex :: NaturalNumber p => VComplex p -> DComplex
toDComplex v = DComplex (toDFloat (realPart v)) (toDFloat (imagPart v))
fromDComplex :: NaturalNumber p => DComplex -> Maybe (VComplex p)
fromDComplex d = do
r <- fromDFloat (dRealPart d)
i <- fromDFloat (dImagPart d)
return (r .+ i)
withDComplex :: DComplex -> (forall p . NaturalNumber p => Maybe (VComplex p) -> r) -> r
withDComplex d f = withDFloat (dRealPart d) $ \r -> f $ do
i <- fromDFloat (dImagPart d)
return (r .+ i)