{-# LANGUAGE CPP #-} module Math.Combinatrics.Double where import qualified Data.Vector.Unboxed as U #define LOG_FACT_CACHE_SIZE 1024 logFactCache :: U.Vector Double logFactCache :: Vector Double logFactCache = (Double -> Double -> Double) -> Double -> Vector Double -> Vector Double forall a b. (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector b -> Vector a U.scanl' Double -> Double -> Double forall a. Num a => a -> a -> a (+) Double 0.0 (Vector Double -> Vector Double) -> Vector Double -> Vector Double forall a b. (a -> b) -> a -> b $ Int -> (Int -> Double) -> Vector Double forall a. Unbox a => Int -> (Int -> a) -> Vector a U.generate LOG_FACT_CACHE_SIZE (log . fromIntegral . (+ 1)) {-# NOINLINE logFactCache #-} logFact :: Int -> Double logFact :: Int -> Double logFact = Vector Double -> Int -> Double forall a. Unbox a => Vector a -> Int -> a U.unsafeIndex Vector Double logFactCache {-# INLINE logFact #-} logPerm :: Int -> Int -> Double logPerm :: Int -> Int -> Double logPerm Int n Int k = Int -> Double logFact Int n Double -> Double -> Double forall a. Num a => a -> a -> a - Int -> Double logFact (Int n Int -> Int -> Int forall a. Num a => a -> a -> a - Int k) {-# INLINE logPerm #-} logComb :: Int -> Int -> Double logComb :: Int -> Int -> Double logComb Int n Int k = Int -> Double logFact Int n Double -> Double -> Double forall a. Num a => a -> a -> a - Int -> Double logFact Int k Double -> Double -> Double forall a. Num a => a -> a -> a - Int -> Double logFact (Int n Int -> Int -> Int forall a. Num a => a -> a -> a - Int k) {-# INLINE logComb #-}