{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -Wno-orphans #-}
{-|
    Module      :  AERN2.Real.Field
    Description :  field operations on CReal
    Copyright   :  (c) Michal Konecny
    License     :  BSD3

    Maintainer  :  mikkonecny@gmail.com
    Stability   :  experimental
    Portability :  portable

    Field operations on Cauchy Real numbers.
-}
module AERN2.Real.Field
(
-- * field ops (`add`, `sub`, `mul`, `div`) for `CReal -> CReal -> CReal`
-- * field ops for `CReal -> t -> CReal` and `t -> CReal -> CReal` where `t` is `Int`, `Integer`, `Rational`, `Dyadic`
-- * field ops for `CReal -> MPBall -> MPBall` and `CReal -> CN MPBall -> CN MPBall`
)
where

import MixedTypesNumPrelude
import qualified Prelude as P

import AERN2.MP.Ball
-- import AERN2.MP.Dyadic

import AERN2.Real.Type
import AERN2.Real.Comparisons ()
import AERN2.Real.FieldTH ()

{- field operations -}

instance Ring CReal
instance OrderedRing CReal
instance Field CReal
instance OrderedField CReal

instance
  (CanAddAsymmetric t1 t2)
  => 
  CanAddAsymmetric (CSequence t1) (CSequence t2) 
  where
  type AddType (CSequence t1) (CSequence t2) = CSequence (AddType t1 t2)
  add :: CSequence t1
-> CSequence t2 -> AddType (CSequence t1) (CSequence t2)
add = (CN t1 -> CN t2 -> CN (AddType t1 t2))
-> CSequence t1 -> CSequence t2 -> CSequence (AddType t1 t2)
forall t1 t2 t3.
(CN t1 -> CN t2 -> CN t3)
-> CSequence t1 -> CSequence t2 -> CSequence t3
lift2 CN t1 -> CN t2 -> CN (AddType t1 t2)
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
add

instance
  (CanSub t1 t2)
  => 
  CanSub (CSequence t1) (CSequence t2) 
  where
  type SubType (CSequence t1) (CSequence t2) = CSequence (SubType t1 t2)
  sub :: CSequence t1
-> CSequence t2 -> SubType (CSequence t1) (CSequence t2)
sub = (CN t1 -> CN t2 -> CN (SubType t1 t2))
-> CSequence t1 -> CSequence t2 -> CSequence (SubType t1 t2)
forall t1 t2 t3.
(CN t1 -> CN t2 -> CN t3)
-> CSequence t1 -> CSequence t2 -> CSequence t3
lift2 CN t1 -> CN t2 -> CN (SubType t1 t2)
forall t1 t2. CanSub t1 t2 => t1 -> t2 -> SubType t1 t2
sub

instance
  (CanMulAsymmetric t1 t2, CanGiveUpIfVeryInaccurate (MulType t1 t2))
  => 
  CanMulAsymmetric (CSequence t1) (CSequence t2) 
  where
  type MulType (CSequence t1) (CSequence t2) = CSequence (MulType t1 t2)
  mul :: CSequence t1
-> CSequence t2 -> MulType (CSequence t1) (CSequence t2)
mul = (CN t1 -> CN t2 -> CN (MulType t1 t2))
-> CSequence t1 -> CSequence t2 -> CSequence (MulType t1 t2)
forall t1 t2 t3.
(CN t1 -> CN t2 -> CN t3)
-> CSequence t1 -> CSequence t2 -> CSequence t3
lift2 CN t1 -> CN t2 -> CN (MulType t1 t2)
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
mul

instance
  (CanDiv t1 t2, CanTestZero t2)
  => 
  CanDiv (CSequence t1) (CSequence t2) 
  where
  type DivType (CSequence t1) (CSequence t2) = CSequence (DivType t1 t2)
  divide :: CSequence t1
-> CSequence t2 -> DivType (CSequence t1) (CSequence t2)
divide = (CN t1 -> CN t2 -> CN (DivType t1 t2))
-> CSequence t1 -> CSequence t2 -> CSequence (DivType t1 t2)
forall t1 t2 t3.
(CN t1 -> CN t2 -> CN t3)
-> CSequence t1 -> CSequence t2 -> CSequence t3
lift2 CN t1 -> CN t2 -> CN (DivType t1 t2)
forall t1 t2. CanDiv t1 t2 => t1 -> t2 -> DivType t1 t2
divide

instance
  (CanPow b e, HasOrderCertainly b Integer, HasOrderCertainly e Integer,
   HasEqCertainly b Integer, CanTestInteger e, CanTestIsIntegerType b, CanTestIsIntegerType e)
  =>
  CanPow (CSequence b) (CSequence e) 
  where
  type PowType (CSequence b) (CSequence e) = CSequence (PowType b e)
  pow :: CSequence b -> CSequence e -> PowType (CSequence b) (CSequence e)
pow = (CN b -> CN e -> CN (PowType b e))
-> CSequence b -> CSequence e -> CSequence (PowType b e)
forall t1 t2 t3.
(CN t1 -> CN t2 -> CN t3)
-> CSequence t1 -> CSequence t2 -> CSequence t3
lift2 CN b -> CN e -> CN (PowType b e)
forall b e. CanPow b e => b -> e -> PowType b e
pow
  type PPowType (CSequence b) (CSequence e) = CSequence (PPowType b e)
  ppow :: CSequence b -> CSequence e -> PPowType (CSequence b) (CSequence e)
ppow = (CN b -> CN e -> CN (PPowType b e))
-> CSequence b -> CSequence e -> CSequence (PPowType b e)
forall t1 t2 t3.
(CN t1 -> CN t2 -> CN t3)
-> CSequence t1 -> CSequence t2 -> CSequence t3
lift2 CN b -> CN e -> CN (PPowType b e)
forall b e. CanPow b e => b -> e -> PPowType b e
ppow

---------------------------------------------------
---------------------------------------------------
-- MPBall and CN MPBall mixed-type arithmetic
---------------------------------------------------
---------------------------------------------------

instance
  (CanAddAsymmetric MPBall b)
  => 
  CanAddAsymmetric MPBall (CSequence b)
  where
  type AddType MPBall (CSequence b) = AddType MPBall b
  add :: MPBall -> CSequence b -> AddType MPBall (CSequence b)
add MPBall
a CSequence b
s = MPBall -> b -> AddType MPBall b
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
add MPBall
a (CN b -> b
forall p. CN p -> p
unCN (CN b -> b) -> CN b -> b
forall a b. (a -> b) -> a -> b
$ CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision MPBall
a))

instance
  (CanAddAsymmetric b MPBall)
  => 
  CanAddAsymmetric (CSequence b) MPBall
  where
  type AddType (CSequence b) MPBall = AddType b MPBall
  add :: CSequence b -> MPBall -> AddType (CSequence b) MPBall
add CSequence b
s MPBall
b = b -> MPBall -> AddType b MPBall
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
add (CN b -> b
forall p. CN p -> p
unCN (CN b -> b) -> CN b -> b
forall a b. (a -> b) -> a -> b
$ CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision MPBall
b)) MPBall
b

instance
  (CanAddAsymmetric MPBall b)
  => 
  CanAddAsymmetric (CN MPBall) (CSequence b)
  where
  type AddType (CN MPBall) (CSequence b) = AddType (CN MPBall) (CN b)
  add :: CN MPBall -> CSequence b -> AddType (CN MPBall) (CSequence b)
add CN MPBall
a CSequence b
s = CN MPBall -> CN b -> AddType (CN MPBall) (CN b)
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
add CN MPBall
a (CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (CN MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision CN MPBall
a))

instance
  (CanAddAsymmetric b MPBall)
  => 
  CanAddAsymmetric (CSequence b) (CN MPBall)
  where
  type AddType (CSequence b) (CN MPBall) = AddType (CN b) (CN MPBall)
  add :: CSequence b -> CN MPBall -> AddType (CSequence b) (CN MPBall)
add CSequence b
s CN MPBall
b = CN b -> CN MPBall -> AddType (CN b) (CN MPBall)
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
add (CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (CN MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision CN MPBall
b)) CN MPBall
b

instance
  (CanSub MPBall b)
  => 
  CanSub MPBall (CSequence b)
  where
  type SubType MPBall (CSequence b) = SubType MPBall b
  sub :: MPBall -> CSequence b -> SubType MPBall (CSequence b)
sub MPBall
a CSequence b
s = MPBall -> b -> SubType MPBall b
forall t1 t2. CanSub t1 t2 => t1 -> t2 -> SubType t1 t2
sub MPBall
a (CN b -> b
forall p. CN p -> p
unCN (CN b -> b) -> CN b -> b
forall a b. (a -> b) -> a -> b
$ CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision MPBall
a))

instance
  (CanSub b MPBall)
  => 
  CanSub (CSequence b) MPBall
  where
  type SubType (CSequence b) MPBall = SubType b MPBall
  sub :: CSequence b -> MPBall -> SubType (CSequence b) MPBall
sub CSequence b
s MPBall
b = b -> MPBall -> SubType b MPBall
forall t1 t2. CanSub t1 t2 => t1 -> t2 -> SubType t1 t2
sub (CN b -> b
forall p. CN p -> p
unCN (CN b -> b) -> CN b -> b
forall a b. (a -> b) -> a -> b
$ CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision MPBall
b)) MPBall
b

instance
  (CanSub MPBall b)
  => 
  CanSub (CN MPBall) (CSequence b)
  where
  type SubType (CN MPBall) (CSequence b) = SubType (CN MPBall) (CN b)
  sub :: CN MPBall -> CSequence b -> SubType (CN MPBall) (CSequence b)
sub CN MPBall
a CSequence b
s = CN MPBall -> CN b -> SubType (CN MPBall) (CN b)
forall t1 t2. CanSub t1 t2 => t1 -> t2 -> SubType t1 t2
sub CN MPBall
a (CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (CN MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision CN MPBall
a))

instance
  (CanSub b MPBall)
  => 
  CanSub (CSequence b) (CN MPBall)
  where
  type SubType (CSequence b) (CN MPBall) = SubType (CN b) (CN MPBall)
  sub :: CSequence b -> CN MPBall -> SubType (CSequence b) (CN MPBall)
sub CSequence b
s CN MPBall
b = CN b -> CN MPBall -> SubType (CN b) (CN MPBall)
forall t1 t2. CanSub t1 t2 => t1 -> t2 -> SubType t1 t2
sub (CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (CN MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision CN MPBall
b)) CN MPBall
b

instance
  (CanMulAsymmetric MPBall b)
  => 
  CanMulAsymmetric MPBall (CSequence b)
  where
  type MulType MPBall (CSequence b) = MulType MPBall b
  mul :: MPBall -> CSequence b -> MulType MPBall (CSequence b)
mul MPBall
a CSequence b
s = MPBall -> b -> MulType MPBall b
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
mul MPBall
a (CN b -> b
forall p. CN p -> p
unCN (CN b -> b) -> CN b -> b
forall a b. (a -> b) -> a -> b
$ CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision MPBall
a))

instance
  (CanMulAsymmetric b MPBall)
  => 
  CanMulAsymmetric (CSequence b) MPBall
  where
  type MulType (CSequence b) MPBall = MulType b MPBall
  mul :: CSequence b -> MPBall -> MulType (CSequence b) MPBall
mul CSequence b
s MPBall
b = b -> MPBall -> MulType b MPBall
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
mul (CN b -> b
forall p. CN p -> p
unCN (CN b -> b) -> CN b -> b
forall a b. (a -> b) -> a -> b
$ CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision MPBall
b)) MPBall
b

instance
  (CanMulAsymmetric MPBall b, CanGiveUpIfVeryInaccurate (MulType MPBall b))
  => 
  CanMulAsymmetric (CN MPBall) (CSequence b)
  where
  type MulType (CN MPBall) (CSequence b) = MulType (CN MPBall) (CN b)
  mul :: CN MPBall -> CSequence b -> MulType (CN MPBall) (CSequence b)
mul CN MPBall
a CSequence b
s = CN MPBall -> CN b -> MulType (CN MPBall) (CN b)
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
mul CN MPBall
a (CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (CN MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision CN MPBall
a))

instance
  (CanMulAsymmetric b MPBall, CanGiveUpIfVeryInaccurate (MulType b MPBall))
  => 
  CanMulAsymmetric (CSequence b) (CN MPBall)
  where
  type MulType (CSequence b) (CN MPBall) = MulType (CN b) (CN MPBall)
  mul :: CSequence b -> CN MPBall -> MulType (CSequence b) (CN MPBall)
mul CSequence b
s CN MPBall
b = CN b -> CN MPBall -> MulType (CN b) (CN MPBall)
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
mul (CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (CN MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision CN MPBall
b)) CN MPBall
b

instance
  (CanDiv MPBall b, CanTestZero b)
  => 
  CanDiv MPBall (CSequence b)
  where
  type DivType MPBall (CSequence b) = DivType MPBall b
  divide :: MPBall -> CSequence b -> DivType MPBall (CSequence b)
divide MPBall
a CSequence b
s = MPBall -> b -> DivType MPBall b
forall t1 t2. CanDiv t1 t2 => t1 -> t2 -> DivType t1 t2
divide MPBall
a (CN b -> b
forall p. CN p -> p
unCN (CN b -> b) -> CN b -> b
forall a b. (a -> b) -> a -> b
$ CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision MPBall
a))

instance
  (CanDiv b MPBall)
  => 
  CanDiv (CSequence b) MPBall
  where
  type DivType (CSequence b) MPBall = DivType b MPBall
  divide :: CSequence b -> MPBall -> DivType (CSequence b) MPBall
divide CSequence b
s MPBall
b = b -> MPBall -> DivType b MPBall
forall t1 t2. CanDiv t1 t2 => t1 -> t2 -> DivType t1 t2
divide (CN b -> b
forall p. CN p -> p
unCN (CN b -> b) -> CN b -> b
forall a b. (a -> b) -> a -> b
$ CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision MPBall
b)) MPBall
b

instance
  (CanDiv MPBall b, CanTestZero b)
  => 
  CanDiv (CN MPBall) (CSequence b)
  where
  type DivType (CN MPBall) (CSequence b) = DivType (CN MPBall) (CN b)
  divide :: CN MPBall -> CSequence b -> DivType (CN MPBall) (CSequence b)
divide CN MPBall
a CSequence b
s = CN MPBall -> CN b -> DivType (CN MPBall) (CN b)
forall t1 t2. CanDiv t1 t2 => t1 -> t2 -> DivType t1 t2
divide CN MPBall
a (CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (CN MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision CN MPBall
a))

instance
  (CanDiv b MPBall)
  => 
  CanDiv (CSequence b) (CN MPBall)
  where
  type DivType (CSequence b) (CN MPBall) = DivType (CN b) (CN MPBall)
  divide :: CSequence b -> CN MPBall -> DivType (CSequence b) (CN MPBall)
divide CSequence b
s CN MPBall
b = CN b -> CN MPBall -> DivType (CN b) (CN MPBall)
forall t1 t2. CanDiv t1 t2 => t1 -> t2 -> DivType t1 t2
divide (CSequence b
s CSequence b
-> Precision -> ExtractedApproximation (CSequence b) Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? (CN MPBall -> Precision
forall t. HasPrecision t => t -> Precision
getPrecision CN MPBall
b)) CN MPBall
b

{- Prelude Num, Real, Fractional instance -}

instance
  P.Num CReal
  where
  fromInteger :: Integer -> CReal
fromInteger = Integer -> CReal
forall t1 t2. ConvertibleExactly t1 t2 => t1 -> t2
convertExactly
  negate :: CReal -> CReal
negate = CReal -> CReal
forall t. CanNeg t => t -> NegType t
negate
  + :: CReal -> CReal -> CReal
(+) = CReal -> CReal -> CReal
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
(+)
  * :: CReal -> CReal -> CReal
(*) = CReal -> CReal -> CReal
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
(*)
  abs :: CReal -> CReal
abs = CReal -> CReal
forall t. CanAbs t => t -> AbsType t
abs
  signum :: CReal -> CReal
signum = [Char] -> CReal -> CReal
forall a. HasCallStack => [Char] -> a
error [Char]
"Prelude.signum not implemented for Sequence"

instance
  P.Fractional CReal
  where
  fromRational :: Rational -> CReal
fromRational = Rational -> CReal
forall t1 t2. ConvertibleExactly t1 t2 => t1 -> t2
convertExactly
  recip :: CReal -> CReal
recip = CReal -> CReal
forall t. CanRecip t => t -> DivType Integer t
recip
  / :: CReal -> CReal -> CReal
(/) = CReal -> CReal -> CReal
forall t1 t2. CanDiv t1 t2 => t1 -> t2 -> DivType t1 t2
(/)