-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAnalysis.hs
39 lines (30 loc) · 1.17 KB
/
Analysis.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
module Analysis where
import Prelude hiding (head, iterate)
import Data.List.Infinite (Infinite ((:<)), head, iterate)
data Criticality = Maximum | Minimum | Inflection
deriving (Eq, Show, Read)
data Extremum p = Extremum
{ exPoint :: p
, exType :: Criticality
} deriving (Eq, Show)
instance Functor Extremum where
fmap f (Extremum p c) = Extremum (f p) c
extremum :: (Fractional t, Ord t) =>
(t -> t) -> (t -> t) -> (t -> t) -> t -> (t, t) -> Extremum (t, t)
extremum f f' f'' e r = Extremum (x, y) t
where x = solve f' f'' e r
y = f x
c = f'' x
t | c > e = Minimum
| c < (-e) = Maximum
| otherwise = Inflection
-- TODO: use bisection to ensure bounds
solve :: (Fractional t, Ord t) =>
(t -> t) -> (t -> t) -> t -> (t, t) -> t
solve f f' e (x0, _) = head . convergedBy e . iterate step $ x0
where step x = x - f x / f' x
dropWhile2 :: (t -> t -> Bool) -> Infinite t -> Infinite t
dropWhile2 p xs@(x :< xs'@(x' :< _)) = if not (p x x') then xs else dropWhile2 p xs'
convergedBy :: (Num t, Ord t) => t -> Infinite t -> Infinite t
convergedBy e = dropWhile2 unconverging
where unconverging x x' = abs (x - x') >= e