module Median ( median ) where
import Control.Monad.Primitive (PrimMonad, PrimState)
import qualified Data.Vector.Algorithms.Merge as Merge
import Data.Vector.Generic.Mutable (MVector)
import qualified Data.Vector.Generic.Mutable as MV
median :: (PrimMonad m, MVector v e, Ord e, Fractional e) => v (PrimState m) e -> m e
median v = do
Merge.sort v
let l = MV.length v
if odd l
then v `MV.read` ((l - 1) `div` 2)
else do
x0 <- v `MV.read` ((l `div` 2) - 1)
x1 <- v `MV.read` (l `div` 2)
pure $ (x0 + x1) / 2