module AERN2.MP.UseMPFR.Ball.Elementary
(
piBallP
, fromApproxWithLipschitz
)
where
import MixedTypesNumPrelude
import qualified Prelude as P
import AERN2.Normalize
import AERN2.MP.Dyadic (Dyadic)
import qualified AERN2.MP.UseMPFR.Float as MPFloat
import AERN2.MP.UseMPFR.Float (MPFloat, mpFloat)
import AERN2.MP.Precision
import qualified AERN2.MP.UseMPFR.ErrorBound as EB
import AERN2.MP.UseMPFR.ErrorBound (errorBound)
import AERN2.MP.UseMPFR.Ball.Type
import AERN2.MP.UseMPFR.Ball.Conversions ()
import AERN2.MP.UseMPFR.Ball.Comparisons ()
import AERN2.MP.UseMPFR.Ball.Field ()
piBallP :: Precision -> MPBall
piBallP p = MPBall piUp (piUp `EB.subMP` piDown)
where
piUp = MPFloat.piUp p
piDown = MPFloat.piDown p
instance CanSinCos MPBall where
sin = sinB 1
cos = cosB 1
sinB :: Integer -> MPBall -> MPBall
sinB i x =
fromApproxWithLipschitz MPFloat.sinDown MPFloat.sinUp lip x
where
lip
| i == 0 = mpFloat 1
| otherwise = snd $ endpointsMP $ abs $ cosB (i 1) x
cosB :: Integer -> MPBall -> MPBall
cosB i x =
fromApproxWithLipschitz MPFloat.cosDown MPFloat.cosUp lip x
where
lip
| i == 0 = mpFloat 1
| otherwise = snd $ endpointsMP $ abs $ sinB (i 1) x
instance CanExp MPBall where
exp = intervalFunctionByEndpointsUpDown MPFloat.expDown MPFloat.expUp
instance CanLog MPBall where
type LogType MPBall = CN MPBall
log x
| x !>! 0 =
cn $ intervalFunctionByEndpointsUpDown MPFloat.logDown MPFloat.logUp x
| x !<=! 0 = noValueNumErrorCertainCN err
| otherwise = noValueNumErrorPotentialCN err
where
err = OutOfRange $ "log: argument must be > 0: " ++ show x
instance CanPow MPBall MPBall where
powNoCN b e = (~!) $ pow b e
pow = powUsingExpLog (mpBall 0) (mpBall 1)
instance CanPow MPBall Dyadic where
powNoCN b e = (~!) $ pow b e
pow b e = powUsingExpLog (mpBall 0) (mpBall 1) b (mpBall e)
instance CanPow MPBall Rational where
powNoCN b e = (~!) $ pow b e
pow b e = powUsingExpLog (mpBall 0) (mpBall 1) b (mpBallP (getPrecision b) e)
instance CanSqrt MPBall where
type SqrtType MPBall = CN MPBall
sqrt x
| x !>=! 0 = cn $ aux x
| x !<! 0 = noValueNumErrorCertainCN err
| otherwise = prependErrorsCN [(ErrorPotential, err)] $ cn $ aux (max 0 x)
where
aux =
intervalFunctionByEndpointsUpDown
(\ e -> MPFloat.sqrtDown (P.max (mpFloat 0) e))
(\ e -> MPFloat.sqrtUp (P.max (mpFloat 0) e))
err = OutOfRange $ "sqrt: argument must be >= 0: " ++ show x
fromApproxWithLipschitz ::
(MPFloat -> MPFloat) ->
(MPFloat -> MPFloat) ->
MPFloat ->
(MPBall -> MPBall)
fromApproxWithLipschitz fDown fUp lip _x@(MPBall xc xe) =
normalize $ MPBall fxc err
where
fxl = fDown xc
fxu = fUp xc
(MPBall fxc fxe) =
setPrecision (getPrecision xc) $
fromEndpointsMP fxl fxu
err = (errorBound lip) * xe + fxe