{-# LANGUAGE BangPatterns, ScopedTypeVariables #-}
module Math.Combinat.Numbers.Sequences where
import Data.Array
import Data.Bits ( shiftL , shiftR , (.&.) )
import Math.Combinat.Helper
import Math.Combinat.Sign
import Math.Combinat.Numbers.Primes ( primes , factorize , productOfFactors )
import qualified Data.Map.Strict as Map
factorial :: Integral a => a -> Integer
factorial :: forall a. Integral a => a -> Integer
factorial = forall a. Integral a => a -> Integer
factorialSplit
factorialSplit :: Integral a => a -> Integer
factorialSplit :: forall a. Integral a => a -> Integer
factorialSplit a
n = forall a. Integral a => a -> a -> Integer
productFromTo a
1 a
n
factorialNaive :: Integral a => a -> Integer
factorialNaive :: forall a. Integral a => a -> Integer
factorialNaive a
n
| a
n forall a. Ord a => a -> a -> Bool
< a
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"factorialNaive: input should be nonnegative"
| a
n forall a. Eq a => a -> a -> Bool
== a
0 = Integer
1
| Bool
otherwise = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product [Integer
1..forall a b. (Integral a, Num b) => a -> b
fromIntegral a
n]
factorialSwing :: Integral a => a -> Integer
factorialSwing :: forall a. Integral a => a -> Integer
factorialSwing a
n = [(Integer, Int)] -> Integer
productOfFactors (Int -> [(Integer, Int)]
factorialPrimeExponents forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral a
n) where
factorialPrimeExponents :: Int -> [(Integer,Int)]
factorialPrimeExponents :: Int -> [(Integer, Int)]
factorialPrimeExponents Int
n = forall a. (a -> Bool) -> [a] -> [a]
filter forall {a} {a}. (Ord a, Num a) => (a, a) -> Bool
cond forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip [Integer]
primes (Int -> [Int]
factorialPrimeExponents_ Int
n) where
cond :: (a, a) -> Bool
cond (a
_,!a
e) = a
e forall a. Ord a => a -> a -> Bool
> a
0
factorialPrimeExponentsNaive :: forall a. Integral a => a -> [(Integer,Int)]
factorialPrimeExponentsNaive :: forall a. Integral a => a -> [(Integer, Int)]
factorialPrimeExponentsNaive a
n = [(Integer, Int)]
result where
fi :: a -> Integer
fi = forall a b. (Integral a, Num b) => a -> b
fromIntegral :: a -> Integer
result :: [(Integer, Int)]
result = forall k a. Map k a -> [(k, a)]
Map.toList
forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
(a -> a -> a) -> f (Map k a) -> Map k a
Map.unionsWith forall a. Num a => a -> a -> a
(+)
forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Integer -> [(Integer, Int)]
factorize
forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map a -> Integer
fi [a
1..a
n]
factorialPrimeExponents_ :: Int -> [Int]
factorialPrimeExponents_ :: Int -> [Int]
factorialPrimeExponents_ = Int -> [Int]
go where
go :: Int -> [Int]
go Int
0 = []
go Int
1 = []
go Int
2 = [Int
1]
go !Int
n = [Int] -> [Int] -> [Int]
longAdd [Int]
half [Int]
swing where
half :: [Int]
half = forall a b. (a -> b) -> [a] -> [b]
map (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Bits a => a -> Int -> a
shiftL Int
1) forall a b. (a -> b) -> a -> b
$ Int -> [Int]
go (forall a. Bits a => a -> Int -> a
shiftR Int
n Int
1)
swing :: [Int]
swing = Int -> [Int]
swingFactorialExponents_ Int
n
longAdd :: [Int] -> [Int] -> [Int]
longAdd :: [Int] -> [Int] -> [Int]
longAdd [Int]
xs [] = [Int]
xs
longAdd [] [Int]
ys = [Int]
ys
longAdd (!Int
x:[Int]
xs) (!Int
y:[Int]
ys) = (Int
xforall a. Num a => a -> a -> a
+Int
y) forall a. a -> [a] -> [a]
: [Int] -> [Int] -> [Int]
longAdd [Int]
xs [Int]
ys
swingFactorialExponents_ :: Int -> [Int]
swingFactorialExponents_ :: Int -> [Int]
swingFactorialExponents_ = Int -> [Int]
go where
go :: Int -> [Int]
go Int
0 = []
go Int
1 = []
go Int
2 = [Int
1]
go Int
n = Int
expo2 forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map Integer -> Int
expo (forall a. [a] -> [a]
tail [Integer]
ps) where
nn :: Integer
nn = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n :: Integer
ps :: [Integer]
ps :: [Integer]
ps = forall a. (a -> Bool) -> [a] -> [a]
takeWhile (forall a. Ord a => a -> a -> Bool
<=Integer
nn) [Integer]
primes
expo2 :: Int
expo2 :: Int
expo2 = Int -> Int -> Int
go Int
0 (forall a. Bits a => a -> Int -> a
shiftR Int
n Int
1) where
go :: Int -> Int -> Int
go :: Int -> Int -> Int
go !Int
acc !Int
r
| Int
r forall a. Ord a => a -> a -> Bool
< Int
1 = Int
acc
| Bool
otherwise = Int -> Int -> Int
go Int
acc' Int
r'
where
acc' :: Int
acc' = Int
acc forall a. Num a => a -> a -> a
+ (Int
r forall a. Bits a => a -> a -> a
.&. Int
1)
r' :: Int
r' = forall a. Bits a => a -> Int -> a
shiftR Int
r Int
1
expo :: Integer -> Int
expo :: Integer -> Int
expo Integer
pp = Int -> Int -> Int
go Int
0 (forall a. Integral a => a -> a -> a
div Int
n Int
p) where
p :: Int
p = forall a. Num a => Integer -> a
fromInteger Integer
pp :: Int
go :: Int -> Int -> Int
go :: Int -> Int -> Int
go !Int
acc !Int
r
| Int
r forall a. Ord a => a -> a -> Bool
< Int
1 = Int
acc
| Bool
otherwise = Int -> Int -> Int
go Int
acc' Int
r'
where
acc' :: Int
acc' = Int
acc forall a. Num a => a -> a -> a
+ (Int
r forall a. Bits a => a -> a -> a
.&. Int
1)
r' :: Int
r' = forall a. Integral a => a -> a -> a
div Int
r Int
p
doubleFactorial :: Integral a => a -> Integer
doubleFactorial :: forall a. Integral a => a -> Integer
doubleFactorial = forall a. Integral a => a -> Integer
doubleFactorialSplit
doubleFactorialSplit :: Integral a => a -> Integer
doubleFactorialSplit :: forall a. Integral a => a -> Integer
doubleFactorialSplit a
n
| a
n forall a. Ord a => a -> a -> Bool
< a
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"doubleFactorialSplit: input should be nonnegative"
| a
n forall a. Eq a => a -> a -> Bool
== a
0 = Integer
1
| forall a. Integral a => a -> Bool
odd a
n = forall a. Integral a => a -> a -> Integer
productFromToStride2 a
2 a
n
| Bool
otherwise = let halfn :: a
halfn = forall a. Integral a => a -> a -> a
div a
n a
2
in forall a. Bits a => a -> Int -> a
shiftL (forall a. Integral a => a -> Integer
factorialSplit a
halfn) (forall a b. (Integral a, Num b) => a -> b
fromIntegral a
halfn)
doubleFactorialNaive :: Integral a => a -> Integer
doubleFactorialNaive :: forall a. Integral a => a -> Integer
doubleFactorialNaive a
n
| a
n forall a. Ord a => a -> a -> Bool
< a
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"doubleFactorialNaive: input should be nonnegative"
| a
n forall a. Eq a => a -> a -> Bool
== a
0 = Integer
1
| forall a. Integral a => a -> Bool
odd a
n = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product [Integer
1,Integer
3..forall a b. (Integral a, Num b) => a -> b
fromIntegral a
n]
| Bool
otherwise = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product [Integer
2,Integer
4..forall a b. (Integral a, Num b) => a -> b
fromIntegral a
n]
binomial :: Integral a => a -> a -> Integer
binomial :: forall a. Integral a => a -> a -> Integer
binomial = forall a. Integral a => a -> a -> Integer
binomialSplit
binomialSplit :: Integral a => a -> a -> Integer
binomialSplit :: forall a. Integral a => a -> a -> Integer
binomialSplit a
n a
k
| a
k forall a. Ord a => a -> a -> Bool
> a
n = Integer
0
| a
k forall a. Ord a => a -> a -> Bool
< a
0 = Integer
0
| a
k forall a. Ord a => a -> a -> Bool
> (a
n forall a. Integral a => a -> a -> a
`div` a
2) = forall a. Integral a => a -> a -> Integer
binomialSplit a
n (a
nforall a. Num a => a -> a -> a
-a
k)
| Bool
otherwise = (forall a. Integral a => a -> a -> Integer
productFromTo (a
nforall a. Num a => a -> a -> a
-a
k) a
n) forall a. Integral a => a -> a -> a
`div` (forall a. Integral a => a -> a -> Integer
productFromTo a
1 a
k)
binomialNaive :: Integral a => a -> a -> Integer
binomialNaive :: forall a. Integral a => a -> a -> Integer
binomialNaive a
n a
k
| a
k forall a. Ord a => a -> a -> Bool
> a
n = Integer
0
| a
k forall a. Ord a => a -> a -> Bool
< a
0 = Integer
0
| a
k forall a. Ord a => a -> a -> Bool
> (a
n forall a. Integral a => a -> a -> a
`div` a
2) = forall a. Integral a => a -> a -> Integer
binomial a
n (a
nforall a. Num a => a -> a -> a
-a
k)
| Bool
otherwise = (forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product [Integer
n'forall a. Num a => a -> a -> a
-Integer
k'forall a. Num a => a -> a -> a
+Integer
1 .. Integer
n']) forall a. Integral a => a -> a -> a
`div` (forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product [Integer
1..Integer
k'])
where
k' :: Integer
k' = forall a b. (Integral a, Num b) => a -> b
fromIntegral a
k
n' :: Integer
n' = forall a b. (Integral a, Num b) => a -> b
fromIntegral a
n
signedBinomial :: Int -> Int -> Integer
signedBinomial :: Int -> Int -> Integer
signedBinomial Int
n Int
k
| Int
n forall a. Ord a => a -> a -> Bool
>= Int
0 = forall a. Integral a => a -> a -> Integer
binomial Int
n Int
k
| Int
k forall a. Ord a => a -> a -> Bool
>= Int
0 = forall a b. (Integral a, Num b) => a -> b -> b
negateIfOdd Int
k forall a b. (a -> b) -> a -> b
$ forall a. Integral a => a -> a -> Integer
binomial (Int
kforall a. Num a => a -> a -> a
-Int
nforall a. Num a => a -> a -> a
-Int
1) Int
k
| Bool
otherwise = forall a b. (Integral a, Num b) => a -> b -> b
negateIfOdd (Int
nforall a. Num a => a -> a -> a
+Int
k) forall a b. (a -> b) -> a -> b
$ forall a. Integral a => a -> a -> Integer
binomial (-Int
kforall a. Num a => a -> a -> a
-Int
1) (-Int
nforall a. Num a => a -> a -> a
-Int
1)
pascalRow :: Integral a => a -> [Integer]
pascalRow :: forall a. Integral a => a -> [Integer]
pascalRow a
n' = Integer -> Integer -> [Integer]
worker Integer
0 Integer
1 where
n :: Integer
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral a
n'
worker :: Integer -> Integer -> [Integer]
worker Integer
j Integer
x
| Integer
jforall a. Ord a => a -> a -> Bool
>Integer
n = []
| Bool
True = let j' :: Integer
j'=Integer
jforall a. Num a => a -> a -> a
+Integer
1 in Integer
x forall a. a -> [a] -> [a]
: Integer -> Integer -> [Integer]
worker Integer
j' (forall a. Integral a => a -> a -> a
div (Integer
xforall a. Num a => a -> a -> a
*(Integer
nforall a. Num a => a -> a -> a
-Integer
j)) Integer
j')
multinomial :: Integral a => [a] -> Integer
multinomial :: forall a. Integral a => [a] -> Integer
multinomial [a]
xs = forall a. Integral a => a -> a -> a
div
(forall a. Integral a => a -> Integer
factorial (forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [a]
xs))
(forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product [ forall a. Integral a => a -> Integer
factorial a
x | a
x<-[a]
xs ])
catalan :: Integral a => a -> Integer
catalan :: forall a. Integral a => a -> Integer
catalan a
n
| a
n forall a. Ord a => a -> a -> Bool
< a
0 = Integer
0
| Bool
otherwise = forall a. Integral a => a -> a -> Integer
binomial (a
nforall a. Num a => a -> a -> a
+a
n) a
n forall a. Integral a => a -> a -> a
`div` forall a b. (Integral a, Num b) => a -> b
fromIntegral (a
nforall a. Num a => a -> a -> a
+a
1)
catalanTriangle :: Integral a => a -> a -> Integer
catalanTriangle :: forall a. Integral a => a -> a -> Integer
catalanTriangle a
n a
k
| a
k forall a. Ord a => a -> a -> Bool
> a
n = Integer
0
| a
k forall a. Ord a => a -> a -> Bool
< a
0 = Integer
0
| Bool
otherwise = (forall a. Integral a => a -> a -> Integer
binomial (a
nforall a. Num a => a -> a -> a
+a
k) a
n forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral (a
nforall a. Num a => a -> a -> a
-a
kforall a. Num a => a -> a -> a
+a
1)) forall a. Integral a => a -> a -> a
`div` forall a b. (Integral a, Num b) => a -> b
fromIntegral (a
nforall a. Num a => a -> a -> a
+a
1)
signedStirling1stArray :: Integral a => a -> Array Int Integer
signedStirling1stArray :: forall a. Integral a => a -> Array Int Integer
signedStirling1stArray a
n
| a
n forall a. Ord a => a -> a -> Bool
< a
1 = forall a. HasCallStack => [Char] -> a
error [Char]
"stirling1stArray: n should be at least 1"
| a
n forall a. Eq a => a -> a -> Bool
== a
1 = forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Int
1,Int
1 ) [Integer
1]
| Bool
otherwise = forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Int
1,Int
n') [ Int -> Integer
lkp (Int
kforall a. Num a => a -> a -> a
-Int
1) forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fromIntegral (a
nforall a. Num a => a -> a -> a
-a
1) forall a. Num a => a -> a -> a
* Int -> Integer
lkp Int
k | Int
k<-[Int
1..Int
n'] ]
where
prev :: Array Int Integer
prev = forall a. Integral a => a -> Array Int Integer
signedStirling1stArray (a
nforall a. Num a => a -> a -> a
-a
1)
n' :: Int
n' = forall a b. (Integral a, Num b) => a -> b
fromIntegral a
n :: Int
lkp :: Int -> Integer
lkp Int
j | Int
j forall a. Ord a => a -> a -> Bool
< Int
1 = Integer
0
| Int
j forall a. Ord a => a -> a -> Bool
>= Int
n' = Integer
0
| Bool
otherwise = Array Int Integer
prev forall i e. Ix i => Array i e -> i -> e
! Int
j
signedStirling1st :: Integral a => a -> a -> Integer
signedStirling1st :: forall a. Integral a => a -> a -> Integer
signedStirling1st a
n a
k
| a
kforall a. Eq a => a -> a -> Bool
==a
0 Bool -> Bool -> Bool
&& a
nforall a. Eq a => a -> a -> Bool
==a
0 = Integer
1
| a
k forall a. Ord a => a -> a -> Bool
< a
1 = Integer
0
| a
k forall a. Ord a => a -> a -> Bool
> a
n = Integer
0
| Bool
otherwise = forall a. Integral a => a -> Array Int Integer
signedStirling1stArray a
n forall i e. Ix i => Array i e -> i -> e
! (forall a b. (Integral a, Num b) => a -> b
fromIntegral a
k)
unsignedStirling1st :: Integral a => a -> a -> Integer
unsignedStirling1st :: forall a. Integral a => a -> a -> Integer
unsignedStirling1st a
n a
k = forall a. Num a => a -> a
abs (forall a. Integral a => a -> a -> Integer
signedStirling1st a
n a
k)
stirling2nd :: Integral a => a -> a -> Integer
stirling2nd :: forall a. Integral a => a -> a -> Integer
stirling2nd a
n a
k
| a
kforall a. Eq a => a -> a -> Bool
==a
0 Bool -> Bool -> Bool
&& a
nforall a. Eq a => a -> a -> Bool
==a
0 = Integer
1
| a
k forall a. Ord a => a -> a -> Bool
< a
1 = Integer
0
| a
k forall a. Ord a => a -> a -> Bool
> a
n = Integer
0
| Bool
otherwise = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Integer]
xs forall a. Integral a => a -> a -> a
`div` forall a. Integral a => a -> Integer
factorial a
k where
xs :: [Integer]
xs = [ forall a b. (Integral a, Num b) => a -> b -> b
negateIfOdd (a
kforall a. Num a => a -> a -> a
-a
i) forall a b. (a -> b) -> a -> b
$ forall a. Integral a => a -> a -> Integer
binomial a
k a
i forall a. Num a => a -> a -> a
* (forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i)forall a b. (Num a, Integral b) => a -> b -> a
^a
n | a
i<-[a
0..a
k] ]
bernoulli :: Integral a => a -> Rational
bernoulli :: forall a. Integral a => a -> Rational
bernoulli a
n
| a
n forall a. Ord a => a -> a -> Bool
< a
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"bernoulli: n should be nonnegative"
| a
n forall a. Eq a => a -> a -> Bool
== a
0 = Rational
1
| a
n forall a. Eq a => a -> a -> Bool
== a
1 = -Rational
1forall a. Fractional a => a -> a -> a
/Rational
2
| Bool
otherwise = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [ a -> Rational
f a
k | a
k<-[a
1..a
n] ]
where
f :: a -> Rational
f a
k = forall a. Real a => a -> Rational
toRational (forall a b. (Integral a, Num b) => a -> b -> b
negateIfOdd (a
nforall a. Num a => a -> a -> a
+a
k) forall a b. (a -> b) -> a -> b
$ forall a. Integral a => a -> Integer
factorial a
k forall a. Num a => a -> a -> a
* forall a. Integral a => a -> a -> Integer
stirling2nd a
n a
k)
forall a. Fractional a => a -> a -> a
/ forall a. Real a => a -> Rational
toRational (a
kforall a. Num a => a -> a -> a
+a
1)
bellNumbersArray :: Integral a => a -> Array Int Integer
bellNumbersArray :: forall a. Integral a => a -> Array Int Integer
bellNumbersArray a
nn = Array Int Integer
arr where
arr :: Array Int Integer
arr = forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array (Int
0::Int,Int
n) [(Int, Integer)]
kvs
n :: Int
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral a
nn :: Int
kvs :: [(Int, Integer)]
kvs = (Int
0,Integer
1) forall a. a -> [a] -> [a]
: [ (Int
k, Int -> Integer
f Int
k) | Int
k<-[Int
1..Int
n] ]
f :: Int -> Integer
f Int
n = forall a. Num a => [a] -> a
sum' [ forall a. Integral a => a -> a -> Integer
binomial (Int
nforall a. Num a => a -> a -> a
-Int
1) Int
k forall a. Num a => a -> a -> a
* Array Int Integer
arr forall i e. Ix i => Array i e -> i -> e
! Int
k | Int
k<-[Int
0..Int
nforall a. Num a => a -> a -> a
-Int
1] ]
bellNumber :: Integral a => a -> Integer
bellNumber :: forall a. Integral a => a -> Integer
bellNumber a
nn
| Int
n forall a. Ord a => a -> a -> Bool
< Int
0 = forall a. HasCallStack => [Char] -> a
error [Char]
"bellNumber: expecting a nonnegative index"
| Int
n forall a. Eq a => a -> a -> Bool
== Int
0 = Integer
1
| Bool
otherwise = forall a. Num a => [a] -> a
sum' [ forall a. Integral a => a -> a -> Integer
stirling2nd Int
n Int
k | Int
k<-[Int
1..Int
n] ]
where
n :: Int
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral a
nn :: Int