module Math.Hypergeometric ( hypergeometric
, erf
, ncdf
) where
import Data.Functor ((<$>))
risingFactorial :: Num a => a -> Int -> a
risingFactorial :: forall a. Num a => a -> Int -> a
risingFactorial a
_ Int
0 = a
1
risingFactorial a
a Int
n = (a
a a -> a -> a
forall a. Num a => a -> a -> a
+ Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n a -> a -> a
forall a. Num a => a -> a -> a
- a
1) a -> a -> a
forall a. Num a => a -> a -> a
* a -> Int -> a
forall a. Num a => a -> Int -> a
risingFactorial a
a (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
factorial :: Num a => Int -> a
factorial :: forall a. Num a => Int -> a
factorial Int
n = [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product (Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> a) -> [Int] -> [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int
1..Int
n])
{-# SPECIALIZE ncdf :: Double -> Double #-}
ncdf :: (Eq a, Floating a) => a -> a
ncdf :: forall a. (Eq a, Floating a) => a -> a
ncdf a
z = (a
1a -> a -> a
forall a. Fractional a => a -> a -> a
/a
2) a -> a -> a
forall a. Num a => a -> a -> a
* (a
1 a -> a -> a
forall a. Num a => a -> a -> a
+ a -> a
forall a. (Eq a, Floating a) => a -> a
erf (a
z a -> a -> a
forall a. Fractional a => a -> a -> a
/ a -> a
forall a. Floating a => a -> a
sqrt a
2))
{-# SPECIALIZE erf :: Double -> Double #-}
erf :: (Eq a, Floating a) => a -> a
erf :: forall a. (Eq a, Floating a) => a -> a
erf a
z = (a
2 a -> a -> a
forall a. Num a => a -> a -> a
* a
z a -> a -> a
forall a. Num a => a -> a -> a
* a -> a
forall a. Floating a => a -> a
exp (-a
za -> Int -> a
forall a b. (Num a, Integral b) => a -> b -> a
^(Int
2::Int)) a -> a -> a
forall a. Fractional a => a -> a -> a
/ a -> a
forall a. Floating a => a -> a
sqrt a
forall a. Floating a => a
pi) a -> a -> a
forall a. Num a => a -> a -> a
* [a] -> [a] -> a -> a
forall a. (Eq a, Fractional a) => [a] -> [a] -> a -> a
hypergeometric [a
1] [a
3a -> a -> a
forall a. Fractional a => a -> a -> a
/a
2] (a
za -> Int -> a
forall a b. (Num a, Integral b) => a -> b -> a
^(Int
2::Int))
{-# SPECIALIZE hypergeometric :: [Double] -> [Double] -> Double -> Double #-}
hypergeometric :: (Eq a, Fractional a)
=> [a]
-> [a]
-> a
-> a
hypergeometric :: forall a. (Eq a, Fractional a) => [a] -> [a] -> a -> a
hypergeometric [a]
as [a]
bs a
z = [a] -> a
forall a. (Eq a, Num a) => [a] -> a
sumUntilEq
[ ([a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product ((a -> a) -> [a] -> [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> Int -> a
forall a. Num a => a -> Int -> a
`risingFactorial` Int
n) [a]
as) a -> a -> a
forall a. Fractional a => a -> a -> a
/ [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product ((a -> a) -> [a] -> [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> Int -> a
forall a. Num a => a -> Int -> a
`risingFactorial` Int
n) [a]
bs)) a -> a -> a
forall a. Num a => a -> a -> a
* (a
z a -> Int -> a
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
n) a -> a -> a
forall a. Fractional a => a -> a -> a
/ Int -> a
forall a. Num a => Int -> a
factorial Int
n | Int
n <- [Int
0..] ]
sumUntilEq :: (Eq a, Num a) => [a] -> a
sumUntilEq :: forall a. (Eq a, Num a) => [a] -> a
sumUntilEq = a -> [a] -> a
forall a. (Eq a, Num a) => a -> [a] -> a
sumUntilEqLoop a
0
sumUntilEqLoop :: (Eq a, Num a) => a -> [a] -> a
sumUntilEqLoop :: forall a. (Eq a, Num a) => a -> [a] -> a
sumUntilEqLoop a
acc (a
x:a
y:[a]
xs) =
if a
step0 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
step1
then a
step0
else a -> [a] -> a
forall a. (Eq a, Num a) => a -> [a] -> a
sumUntilEqLoop a
step1 [a]
xs
where step0 :: a
step0 = a
acc a -> a -> a
forall a. Num a => a -> a -> a
+ a
x
step1 :: a
step1 = a
acc a -> a -> a
forall a. Num a => a -> a -> a
+ a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a
y