module Data.Pass.Robust ( Robust(..) , median , iqm , idm , tercile, t1, t2 , quartile, q1, q2, q3 , quintile, qu1, qu2, qu3, qu4 , percentile , permille ) where import Data.Pass.Type import Data.Pass.Calc import Data.Pass.Fun import Data.Pass.Thrist import Data.Pass.L import Data.Pass.L.Estimator -- | embedding for L-estimators class Robust l where robust :: L a b -> l a b winsorized :: (Fractional b, Ord b) => Rational -> L a b -> l a b winsorized p f = robust $ Winsorized p f trimmed :: (Fractional b, Ord b) => Rational -> L a b -> l a b trimmed p f = robust $ Trimmed p f jackknifed :: (Fractional b, Ord b) => L a b -> l a b jackknifed f = robust $ Jackknifed f lscale :: (Fractional a, Ord a) => l a a lscale = robust LScale quantile :: (Fractional a, Ord a) => Rational -> l a a quantile p = robust $ QuantileBy R2 p midhinge :: (Fractional a, Ord a) => l a a midhinge = robust $ 0.5 :* (q1 :+ q3) -- | Tukey's trimean trimean :: (Fractional a, Ord a) => l a a trimean = robust $ 0.25 :* (q1 :+ 2 :* q2 :+ q3) -- | interquartile range iqr :: (Fractional a, Ord a) => l a a iqr = robust $ ((-1) :* q1) :+ q3 idr :: (Fractional a, Ord a) => l a a idr = robust $ ((-1) :* quantile 0.1) :+ quantile 0.9 -- | interquartile mean iqm :: (Robust l, Fractional a, Ord a) => l a a iqm = trimmed 0.25 LMean idm :: (Robust l, Fractional a, Ord a) => l a a idm = trimmed 0.1 LMean median :: (Robust l, Fractional a, Ord a) => l a a median = quantile 0.5 tercile :: (Robust l, Fractional a, Ord a) => Rational -> l a a tercile n = quantile (n/3) -- | terciles 1 and 2 t1, t2 :: (Robust l, Fractional a, Ord a) => l a a t1 = tercile 1 t2 = tercile 2 quartile :: (Robust l, Fractional a, Ord a) => Rational -> l a a quartile n = quantile (n/4) -- | quantiles, with breakdown points 25%, 50%, and 25% respectively q1, q2, q3 :: (Robust l, Fractional a, Ord a) => l a a q1 = quantile 0.25 q2 = median q3 = quantile 0.75 quintile :: (Robust l, Fractional a, Ord a) => Rational -> l a a quintile n = quantile (n/5) -- | quintiles 1 through 4 qu1, qu2, qu3, qu4 :: (Robust l, Fractional a, Ord a) => l a a qu1 = quintile 1 qu2 = quintile 2 qu3 = quintile 3 qu4 = quintile 4 percentile :: (Robust l, Fractional a, Ord a) => Rational -> l a a percentile n = quantile (n/100) permille :: (Robust l, Fractional a, Ord a) => Rational -> l a a permille n = quantile (n/1000) instance Robust L where robust = id instance Robust l => Robust (Fun l) where robust = Fun . robust newtype Flip f a b = Flip { flop :: f b a } instance Robust (Pass k) where robust l = L id (flop (eqL l (Flip l))) (eqL l Nil) midhinge = (q1 + q3) / 2 trimean = (q1 + 2 * q2 + q3) / 4 iqr = q3 - q1 instance Robust (Calc k) where robust l = robust l :& Stop midhinge = midhinge :& Stop trimean = trimean :& Stop iqr = iqr :& Stop