{-
- ``Data/Random/Internal/Find''
- Utilities for searching fractional domains. Needs cleanup, testing,
- and such. Used for constructing generic ziggurats.
-}moduleData.Random.Internal.FindwherefindMax::(Fractionala,Orda)=>(a->Bool)->afindMaxp=negate(findMin(p.negate))-- |Given an upward-closed predicate on an ordered Fractional type,-- find the smallest value satisfying the predicate.findMin::(Fractionala,Orda)=>(a->Bool)->afindMin=findMinFrom01-- |Given an upward-closed predicate on an ordered Fractional type,-- find the smallest value satisfying the predicate. Starts at the-- specified point with the specified stepsize, performs an exponential-- search out from there until it finds an interval bracketing the-- change-point of the predicate, and then performs a bisection search-- to isolate the change point. Note that infinitely-divisible domains -- such as 'Rational' cannot be searched by this function because it does-- not terminate until it reaches a point where further subdivision of the-- interval has no effect.findMinFrom::(Fractionala,Orda)=>a->a->(a->Bool)->afindMinFromz00p=findMinFromz01pfindMinFromz0step1p|pz0=descend(z0-step1)z0|otherwise=fixZero(ascendz0(z0+step1))where-- eliminate negative zero, which, in many domains, is technically-- a feasible answerfixZero0=0fixZeroz=z-- preconditions:-- not (p l)-- 0 <= l < xascendlx|px=bisectlx|otherwise=ascendx$!2*x-z0-- preconditions:-- p h-- x < h <= 0descendxh|px=(descend$!2*x-z0)x|otherwise=bisectxh-- preconditions:-- not (p l)-- p h-- l <= hbisectlh|l/<h=h|l/<mid||mid/<h=ifpmidthenmidelseh|pmid=bisectlmid|otherwise=bisectmidhwherea/<b=not(a<b)mid=(l+h)*0.5