polynomial-algebra-0.1: src/Math/Algebra/Polynomial/Univariate/Pochhammer.hs
-- | Rising and falling factorials
--
-- See <https://en.wikipedia.org/wiki/Falling_and_rising_factorials>
{-# LANGUAGE BangPatterns, DataKinds, KindSignatures #-}
module Math.Algebra.Polynomial.Univariate.Pochhammer where
--------------------------------------------------------------------------------
import Data.Array ( Array , (!) , listArray , assocs )
import Data.List
import Data.Typeable
import GHC.TypeLits
import Data.Proxy
import Math.Algebra.Polynomial.Pretty
import Math.Algebra.Polynomial.Misc
import qualified Math.Algebra.Polynomial.FreeModule as ZMod
import Math.Algebra.Polynomial.FreeModule ( FreeMod , ZMod , QMod )
import Math.Algebra.Polynomial.Monomial.Univariate ( U(..) )
import Math.Algebra.Polynomial.Univariate
--------------------------------------------------------------------------------
-- * Rising and Falling factorials
risingFactorial :: Int -> Univariate Integer "x"
risingFactorial n = expandRisingFactorial (RF n)
fallingFactorial :: Int -> Univariate Integer "x"
fallingFactorial n = expandFallingFactorial (FF n)
--------------------------------------------------------------------------------
-- * Polynomials using rising or falling factorials as bases
-- | Univariate polynomials using /rising factorials/ as a basis function
newtype RisingPoly coeff = RisingPoly { fromRisingPoly :: FreeMod coeff RisingF } deriving (Eq,Show)
-- | Univariate polynomials using /falling factorials/ as a basis function
newtype FallingPoly coeff = FallingPoly { fromFallingPoly :: FreeMod coeff FallingF } deriving (Eq,Show)
expandRisingPoly :: (KnownSymbol var, Typeable c, Eq c, Num c) => FreeMod c RisingF -> Univariate c var
expandRisingPoly = Uni . ZMod.flatMap (unUni . expandRisingFactorial)
expandFallingPoly :: (KnownSymbol var, Typeable c, Eq c, Num c) => FreeMod c FallingF -> Univariate c var
expandFallingPoly = Uni . ZMod.flatMap (unUni . expandFallingFactorial)
--------------------------------------------------------------------------------
-- * Rising and falling factorial types
-- | Rising factorial @x^(k) = x(x+1)(x+2)...(x+k-1)@
newtype RisingF = RF Int deriving (Eq,Ord,Show)
-- | Falling factorial @x_(k) = x(x-1)(x-2)...(x-k+1)@
newtype FallingF = FF Int deriving (Eq,Ord,Show)
instance Pretty RisingF where
pretty (RF k) = case k of
0 -> "1"
1 -> "x"
_ -> "x^(" ++ show k ++ ")"
instance Pretty FallingF where
pretty (FF k) = case k of
0 -> "1"
1 -> "x"
_ -> "x_(" ++ show k ++ ")"
expandRisingFactorial :: (KnownSymbol var, Typeable c, Eq c, Num c) => RisingF -> Univariate c var
expandRisingFactorial = Uni . ZMod.fromZMod . unUni . expandRisingFactorialZ
expandFallingFactorial ::(KnownSymbol var, Typeable c, Eq c, Num c) => FallingF -> Univariate c var
expandFallingFactorial = Uni . ZMod.fromZMod . unUni . expandFallingFactorialZ
expandRisingFactorialZ :: RisingF -> Univariate Integer var
expandRisingFactorialZ (RF k) = Uni $ ZMod.fromList
[ (U p, abs c) | (p,c) <- assocs (signedStirling1stArray k) ]
expandFallingFactorialZ :: FallingF -> Univariate Integer var
expandFallingFactorialZ (FF k) = Uni $ ZMod.fromList
[ (U p, c) | (p,c) <- assocs (signedStirling1stArray k) ]
--------------------------------------------------------------------------------