{-| Module : Numeric.MixedType.Complex Description : Instances for Data.Complex Copyright : (c) Michal Konecny License : BSD3 Maintainer : mikkonecny@gmail.com Stability : experimental Portability : portable Instances for "Data.Complex". -} module Numeric.MixedTypes.Complex ( ) where import Numeric.MixedTypes.PreludeHiding -- import qualified Prelude as P -- import Text.Printf import Data.Complex import Numeric.MixedTypes.Literals import Numeric.MixedTypes.Bool import Numeric.MixedTypes.Eq import Numeric.MixedTypes.MinMaxAbs import Numeric.MixedTypes.AddSub import Numeric.MixedTypes.Ring import Numeric.MixedTypes.Field import Numeric.MixedTypes.Elementary instance (ConvertibleExactly Integer t) => (ConvertibleExactly Integer (Complex t)) where safeConvertExactly n = do nT <- safeConvertExactly n zT <- safeConvertExactly 0 return $ nT :+ zT instance (ConvertibleExactly Int t) => (ConvertibleExactly Int (Complex t)) where safeConvertExactly n = do nT <- safeConvertExactly n zT <- safeConvertExactly (int 0) return $ nT :+ zT instance (ConvertibleExactly Rational t) => (ConvertibleExactly Rational (Complex t)) where safeConvertExactly r = do rT <- safeConvertExactly r zT <- safeConvertExactly 0.0 return $ rT :+ zT instance (ConvertibleExactly t1 t2) => (ConvertibleExactly (Complex t1) (Complex t2)) where safeConvertExactly (a1 :+ i1) = do a2 <- safeConvertExactly a1 i2 <- safeConvertExactly i1 return $ a2 :+ i2 instance (HasEqAsymmetric a b) => HasEqAsymmetric (Complex a) (Complex b) where type EqCompareType (Complex a) (Complex b) = EqCompareType a b equalTo (a1 :+ i1) (a2 :+ i2) = (a1 == a2) && (i1 == i2) instance (HasEqAsymmetric Integer b) => HasEqAsymmetric Integer (Complex b) where type EqCompareType Integer (Complex b) = EqCompareType Integer b equalTo n (a2 :+ i2) = (n == a2) && (0 == i2) instance (HasEqAsymmetric a Integer) => HasEqAsymmetric (Complex a) Integer where type EqCompareType (Complex a) Integer = EqCompareType a Integer equalTo (a1 :+ i1) n = (a1 == n) && (i1 == 0) instance (HasEqAsymmetric Rational b) => HasEqAsymmetric Rational (Complex b) where type EqCompareType Rational (Complex b) = EqCompareType Rational b equalTo n (a2 :+ i2) = (n == a2) && (0.0 == i2) instance (HasEqAsymmetric a Rational) => HasEqAsymmetric (Complex a) Rational where type EqCompareType (Complex a) Rational = EqCompareType a Rational equalTo (a1 :+ i1) n = (a1 == n) && (i1 == 0.0) instance (HasEqAsymmetric Int b) => HasEqAsymmetric Int (Complex b) where type EqCompareType Int (Complex b) = EqCompareType Int b equalTo n (a2 :+ i2) = (n == a2) && ((int 0) == i2) instance (HasEqAsymmetric a Int) => HasEqAsymmetric (Complex a) Int where type EqCompareType (Complex a) Int = EqCompareType a Int equalTo (a1 :+ i1) n = (a1 == n) && (i1 == (int 0)) instance (HasEqAsymmetric Double b) => HasEqAsymmetric Double (Complex b) where type EqCompareType Double (Complex b) = EqCompareType Double b equalTo n (a2 :+ i2) = (n == a2) && ((double 0) == i2) instance (HasEqAsymmetric a Double) => HasEqAsymmetric (Complex a) Double where type EqCompareType (Complex a) Double = EqCompareType a Double equalTo (a1 :+ i1) n = (a1 == n) && (i1 == (double 0)) instance (CanTestInteger t, CanTestZero t) => CanTestInteger (Complex t) where certainlyNotInteger (a :+ i) = certainlyNotInteger a || isCertainlyNonZero i certainlyIntegerGetIt (a :+ i) = case (certainlyIntegerGetIt a, certainlyIntegerGetIt i) of (Just aN, Just iN) | iN == 0 -> Just aN _ -> Nothing instance CanNeg t => CanNeg (Complex t) where type NegType (Complex t) = Complex (NegType t) negate (a :+ i) = (negate a) :+ (negate i) instance (CanAddAsymmetric a b) => CanAddAsymmetric (Complex a) (Complex b) where type AddType (Complex a) (Complex b) = Complex (AddType a b) add (a1 :+ i1) (a2 :+ i2) = (a1 + a2) :+ (i1 + i2) instance (CanAddAsymmetric Integer b) => CanAddAsymmetric Integer (Complex b) where type AddType Integer (Complex b) = Complex (AddType Integer b) add n (a2 :+ i2) = (n + a2) :+ (0 + i2) instance (CanAddAsymmetric a Integer) => CanAddAsymmetric (Complex a) Integer where type AddType (Complex a) Integer = Complex (AddType a Integer) add (a1 :+ i1) n = (a1 + n) :+ (i1 + 0) instance (CanAddAsymmetric Rational b) => CanAddAsymmetric Rational (Complex b) where type AddType Rational (Complex b) = Complex (AddType Rational b) add n (a2 :+ i2) = (n + a2) :+ (0.0 + i2) instance (CanAddAsymmetric a Rational) => CanAddAsymmetric (Complex a) Rational where type AddType (Complex a) Rational = Complex (AddType a Rational) add (a1 :+ i1) n = (a1 + n) :+ (i1 + 0.0) instance (CanAddAsymmetric Int b) => CanAddAsymmetric Int (Complex b) where type AddType Int (Complex b) = Complex (AddType Int b) add n (a2 :+ i2) = (n + a2) :+ ((int 0) + i2) instance (CanAddAsymmetric a Int) => CanAddAsymmetric (Complex a) Int where type AddType (Complex a) Int = Complex (AddType a Int) add (a1 :+ i1) n = (a1 + n) :+ (i1 + (int 0)) instance (CanAddAsymmetric Double b) => CanAddAsymmetric Double (Complex b) where type AddType Double (Complex b) = Complex (AddType Double b) add n (a2 :+ i2) = (n + a2) :+ ((double 0) + i2) instance (CanAddAsymmetric a Double) => CanAddAsymmetric (Complex a) Double where type AddType (Complex a) Double = Complex (AddType a Double) add (a1 :+ i1) n = (a1 + n) :+ (i1 + (double 0)) instance (CanSub a b) => CanSub (Complex a) (Complex b) where type SubType (Complex a) (Complex b) = Complex (SubType a b) sub (a1 :+ i1) (a2 :+ i2) = (a1 - a2) :+ (i1 - i2) instance (CanSub Integer b) => CanSub Integer (Complex b) where type SubType Integer (Complex b) = Complex (SubType Integer b) sub n (a2 :+ i2) = (n - a2) :+ (0 - i2) instance (CanSub a Integer) => CanSub (Complex a) Integer where type SubType (Complex a) Integer = Complex (SubType a Integer) sub (a1 :+ i1) n = (a1 - n) :+ (i1 - 0) instance (CanSub Rational b) => CanSub Rational (Complex b) where type SubType Rational (Complex b) = Complex (SubType Rational b) sub n (a2 :+ i2) = (n - a2) :+ (0.0 - i2) instance (CanSub a Rational) => CanSub (Complex a) Rational where type SubType (Complex a) Rational = Complex (SubType a Rational) sub (a1 :+ i1) n = (a1 - n) :+ (i1 - 0.0) instance (CanSub Int b) => CanSub Int (Complex b) where type SubType Int (Complex b) = Complex (SubType Int b) sub n (a2 :+ i2) = (n - a2) :+ ((int 0) - i2) instance (CanSub a Int) => CanSub (Complex a) Int where type SubType (Complex a) Int = Complex (SubType a Int) sub (a1 :+ i1) n = (a1 - n) :+ (i1 - (int 0)) instance (CanSub Double b) => CanSub Double (Complex b) where type SubType Double (Complex b) = Complex (SubType Double b) sub n (a2 :+ i2) = (n - a2) :+ ((double 0) - i2) instance (CanSub a Double) => CanSub (Complex a) Double where type SubType (Complex a) Double = Complex (SubType a Double) sub (a1 :+ i1) n = (a1 - n) :+ (i1 - (double 0)) instance (CanMulAsymmetric a b , CanAddSameType (MulType a b), CanSubSameType (MulType a b)) => CanMulAsymmetric (Complex a) (Complex b) where type MulType (Complex a) (Complex b) = Complex (MulType a b) mul (a1 :+ i1) (a2 :+ i2) = (a1*a2 - i1*i2) :+ (a1*i2 + i1*a2) instance (CanMulAsymmetric Integer b) => CanMulAsymmetric Integer (Complex b) where type MulType Integer (Complex b) = Complex (MulType Integer b) mul n (a2 :+ i2) = (n*a2) :+ (n*i2) instance (CanMulAsymmetric a Integer) => CanMulAsymmetric (Complex a) Integer where type MulType (Complex a) Integer = Complex (MulType a Integer) mul (a1 :+ i1) n = (a1*n) :+ (i1*n) instance (CanMulAsymmetric Int b) => CanMulAsymmetric Int (Complex b) where type MulType Int (Complex b) = Complex (MulType Int b) mul n (a2 :+ i2) = (n*a2) :+ (n*i2) instance (CanMulAsymmetric a Int) => CanMulAsymmetric (Complex a) Int where type MulType (Complex a) Int = Complex (MulType a Int) mul (a1 :+ i1) n = (a1*n) :+ (i1*n) instance (CanMulAsymmetric Rational b) => CanMulAsymmetric Rational (Complex b) where type MulType Rational (Complex b) = Complex (MulType Rational b) mul n (a2 :+ i2) = (n*a2) :+ (n*i2) instance (CanMulAsymmetric a Rational) => CanMulAsymmetric (Complex a) Rational where type MulType (Complex a) Rational = Complex (MulType a Rational) mul (a1 :+ i1) n = (a1*n) :+ (i1*n) instance (CanMulAsymmetric Double b) => CanMulAsymmetric Double (Complex b) where type MulType Double (Complex b) = Complex (MulType Double b) mul n (a2 :+ i2) = (n*a2) :+ (n*i2) instance (CanMulAsymmetric a Double) => CanMulAsymmetric (Complex a) Double where type MulType (Complex a) Double = Complex (MulType a Double) mul (a1 :+ i1) n = (a1*n) :+ (i1*n) instance (CanMulAsymmetric a b , CanAddSameType (MulType a b), CanSubSameType (MulType a b) , CanMulAsymmetric b b, CanAddSameType (MulType b b) , CanDiv (MulType a b) (MulType b b)) => CanDiv (Complex a) (Complex b) where type DivType (Complex a) (Complex b) = Complex (DivType (MulType a b) (MulType b b)) divide (a1 :+ i1) (a2 :+ i2) = let d = a2*a2 + i2*i2 in ((a1*a2 + i1*i2)/d) :+ ((i1*a2-a1*i2)/d) instance (CanMulAsymmetric Integer b , CanMulAsymmetric b b, CanAddSameType (MulType b b) , CanDiv (MulType Integer b) (MulType b b)) => CanDiv Integer (Complex b) where type DivType Integer (Complex b) = Complex (DivType (MulType Integer b) (MulType b b)) divide n (a2 :+ i2) = let d = a2*a2 + i2*i2 in ((n*a2)/d) :+ (((-n)*i2)/d) instance (CanMulAsymmetric Rational b , CanMulAsymmetric b b, CanAddSameType (MulType b b) , CanDiv (MulType Rational b) (MulType b b)) => CanDiv Rational (Complex b) where type DivType Rational (Complex b) = Complex (DivType (MulType Rational b) (MulType b b)) divide n (a2 :+ i2) = let d = a2*a2 + i2*i2 in ((n*a2)/d) :+ (((-n)*i2)/d) instance (CanMulAsymmetric Int b , CanMulAsymmetric b b, CanAddSameType (MulType b b) , CanDiv (MulType Int b) (MulType b b)) => CanDiv Int (Complex b) where type DivType Int (Complex b) = Complex (DivType (MulType Int b) (MulType b b)) divide n (a2 :+ i2) = let d = a2*a2 + i2*i2 in ((n*a2)/d) :+ (((-n)*i2)/d) instance (CanMulAsymmetric Double b , CanMulAsymmetric b b, CanAddSameType (MulType b b) , CanDiv (MulType Double b) (MulType b b)) => CanDiv Double (Complex b) where type DivType Double (Complex b) = Complex (DivType (MulType Double b) (MulType b b)) divide n (a2 :+ i2) = let d = a2*a2 + i2*i2 in ((n*a2)/d) :+ (((-n)*i2)/d) instance (CanDiv a Integer) => CanDiv (Complex a) Integer where type DivType (Complex a) Integer = Complex (DivType a Integer) divide (a1 :+ i1) n = (a1/n) :+ (i1/n) instance (CanDiv a Int) => CanDiv (Complex a) Int where type DivType (Complex a) Int = Complex (DivType a Int) divide (a1 :+ i1) n = (a1/n) :+ (i1/n) instance (CanDiv a Rational) => CanDiv (Complex a) Rational where type DivType (Complex a) Rational = Complex (DivType a Rational) divide (a1 :+ i1) n = (a1/n) :+ (i1/n) instance (CanDiv a Double) => CanDiv (Complex a) Double where type DivType (Complex a) Double = Complex (DivType a Double) divide (a1 :+ i1) n = (a1/n) :+ (i1/n) instance (CanMulAsymmetric t t , CanAddSameType (MulType t t) , CanSqrt (MulType t t)) => CanAbs (Complex t) where type AbsType (Complex t) = SqrtType (MulType t t) abs (a :+ i) = sqrt (a*a + i*i) instance (CanExp t , CanSinCos t , CanMulAsymmetric (ExpType t) (SinCosType t)) => CanExp (Complex t) where type ExpType (Complex t) = Complex (MulType (ExpType t) (SinCosType t)) exp (a :+ i) = let ea = exp a in (ea * cos i) :+ (ea * sin i)