module Numerics.ConvergentRecursion (
retryLinearlyUntilPrecision
, retryExponentiallyUntilPrecision
, recurseUntilPrecision
) where
import qualified Data.List as L
findCloseConsecutives :: [Double] -> Double -> Double
findCloseConsecutives :: [Double] -> Double -> Double
findCloseConsecutives [Double]
values Double
precision
= let closeEnoughPair :: (Double, Double) -> Bool
closeEnoughPair (Double
x,Double
y) = (Double
xDouble -> Double -> Double
forall a. Num a => a -> a -> a
-Double
y)Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
x Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
precision
Just (Double
_good, Double
evenBetter) = ((Double, Double) -> Bool)
-> [(Double, Double)] -> Maybe (Double, Double)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
L.find (Double, Double) -> Bool
closeEnoughPair ([Double] -> [(Double, Double)]
forall a. [a] -> [(a, a)]
pairsOf [Double]
values)
in Double
evenBetter
pairsOf :: [a] -> [(a, a)]
pairsOf :: forall a. [a] -> [(a, a)]
pairsOf [a]
xs = [a] -> [a] -> [(a, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [a]
xs ([a] -> [a]
forall a. HasCallStack => [a] -> [a]
tail [a]
xs)
retryExponentiallyUntilPrecision
:: (Int -> Double)
-> Double
-> Double
retryExponentiallyUntilPrecision :: (Int -> Double) -> Double -> Double
retryExponentiallyUntilPrecision Int -> Double
f Double
precision = [Double] -> Double -> Double
findCloseConsecutives [Int -> Double
f (Int
2Int -> Integer -> Int
forall a b. (Num a, Integral b) => a -> b -> a
^Integer
n) | Integer
n <- [Integer
1..]] Double
precision
retryLinearlyUntilPrecision
:: (Int -> Double)
-> Double
-> Double
retryLinearlyUntilPrecision :: (Int -> Double) -> Double -> Double
retryLinearlyUntilPrecision Int -> Double
f Double
precision = [Double] -> Double -> Double
findCloseConsecutives [Int -> Double
f Int
n | Int
n <- [Int
0..]] Double
precision
recurseUntilPrecision
:: (Double -> Double)
-> Double
-> Double
-> Double
recurseUntilPrecision :: (Double -> Double) -> Double -> Double -> Double
recurseUntilPrecision Double -> Double
f Double
x0 = [Double] -> Double -> Double
findCloseConsecutives ((Double -> Double) -> Double -> [Double]
forall a. (a -> a) -> a -> [a]
iterate Double -> Double
f Double
x0)