content: -- |
  -- Module: Statistics
  -- Description: Basic bounded statistics
  -- Copyright: (c) 2011 National Institute of Aerospace / Galois, Inc.
  --
  -- Basic bounded statistics.  In the following, a bound @n@ is given stating
  -- the number of periods over which to compute the statistic (@n == 1@ computes
  -- it only over the current period).
  
  {-# LANGUAGE NoImplicitPrelude #-}
  
  module Copilot.Library.Statistics
      ( max, min, sum, mean, meanNow ) where
  
  import Copilot.Language
  import Copilot.Library.Utils
  
  -- | Summation.
  sum :: ( Typed a, Num a, Eq a ) => Int -> Stream a -> Stream a
  sum n s = nfoldl1 n (+) s
  
  -- | Maximum value.
  max :: ( Typed a, Ord a ) => Int -> Stream a -> Stream a
  max n s = nfoldl1 n largest s
      where
        largest  = \ x y -> mux ( x >= y ) x y
  
  -- | Minimum value.
  min :: ( Typed a, Ord a ) => Int -> Stream a -> Stream a
  min n s = nfoldl1 n smallest s
      where
        smallest = \ x y -> mux ( x <= y ) x y
  
  -- | Mean value.  @n@ must not overflow
  -- for word size @a@ for streams over which computation is peformed.
  mean :: ( Typed a, Eq a, Fractional a ) => Int -> Stream a -> Stream a
  mean n s = ( sum n s ) / ( fromIntegral n )
  
  -- | Mean value over the current set of streams passed in.
  meanNow :: ( Typed a, Integral a ) => [ Stream a ] -> Stream a
  meanNow [] =
    badUsage "list of arguments to meanNow must be nonempty"
  meanNow ls = ( foldl1 (+) ls ) `div` ( fromIntegral $ length ls )
  