{-# LANGUAGE CPP #-} module Data.RangeMin.Vector ( unsafeVecRangeMinBy, unsafeVecRangeMin, unsafeVecRangeMax, vecRangeMinBy, vecRangeMin, vecRangeMax) where import Data.RangeMin.Common import Data.RangeMin.Int import Data.RangeMin.Cartesian.Spec import qualified Data.Vector.Generic as G #define vec ('PV.fromList' [0,7,-10,4,5,4]) #define cmp (\\ i j -> 'abs' i '>=' 'abs' j) {-# INLINE [1] unsafeVecRangeMinBy #-} -- | /O(n)/. Returns a range-min function on the vector, under the specified ordering. -- The returned function /does not/ do bounds checks; see 'unsafeIntRangeMin' for details. -- -- Example: -- -- @ -- -- Finding the element with the /largest absolute value/ in a subrange. -- 'unsafeVecRangeMinBy' cmp vec 0 6 == 2 -- 'unsafeVecRangeMinBy' cmp vec 2 3 == 2 -- 'unsafeVecRangeMinBy' cmp vec 3 3 == 4 -- @ -- unsafeVecRangeMinBy :: G.Vector v a => LEq a -- ^ A total ordering on the type @a@. -> v a -- ^ A vector of elements of type @a@. -> RangeMin -- ^ A range-min function on the vector which runs in /O(1)/. {-# INLINE unsafeVecRangeMin #-} -- | /O(n)/. Equivalent to @'unsafeVecRangeMinBy' ('<=')@. Specialized for instances of 'Injective'. -- The returned function /does not/ do bounds checks; see 'unsafeIntRangeMin' for details. -- -- Example: -- -- @ -- -- In reality, these would be rewritten into calls to 'unsafeIntRangeMin', since 'Char' is an -- -- instance of 'Injective'. -- 'unsafeVecRangeMin' ('PV.fromList' \"banana\") 0 6 == 1 -- 'unsafeVecRangeMin' ('PV.fromList' \"banana\") 1 1 == 1 -- 'unsafeVecRangeMin' ('PV.fromList' \"banana\") 3 3 == 3 -- @ unsafeVecRangeMin :: (G.Vector v a, Ord a) => v a -- ^ A vector of elements of type @a@. -> RangeMin -- ^ A range-min function (under the natural ordering) -- on the vector which runs in /O(1)/. {-# INLINE unsafeVecRangeMax #-} -- | /O(n)/. Equivalent to @'unsafeVecRangeMinBy' ('>=')@. Specialized for instances of 'Injective'. -- The returned function /does not/ do bounds checks; see 'unsafeIntRangeMin' for details. -- -- Example: -- -- @ -- -- In reality, these would be rewritten into calls to 'unsafeIntRangeMin', since 'Char' -- -- is an instance of 'Injective'. -- 'unsafeVecRangeMax' ('PV.fromList' \"banana\") 0 6 == 2 -- 'unsafeVecRangeMax' ('PV.fromList' \"banana\") 1 1 == 1 -- 'unsafeVecRangeMax' ('PV.fromList' \"banana\") 3 3 == 4 -- @ unsafeVecRangeMax :: (G.Vector v a, Ord a) => v a -- ^ A vector of elements of type @a@. -> RangeMin -- ^ A range-max function (under the natural ordering) -- on the vector which runs in /O(1)/. {-# INLINE [1] vecRangeMinBy #-} -- | /O(n)/. Returns a range-min function on the vector, under the specified ordering. -- The returned function /does/ do bounds checks; see 'intRangeMin' for details. vecRangeMinBy :: G.Vector v a => LEq a -- ^ A total ordering on the type @a@. -> v a -- ^ A vector of elements of type @a@. -> RangeMin -- ^ A range-min function on the vector which runs in /O(1)/. {-# INLINE vecRangeMin #-} -- | /O(n)/. Equivalent to @'vecRangeMinBy' ('<=')@; a safer version of 'unsafeVecRangeMin'. -- Specialized for instances of 'Injective'. The returned function /does/ do bounds checks; see 'intRangeMin' for details. vecRangeMin :: (G.Vector v a, Ord a) => v a -- ^ A vector of elements of type @a@. -> RangeMin -- ^ A range-min function (under the natural ordering) -- on the vector which runs in /O(1)/. {-# INLINE vecRangeMax #-} -- | /O(n)/. Equivalent to @'vecRangeMinBy' ('>=')@; a safer version of 'unsafeVecRangeMax'. -- Specialized for instances of 'Injective'. The returned function /does/ do bounds checks; see 'intRangeMin' for details. vecRangeMax :: (G.Vector v a, Ord a) => v a -- ^ A vector of elements of type @a@. -> RangeMin -- ^ A range-max function (under the natural ordering) -- on the vector which runs in /O(1)/. unsafeVecRangeMinBy (<=?) xs = unsafeIntRangeMin (equivVectorBy (<=?) xs) unsafeVecRangeMin xs = unsafeIntRangeMin (equivVectorMin xs) unsafeVecRangeMax xs = unsafeIntRangeMin (equivVectorMax xs) vecRangeMinBy (<=?) xs = intRangeMin (equivVectorBy (<=?) xs) vecRangeMin xs = intRangeMin (equivVectorMin xs) vecRangeMax xs = intRangeMin (equivVectorMax xs)