{-# OPTIONS_HADDOCK prune #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE RecordWildCards #-}
module Numeric.Eproc.Bounded (
Config
, State
, Verdict(..)
, Bettor(..)
, config
, initial
, update
, decide
, log_wealth
, samples
) where
import GHC.Exts (Double(D#))
import Numeric.Eproc.Common (Bettor(..), Verdict(..))
data BetState =
SFixed
| SAdaptive
{-# UNPACK #-} !Double
{-# UNPACK #-} !Double
{-# UNPACK #-} !Int
| SNewton
{-# UNPACK #-} !Double
{-# UNPACK #-} !Double
data Config = Config {
Config -> Bettor
cfg_bettor :: !Bettor
, Config -> Double
cfg_lam_max_pos :: {-# UNPACK #-} !Double
, Config -> Double
cfg_lam_max_neg :: {-# UNPACK #-} !Double
, Config -> Double
cfg_null_mean :: {-# UNPACK #-} !Double
, Config -> Double
cfg_alpha :: {-# UNPACK #-} !Double
, Config -> Double
cfg_log_thresh :: {-# UNPACK #-} !Double
}
data State = State {
State -> Int
st_n :: {-# UNPACK #-} !Int
, State -> Double
st_log_w_pos :: {-# UNPACK #-} !Double
, State -> Double
st_log_w_neg :: {-# UNPACK #-} !Double
, State -> BetState
st_bet_pos :: !BetState
, State -> BetState
st_bet_neg :: !BetState
}
tiny :: Double
tiny :: Double
tiny = Double# -> Double
D# Double#
1.0e-300##
{-# INLINE tiny #-}
init_bet :: Bettor -> BetState
init_bet :: Bettor -> BetState
init_bet Bettor
b = case Bettor
b of
Fixed Double
_ -> BetState
SFixed
Bettor
Adaptive -> Double -> Double -> Int -> BetState
SAdaptive Double
0 Double
0 Int
0
Bettor
Newton -> Double -> Double -> BetState
SNewton Double
0 Double
1.0e-6
{-# INLINE init_bet #-}
bet_lambda :: Bettor -> Double -> BetState -> Double
bet_lambda :: Bettor -> Double -> BetState -> Double
bet_lambda Bettor
b !Double
lam_max !BetState
s = case Bettor
b of
Fixed Double
lam -> Double
lam
Bettor
Adaptive -> case BetState
s of
SAdaptive !Double
sm !Double
sm2 !Int
n
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 -> Double
0
| Bool
otherwise ->
let !nd :: Double
nd = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n
!mu :: Double
mu = Double
sm Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
nd
!mu2 :: Double
mu2 = Double
mu Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
mu
!var :: Double
var = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
0 (Double
sm2 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
nd Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
mu2)
!den :: Double
den = Double
var Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
mu2
!raw :: Double
raw = if Double
den Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
0 then Double
0 else Double
mu Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
den
in Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
0 (Double -> Double -> Double
forall a. Ord a => a -> a -> a
min Double
lam_max Double
raw)
BetState
_ -> Double
0
Bettor
Newton -> case BetState
s of
SNewton !Double
lam Double
_ -> Double
lam
BetState
_ -> Double
0
{-# INLINE bet_lambda #-}
step_bet :: Bettor -> Double -> BetState -> Double -> BetState
step_bet :: Bettor -> Double -> BetState -> Double -> BetState
step_bet Bettor
b !Double
lam_max !BetState
s !Double
z = case Bettor
b of
Fixed Double
_ -> BetState
SFixed
Bettor
Adaptive -> case BetState
s of
SAdaptive !Double
sm !Double
sm2 !Int
n -> Double -> Double -> Int -> BetState
SAdaptive (Double
sm Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
z) (Double
sm2 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
z Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
z) (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
BetState
_ -> Double -> Double -> Int -> BetState
SAdaptive Double
z (Double
z Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
z) Int
1
Bettor
Newton -> case BetState
s of
SNewton !Double
lam !Double
acc ->
let !denom :: Double
denom = Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
lam Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
z
!g :: Double
g = if Double
denom Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
0 then Double
0 else Double -> Double
forall a. Num a => a -> a
negate Double
z Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
denom
!acc' :: Double
acc' = Double
acc Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
g Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
g
!lam' :: Double
lam' = Double
lam Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
g Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
acc'
!clp :: Double
clp = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
0 (Double -> Double -> Double
forall a. Ord a => a -> a -> a
min Double
lam_max Double
lam')
in Double -> Double -> BetState
SNewton Double
clp Double
acc'
BetState
_ -> Double -> Double -> BetState
SNewton Double
0 Double
1.0e-6
{-# INLINE step_bet #-}
config
:: Double
-> Double
-> Double
-> Double
-> Bettor
-> Config
config :: Double -> Double -> Double -> Double -> Bettor -> Config
config !Double
m !Double
lo !Double
hi !Double
alpha !Bettor
b = Config {
cfg_bettor :: Bettor
cfg_bettor = Bettor
b
, cfg_lam_max_pos :: Double
cfg_lam_max_pos = Double
0.5 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
m Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
lo)
, cfg_lam_max_neg :: Double
cfg_lam_max_neg = Double
0.5 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
hi Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
m)
, cfg_null_mean :: Double
cfg_null_mean = Double
m
, cfg_alpha :: Double
cfg_alpha = Double
alpha
, cfg_log_thresh :: Double
cfg_log_thresh = Double -> Double
forall a. Floating a => a -> a
log (Double
2 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
alpha)
}
{-# INLINE config #-}
initial :: Config -> State
initial :: Config -> State
initial Config{Double
Bettor
cfg_bettor :: Config -> Bettor
cfg_lam_max_pos :: Config -> Double
cfg_lam_max_neg :: Config -> Double
cfg_null_mean :: Config -> Double
cfg_alpha :: Config -> Double
cfg_log_thresh :: Config -> Double
cfg_bettor :: Bettor
cfg_lam_max_pos :: Double
cfg_lam_max_neg :: Double
cfg_null_mean :: Double
cfg_alpha :: Double
cfg_log_thresh :: Double
..} =
let !s0 :: BetState
s0 = Bettor -> BetState
init_bet Bettor
cfg_bettor
in State {
st_n :: Int
st_n = Int
0
, st_log_w_pos :: Double
st_log_w_pos = Double
0
, st_log_w_neg :: Double
st_log_w_neg = Double
0
, st_bet_pos :: BetState
st_bet_pos = BetState
s0
, st_bet_neg :: BetState
st_bet_neg = BetState
s0
}
{-# INLINE initial #-}
update :: Config -> State -> Double -> State
update :: Config -> State -> Double -> State
update Config{Double
Bettor
cfg_bettor :: Config -> Bettor
cfg_lam_max_pos :: Config -> Double
cfg_lam_max_neg :: Config -> Double
cfg_null_mean :: Config -> Double
cfg_alpha :: Config -> Double
cfg_log_thresh :: Config -> Double
cfg_bettor :: Bettor
cfg_lam_max_pos :: Double
cfg_lam_max_neg :: Double
cfg_null_mean :: Double
cfg_alpha :: Double
cfg_log_thresh :: Double
..} State{Double
Int
BetState
st_n :: State -> Int
st_log_w_pos :: State -> Double
st_log_w_neg :: State -> Double
st_bet_pos :: State -> BetState
st_bet_neg :: State -> BetState
st_n :: Int
st_log_w_pos :: Double
st_log_w_neg :: Double
st_bet_pos :: BetState
st_bet_neg :: BetState
..} !Double
x =
let !z :: Double
z = Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
cfg_null_mean
!lam_p :: Double
lam_p = Bettor -> Double -> BetState -> Double
bet_lambda Bettor
cfg_bettor Double
cfg_lam_max_pos BetState
st_bet_pos
!lam_n :: Double
lam_n = Bettor -> Double -> BetState -> Double
bet_lambda Bettor
cfg_bettor Double
cfg_lam_max_neg BetState
st_bet_neg
!fac_p :: Double
fac_p = Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
lam_p Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
z
!fac_n :: Double
fac_n = Double
1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
lam_n Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
z
!logw_p :: Double
logw_p = Double
st_log_w_pos Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
forall a. Floating a => a -> a
log (Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
tiny Double
fac_p)
!logw_n :: Double
logw_n = Double
st_log_w_neg Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
forall a. Floating a => a -> a
log (Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
tiny Double
fac_n)
!sp :: BetState
sp = Bettor -> Double -> BetState -> Double -> BetState
step_bet Bettor
cfg_bettor Double
cfg_lam_max_pos BetState
st_bet_pos Double
z
!sn :: BetState
sn = Bettor -> Double -> BetState -> Double -> BetState
step_bet Bettor
cfg_bettor Double
cfg_lam_max_neg BetState
st_bet_neg (Double -> Double
forall a. Num a => a -> a
negate Double
z)
in Int -> Double -> Double -> BetState -> BetState -> State
State (Int
st_n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Double
logw_p Double
logw_n BetState
sp BetState
sn
{-# INLINE update #-}
decide :: Config -> State -> Verdict
decide :: Config -> State -> Verdict
decide Config{Double
Bettor
cfg_bettor :: Config -> Bettor
cfg_lam_max_pos :: Config -> Double
cfg_lam_max_neg :: Config -> Double
cfg_null_mean :: Config -> Double
cfg_alpha :: Config -> Double
cfg_log_thresh :: Config -> Double
cfg_bettor :: Bettor
cfg_lam_max_pos :: Double
cfg_lam_max_neg :: Double
cfg_null_mean :: Double
cfg_alpha :: Double
cfg_log_thresh :: Double
..} State{Double
Int
BetState
st_n :: State -> Int
st_log_w_pos :: State -> Double
st_log_w_neg :: State -> Double
st_bet_pos :: State -> BetState
st_bet_neg :: State -> BetState
st_n :: Int
st_log_w_pos :: Double
st_log_w_neg :: Double
st_bet_pos :: BetState
st_bet_neg :: BetState
..}
| Double
st_log_w_pos Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
>= Double
cfg_log_thresh = Verdict
Reject
| Double
st_log_w_neg Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
>= Double
cfg_log_thresh = Verdict
Reject
| Bool
otherwise = Verdict
Continue
{-# INLINE decide #-}
log_wealth :: State -> Double
log_wealth :: State -> Double
log_wealth State{Double
Int
BetState
st_n :: State -> Int
st_log_w_pos :: State -> Double
st_log_w_neg :: State -> Double
st_bet_pos :: State -> BetState
st_bet_neg :: State -> BetState
st_n :: Int
st_log_w_pos :: Double
st_log_w_neg :: Double
st_bet_pos :: BetState
st_bet_neg :: BetState
..} = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
st_log_w_pos Double
st_log_w_neg
{-# INLINE log_wealth #-}
samples :: State -> Int
samples :: State -> Int
samples = State -> Int
st_n
{-# INLINE samples #-}