Skip to content

Commit 030bc02

Browse files
committed
Add documentation
1 parent e967529 commit 030bc02

File tree

1 file changed

+42
-7
lines changed

1 file changed

+42
-7
lines changed

src/Numeric/Roots.hs

+42-7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
1+
{-|
2+
Module: Numeric.Roots
3+
Description: Root finding algorithms
4+
Copyright: (c) A.E. Drew, 2023
5+
-}
16
module Numeric.Roots (
7+
-- * Runner
8+
solve,
9+
-- * Iterative steps
210
bisect,
311
falsePosition,
412
fixedPoint,
513
newton,
614
secant,
7-
solve,
815
) where
916

1017
import Control.Monad.State
1118

19+
-- | Runs an iterative algorithm until it satisfies a stopping condition or
20+
-- performs n iterations. The stopping condition takes the last two
21+
-- approxiamtions.
1222
solve :: (a -> a -> Bool) -> Int -> State b a -> b -> Maybe a
1323
solve stop n step s0 = case solutions of
1424
[] -> Nothing
@@ -19,6 +29,13 @@ solve stop n step s0 = case solutions of
1929
ps = evalState (replicateM n step) s0
2030
ps' = tail ps
2131

32+
-- | \[
33+
-- p_n = \frac{a_n + b_n}{2} \\
34+
-- (a_n,b_n) = \begin{cases}
35+
-- (p_{n-1},b_{n-1}) & \quad \text{if } f(a_{n-1})f(p) < 0 \\
36+
-- (a_{n-1}, p_{n-1}) & \quad \text{else}
37+
-- \end{cases}
38+
-- \]
2239
bisect :: (Eq a,Fractional a) => (a -> a) -> State (a,a) a
2340
bisect f = do (a,b) <- get
2441
let s' | signAt p == signAt a = (p,b)
@@ -28,26 +45,44 @@ bisect f = do (a,b) <- get
2845
put s'
2946
return p
3047

48+
-- | \[
49+
-- p_n = f(p_{n-1})
50+
-- \]
3151
fixedPoint :: (a -> a) -> State a a
3252
fixedPoint f = state $ \p -> let p' = f p in (p', p')
3353

54+
-- | \[
55+
-- p_n = \frac{p_{n-2}f(p_{n-1}) - p_{n-1}f(p_{n-2})}{f(p_{n-1}) - f(p_{n-2})}
56+
-- \]
3457
secant :: Fractional a => (a -> a) -> State (a,a) a
3558
secant f = do (p,p') <- get
36-
let fp = f p
37-
fp' = f p'
38-
p'' = (p*fp' - p'*fp)/(fp' - fp)
59+
let p'' = calcSecant f p p'
3960
put (p',p'')
4061
return p''
4162

63+
-- | \[
64+
-- p_n = p_{n-1} - \frac{f(p_{n-1})}{f'(p_{n-1})}
65+
-- \]
4266
newton :: Fractional a => (a -> a) -> (a -> a) -> State a a
4367
newton f f' = fixedPoint $ \p -> p - (f p)/(f' p)
4468

69+
-- | \[
70+
-- p_n = \frac{p_{n-2}f(p_{n-1}) - p_{n-1}f(p_{n-2})}
71+
-- {f(p_{n-1}) - f(p_{n-2})} \\
72+
-- p_{n-1} = \begin{cases}
73+
-- p_{n-1} & \quad \text{if } f(p_n)f(p_{n-1}) < 0 \\
74+
-- p_{n-2} & \quad \text{else}
75+
-- \end{cases}
76+
-- \]
4577
falsePosition :: (Eq a, Fractional a) => (a -> a) -> State (a,a) a
4678
falsePosition f = do (p,p') <- get
47-
let fp = f p
48-
fp' = f p'
49-
p'' = (p*fp' - p'*fp)/(fp' - fp)
79+
let p'' = calcSecant f p p'
5080
if signum (f p'') == signum (f p')
5181
then put (p,p'')
5282
else put (p',p'')
5383
return p''
84+
85+
calcSecant :: Fractional a => (a -> a) -> a -> a -> a
86+
calcSecant f p p' = (p*fp' - p'*fp)/(fp' - fp)
87+
where fp = f p
88+
fp' = f p'

0 commit comments

Comments
 (0)