{-# LANGUAGE CPP #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE PatternGuards #-}
module Math.Combinatorics.Species.Labeled
( labeled
, labelled
) where
import Math.Combinatorics.Species.Class
import Math.Combinatorics.Species.Types
import Math.Combinatorics.Species.NewtonRaphson
import qualified MathObj.FactoredRational as FQ
import qualified MathObj.PowerSeries as PS
import NumericPrelude
#if MIN_VERSION_numeric_prelude(0,2,0)
#else
import PreludeBase hiding (cycle)
#endif
facts :: [Integer]
facts = 1 : zipWith (*) [1..] facts
instance Species EGF where
singleton = egfFromCoeffs [0,1]
set = egfFromCoeffs (map (1%) facts)
cycle = egfFromCoeffs (0 : map (1%) [1..])
bracelet = egfFromCoeffs (0 : 1 : 1%2 : map (1%) [6, 8 ..])
o = liftEGF2 PS.compose
(><) = liftEGF2 . PS.lift2 $ \xs ys ->
zipWith3 (\a b c -> a*b*c) xs ys (map fromIntegral facts)
(@@) = liftEGF2 . PS.lift2 $ \fs gs ->
map (\(n,gn) -> let gn' = numerator $ gn
in (fs `safeIndex` gn') *
toRational (FQ.factorial gn' / FQ.factorial n))
(zip [0..] $ zipWith (*) (map fromIntegral facts) gs)
where safeIndex [] _ = 0
safeIndex (a:_) 0 = a
safeIndex (_:as) n = safeIndex as (n-1)
ofSize s p = (liftEGF . PS.lift1 $ filterCoeffs p) s
ofSizeExactly s n = (liftEGF . PS.lift1 $ selectIndex n) s
rec f = case newtonRaphsonRec f 100 of
Nothing -> error $ "Unable to express " ++ show f ++ " in the form T = TX*R(T)."
Just ls -> ls
labeled :: EGF -> [Integer]
labeled (EGF f) = (++repeat 0)
. map numerator
. zipWith (*) (map fromInteger facts)
$ PS.coeffs f
labelled :: EGF -> [Integer]
labelled = labeled