module Simulation.Aivika.Statistics
(Statistics,
newStatistics,
addStatistics,
statisticsData,
analyzeData,
AnalysisResults(..),
showResults) where
import Data.Foldable
import Data.Array
import Data.Array.IO
import Control.Monad
import Control.Monad.Trans
import Control.Concurrent.MVar
import Simulation.Aivika.UVector
data Statistics a = Statistics { statData :: UVector a,
statLock :: MVar () }
newStatistics :: (MArray IOUArray a IO) => IO (Statistics a)
newStatistics =
do v <- newVector
l <- newMVar ()
return Statistics { statData = v,
statLock = l }
addStatistics :: (MArray IOUArray a IO) => Statistics a -> a -> IO ()
addStatistics s x =
withMVar (statLock s) $ \() ->
appendVector (statData s) x
statisticsData :: (MArray IOUArray a IO) => Statistics a -> IO (Array Int a)
statisticsData s =
withMVar (statLock s) $ \() -> freezeVector (statData s)
data AnalysisResults a =
AnalysisResults { resultsData :: Array Int a,
resultsMean :: Double,
resultsVariance :: Double,
resultsMin :: a,
resultsMax :: a
} deriving (Eq, Ord, Show)
analyzeData :: Real a => Array Int a -> AnalysisResults a
analyzeData xs =
let (i1, i2) = bounds xs
meanx = foldl' (\y i -> y * (1 k i) + f i * k i) 0 [i1 .. i2]
sqrx = foldl' (\y i -> y * (1 k i) + g i * k i) 0 [i1 .. i2]
minx = foldl' (\y i -> if i == 0 then x i else min y (x i)) 0 [i1 .. i2]
maxx = foldl' (\y i -> if i == 0 then x i else max y (x i)) 0 [i1 .. i2]
x i = xs ! i
f i = fromRational (toRational (x i))
g i = let y = f i in y * y
k i = 1 / fromInteger (toInteger (i i1 + 1))
in AnalysisResults { resultsData = xs,
resultsMean = meanx,
resultsVariance = sqrx meanx * meanx,
resultsMin = minx,
resultsMax = maxx }
showResults :: (Show a) => AnalysisResults a -> Int -> ShowS
showResults rs indent =
let (i1, i2) = bounds (resultsData rs)
tab = replicate indent ' '
in if i1 <= i2
then
showString tab .
showString "mean = " . shows (resultsMean rs) .
showString "\n" .
showString tab .
showString "deviation = " . shows (sqrt (resultsVariance rs)) .
showString "\n" .
showString tab .
showString "minimum = " . shows (resultsMin rs) .
showString "\n" .
showString tab .
showString "maximum = " . shows (resultsMax rs)
else
showString tab .
showString "mean = ---" .
showString "\n" .
showString tab .
showString "deviation = ---" .
showString "\n" .
showString tab .
showString "minimum = ---" .
showString "\n" .
showString tab .
showString "maximum = ---"