module Data.Number.ER.Real.Approx.Sequence
(
ConvergRealSeq(..),
makeFastConvergRealSeq,
convertFuncRA2Seq,
convertBinFuncRA2Seq,
convergRealSeqElem,
showConvergRealSeq,
showConvergRealSeqAuto
)
where
import qualified Data.Number.ER.Real.Approx as RA
import Data.Number.ER.BasicTypes
import Data.Maybe
import Data.Ratio
data ConvergRealSeq ra =
ConvergRealSeq (EffortIndex -> ra)
convergRealSeqElem :: (ConvergRealSeq ra) -> EffortIndex -> ra
convergRealSeqElem (ConvergRealSeq sq) ix = sq ix
convertFuncRA2Seq ::
(EffortIndex -> ra -> ra) ->
(ConvergRealSeq ra) ->
(ConvergRealSeq ra)
convertFuncRA2Seq f (ConvergRealSeq argSeq) =
ConvergRealSeq resultSeq
where
resultSeq ix =
f ix (argSeq ix)
convertBinFuncRA2Seq ::
(EffortIndex -> ra -> ra -> ra) ->
(ConvergRealSeq ra) ->
(ConvergRealSeq ra) ->
(ConvergRealSeq ra)
convertBinFuncRA2Seq f (ConvergRealSeq arg1) (ConvergRealSeq arg2) =
ConvergRealSeq resultSeq
where
resultSeq ix =
f ix (arg1 ix) (arg2 ix)
makeFastConvergRealSeq ::
(RA.ERApprox ra) =>
(ConvergRealSeq ra) ->
(ConvergRealSeq ra)
makeFastConvergRealSeq (ConvergRealSeq argSeq) =
ConvergRealSeq fastSeq
where
fastSeq ix =
head $ catMaybes $ map (precisionOK . argSeq) indexSeries
where
indexSeries =
binGeomSeries (max 1 ix)
precisionOK ra
| RA.getPrecision ra >= (effIx2prec ix) = Just ra
| otherwise = Nothing
binGeomSeries
:: (Num a)
=> a
-> [a]
binGeomSeries n =
n : (binGeomSeries (2 * n))
instance (RA.ERApprox ra) => Show (ConvergRealSeq ra)
where
show = showConvergRealSeq 6 True False 10
showConvergRealSeq
:: (RA.ERApprox ra)
=> Int
-> Bool
-> Bool
-> Precision
-> (ConvergRealSeq ra)
-> String
showConvergRealSeq numDigits showGran showComponents prec r =
RA.showApprox numDigits showGran showComponents $
convergRealSeqElem (makeFastConvergRealSeq r) (prec2effIx prec)
showConvergRealSeqAuto
:: (RA.ERApprox ra)
=> Int
-> (ConvergRealSeq ra)
-> String
showConvergRealSeqAuto numDigits argSeq =
showConvergRealSeq numDigits True False prec argSeq
where
prec = effIx2prec $ ceiling $ (fromInteger $ toInteger numDigits) * 3.3219280948873626
instance
(RA.ERApprox ra)
=> Eq (ConvergRealSeq ra)
where
r1 == r2 =
iterateRA_A raEq 2 [r1, r2]
where
raEq _ ([a1,a2]) = RA.equalReals a1 a2
instance
(RA.ERApprox ra)
=> Ord (ConvergRealSeq ra)
where
compare r1 r2 =
iterateRA_A eraComp 2 [r1, r2]
where
eraComp _ ([a1,a2]) = RA.compareReals a1 a2
pointwiseConvergRealSeq1 f (ConvergRealSeq sq) =
ConvergRealSeq (f . sq)
pointwiseConvergRealSeq2 f (ConvergRealSeq sq1) (ConvergRealSeq sq2) =
ConvergRealSeq (\ix -> f (sq1 ix) (sq2 ix))
instance
(RA.ERApprox ra)
=> Num (ConvergRealSeq ra)
where
fromInteger n = ConvergRealSeq sq
where
sq ix =
RA.setMinGranularity (effIx2gran ix) $ fromInteger n
abs = pointwiseConvergRealSeq1 $ abs
signum = pointwiseConvergRealSeq1 $ signum
negate = pointwiseConvergRealSeq1 $ negate
(+) = pointwiseConvergRealSeq2 $ (+)
(*) = pointwiseConvergRealSeq2 $ (*)
instance
(RA.ERApprox ra)
=> Fractional (ConvergRealSeq ra)
where
fromRational q = ConvergRealSeq sq
where
sq ix =
(RA.setMinGranularity (effIx2gran ix) num) / denom
num = fromInteger $ numerator q
denom = fromInteger $ denominator q
recip = pointwiseConvergRealSeq1 $ recip
iterateRA_A
:: (EffortIndex -> [ra] -> Maybe a)
-> EffortIndex
-> ([ConvergRealSeq ra] -> a)
iterateRA_A fn_RA startIx args =
head $ catMaybes $ map ((uncurry fn_RA) . args_Prec) indexSeries
where
indexSeries =
binGeomSeries $ max 1 startIx
args_Prec currentIndex =
(currentIndex, map (\ arg -> convergRealSeqElem arg currentIndex) args)