module Math.IRT.Fisher
( FisherInfo(..)
, fisherInfoObserved
, fisherInfoExpected
, l'
, l''
) where
import Statistics.Distribution
import Math.IRT.Internal.Distribution
data FisherInfo = FisherInfo { items :: [Double]
, test :: !Double
, sem :: !Double
} deriving (Show)
fisherInfoObserved :: (ContDistr d, DensityDeriv d) => Double -> [Bool] -> [d] -> FisherInfo
fisherInfoObserved theta resps params =
let is = zipWith go resps params
t = sum is
s = sqrt (1 / t)
in FisherInfo is t s
where go u x = negate $ l'' u x theta
fisherInfoExpected :: ContDistr d => Double -> [d] -> FisherInfo
fisherInfoExpected theta params =
let is = map go params
t = sum is
s = sqrt (1 / t)
in FisherInfo is t s
where go x = let (cdf, ccdf, pdf) = pqDers x theta
in (square pdf) / (cdf * ccdf)
l' :: ContDistr d => Bool -> d -> Double -> Double
l' u x theta =
let (cdf, ccdf, pdf) = pqDers x theta
denom = cdf * ccdf
f k = k * pdf / denom
in case u of
True -> f ccdf
False -> f cdf
l'' :: (ContDistr d, DensityDeriv d) => Bool -> d -> Double -> Double
l'' u x theta =
let (cdf, ccdf, pdf) = pqDers x theta
pdf' = densityDeriv x theta
in case u of
True -> (((1) / square cdf) * (square pdf))
+ (1 / cdf * pdf')
False -> negate $ ((1 / square ccdf) * square pdf)
+ (1 / ccdf * pdf')
pqDers :: ContDistr d => d -> Double -> (Double, Double, Double)
pqDers x theta = let pComp = cumulative x theta
p' = density x theta
in ( pComp
, (1 pComp)
, p')
square :: Double -> Double
square = (^^ (2 :: Int))