module Data.Random.Internal.Find where
findMax :: (Fractional a, Ord a) => (a -> Bool) -> a
findMax :: forall a. (Fractional a, Ord a) => (a -> Bool) -> a
findMax a -> Bool
p = forall a. Num a => a -> a
negate (forall a. (Fractional a, Ord a) => (a -> Bool) -> a
findMin (a -> Bool
pforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. Num a => a -> a
negate))
findMin :: (Fractional a, Ord a) => (a -> Bool) -> a
findMin :: forall a. (Fractional a, Ord a) => (a -> Bool) -> a
findMin = forall a. (Fractional a, Ord a) => a -> a -> (a -> Bool) -> a
findMinFrom a
0 a
1
findMinFrom :: (Fractional a, Ord a) => a -> a -> (a -> Bool) -> a
findMinFrom :: forall a. (Fractional a, Ord a) => a -> a -> (a -> Bool) -> a
findMinFrom a
z0 a
0 a -> Bool
p = forall a. (Fractional a, Ord a) => a -> a -> (a -> Bool) -> a
findMinFrom a
z0 a
1 a -> Bool
p
findMinFrom a
z0 a
step1 a -> Bool
p
| a -> Bool
p a
z0 = a -> a -> a
descend (a
z0forall a. Num a => a -> a -> a
-a
step1) a
z0
| Bool
otherwise = forall {a}. (Eq a, Num a) => a -> a
fixZero (a -> a -> a
ascend a
z0 (a
z0forall a. Num a => a -> a -> a
+a
step1))
where
fixZero :: a -> a
fixZero a
0 = a
0
fixZero a
z = a
z
ascend :: a -> a -> a
ascend a
l a
x
| a -> Bool
p a
x = a -> a -> a
bisect a
l a
x
| Bool
otherwise = a -> a -> a
ascend a
x forall a b. (a -> b) -> a -> b
$! a
2forall a. Num a => a -> a -> a
*a
xforall a. Num a => a -> a -> a
-a
z0
descend :: a -> a -> a
descend a
x a
h
| a -> Bool
p a
x = (a -> a -> a
descend forall a b. (a -> b) -> a -> b
$! a
2forall a. Num a => a -> a -> a
*a
xforall a. Num a => a -> a -> a
-a
z0) a
x
| Bool
otherwise = a -> a -> a
bisect a
x a
h
bisect :: a -> a -> a
bisect a
l a
h
| a
l forall {a}. Ord a => a -> a -> Bool
/< a
h = a
h
| a
l forall {a}. Ord a => a -> a -> Bool
/< a
mid Bool -> Bool -> Bool
|| a
mid forall {a}. Ord a => a -> a -> Bool
/< a
h
= if a -> Bool
p a
mid then a
mid else a
h
| a -> Bool
p a
mid = a -> a -> a
bisect a
l a
mid
| Bool
otherwise = a -> a -> a
bisect a
mid a
h
where
a
a /< :: a -> a -> Bool
/< a
b = Bool -> Bool
not (a
a forall {a}. Ord a => a -> a -> Bool
< a
b)
mid :: a
mid = (a
lforall a. Num a => a -> a -> a
+a
h)forall a. Num a => a -> a -> a
*a
0.5