    {-# LANGUAGE FlexibleContexts #-}

    -- |
    -- Module    : Statistics.Sample.Normalize
    -- Copyright : (c) 2017 Gregory W. Schwartz
    -- License   : BSD3
    --
    -- Maintainer  : gsch@mail.med.upenn.edu
    -- Stability   : experimental
    -- Portability : portable
    --
    -- Functions for normalizing samples.

    module Statistics.Sample.Normalize
        (
          standardize
        ) where

    import Statistics.Sample
    import qualified Data.Vector.Generic  as G
    import qualified Data.Vector          as V
    import qualified Data.Vector.Unboxed  as U
    import qualified Data.Vector.Storable as S

    -- | /O(n)/ Normalize a sample using standard scores:
    --
    --   \[ z = \frac{x - \mu}{\sigma} \]
    --
    --   Where μ is sample mean and σ is standard deviation computed from
    --   unbiased variance estimation. If sample to small to compute σ or
    --   it's equal to 0 @Nothing@ is returned.
    standardize :: (G.Vector v Double) => v Double -> Maybe (v Double)
    standardize :: v Double -> Maybe (v Double)
    standardize xs :: v Double
    xs
      | v Double -> Int
    forall (v :: * -> *) a. Vector v a => v a -> Int
    G.length v Double
    xs Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 2 = Maybe (v Double)
    forall a. Maybe a
    Nothing
      | Double
    sigma Double -> Double -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0      = Maybe (v Double)
    forall a. Maybe a
    Nothing
      | Bool
    otherwise       = v Double -> Maybe (v Double)
    forall a. a -> Maybe a
    Just (v Double -> Maybe (v Double)) -> v Double -> Maybe (v Double)
    forall a b. (a -> b) -> a -> b
    $ (Double -> Double) -> v Double -> v Double
    forall (v :: * -> *) a b.
    (Vector v a, Vector v b) =>
    (a -> b) -> v a -> v b
    G.map (\x :: Double
    x -> (Double
    x Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double
    mu) Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    sigma) v Double
    xs
      where
        mu :: Double
    mu    = v Double -> Double
    forall (v :: * -> *). Vector v Double => v Double -> Double
    mean   v Double
    xs
        sigma :: Double
    sigma = v Double -> Double
    forall (v :: * -> *). Vector v Double => v Double -> Double
    stdDev v Double
    xs
    {-# INLINABLE  standardize #-}
    {-# SPECIALIZE standardize :: V.Vector Double -> Maybe (V.Vector Double) #-}
    {-# SPECIALIZE standardize :: U.Vector Double -> Maybe (U.Vector Double) #-}
    {-# SPECIALIZE standardize :: S.Vector Double -> Maybe (S.Vector Double) #-}