hanalyze-0.2.0.0: test/Hanalyze/Model/AFTSpec.hs
{-# OPTIONS_GHC -Wno-unused-imports #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module Hanalyze.Model.AFTSpec (spec) where
import Test.Hspec
import Test.Hspec.QuickCheck (prop)
import Test.QuickCheck
import Hanalyze.Model.Formula
import Hanalyze.Model.Formula.Frame
import Hanalyze.Model.Formula.Design
import Hanalyze.Model.Formula.RFormula
import Hanalyze.Model.Formula.Nonlinear
import Hanalyze.Model.Formula.Mixed
import Hanalyze.Model.GLMM
import Hanalyze.Model.GLM (Family (..), LinkFn (..))
import Hanalyze.Stat.Distribution (Transform)
import Data.List (sort, nub)
import Control.Monad (forM, forM_)
import System.IO.Temp (withSystemTempFile)
import System.IO (hPutStr, hClose)
import Hanalyze.Model.HBM.Ast (Expr (..), Lit (..), DoStmt (..), Err)
import Data.IORef (newIORef, readIORef, modifyIORef')
import qualified Data.Vector as V
import qualified Data.Text as T
import qualified Numeric.LinearAlgebra as LA
import qualified Hanalyze.Model.AFT as AFT
import SpecHelper
spec :: Spec
spec = do
describe "Hanalyze.Model.AFT (Phase 12)" $ do
let ts = LA.fromList [exp 1.5, exp 1.8, exp 2.0, exp 2.1, exp 2.3,
exp 1.9, exp 2.05, exp 2.15, exp 1.95, exp 2.2]
delta = V.replicate 10 True
x1 = LA.fromColumns [LA.fromList (replicate 10 1.0)]
it "fitAFT LogNormal intercept-only: β₀ ≈ mean(log t)" $ do
r <- AFT.fitAFT AFT.AFTLogNormal x1 ts delta
case r of
Left e -> expectationFailure (T.unpack e)
Right fit -> do
let b0 = LA.atIndex (AFT.aftBeta fit) 0
meanLogT = LA.sumElements (LA.cmap log ts) / fromIntegral (LA.size ts)
abs (b0 - meanLogT) `shouldSatisfy` (< 0.05)
it "fitAFT Weibull: 打ち切り混在で動く" $ do
let delta2 = V.fromList [True, True, False, True, True,
True, False, True, True, True]
r <- AFT.fitAFT AFT.AFTWeibull x1 ts delta2
case r of
Left e -> expectationFailure (T.unpack e)
Right fit -> AFT.aftScale fit `shouldSatisfy` (> 0)
it "fitAFT 入力長 mismatch は Left" $ do
r <- AFT.fitAFT AFT.AFTLogNormal x1 (LA.fromList [1, 2]) delta
case r of
Left _ -> pure ()
Right _ -> expectationFailure "expected Left"
it "predictAFT Exponential: E[T] = exp(X β)" $ do
r <- AFT.fitAFT AFT.AFTExponential x1 ts delta
case r of
Left e -> expectationFailure (T.unpack e)
Right fit -> do
let preds = AFT.predictAFT fit x1
b0 = LA.atIndex (AFT.aftBeta fit) 0
abs (LA.atIndex preds 0 - exp b0) `shouldSatisfy` (< 1e-6)