module Simulation.Aivika.Experiment.Histogram
(
Histogram(..),
histogram,
histogramBinSize,
histogramNumBins,
BinningStrategy(..),
binSturges,
binDoane,
binSqrt,
binScott) where
import Data.List
import Data.Monoid
import qualified Data.Map as Map
import Numeric
type Histogram = [(Double, [Int])]
type BinningStrategy = [Double] -> Int
stratFromBinWidth :: [Double] -> Double -> Int
stratFromBinWidth :: [Double] -> Double -> Int
stratFromBinWidth [Double]
xs Double
h = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> Int) -> Double -> Int
forall a b. (a -> b) -> a -> b
$ ([Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [Double]
xs Double -> Double -> Double
forall a. Num a => a -> a -> a
- [Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [Double]
xs) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
h
binSturges :: BinningStrategy
binSturges :: BinningStrategy
binSturges [Double]
xs = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> Int) -> Double -> Int
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
forall a. Floating a => a -> a -> a
logBase Double
2 Double
n Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
1
where n :: Double
n = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Double) -> Int -> Double
forall a b. (a -> b) -> a -> b
$ BinningStrategy
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Double]
xs
binDoane :: BinningStrategy
binDoane :: BinningStrategy
binDoane [Double]
xs = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> Int) -> Double -> Int
forall a b. (a -> b) -> a -> b
$ Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
forall a. Floating a => a -> a
log Double
n Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
forall a. Floating a => a -> a
log (Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
a Double -> Double -> Double
forall a. Num a => a -> a -> a
* ((Double
nDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
6)Double -> Double -> Double
forall a. Floating a => a -> a -> a
**(Double
1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2)))
where
n :: Double
n = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Double) -> Int -> Double
forall a b. (a -> b) -> a -> b
$ BinningStrategy
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Double]
xs
a :: Double
a = [Double] -> Double
forall a. Floating a => [a] -> a
kurtosis [Double]
xs
binSqrt :: BinningStrategy
binSqrt :: BinningStrategy
binSqrt [Double]
xs = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
round (Double -> Int) -> Double -> Int
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
sqrt Double
n
where
n :: Double
n = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Double) -> Int -> Double
forall a b. (a -> b) -> a -> b
$ BinningStrategy
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Double]
xs
binScott :: BinningStrategy
binScott :: BinningStrategy
binScott [Double]
xs = [Double] -> Double -> Int
stratFromBinWidth [Double]
xs (Double -> Int) -> Double -> Int
forall a b. (a -> b) -> a -> b
$ Double
3.5 Double -> Double -> Double
forall a. Num a => a -> a -> a
* [Double] -> Double
forall a. Floating a => [a] -> a
stddev [Double]
xs Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
nDouble -> Double -> Double
forall a. Floating a => a -> a -> a
**(Double
1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
3))
where
n :: Double
n = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Double) -> Int -> Double
forall a b. (a -> b) -> a -> b
$ BinningStrategy
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Double]
xs
histogram :: BinningStrategy -> [[Double]] -> Histogram
histogram :: BinningStrategy -> [[Double]] -> Histogram
histogram BinningStrategy
strat [[Double]]
xs = Int -> [[Double]] -> Histogram
histogramNumBins (BinningStrategy
strat BinningStrategy -> BinningStrategy
forall a b. (a -> b) -> a -> b
$ [[Double]] -> [Double]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Double]]
xs) [[Double]]
xs
histogramBinSize :: Double -> [[Double]] -> Histogram
histogramBinSize :: Double -> [[Double]] -> Histogram
histogramBinSize Double
size = [[(Double, Int)]] -> Histogram
combineBins ([[(Double, Int)]] -> Histogram)
-> ([[Double]] -> [[(Double, Int)]]) -> [[Double]] -> Histogram
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Double] -> [(Double, Int)]) -> [[Double]] -> [[(Double, Int)]]
forall a b. (a -> b) -> [a] -> [b]
map (Double -> [Double] -> [(Double, Int)]
histBins Double
size ([Double] -> [(Double, Int)])
-> ([Double] -> [Double]) -> [Double] -> [(Double, Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> [Double] -> [Double]
bin Double
size)
histogramNumBins :: Int -> [[Double]] -> Histogram
histogramNumBins :: Int -> [[Double]] -> Histogram
histogramNumBins Int
n [[Double]]
xs =
Double -> [[Double]] -> Histogram
histogramBinSize Double
size [[Double]]
xs
where
size :: Double
size = Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Double -> Integer
forall {a} {b}. (RealFrac a, Floating a, Integral b) => a -> b
firstdigit Double
diff) Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double
10 Double -> Double -> Double
forall a. Floating a => a -> a -> a
** Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Double -> Integer
forall {a} {b}. (RealFrac a, Integral b, Floating a) => a -> b
exponent10 Double
diff))
diff :: Double
diff = if Double
diff_test Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
0
then Double
diff_test
else Double
1
diff_test :: Double
diff_test = ([Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum (([Double] -> Double) -> [[Double]] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map [Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [[Double]]
xs) Double -> Double -> Double
forall a. Num a => a -> a -> a
-
[Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum (([Double] -> Double) -> [[Double]] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map [Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [[Double]]
xs)) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
n)
firstdigit :: a -> b
firstdigit a
dbl = a -> b
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ a
dbl a -> a -> a
forall a. Fractional a => a -> a -> a
/ (a
10 a -> a -> a
forall a. Floating a => a -> a -> a
** Integer -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Integer
forall {a} {b}. (RealFrac a, Integral b, Floating a) => a -> b
exponent10 a
dbl))
exponent10 :: a -> b
exponent10 a
dbl = a -> b
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ a -> a -> a
forall a. Floating a => a -> a -> a
logBase a
10 a
dbl
histBins :: Double -> [Double] -> [(Double, Int)]
histBins :: Double -> [Double] -> [(Double, Int)]
histBins Double
size [Double]
xs = [ ([Double] -> Double
forall a. HasCallStack => [a] -> a
head [Double]
l, BinningStrategy
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Double]
l) | [Double]
l <- [Double] -> [[Double]]
forall a. Eq a => [a] -> [[a]]
group ([Double] -> [Double]
forall a. Ord a => [a] -> [a]
sort [Double]
xs) ]
bin :: Double -> [Double] -> [Double]
bin :: Double -> [Double] -> [Double]
bin Double
size xs :: [Double]
xs@[Double
_] = [Double]
xs
bin Double
size [Double]
xs = (Double -> Double) -> [Double] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map (\Double
x -> Double
size Double -> Double -> Double
forall a. Num a => a -> a -> a
* Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Double -> Integer
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (Double
x Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
size)) Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
size Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
2) [Double]
xs
combineBins :: [[(Double, Int)]] -> [(Double, [Int])]
combineBins :: [[(Double, Int)]] -> Histogram
combineBins [[(Double, Int)]
xs] = ((Double, Int) -> (Double, [Int])) -> [(Double, Int)] -> Histogram
forall a b. (a -> b) -> [a] -> [b]
map (\(Double
t, Int
n) -> (Double
t, [Int
n])) [(Double, Int)]
xs
combineBins [[(Double, Int)]]
xss = [[(Double, Int)]] -> Histogram
combineBins' [[(Double, Int)]]
xss
combineBins' :: [[(Double, Int)]] -> [(Double, [Int])]
combineBins' :: [[(Double, Int)]] -> Histogram
combineBins' [[(Double, Int)]]
xs = ([(Int, Double, Int)] -> (Double, [Int]))
-> [[(Int, Double, Int)]] -> Histogram
forall a b. (a -> b) -> [a] -> [b]
map ([(Int, Double, Int)] -> (Double, [Int])
forall {a} {a}. Num a => [(Int, a, a)] -> (a, [a])
merging ([(Int, Double, Int)] -> (Double, [Int]))
-> ([(Int, Double, Int)] -> [(Int, Double, Int)])
-> [(Int, Double, Int)]
-> (Double, [Int])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Int, Double, Int)] -> [(Int, Double, Int)]
forall {b} {c}. [(Int, b, c)] -> [(Int, b, c)]
sorting) ([[(Int, Double, Int)]] -> Histogram)
-> [[(Int, Double, Int)]] -> Histogram
forall a b. (a -> b) -> a -> b
$
[(Int, Double, Int)] -> [[(Int, Double, Int)]]
forall {a} {c}. [(a, Double, c)] -> [[(a, Double, c)]]
groupping ([(Int, Double, Int)] -> [[(Int, Double, Int)]])
-> [(Int, Double, Int)] -> [[(Int, Double, Int)]]
forall a b. (a -> b) -> a -> b
$ [(Int, Double, Int)] -> [(Int, Double, Int)]
forall {a} {c}. [(a, Double, c)] -> [(a, Double, c)]
ordering ([(Int, Double, Int)] -> [(Int, Double, Int)])
-> [(Int, Double, Int)] -> [(Int, Double, Int)]
forall a b. (a -> b) -> a -> b
$ [[(Int, Double, Int)]] -> [(Int, Double, Int)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[(Int, Double, Int)]] -> [(Int, Double, Int)])
-> [[(Int, Double, Int)]] -> [(Int, Double, Int)]
forall a b. (a -> b) -> a -> b
$ [[(Double, Int)]] -> [[(Int, Double, Int)]]
forall {b} {c}. [[(b, c)]] -> [[(Int, b, c)]]
numbering [[(Double, Int)]]
xs
where numbering :: [[(b, c)]] -> [[(Int, b, c)]]
numbering = (Int -> [(b, c)] -> [(Int, b, c)])
-> [Int] -> [[(b, c)]] -> [[(Int, b, c)]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (((Int, [(b, c)]) -> [(Int, b, c)])
-> Int -> [(b, c)] -> [(Int, b, c)]
forall a b c. ((a, b) -> c) -> a -> b -> c
curry (Int, [(b, c)]) -> [(Int, b, c)]
forall {a} {b} {c}. (a, [(b, c)]) -> [(a, b, c)]
indexing) [Int
1..]
indexing :: (a, [(b, c)]) -> [(a, b, c)]
indexing (a
i, [(b, c)]
x) = ((b, c) -> (a, b, c)) -> [(b, c)] -> [(a, b, c)]
forall a b. (a -> b) -> [a] -> [b]
map (\(b
t, c
n) -> (a
i, b
t, c
n)) [(b, c)]
x
ordering :: [(a, Double, c)] -> [(a, Double, c)]
ordering = ((a, Double, c) -> (a, Double, c) -> Ordering)
-> [(a, Double, c)] -> [(a, Double, c)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((a, Double, c) -> (a, Double, c) -> Ordering)
-> [(a, Double, c)] -> [(a, Double, c)])
-> ((a, Double, c) -> (a, Double, c) -> Ordering)
-> [(a, Double, c)]
-> [(a, Double, c)]
forall a b. (a -> b) -> a -> b
$ \(a
_, Double
t1, c
_) (a
_, Double
t2, c
_) -> Double -> Double -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Double
t1 Double
t2
groupping :: [(a, Double, c)] -> [[(a, Double, c)]]
groupping = ((a, Double, c) -> (a, Double, c) -> Bool)
-> [(a, Double, c)] -> [[(a, Double, c)]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (((a, Double, c) -> (a, Double, c) -> Bool)
-> [(a, Double, c)] -> [[(a, Double, c)]])
-> ((a, Double, c) -> (a, Double, c) -> Bool)
-> [(a, Double, c)]
-> [[(a, Double, c)]]
forall a b. (a -> b) -> a -> b
$ \(a
_, Double
t1, c
_) (a
_, Double
t2, c
_) -> Double
t1 Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
t2
sorting :: [(Int, b, c)] -> [(Int, b, c)]
sorting = ((Int, b, c) -> (Int, b, c) -> Ordering)
-> [(Int, b, c)] -> [(Int, b, c)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((Int, b, c) -> (Int, b, c) -> Ordering)
-> [(Int, b, c)] -> [(Int, b, c)])
-> ((Int, b, c) -> (Int, b, c) -> Ordering)
-> [(Int, b, c)]
-> [(Int, b, c)]
forall a b. (a -> b) -> a -> b
$ \(Int
i1, b
_, c
_) (Int
i2, b
_, c
_) -> Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
i1 Int
i2
merging :: [(Int, a, a)] -> (a, [a])
merging zs :: [(Int, a, a)]
zs@((Int
_, a
t, a
_) : [(Int, a, a)]
_) = [(Int, a, a)] -> a -> Int -> [a] -> (a, [a])
forall {a} {b} {a}.
Num a =>
[(Int, b, a)] -> a -> Int -> [a] -> (a, [a])
merging' [(Int, a, a)]
zs a
t Int
1 []
merging' :: [(Int, b, a)] -> a -> Int -> [a] -> (a, [a])
merging' [] a
t Int
k [a]
acc
| Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
count = [(Int, b, a)] -> a -> Int -> [a] -> (a, [a])
merging' [] a
t (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (a
0 a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
acc)
| Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
count = (a
t, [a] -> [a]
forall a. [a] -> [a]
reverse [a]
acc)
merging' zs :: [(Int, b, a)]
zs@((Int
i, b
_, a
n) : [(Int, b, a)]
xs) a
t Int
k [a]
acc
| Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
k = [(Int, b, a)] -> a -> Int -> [a] -> (a, [a])
merging' [(Int, b, a)]
xs a
t (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (a
n a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
acc)
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
k = [(Int, b, a)] -> a -> Int -> [a] -> (a, [a])
merging' [(Int, b, a)]
zs a
t (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (a
0 a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
acc)
count :: Int
count = [[(Double, Int)]] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[(Double, Int)]]
xs
mean :: Floating a => [a] -> a
mean :: forall a. Floating a => [a] -> a
mean [a]
x = (a, a) -> a
forall a b. (a, b) -> a
fst ((a, a) -> a) -> (a, a) -> a
forall a b. (a -> b) -> a -> b
$ ((a, a) -> a -> (a, a)) -> (a, a) -> [a] -> (a, a)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\(a
m, a
n) a
x -> (a
ma -> a -> a
forall a. Num a => a -> a -> a
+(a
xa -> a -> a
forall a. Num a => a -> a -> a
-a
m)a -> a -> a
forall a. Fractional a => a -> a -> a
/(a
na -> a -> a
forall a. Num a => a -> a -> a
+a
1),a
na -> a -> a
forall a. Num a => a -> a -> a
+a
1)) (a
0,a
0) [a]
x
stddev :: (Floating a) => [a] -> a
stddev :: forall a. Floating a => [a] -> a
stddev [a]
xs = a -> a
forall a. Floating a => a -> a
sqrt (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ [a] -> a
forall a. Floating a => [a] -> a
var [a]
xs
var :: (Floating a) => [a] -> a
var :: forall a. Floating a => [a] -> a
var [a]
xs = a -> Integer -> a -> [a] -> a
forall {t} {t}.
(Fractional t, Integral t) =>
t -> t -> t -> [t] -> t
var' a
0 Integer
0 a
0 [a]
xs a -> a -> a
forall a. Fractional a => a -> a -> a
/ Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
where
var' :: t -> t -> t -> [t] -> t
var' t
_ t
_ t
s [] = t
s
var' t
m t
n t
s (t
x:[t]
xs) = t -> t -> t -> [t] -> t
var' t
nm (t
n t -> t -> t
forall a. Num a => a -> a -> a
+ t
1) (t
s t -> t -> t
forall a. Num a => a -> a -> a
+ t
delta t -> t -> t
forall a. Num a => a -> a -> a
* (t
x t -> t -> t
forall a. Num a => a -> a -> a
- t
nm)) [t]
xs
where
delta :: t
delta = t
x t -> t -> t
forall a. Num a => a -> a -> a
- t
m
nm :: t
nm = t
m t -> t -> t
forall a. Num a => a -> a -> a
+ t
delta t -> t -> t
forall a. Fractional a => a -> a -> a
/ t -> t
forall a b. (Integral a, Num b) => a -> b
fromIntegral (t
n t -> t -> t
forall a. Num a => a -> a -> a
+ t
1)
kurtosis :: (Floating a) => [a] -> a
kurtosis :: forall a. Floating a => [a] -> a
kurtosis [a]
xs = ((a
1a -> a -> a
forall a. Fractional a => a -> a -> a
/a
n) a -> a -> a
forall a. Num a => a -> a -> a
* [a] -> a
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [(a
xa -> a -> a
forall a. Num a => a -> a -> a
-a
x_bar)a -> Integer -> a
forall a b. (Num a, Integral b) => a -> b -> a
^Integer
4 | a
x <- [a]
xs])
a -> a -> a
forall a. Fractional a => a -> a -> a
/ ((a
1a -> a -> a
forall a. Fractional a => a -> a -> a
/a
n) a -> a -> a
forall a. Num a => a -> a -> a
* [a] -> a
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [(a
xa -> a -> a
forall a. Num a => a -> a -> a
-a
x_bar)a -> Integer -> a
forall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 | a
x <- [a]
xs])a -> Integer -> a
forall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 a -> a -> a
forall a. Num a => a -> a -> a
-a
3
where
n :: a
n = Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> a) -> Int -> a
forall a b. (a -> b) -> a -> b
$ [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs
x_bar :: a
x_bar = [a] -> a
forall a. Floating a => [a] -> a
mean [a]
xs