{-# LANGUAGE PostfixOperators #-}
{-# LANGUAGE TypeApplications #-}
module Math.NumberTheory.Recurrences.Pentagonal
( partition
) where
import qualified Data.Chimera as Ch
import Data.List.Infinite (Infinite(..), (...))
import qualified Data.List.Infinite as Inf
import Data.Vector (Vector)
import Numeric.Natural (Natural)
pents :: (Enum a, Num a) => Infinite a
pents :: forall a. (Enum a, Num a) => Infinite a
pents = Infinite a -> Infinite a -> Infinite a
forall a. Infinite a -> Infinite a -> Infinite a
Inf.interleave
((a -> a -> a) -> a -> Infinite a -> Infinite a
forall b a. (b -> a -> b) -> b -> Infinite a -> Infinite b
Inf.scanl (\a
acc a
n -> a
acc a -> a -> a
forall a. Num a => a -> a -> a
+ a
3 a -> a -> a
forall a. Num a => a -> a -> a
* a
n a -> a -> a
forall a. Num a => a -> a -> a
- a
1) a
0 (a
1...))
((a -> a -> a) -> a -> Infinite a -> Infinite a
forall b a. (b -> a -> b) -> b -> Infinite a -> Infinite b
Inf.scanl (\a
acc a
n -> a
acc a -> a -> a
forall a. Num a => a -> a -> a
+ a
3 a -> a -> a
forall a. Num a => a -> a -> a
* a
n a -> a -> a
forall a. Num a => a -> a -> a
- a
2) a
1 (a
2...))
partitionF :: Num a => (Word -> a) -> Word -> a
partitionF :: forall a. Num a => (Word -> a) -> Word -> a
partitionF Word -> a
_ Word
0 = a
1
partitionF Word -> a
f Word
n
= [a] -> a
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum
([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$ (a -> a -> a) -> [a] -> [a] -> [a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith a -> a -> a
forall a. Num a => a -> a -> a
(*) ([a] -> [a]
forall a. HasCallStack => [a] -> [a]
cycle [a
1, a
1, -a
1, -a
1])
([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ (Word -> a) -> [Word] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (Word -> a
f (Word -> a) -> (Word -> Word) -> Word -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word
n -))
([Word] -> [a]) -> [Word] -> [a]
forall a b. (a -> b) -> a -> b
$ (Word -> Bool) -> Infinite Word -> [Word]
forall a. (a -> Bool) -> Infinite a -> [a]
Inf.takeWhile (Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
<= Word
n)
(Infinite Word -> [Word]) -> Infinite Word -> [Word]
forall a b. (a -> b) -> a -> b
$ Infinite Word -> Infinite Word
forall a. Infinite a -> Infinite a
Inf.tail Infinite Word
forall a. (Enum a, Num a) => Infinite a
pents
partition :: Num a => Infinite a
partition :: forall a. Num a => Infinite a
partition = (Word -> a) -> Infinite a
forall a. (Word -> a) -> Infinite a
Inf.tabulate (Chimera Vector a -> Word -> a
forall (v :: * -> *) a. Vector v a => Chimera v a -> Word -> a
Ch.index Chimera Vector a
ch)
where
ch :: Chimera Vector a
ch = forall (v :: * -> *) a.
(Vector v a, Typeable v) =>
((Word -> a) -> Word -> a) -> Chimera v a
Ch.tabulateFix @Vector (Word -> a) -> Word -> a
forall a. Num a => (Word -> a) -> Word -> a
partitionF
{-# SPECIALIZE partition :: Infinite Int #-}
{-# SPECIALIZE partition :: Infinite Word #-}
{-# SPECIALIZE partition :: Infinite Integer #-}
{-# SPECIALIZE partition :: Infinite Natural #-}