jackpolynomials 1.4.6.0 → 1.4.7.0
raw patch · 11 files changed
+700/−374 lines, 11 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Math.Algebra.Combinatorics: kostkaNumbers :: Int -> Rational -> Map Partition (Map Partition Rational)
- Math.Algebra.Combinatorics: semiStandardTableauxWithGivenShapeAndWeight :: Partition -> [Int] -> [[[Int]]]
- Math.Algebra.Combinatorics: skewGelfandTsetlinPatterns :: Partition -> Partition -> [Int] -> [[Partition]]
- Math.Algebra.Combinatorics: skewKostkaNumbers :: Rational -> Partition -> Partition -> Map Partition Rational
- Math.Algebra.Combinatorics: skewTableauxWithGivenShapeAndWeight :: Partition -> Partition -> [Int] -> [SkewTableau Int]
- Math.Algebra.Combinatorics: symbolicKostkaNumbers :: Int -> Map Partition (Map Partition RatioOfQSprays)
- Math.Algebra.Combinatorics: symbolicSkewKostkaNumbers :: Partition -> Partition -> Map Partition RatioOfQSprays
+ Math.Algebra.SymmetricPolynomials: hallPolynomials :: Partition -> Partition -> Map Partition QSpray
+ Math.Algebra.SymmetricPolynomials: jackCombination' :: (FunctionLike b, Eq b, C b, Eq (BaseRing b), C (BaseRing b)) => BaseRing b -> Char -> Spray b -> Map Partition b
+ Math.Combinatorics.Kostka: kostkaNumbers :: Int -> Rational -> Map Partition (Map Partition Rational)
+ Math.Combinatorics.Kostka: kostkaNumbersWithGivenLambda :: Partition -> Rational -> Map Partition Rational
+ Math.Combinatorics.Kostka: skewKostkaNumbers :: Rational -> Partition -> Partition -> Map Partition Rational
+ Math.Combinatorics.Kostka: symbolicKostkaNumbers :: Int -> Map Partition (Map Partition RatioOfQSprays)
+ Math.Combinatorics.Kostka: symbolicKostkaNumbersWithGivenLambda :: Partition -> Map Partition RatioOfQSprays
+ Math.Combinatorics.Kostka: symbolicSkewKostkaNumbers :: Partition -> Partition -> Map Partition RatioOfQSprays
+ Math.Combinatorics.Tableaux: semiStandardTableauxWithGivenShapeAndWeight :: Partition -> [Int] -> [[[Int]]]
+ Math.Combinatorics.Tableaux: skewGelfandTsetlinPatterns :: Partition -> Partition -> [Int] -> [[Partition]]
+ Math.Combinatorics.Tableaux: skewTableauxWithGivenShapeAndWeight :: Partition -> Partition -> [Int] -> [SkewTableau Int]
Files
- CHANGELOG.md +11/−1
- README.md +18/−15
- jackpolynomials.cabal +5/−4
- src/Math/Algebra/Combinatorics.hs +0/−172
- src/Math/Algebra/Jack.hs +12/−6
- src/Math/Algebra/Jack/Internal.hs +211/−136
- src/Math/Algebra/JackPol.hs +8/−3
- src/Math/Algebra/SymmetricPolynomials.hs +90/−22
- src/Math/Combinatorics/Kostka.hs +166/−0
- src/Math/Combinatorics/Tableaux.hs +78/−0
- tests/Main.hs +101/−15
CHANGELOG.md view
@@ -158,7 +158,7 @@ 1.4.6.0 ------- -* new module `Combinatorics` +* new modules `Math.Combinatorics.Kostka` and `Math.Combinatorics.Tableaux` * new function `semiStandardTableauxWithGivenShapeAndWeight`, to get all semistandard tableaux with a given shape and a given weight @@ -168,4 +168,14 @@ * new function `skewGelfandTsetlinPatterns`, to get Gelfand-Tsetlin patterns defined by a skew partition + +1.4.7.0 +------- +* new function `kostkaNumbersWithGivenLambda`, to get the Kostka-Jack numbers +with a given Jack parameter and a given partition `lambda` + +* new function `symbolicKostkaNumbersWithGivenLambda`, to get the Kostka-Jack +numbers with a symbolic Jack parameter for a given partition `lambda` + +* new function `hallPolynomials`, to get the Hall polynomials
README.md view
@@ -9,12 +9,14 @@ Schur polynomials have applications in combinatorics and zonal polynomials have applications in multivariate statistics. They are particular cases of -[Jack polynomials](https://en.wikipedia.org/wiki/Jack_function). This package +[Jack polynomials](https://en.wikipedia.org/wiki/Jack_function), which are +multivariate symmetric polynomials. This package allows to compute these polynomials. It also allows to compute other -symmetric polynomials: Kostka-Foulkes polynomials, t-Schur polynomials, -Hall-Littlewood polynomials, Kostka-Macdonald polynomials, and Macdonald -polynomials. In addition, it provides some functions to compute Kostka -numbers and to enumerate Gelfand-Tsetlin patterns. +symmetric polynomials: $t$-Schur polynomials, +Hall-Littlewood polynomials, and Macdonald +polynomials. In addition, it provides some functions to compute Kostka-Jack +numbers, Kostka-Foulkes polynomials, Kostka-Macdonald polynomials, Hall +polynomials, and to enumerate Gelfand-Tsetlin patterns. ___ @@ -203,7 +205,7 @@ `hallLittlewoodPolynomial` function, are represented by some sprays of type `SimpleParametricSpray a`, an alias of the type `Spray (Spray a)`. -When the value of the parameter of a Hall-Littlewood polynomial is `0`, then +When the value of the parameter of a Hall-Littlewood $P$-polynomial is `0`, then this polynomial is the Schur polynomial of the given partition. ```haskell @@ -225,9 +227,9 @@ As of version 1.4.5.0, the package can compute some Macdonald polynomials. The Macdonald polynomials are symmetric multivariate polynomials whose coefficients depend on two parameters usually denoted by $q$ and $t$. -Let's consider for example the Macdonald P-polynomial. It generalizes -the Hall-Littlewood P-polynomial: the Hall-Littlewood P-polynomial with -parameter $t$ is obtained from the Macdonald P-polynomial by substituting +Let's consider for example the Macdonald $P$-polynomial. It generalizes +the Hall-Littlewood $P$-polynomial: the Hall-Littlewood $P$-polynomial with +parameter $t$ is obtained from the Macdonald $P$-polynomial by substituting the parameter $q$ with $0$. ```haskell @@ -243,7 +245,7 @@ ``` We use `asSimpleParametricSpray` because, contrary to the Hall-Littlewood -J-polynomial, the Macdonald J-polynomial is not represented by a +$P$-polynomial, the Macdonald $P$-polynomial is not represented by a `SimpleParametricSpray a` spray but by a `ParametricSpray a` spray, because its coefficients are not polynomials in the two parameters $q$ and $t$, but ratios of polynomials. @@ -251,11 +253,12 @@ ### Combinatorics -The module `Math.Algebra.Combinatorics` appeared in version 1.4.6.0. -It provides some functions to compute Kostka numbers, possibly skew, -to enumerate the semistandard Young tableaux with a given shape and -a given weight, possibly skew, and to enumerate Gelfand-Tsetlin patterns. -The reason to include this module in the package is that these functions +The modules `Math.Combinatorics.Kostka` and `Math.Combinatorics.Tableaux` +appeared in version 1.4.6.0. They provide some functions to compute Kostka-Jack +numbers, possibly skew, to enumerate the semistandard Young tableaux with a +given shape and a given weight, possibly skew, and to enumerate +Gelfand-Tsetlin patterns. +The reason to include these modules in the package is that these functions are used to compute the symmetric polynomials.
jackpolynomials.cabal view
@@ -1,14 +1,14 @@ name: jackpolynomials -version: 1.4.6.0 +version: 1.4.7.0 synopsis: Jack, zonal, Schur, and other symmetric polynomials -description: This library can compute Jack polynomials, zonal polynomials, Schur polynomials, flagged Schur polynomials, factorial Schur polynomials, t-Schur polynomials, Hall-Littlewood polynomials, Macdonald polynomials, Kostka-Foulkes polynomials, and Kostka-Macdonald polynomials. It also provides some functions to compute Kostka numbers and to enumerate Gelfand-Tsetlin patterns. +description: This library can compute Jack polynomials, zonal polynomials, Schur polynomials, flagged Schur polynomials, factorial Schur polynomials, t-Schur polynomials, Hall-Littlewood polynomials, Macdonald polynomials, Kostka-Foulkes polynomials, Kostka-Macdonald polynomials, and Hall polynomials. It also provides some functions to compute Kostka numbers and to enumerate Gelfand-Tsetlin patterns. homepage: https://github.com/stla/jackpolynomials#readme license: GPL-3 license-file: LICENSE author: Stéphane Laurent maintainer: laurent_step@outlook.fr copyright: 2022-2024 Stéphane Laurent -category: Math, Algebra +category: Math, Algebra, Combinatorics build-type: Simple extra-source-files: README.md CHANGELOG.md @@ -18,7 +18,8 @@ hs-source-dirs: src exposed-modules: Math.Algebra.Jack.HypergeoPQ , Math.Algebra.SymmetricPolynomials - , Math.Algebra.Combinatorics + , Math.Combinatorics.Kostka + , Math.Combinatorics.Tableaux , Math.Algebra.Jack , Math.Algebra.JackPol , Math.Algebra.JackSymbolicPol
− src/Math/Algebra/Combinatorics.hs
@@ -1,172 +0,0 @@-{-| -Module : Math.Algebra.Combinatorics -Description : -Copyright : (c) Stéphane Laurent, 2024 -License : GPL-3 -Maintainer : laurent_step@outlook.fr - -This module provides some functions to compute Kostka numbers with a Jack -parameter, possibly skew, some functions to enumerate semistandard tableaux, -possibly skew, with a given shape and a given weight, and a function to -enumerate the Gelfand-Tsetlin patterns defined by a skew partition. --} - -module Math.Algebra.Combinatorics - ( - -- * Kostka numbers - kostkaNumbers - , symbolicKostkaNumbers - , skewKostkaNumbers - , symbolicSkewKostkaNumbers - -- * Tableaux - , semiStandardTableauxWithGivenShapeAndWeight - , skewTableauxWithGivenShapeAndWeight - -- * Gelfand-Tsetlin patterns - , skewGelfandTsetlinPatterns - ) where -import qualified Data.Foldable as DF -import Data.Map.Strict ( - Map - ) -import qualified Data.Map.Strict as DM -import Data.Tuple.Extra ( - second - ) -import Math.Algebra.Hspray ( - RatioOfQSprays - , unitRatioOfSprays - ) -import Math.Algebra.Jack.Internal ( - Partition - , _isPartition - , _kostkaNumbers - , _symbolicKostkaNumbers - , isSkewPartition - , skewJackInMSPbasis - , skewSymbolicJackInMSPbasis - , _skewGelfandTsetlinPatterns - , _skewTableauxWithGivenShapeAndWeight - , _semiStandardTableauxWithGivenShapeAndWeight - ) -import Math.Combinat.Tableaux.Skew ( - SkewTableau (..) - ) - --- | Kostka numbers \(K_{\lambda,\mu}(\alpha)\) with Jack parameter, or --- Kostka-Jack numbers, for a given weight of the --- partitions \(\lambda\) and \(\mu\) and a given Jack parameter --- \(\alpha\) (these are the standard Kostka numbers when --- \(\alpha=1\)). This returns a map whose keys represent the --- partitions \(\lambda\) and the value attached to a partition \(\lambda\) --- represents the map \(\mu \mapsto K_{\lambda,\mu}(\alpha)\) where the --- partition \(\mu\) is included in the keys of this map if and only if --- \(K_{\lambda,\mu}(\alpha) \neq 0\). The Kostka-Jack number --- \(K_{\lambda,\mu}(\alpha)\) is the coefficient of the monomial symmetric --- polynomial \(m_\mu\) in the expression of the \(P\)-Jack polynomial --- \(P_\lambda(\alpha)\) as a linear combination of monomial symmetric --- polynomials. -kostkaNumbers :: - Int -- ^ weight of the partitions - -> Rational -- ^ Jack parameter - -> Map Partition (Map Partition Rational) -kostkaNumbers weight alpha - | weight < 0 = - error "kostkaNumbers: negative weight." - | weight == 0 = - DM.singleton [] (DM.singleton [] 1) - | otherwise = - _kostkaNumbers weight weight alpha 'P' - --- | Kostka numbers \(K_{\lambda,\mu}(\alpha)\) with symbolic Jack parameter \(\alpha\) --- for a given weight of the partitions \(\lambda\) and \(\mu\). This returns a map --- whose keys represent the --- partitions \(\lambda\) and the value attached to a partition \(\lambda\) --- represents the map \(\mu \mapsto K_{\lambda,\mu}(\alpha)\) where the --- partition \(\mu\) is included in the keys of this map if and only if --- \(K_{\lambda,\mu}(\alpha) \neq 0\). -symbolicKostkaNumbers :: - Int -- ^ weight of the partitions - -> Map Partition (Map Partition RatioOfQSprays) -symbolicKostkaNumbers weight - | weight < 0 = - error "symbolicKostkaNumbers: negative weight." - | weight == 0 = - DM.singleton [] (DM.singleton [] unitRatioOfSprays) - | otherwise = - _symbolicKostkaNumbers weight weight 'P' - --- | Skew Kostka numbers \(K_{\lambda/\mu, \nu}(\alpha)\) with a given Jack --- parameter \(\alpha\) and a given skew partition \(\lambda/\mu\). For \(\alpha=1\) --- these are the ordinary skew Kostka numbers. --- The function returns a map whose keys represent the partitions \(\nu\). --- The skew Kostka-Jack number \(K_{\lambda/\mu, \nu}(\alpha)\) --- is the coefficient of the monomial symmetric --- polynomial \(m_\nu\) in the expression of the skew \(P\)-Jack polynomial --- \(P_{\lambda/\mu}(\alpha)\) as a linear combination of monomial symmetric --- polynomials. -skewKostkaNumbers :: - Rational -- ^ Jack parameter - -> Partition -- ^ outer partition of the skew partition - -> Partition -- ^ inner partition of the skew partition - -> Map Partition Rational -skewKostkaNumbers alpha lambda mu - | not (isSkewPartition lambda mu) = - error "skewKostkaNumbers: invalid skew partition." - | otherwise = - DM.map snd (skewJackInMSPbasis alpha 'P' lambda mu) - --- | Skew Kostka numbers \(K_{\lambda/\mu, \nu}(\alpha)\) with symbolic Jack --- parameter \(\alpha\) for a given skew partition \(\lambda/\mu\). --- This returns a map whose keys represent the partitions \(\nu\). -symbolicSkewKostkaNumbers :: - Partition -- ^ outer partition of the skew partition - -> Partition -- ^ inner partition of the skew partition - -> Map Partition RatioOfQSprays -symbolicSkewKostkaNumbers lambda mu - | not (isSkewPartition lambda mu) = - error "symbolicSkewKostkaNumbers: invalid skew partition." - | otherwise = - DM.map snd (skewSymbolicJackInMSPbasis 'P' lambda mu) - --- | Skew Gelfand-Tsetlin patterns defined by a skew partition and a weight vector. -skewGelfandTsetlinPatterns :: - Partition -- ^ outer partition of the skew partition - -> Partition -- ^ inner partition of the skew partition - -> [Int] -- ^ weight - -> [[Partition]] -skewGelfandTsetlinPatterns lambda mu weight - | not (isSkewPartition lambda mu) = - error "skewGelfandTsetlinPatterns: invalid skew partition." - | otherwise = - map (map DF.toList) (_skewGelfandTsetlinPatterns lambda mu weight) - --- | Skew semistandard tableaux with a given shape (a skew partition) and --- a given weight vector. The weight is the vector whose @i@-th element is the --- number of occurrences of @i@ in the tableau. -skewTableauxWithGivenShapeAndWeight :: - Partition -- ^ outer partition of the skew partition - -> Partition -- ^ inner partition of the skew partition - -> [Int] -- ^ weight - -> [SkewTableau Int] -skewTableauxWithGivenShapeAndWeight lambda mu weight - | not (isSkewPartition lambda mu) = - error "skewTableauxWithGivenShapeAndWeight: invalid skew partition." - | otherwise = - map (SkewTableau . (map (second DF.toList))) - (_skewTableauxWithGivenShapeAndWeight lambda mu weight) - --- | Semistandard tableaux with a given shape (an integer partition) and --- a given weight vector. The weight is the vector whose @i@-th element is the --- number of occurrences of @i@ in the tableau. -semiStandardTableauxWithGivenShapeAndWeight :: - Partition -- ^ shape, integer partition - -> [Int] -- ^ weight - -> [[[Int]]] -semiStandardTableauxWithGivenShapeAndWeight lambda weight - | not (_isPartition lambda) = - error "semiStandardTableauxWithGivenShapeAndWeight: invalid partition." - | any (< 0) weight = - [] - | otherwise = - map (map DF.toList) - (_semiStandardTableauxWithGivenShapeAndWeight lambda weight)
src/Math/Algebra/Jack.hs view
@@ -57,11 +57,14 @@ -- | Evaluation of a Jack polynomial. jack :: forall a. (Eq a, AlgField.C a) => [a] -- ^ values of the variables - -> Partition -- ^ partition of integers + -> Partition -- ^ integer partition -> a -- ^ Jack parameter -> Char -- ^ which Jack polynomial, @'J'@, @'C'@, @'P'@ or @'Q'@ -> a -jack [] _ _ _ = error "jack: empty list of variables." +jack [] lambda _ _ = + if null lambda + then one + else zero jack x@(x0:_) lambda alpha which = case _isPartition lambda of False -> error "jack: invalid integer partition." @@ -154,12 +157,15 @@ -- Jack \(P\)-polynomials with Jack parameter \(\alpha=1\). schur :: forall a. AlgRing.C a => [a] -- ^ values of the variables - -> Partition -- ^ partition of integers + -> Partition -- ^ integer partition -> a -schur [] _ = error "schur: empty list of variables" +schur [] lambda = + if null lambda + then one + else zero schur x@(x0:_) lambda = case _isPartition lambda of - False -> error "schur: invalid integer partition" + False -> error "schur: invalid integer partition." True -> sch n 1 lambda arr0 where n = length x @@ -219,7 +225,7 @@ skewSchur xs lambda mu = if isSkewPartition lambda mu then DM.foldlWithKey' f zero lrCoefficients - else error "skewSchur: invalid skew partition" + else error "skewSchur: invalid skew partition." where lrCoefficients = skewSchurLRCoefficients lambda mu f :: a -> Partition -> Int -> a
src/Math/Algebra/Jack/Internal.hs view
@@ -2,6 +2,9 @@ {-# LANGUAGE ScopedTypeVariables #-} module Math.Algebra.Jack.Internal ( Partition + , msPolynomialUnsafe + , _esPolynomial + , jackJpol0 , jackCoeffP , jackCoeffQ , jackCoeffC @@ -17,8 +20,10 @@ , isSkewPartition , sprayToMap , comboToSpray + , _kostkaNumbersWithGivenLambda , _kostkaNumbers , _inverseKostkaMatrix + , _symbolicKostkaNumbersWithGivenLambda , _symbolicKostkaNumbers , _inverseSymbolicKostkaMatrix , _kostkaFoulkesPolynomial @@ -46,6 +51,7 @@ , _skewGelfandTsetlinPatterns , _skewTableauxWithGivenShapeAndWeight , _semiStandardTableauxWithGivenShapeAndWeight + , _msPolynomialInHLPbasis ) where import Prelude @@ -70,8 +76,7 @@ , tails ) import Data.List.Extra ( - unsnoc - , drop1 + drop1 ) import Data.List.Index ( iconcatMap ) import Data.Map.Strict ( Map ) @@ -116,12 +121,13 @@ , sumOfSprays , productOfSprays , FunctionLike (..) + , fromList ) import Math.Combinat.Partitions.Integer ( fromPartition , dualPartition , partitions - , dominates + , partitions' , dominatedPartitions , partitionWidth , toPartitionUnsafe @@ -143,6 +149,40 @@ type PartitionsPair = (Seq Int, Seq Int) type PairsMap = Map PartitionsPair ([(Int,Int)], [(Int,Int)]) +-- | monomial symmetric polynomial +msPolynomialUnsafe :: (AlgRing.C a, Eq a) + => Int -- ^ number of variables + -> Partition -- ^ integer partition + -> Spray a +msPolynomialUnsafe n lambda + = fromList $ zip permutations coefficients + where + ellLambda = length lambda + permutations = permuteMultiset (lambda ++ replicate (n-ellLambda) 0) + coefficients = repeat AlgRing.one + +-- | elementary symmetric polynomial. +_esPolynomial :: (AlgRing.C a, Eq a) + => Int -- ^ number of variables + -> Partition -- ^ integer partition + -> Spray a +_esPolynomial n lambda = + productOfSprays (map esPolynomialK lambda) + where + esPolynomialK k = msPolynomialUnsafe n (replicate k 1) + +-- | Jack polynomial for alpha=0. +jackJpol0 :: (AlgRing.C a, Eq a) + => Int -- ^ number of variables + -> Partition -- ^ integer partition + -> Spray a +jackJpol0 n lambda = + f .^ _esPolynomial n (DF.toList lambda') + where + lambda' = _dualPartition' (S.fromList lambda) + factorial i = P.product [2 .. i] + f = DF.product (fmap factorial lambda') + inverseKostkaNumbers :: Int -> Map Partition (Map Partition Int) inverseKostkaNumbers n = DM.fromDistinctDescList (zip lambdas' (map maps [1 .. length lambdas])) @@ -1000,6 +1040,47 @@ coeffs = DM.filter (not . isZeroSpray) (DM.fromDistinctDescList (zip lambdas (V.toList (getRow 1 matrix)))) +-- _hallLittlewoodPpolynomialInMSPbasis :: +-- (Eq a, AlgRing.C a) => Partition -> Map Partition (Spray a) +-- _hallLittlewoodPpolynomialInMSPbasis lambda = +-- DM.unionsWith (^+^) msCombos +-- where +-- schurCombo = _hallLittlewoodPolynomialsInSchurBasis 'P' lambda +-- schurAssocs = DM.assocs schurCombo +-- msCombos = +-- map +-- (\(kappa, spray) -> +-- DM.mapKeys fromPartition +-- (DM.map (\kn -> kn .^ spray) +-- (kostkaNumbersWithGivenLambda (toPartitionUnsafe kappa)))) +-- schurAssocs + +-- | monomial symmetric polynomials in Schur polynomials basis +msPolynomialsInSchurBasis :: + Int -> Int -> Map Partition (Map Partition Rational) +msPolynomialsInSchurBasis n weight = + _inverseKostkaMatrix n weight 1 'P' + +-- | monomial symmetric polynomial in Hall-Littlewood P-polynomials basis +_msPolynomialInHLPbasis :: + Int -> Partition -> Map Partition (Spray Rational) +_msPolynomialInHLPbasis n lambda = + DM.filter (not . isZeroSpray) (DM.unionsWith (^+^) hlpCombos) + where + weight = sum lambda + msCombos = msPolynomialsInSchurBasis n weight + lambdas = DM.keys msCombos + hlpCombo mu = + DM.filter (not . isZeroSpray) $ + DM.fromDistinctAscList + (map (\kappa -> (kappa, _kostkaFoulkesPolynomial mu kappa)) lambdas) + msAssocs = DM.assocs (msCombos DM.! lambda) + hlpCombos = + map + (\(mu, r) -> + DM.map (\spray -> r *^ spray) (hlpCombo mu)) + msAssocs + _e :: AlgRing.C a => MCP.Partition -> a -> a _e lambda alpha = alpha * fromIntegral (_n (dualPartition lambda)) - fromIntegral (_n lambda) @@ -1013,6 +1094,69 @@ alpha = lone 1 _n mu = sum (zipWith (P.*) [0 .. ] (fromPartition mu)) +_kostkaNumbersWithGivenLambda :: + forall a. (AlgField.C a) + => Int -> Partition -> a -> Char -> Map Partition a +_kostkaNumbersWithGivenLambda nv lambda alpha which = rec (length mus') + where + kN1 = case which of + 'J' -> recip (jackCoeffP lambda alpha) + 'P' -> AlgRing.one + 'C' -> jackCoeffC lambda alpha / jackCoeffP lambda alpha + 'Q' -> jackCoeffQ lambda alpha / jackCoeffP lambda alpha + _ -> error "_kostkaNumbersWithGivenLambda: should not happen." + mu_r_plus :: + Seq Int -> (Int, Int) -> Int -> (Partition, (Int, Int), Int) + mu_r_plus mu pair@(i, j) r = + ( + DF.toList $ S.reverse $ S.sort $ + S.adjust' ((P.+) r) i (S.adjust' (subtract r) j mu) + , pair + , r + ) + mu_r_plus' :: + Seq Int -> (Int, Int) -> Int -> (Partition, (Int, Int), Int) + mu_r_plus' mu pair@(i, j) r = + ( + DF.toList $ S.reverse $ S.sort $ + S.deleteAt j (S.adjust' ((P.+) r) i mu) + , pair + , r + ) + lambda' = toPartitionUnsafe lambda + mus' = reverse $ + filter (\part -> partitionWidth part <= nv) (dominatedPartitions lambda') + _e_lambda_alpha = _e lambda' alpha + rec :: Int -> Map Partition a + rec n = if n == 1 + then DM.singleton lambda kN1 + else DM.insert mu kNumber previous + where + previous = rec (n - 1) + parts = DM.keys previous + mu' = mus' !! (n - 1) + mu = fromPartition mu' + _e_mu_alpha = _e mu' alpha + ee = _e_lambda_alpha - _e_mu_alpha + mu'' = S.fromList mu + l = S.length mu'' + pairs = [(i, j) | i <- [0 .. l-2], j <- [i+1 .. l-1]] + triplets = + filter ((\nu -> nu `elem` parts) . fst3) + ( + [mu_r_plus mu'' (i, j) r + | (i, j) <- pairs, r <- [1 .. S.index mu'' j - 1]] + ++ + [mu_r_plus' mu'' (i, j) (S.index mu'' j) + | (i, j) <- pairs] + ) + kNumber = + AlgAdd.sum [ + fromIntegral (S.index mu'' i P.- S.index mu'' j P.+ 2 P.* r) + * (previous DM.! nu) + | (nu, (i, j), r) <- triplets + ] / ee + _inverseKostkaMatrix :: (Eq a, AlgField.C a) => Int -> Int -> a -> Char -> Map Partition (Map Partition a) @@ -1031,156 +1175,87 @@ _kostkaNumbers :: forall a. (AlgField.C a) => Int -> Int -> a -> Char -> Map Partition (Map Partition a) -_kostkaNumbers nv weight alpha which = kostkaMatrix' +_kostkaNumbers nv weight alpha which = + DM.fromDistinctAscList + [ + (lambda, _kostkaNumbersWithGivenLambda nv lambda alpha which) + | lambda' <- partitions' (weight, nv) weight + , let lambda = fromPartition lambda' + ] + +_symbolicKostkaNumbersWithGivenLambda :: + forall a. (Eq a, AlgField.C a) + => Int -> Partition -> Char -> Map Partition (RatioOfSprays a) +_symbolicKostkaNumbersWithGivenLambda nv lambda which = rec (length mus') where - coeffsP = DM.fromDistinctDescList - [(kappa, recip (jackCoeffP kappa alpha))| kappa <- lambdas'] - coeffsC = DM.fromDistinctDescList - [(kappa, jackCoeffC kappa alpha / jackCoeffP kappa alpha) - | kappa <- lambdas'] - coeffsQ = DM.fromDistinctDescList - [(kappa, jackCoeffQ kappa alpha / jackCoeffP kappa alpha) - | kappa <- lambdas'] - kostkaMatrix = DM.mapKeys fromPartition (rec (length lambdas)) - kostkaMatrix' = case which of - 'J' -> DM.mapWithKey (\kappa m -> DM.map ((*) (coeffsP DM.! kappa)) m) - kostkaMatrix - 'P' -> kostkaMatrix - 'C' -> DM.mapWithKey (\kappa m -> DM.map ((*) (coeffsC DM.! kappa)) m) - kostkaMatrix - 'Q' -> DM.mapWithKey (\kappa m -> DM.map ((*) (coeffsQ DM.! kappa)) m) - kostkaMatrix - _ -> error "_kostkaNumbers: should not happen." + kN1 = case which of + 'J' -> asRatioOfSprays (jackSymbolicCoeffPinv lambda) + 'P' -> unitRatioOfSprays + 'C' -> (jackSymbolicCoeffPinv lambda :: Spray a) *> jackSymbolicCoeffC lambda + 'Q' -> jackSymbolicCoeffPinv lambda %//% jackSymbolicCoeffQinv lambda + _ -> error "_symbolicKostkaNumbersWithGivenLambda: should not happen." mu_r_plus :: - Seq Int -> (Int, Int) -> Int -> (MCP.Partition, (Int, Int), Int) + Seq Int -> (Int, Int) -> Int -> (Partition, (Int, Int), Int) mu_r_plus mu pair@(i, j) r = ( - MCP.Partition $ - DF.toList $ S.dropWhileR (== 0) $ S.reverse $ S.sort $ + DF.toList $ S.reverse $ S.sort $ S.adjust' ((P.+) r) i (S.adjust' (subtract r) j mu) , pair , r ) - lambdas = reverse $ - filter (\part -> partitionWidth part <= nv) (partitions weight) - lambdas' = map fromPartition lambdas - rec :: Int -> Map MCP.Partition (Map Partition a) - rec n = if n == 1 - then DM.singleton (MCP.Partition [weight]) - (DM.singleton [weight] AlgRing.one) - else DM.insert mu (DM.singleton mu' AlgRing.one) - ( - DM.fromDistinctDescList - [( - kappa - , DM.insert mu' (newColumn DM.! kappa) (previous DM.! kappa) - ) | kappa <- kappas] - ) - where - previous = rec (n - 1) - parts = take n lambdas - (kappas, mu) = fromJust (unsnoc parts) - _e_mu_alpha = _e mu alpha - mu' = fromPartition mu - mu'' = S.fromList mu' - l = S.length mu'' - pairs = [(i, j) | i <- [0 .. l-2], j <- [i+1 .. l-1]] - triplets = [mu_r_plus mu'' (i, j) r - | (i, j) <- pairs, r <- [1 .. S.index mu'' j]] - newColumn = - DM.fromDistinctDescList [(kappa, f kappa) | kappa <- kappas] - f kappa = AlgAdd.sum xs - where - previousRow = previous DM.! kappa - triplets' = filter ((dominates kappa) . fst3) triplets - ee = _e kappa alpha - _e_mu_alpha - xs = [ - fromIntegral (S.index mu'' i P.- S.index mu'' j P.+ 2 P.* r) - * (previousRow DM.! (fromPartition nu)) / ee - | (nu, (i, j), r) <- triplets' - ] - -_symbolicKostkaNumbers :: - forall a. (Eq a, AlgField.C a) - => Int -> Int -> Char -> Map Partition (Map Partition (RatioOfSprays a)) -_symbolicKostkaNumbers nv weight which = kostkaMatrix' - where - coeffsP = DM.fromDistinctDescList - [(kappa, asRatioOfSprays (jackSymbolicCoeffPinv kappa)) - | kappa <- lambdas'] - coeffsC = DM.fromDistinctDescList - [( - kappa - , (jackSymbolicCoeffPinv kappa :: Spray a) *> jackSymbolicCoeffC kappa - ) | kappa <- lambdas'] - coeffsQ = DM.fromDistinctDescList - [( - kappa - , jackSymbolicCoeffPinv kappa %//% jackSymbolicCoeffQinv kappa - ) | kappa <- lambdas'] - kostkaMatrix = DM.mapKeys fromPartition (rec (length lambdas)) - kostkaMatrix' = case which of - 'J' -> DM.mapWithKey (\kappa m -> DM.map ((*) (coeffsP DM.! kappa)) m) - kostkaMatrix - 'P' -> kostkaMatrix - 'C' -> DM.mapWithKey (\kappa m -> DM.map ((*) (coeffsC DM.! kappa)) m) - kostkaMatrix - 'Q' -> DM.mapWithKey (\kappa m -> DM.map ((*) (coeffsQ DM.! kappa)) m) - kostkaMatrix - _ -> error "_symbolicKostkaNumbers: should not happen." - mu_r_plus :: - Seq Int -> (Int, Int) -> Int -> (MCP.Partition, (Int, Int), Int) - mu_r_plus mu pair@(i, j) r = + mu_r_plus' :: + Seq Int -> (Int, Int) -> Int -> (Partition, (Int, Int), Int) + mu_r_plus' mu pair@(i, j) r = ( - MCP.Partition $ - DF.toList $ S.dropWhileR (== 0) $ S.reverse $ S.sort $ - S.adjust' ((P.+) r) i (S.adjust' (subtract r) j mu) + DF.toList $ S.reverse $ S.sort $ + S.deleteAt j (S.adjust' ((P.+) r) i mu) , pair , r ) - lambdas = reverse $ - filter (\part -> partitionWidth part <= nv) (partitions weight) - lambdas' = map fromPartition lambdas - rec :: Int -> Map MCP.Partition (Map Partition (RatioOfSprays a)) + lambda' = toPartitionUnsafe lambda + mus' = reverse $ + filter (\part -> partitionWidth part <= nv) (dominatedPartitions lambda') + _e_lambda = _eSymbolic lambda' + rec :: Int -> Map Partition (RatioOfSprays a) rec n = if n == 1 - then DM.singleton (MCP.Partition [weight]) - (DM.singleton [weight] unitRatioOfSprays) - else DM.insert mu (DM.singleton mu' unitRatioOfSprays) - ( - DM.fromDistinctDescList - [ - ( - kappa - , DM.insert mu' (newColumn DM.! kappa) (previous DM.! kappa) - ) - | kappa <- kappas - ] - ) + then DM.singleton lambda kN1 + else DM.insert mu kNumber previous where previous = rec (n - 1) - parts = take n lambdas - (kappas, mu) = fromJust (unsnoc parts) - _eSymbolic_mu = _eSymbolic mu - mu' = fromPartition mu - mu'' = S.fromList mu' + parts = DM.keys previous + mu' = mus' !! (n - 1) + mu = fromPartition mu' + _e_mu = _eSymbolic mu' + ee = _e_lambda - _e_mu + mu'' = S.fromList mu l = S.length mu'' pairs = [(i, j) | i <- [0 .. l-2], j <- [i+1 .. l-1]] - triplets = [mu_r_plus mu'' (i, j) r - | (i, j) <- pairs, r <- [1 .. S.index mu'' j]] - newColumn = - DM.fromDistinctDescList [(kappa, f kappa) | kappa <- kappas] - f kappa = AlgAdd.sum xs - where - previousRow = previous DM.! kappa - triplets' = filter ((dominates kappa) . fst3) triplets - ee = _eSymbolic kappa - _eSymbolic_mu - xs = [ - ( - (S.index mu'' i P.- S.index mu'' j P.+ 2 P.* r) - .^ (previousRow DM.! (fromPartition nu)) - ) %/% ee - | (nu, (i, j), r) <- triplets' - ] + triplets = + filter ((\nu -> nu `elem` parts) . fst3) + ( + [mu_r_plus mu'' (i, j) r + | (i, j) <- pairs, r <- [1 .. S.index mu'' j - 1]] + ++ + [mu_r_plus' mu'' (i, j) (S.index mu'' j) + | (i, j) <- pairs] + ) + kNumber = + AlgAdd.sum [ + (S.index mu'' i P.- S.index mu'' j P.+ 2 P.* r) + .^ (previous DM.! nu) + | (nu, (i, j), r) <- triplets + ] %/% ee + +_symbolicKostkaNumbers :: + forall a. (Eq a, AlgField.C a) + => Int -> Int -> Char -> Map Partition (Map Partition (RatioOfSprays a)) +_symbolicKostkaNumbers nv weight which = + DM.fromDistinctAscList + [ + (lambda, _symbolicKostkaNumbersWithGivenLambda nv lambda which) + | lambda' <- partitions' (weight, nv) weight + , let lambda = fromPartition lambda' + ] _inverseSymbolicKostkaMatrix :: (Eq a, AlgField.C a)
src/Math/Algebra/JackPol.hs view
@@ -33,7 +33,7 @@ where import Prelude hiding ((*), (+), (-), (/), (^), (*>), product, sum, fromIntegral, fromInteger) -import Algebra.Additive ( (+), (-), sum ) +import Algebra.Additive ( (+), (-), sum, zero ) import qualified Algebra.Field as AlgField import Algebra.Ring ( (*), product, one, fromInteger ) import qualified Algebra.Ring as AlgRing @@ -47,7 +47,9 @@ , jackCoeffP, jackCoeffQ , skewSchurLRCoefficients , isSkewPartition, _fromInt - , skewJackInMSPbasis ) + , skewJackInMSPbasis + , jackJpol0 + ) import Math.Algebra.Hspray ( FunctionLike (..), (.^) , lone, lone', Spray, QSpray , zeroSpray, unitSpray @@ -85,8 +87,11 @@ 'P' -> jackCoeffP lambda alpha *^ resultJ _ -> jackCoeffQ lambda alpha *^ resultJ where + resultJ = + if alpha == zero + then jackJpol0 n lambda + else jck n lambda arr0 jck m kappa arr = jac m 0 kappa kappa arr - resultJ = jck n lambda arr0 nll = _N lambda lambda arr0 = listArray ((1, 1), (nll, n)) (replicate (nll * n) Nothing) jac :: Int -> Int -> Partition -> Partition
src/Math/Algebra/SymmetricPolynomials.hs view
@@ -36,6 +36,7 @@ , schurCombination , schurCombination' , jackCombination + , jackCombination' , jackSymbolicCombination , jackSymbolicCombination' -- * Printing symmetric polynomials @@ -72,6 +73,8 @@ , transitionsSchurToHallLittlewood , skewHallLittlewoodPolynomial , skewHallLittlewoodPolynomial' + -- * Hall polynomials + , hallPolynomials -- * t-Schur polynomials , tSchurPolynomial , tSchurPolynomial' @@ -156,6 +159,7 @@ , lone , qlone , lone' + , qlone' , fromList , getCoefficient , getConstantTerm @@ -164,6 +168,8 @@ , (%/%) , RatioOfSprays (..) , RatioOfQSprays + , asRatioOfSprays + , evalRatioOfSprays' , constantRatioOfSprays , zeroRatioOfSprays , prettyRatioOfQSpraysXYZ @@ -183,6 +189,8 @@ import Math.Algebra.Jack.Internal ( Partition , _isPartition + , msPolynomialUnsafe + , _esPolynomial , sprayToMap , comboToSpray , _inverseKostkaMatrix @@ -209,6 +217,7 @@ , macdonaldJinMSPbasis , inverseKostkaNumbers , skewSchurLRCoefficients + , _msPolynomialInHLPbasis ) import Math.Algebra.JackPol ( schurPol @@ -232,18 +241,6 @@ , semiStandardSkewTableaux ) --- | monomial symmetric polynomial -msPolynomialUnsafe :: (AlgRing.C a, Eq a) - => Int -- ^ number of variables - -> Partition -- ^ integer partition - -> Spray a -msPolynomialUnsafe n lambda - = fromList $ zip permutations coefficients - where - llambda = length lambda - permutations = permuteMultiset (lambda ++ replicate (n-llambda) 0) - coefficients = repeat AlgRing.one - -- | Monomial symmetric polynomial -- -- >>> putStrLn $ prettySpray' (msPolynomial 3 [2, 1]) @@ -740,12 +737,11 @@ error "esPolynomial: negative number of variables." | not (_isPartition lambda) = error "esPolynomial: invalid partition." - | null lambda = unitSpray - | l > n || any (>n) lambda = zeroSpray - | otherwise = productOfSprays (map esPolynomialK lambda) + | null lambda = unitSpray + | l > n || any (> n) lambda = zeroSpray + | otherwise = _esPolynomial n lambda where l = length lambda - esPolynomialK k = msPolynomialUnsafe n (replicate k 1) -- | power sum polynomial as a linear combination of -- elementary symmetric polynomials @@ -874,6 +870,29 @@ IM.fromList (zip weights (map (msPolynomialsInJackBasis alpha which n) weights)) +-- | Symmetric parametric polynomial as a linear combination of Jack +-- polynomials with a given Jack parameter. Symmetry is not checked. +-- Similar to @jackCombination@ but for a parametric spray. +jackCombination' :: + (FunctionLike b, Eq b, AlgRing.C b, Eq (BaseRing b), AlgField.C (BaseRing b)) + => BaseRing b -- ^ Jack parameter + -> Char -- ^ which Jack polynomials, @'J'@, @'C'@, @'P'@ or @'Q'@ + -> Spray b -- ^ parametric spray representing a symmetric polynomial + -> Map Partition b +jackCombination' alpha which spray = + if not (which `elem` ['J', 'C', 'P', 'Q']) + then error "jackCombination': invalid character, must be 'J', 'C', 'P' or 'Q'." + else + _symmPolyCombination + (\lambda -> (combos IM.! (sum lambda)) DM.! lambda) + (flip (*^)) spray + where + weights = filter (/= 0) (map DF.sum (allExponents spray)) + n = numberOfVariables spray + combos = + IM.fromList + (zip weights (map (msPolynomialsInJackBasis alpha which n) weights)) + -- | Symmetric polynomial as a linear combination of Jack polynomials with -- symbolic parameter. Symmetry is not checked. jackSymbolicCombination :: @@ -897,7 +916,7 @@ -- with symbolic parameter. -- Similar to @jackSymbolicCombination@ but for a parametric spray. jackSymbolicCombination' :: - (Eq a, AlgField.C a) + (Eq a, AlgField.C a) => Char -- ^ which Jack polynomials, @'J'@, @'C'@, @'P'@ or @'Q'@ -> ParametricSpray a -- ^ parametric spray representing a symmetric polynomial -> Map Partition (RatioOfSprays a) -- ^ map representing the linear combination; a partition @lambda@ in the keys of this map corresponds to the term @coeff *^ jackSymbolicPol' n lambda which@, where @coeff@ is the value attached to this key and @n@ is the number of variables of the spray @@ -914,6 +933,49 @@ IM.fromList (zip weights (map (msPolynomialsInJackSymbolicBasis which n) weights)) +-- | symmetric simple parametric spray as a linear combination of +-- Hall-Littlewood P-polynomials +hlpCombination :: + SimpleParametricQSpray -> Map Partition QSpray +hlpCombination spray = + _symmPolyCombination + (\lambda -> _msPolynomialInHLPbasis n lambda) + (AlgRing.*) spray + where + n = numberOfVariables spray + +-- | Hall polynomials \(g^{\lambda}_{\mu,\nu}(t)\) for given integer partitions +-- \(\mu\) and \(\nu\). The keys of the map returned by this function are the +-- partitions \(\lambda\) and the value attached to a key \(\lambda\) is the +-- Hall polynomial \(g^{\lambda}_{\mu,\nu}(t)\) (it is given as a @QSpray@ +-- spray but actually all its coefficients are integer). __Warning:__ slow. +hallPolynomials :: + Partition -- ^ the integer partition \(\mu\) + -> Partition -- ^ the integer partition \(\nu\) + -> Map Partition QSpray +hallPolynomials mu nu + | not (_isPartition mu) = + error "hallPolynomials: invalid integer partition `mu`." + | not (_isPartition nu) = + error "hallPolynomials: invalid integer partition `nu`." + | otherwise = + DM.mapWithKey f + (hlpCombination + (hallLittlewoodPolynomial' n mu 'P' + ^*^ hallLittlewoodPolynomial' n nu 'P')) + where + n = sum mu + sum nu + _n :: Partition -> Int + _n lambda = sum (zipWith (*) [1 .. ] (drop1 lambda)) + _n_mu_nu = _n mu + _n nu + t = qlone' 1 + invt = RatioOfSprays unitSpray (qlone 1) + f :: Partition -> QSpray -> QSpray + f lambda spray = + _numerator $ + (t (_n lambda - _n_mu_nu)) + AlgMod.*> (evalRatioOfSprays' (asRatioOfSprays spray) [invt]) + -- | Kostka-Foulkes polynomial of two given partitions. This is a univariate -- polynomial whose value at @1@ is the Kostka number of the two partitions. kostkaFoulkesPolynomial :: @@ -959,7 +1021,7 @@ skewKostkaFoulkesPolynomial' = skewKostkaFoulkesPolynomial -- | qt-Kostka polynomials, aka Kostka-Macdonald polynomials. These are bivariate --- symmetric polynomials usually denoted by \(K_{\lambda, \mu}(q,t)\) for two +-- polynomials usually denoted by \(K_{\lambda, \mu}(q,t)\) for two -- integer partitions \(\lambda\) and \(mu\), and \(q\) and \(t\) denote the -- variables. One obtains the Kostka-Foulkes polynomials by substituting \(q\) -- with \(0\). For a given partition \(\mu\), the function returns the polynomials @@ -1001,7 +1063,7 @@ DM.empty psCombo -- | qt-Kostka polynomials, aka Kostka-Macdonald polynomials. These are bivariate --- symmetric polynomials usually denoted by \(K_{\lambda, \mu}(q,t)\) for two +-- polynomials usually denoted by \(K_{\lambda, \mu}(q,t)\) for two -- integer partitions \(\lambda\) and \(mu\), and \(q\) and \(t\) denote the -- variables. One obtains the Kostka-Foulkes polynomials by substituting \(q\) -- with \(0\). For a given partition \(\mu\), the function returns the polynomials @@ -1013,7 +1075,7 @@ qtKostkaPolynomials' = qtKostkaPolynomials -- | Skew qt-Kostka polynomials. These are bivariate --- symmetric polynomials usually denoted by \(K_{\lambda/\mu, \nu}(q,t)\) for two +-- polynomials usually denoted by \(K_{\lambda/\mu, \nu}(q,t)\) for two -- integer partitions \(\lambda\) and \(mu\) defining a skew partition, an -- integer partition \(\nu\), and \(q\) and \(t\) denote the -- variables. One obtains the skew Kostka-Foulkes polynomials by substituting \(q\) @@ -1046,7 +1108,7 @@ ) -- | Skew qt-Kostka polynomials. These are bivariate --- symmetric polynomials usually denoted by \(K_{\lambda/\mu, \nu}(q,t)\) for two +-- polynomials usually denoted by \(K_{\lambda/\mu, \nu}(q,t)\) for two -- integer partitions \(\lambda\) and \(mu\) defining a skew partition, an -- integer partition \(\nu\), and \(q\) and \(t\) denote the -- variables. One obtains the skew Kostka-Foulkes polynomials by substituting \(q\) @@ -1180,7 +1242,10 @@ -- | t-Schur polynomial. This is a multivariate symmetric polynomial whose -- coefficients are polynomial in a single parameter usually denoted by \(t\). --- One obtains the Schur polynomials by substituting \(t\) with \(0\). +-- One obtains the Schur polynomials by substituting \(t\) with \(0\). +-- The name \"\(t\)-Schur polynomial\" is taken from +-- [Wheeler and Zinn-Justin's paper](https://www.sciencedirect.com/science/article/pii/S0097316518300724) +-- /Hall polynomials, inverse Kostka polynomials and puzzles/. tSchurPolynomial :: (Eq a, AlgField.C a) => Int -- ^ number of variables @@ -1199,6 +1264,9 @@ -- | t-Schur polynomial. This is a multivariate symmetric polynomial whose -- coefficients are polynomial in a single parameter usually denoted by \(t\). -- One obtains the Schur polynomials by substituting \(t\) with \(0\). +-- The name \"\(t\)-Schur polynomial\" is taken from +-- [Wheeler and Zinn-Justin's paper](https://www.sciencedirect.com/science/article/pii/S0097316518300724) +-- /Hall polynomials, inverse Kostka polynomials and puzzles/. tSchurPolynomial' :: Int -- ^ number of variables -> Partition -- ^ integer partition
+ src/Math/Combinatorics/Kostka.hs view
@@ -0,0 +1,166 @@+{-| +Module : Math.Combinatorics.Kostka +Description : +Copyright : (c) Stéphane Laurent, 2024 +License : GPL-3 +Maintainer : laurent_step@outlook.fr + +This module provides some functions to compute Kostka-Jack numbers, i.e. +Kostka numbers with a Jack parameter, possibly skew. +-} + +module Math.Combinatorics.Kostka + ( + -- * Kostka numbers + kostkaNumbersWithGivenLambda + , kostkaNumbers + , symbolicKostkaNumbersWithGivenLambda + , symbolicKostkaNumbers + , skewKostkaNumbers + , symbolicSkewKostkaNumbers + ) where +import Data.Map.Strict ( + Map + ) +import qualified Data.Map.Strict as DM +import Math.Algebra.Hspray ( + RatioOfQSprays + , unitRatioOfSprays + ) +import Math.Algebra.Jack.Internal ( + Partition + , _isPartition + , _kostkaNumbers + , _symbolicKostkaNumbers + , _kostkaNumbersWithGivenLambda + , _symbolicKostkaNumbersWithGivenLambda + , isSkewPartition + , skewJackInMSPbasis + , skewSymbolicJackInMSPbasis + ) + +-- | Kostka numbers \(K_{\lambda,\mu}(\alpha)\) with Jack parameter, or +-- Kostka-Jack numbers, for a given integer partition \(\lambda\) and a +-- given Jack parameter \(\alpha\). These are the ordinary Kostka numbers when +-- \(\alpha=1\). The function returns a map whose keys represent the +-- partitions \(\mu\) and the value attached to a partition \(\mu\) is the +-- Kostka-Jack number \(K_{\lambda,\mu}(\alpha)\). The +-- partition \(\mu\) is included in the keys of this map if and only if +-- \(K_{\lambda,\mu}(\alpha) \neq 0\). The Kostka-Jack number +-- \(K_{\lambda,\mu}(\alpha)\) is the coefficient of the monomial symmetric +-- polynomial \(m_\mu\) in the expression of the \(P\)-Jack polynomial +-- \(P_\lambda(\alpha)\) as a linear combination of monomial symmetric +-- polynomials. +kostkaNumbersWithGivenLambda :: + Partition -- ^ the integer partition @lambda@ + -> Rational -- ^ Jack parameter + -> Map Partition Rational +kostkaNumbersWithGivenLambda lambda alpha + | not (_isPartition lambda) = + error "kostkaNumbersWithGivenLambda: invalid integer partition." + | null lambda = + DM.singleton [] 1 + | otherwise = + _kostkaNumbersWithGivenLambda (sum lambda) lambda alpha 'P' + +-- | Kostka numbers \(K_{\lambda,\mu}(\alpha)\) with Jack parameter, or +-- Kostka-Jack numbers, for a given weight of the +-- partitions \(\lambda\) and \(\mu\) and a given Jack parameter +-- \(\alpha\). These are the ordinary Kostka numbers when +-- \(\alpha=1\). The function returns a map whose keys represent the +-- partitions \(\lambda\) and the value attached to a partition \(\lambda\) +-- represents the map \(\mu \mapsto K_{\lambda,\mu}(\alpha)\) where the +-- partition \(\mu\) is included in the keys of this map if and only if +-- \(K_{\lambda,\mu}(\alpha) \neq 0\). The Kostka-Jack number +-- \(K_{\lambda,\mu}(\alpha)\) is the coefficient of the monomial symmetric +-- polynomial \(m_\mu\) in the expression of the \(P\)-Jack polynomial +-- \(P_\lambda(\alpha)\) as a linear combination of monomial symmetric +-- polynomials. +kostkaNumbers :: + Int -- ^ weight of the partitions + -> Rational -- ^ Jack parameter + -> Map Partition (Map Partition Rational) +kostkaNumbers weight alpha + | weight < 0 = + error "kostkaNumbers: negative weight." + | weight == 0 = + DM.singleton [] (DM.singleton [] 1) + | otherwise = + _kostkaNumbers weight weight alpha 'P' + +-- | Kostka-Jack numbers \(K_{\lambda,\mu}(\alpha)\) with symbolic Jack +-- parameter \(\alpha\) for a given weight of the partitions \(\lambda\) +-- and \(\mu\). This function returns a map whose keys represent the +-- partitions \(\lambda\) and the value attached to a partition \(\lambda\) +-- represents the map \(\mu \mapsto K_{\lambda,\mu}(\alpha)\) where the +-- partition \(\mu\) is included in the keys of this map if and only if +-- \(K_{\lambda,\mu}(\alpha) \neq 0\). +symbolicKostkaNumbers :: + Int -- ^ weight of the partitions + -> Map Partition (Map Partition RatioOfQSprays) +symbolicKostkaNumbers weight + | weight < 0 = + error "symbolicKostkaNumbers: negative weight." + | weight == 0 = + DM.singleton [] (DM.singleton [] unitRatioOfSprays) + | otherwise = + _symbolicKostkaNumbers weight weight 'P' + +-- | Kostka-Jack numbers \(K_{\lambda,\mu}(\alpha)\) with symbolic Jack +-- parameter \(\alpha\) for a given integer partition \(\lambda\). This +-- function returns a map whose keys represent the +-- partitions \(\mu\) and the value attached to a partition \(\mu\) is the +-- Kostka-Jack number \(K_{\lambda,\mu}(\alpha)\). The +-- partition \(\mu\) is included in the keys of this map if and only if +-- \(K_{\lambda,\mu}(\alpha) \neq 0\). +symbolicKostkaNumbersWithGivenLambda :: + Partition -- ^ the integer partition @lambda@ + -> Map Partition RatioOfQSprays +symbolicKostkaNumbersWithGivenLambda lambda + | not (_isPartition lambda) = + error "symbolicKostkaNumbersWithGivenLambda: invalid integer partition." + | null lambda = + DM.singleton [] unitRatioOfSprays + | otherwise = + _symbolicKostkaNumbersWithGivenLambda (sum lambda) lambda 'P' + +-- | Skew Kostka numbers \(K_{\lambda/\mu, \nu}(\alpha)\) with a given Jack +-- parameter \(\alpha\) and a given skew partition \(\lambda/\mu\). For \(\alpha=1\) +-- these are the ordinary skew Kostka numbers. +-- The function returns a map whose keys represent the partitions \(\nu\). +-- The skew Kostka-Jack number \(K_{\lambda/\mu, \nu}(\alpha)\) +-- is the coefficient of the monomial symmetric +-- polynomial \(m_\nu\) in the expression of the skew \(P\)-Jack polynomial +-- \(P_{\lambda/\mu}(\alpha)\) as a linear combination of monomial symmetric +-- polynomials. +-- /Note:/ the skew Kostka-Jack numbers \(K_{\lambda/\mu, \nu}(\alpha)\) are +-- well defined when the Jack parameter \(\alpha\) is zero, however this +-- function does not work for \(\alpha=0\); a possible way to get the +-- skew Kostka-Jack numbers \(K_{\lambda/\mu, \nu}(0)\) is to use the +-- function @symbolicSkewKostkaNumbers@ to get the skew Kostka-Jack numbers +-- with a symbolic Jack parameter \(\alpha\), and then to substitute \(\alpha\) +-- with \(0\). +skewKostkaNumbers :: + Rational -- ^ Jack parameter + -> Partition -- ^ outer partition of the skew partition + -> Partition -- ^ inner partition of the skew partition + -> Map Partition Rational +skewKostkaNumbers alpha lambda mu + | not (isSkewPartition lambda mu) = + error "skewKostkaNumbers: invalid skew partition." + | otherwise = + DM.map snd (skewJackInMSPbasis alpha 'P' lambda mu) + +-- | Skew Kostka numbers \(K_{\lambda/\mu, \nu}(\alpha)\) with symbolic Jack +-- parameter \(\alpha\) for a given skew partition \(\lambda/\mu\). +-- This function returns a map whose keys represent the partitions \(\nu\). +symbolicSkewKostkaNumbers :: + Partition -- ^ outer partition of the skew partition + -> Partition -- ^ inner partition of the skew partition + -> Map Partition RatioOfQSprays +symbolicSkewKostkaNumbers lambda mu + | not (isSkewPartition lambda mu) = + error "symbolicSkewKostkaNumbers: invalid skew partition." + | otherwise = + DM.map snd (skewSymbolicJackInMSPbasis 'P' lambda mu) +
+ src/Math/Combinatorics/Tableaux.hs view
@@ -0,0 +1,78 @@+{-| +Module : Math.Combinatorics.Tableaux +Description : +Copyright : (c) Stéphane Laurent, 2024 +License : GPL-3 +Maintainer : laurent_step@outlook.fr + +This module provides some functions to enumerate semistandard tableaux, +possibly skew, with a given shape and a given weight, and a function to +enumerate the Gelfand-Tsetlin patterns defined by a skew partition. +-} + +module Math.Combinatorics.Tableaux + ( + -- * Tableaux + semiStandardTableauxWithGivenShapeAndWeight + , skewTableauxWithGivenShapeAndWeight + -- * Gelfand-Tsetlin patterns + , skewGelfandTsetlinPatterns + ) where +import qualified Data.Foldable as DF +import Data.Tuple.Extra ( + second + ) +import Math.Algebra.Jack.Internal ( + Partition + , _isPartition + , isSkewPartition + , _skewGelfandTsetlinPatterns + , _skewTableauxWithGivenShapeAndWeight + , _semiStandardTableauxWithGivenShapeAndWeight + ) +import Math.Combinat.Tableaux.Skew ( + SkewTableau (..) + ) + +-- | Skew Gelfand-Tsetlin patterns defined by a skew partition and a weight vector. +skewGelfandTsetlinPatterns :: + Partition -- ^ outer partition of the skew partition + -> Partition -- ^ inner partition of the skew partition + -> [Int] -- ^ weight + -> [[Partition]] +skewGelfandTsetlinPatterns lambda mu weight + | not (isSkewPartition lambda mu) = + error "skewGelfandTsetlinPatterns: invalid skew partition." + | otherwise = + map (map DF.toList) (_skewGelfandTsetlinPatterns lambda mu weight) + +-- | Skew semistandard tableaux with a given shape (a skew partition) and +-- a given weight vector. The weight is the vector whose @i@-th element is the +-- number of occurrences of @i@ in the tableau. +skewTableauxWithGivenShapeAndWeight :: + Partition -- ^ outer partition of the skew partition + -> Partition -- ^ inner partition of the skew partition + -> [Int] -- ^ weight + -> [SkewTableau Int] +skewTableauxWithGivenShapeAndWeight lambda mu weight + | not (isSkewPartition lambda mu) = + error "skewTableauxWithGivenShapeAndWeight: invalid skew partition." + | otherwise = + map (SkewTableau . (map (second DF.toList))) + (_skewTableauxWithGivenShapeAndWeight lambda mu weight) + +-- | Semistandard tableaux with a given shape (an integer partition) and +-- a given weight vector. The weight is the vector whose @i@-th element is the +-- number of occurrences of @i@ in the tableau. +semiStandardTableauxWithGivenShapeAndWeight :: + Partition -- ^ shape, integer partition + -> [Int] -- ^ weight + -> [[[Int]]] +semiStandardTableauxWithGivenShapeAndWeight lambda weight + | not (_isPartition lambda) = + error "semiStandardTableauxWithGivenShapeAndWeight: invalid partition." + | any (< 0) weight = + [] + | otherwise = + map (map DF.toList) + (_semiStandardTableauxWithGivenShapeAndWeight lambda weight)
tests/Main.hs view
@@ -11,12 +11,6 @@ fromLists ) import Data.Ratio ( (%) ) -import Math.Algebra.Combinatorics ( - kostkaNumbers - , symbolicKostkaNumbers - , skewKostkaNumbers - , skewGelfandTsetlinPatterns - ) import Math.Algebra.Hspray ( FunctionLike (..) , Spray, QSpray , SimpleParametricSpray @@ -28,6 +22,7 @@ , evalSpray , evalParametricSpray' , substituteParameters + , changeParameters , canCoerceToSimpleParametricSpray , isHomogeneousSpray , asRatioOfSprays @@ -38,6 +33,7 @@ , productOfSprays , detLaplace , getConstantTerm + , getCoefficient ) import qualified Math.Algebra.Hspray as Hspray import Math.Algebra.Jack ( schur, skewSchur @@ -85,6 +81,7 @@ , qtKostkaPolynomials' , modifiedMacdonaldPolynomial' , qtSkewKostkaPolynomials' + , hallPolynomials ) import Math.Combinat.Partitions.Integer ( toPartition @@ -96,6 +93,16 @@ import qualified Math.Combinat.Partitions.Integer as PI import Math.Combinat.Tableaux.GelfandTsetlin ( kostkaNumber ) import qualified Math.Combinat.Tableaux.GelfandTsetlin as GT +import Math.Combinat.Tableaux.LittlewoodRichardson ( lrMult ) +import Math.Combinatorics.Kostka ( + kostkaNumbers + , kostkaNumbersWithGivenLambda + , symbolicKostkaNumbers + , skewKostkaNumbers + ) +import Math.Combinatorics.Tableaux ( + skewGelfandTsetlinPatterns + ) import Math.HypergeoMatrix ( hypergeomat ) import Test.Tasty ( defaultMain , testGroup @@ -105,16 +112,21 @@ , testCase ) +-- b_lambda_mu :: [Int] -> [Int] -> Int +-- b_lambda_mu lambda mu = sum $ DM.elems wholeMap +-- where +-- parts = partitions (sum lambda) +-- zeros = DM.fromList (zip parts (repeat 0)) +-- map1 = DM.union (GT.kostkaNumbersWithGivenMu (mkPartition lambda)) zeros +-- map2 = DM.union (GT.kostkaNumbersWithGivenMu (mkPartition mu)) zeros +-- wholeMap = DM.unionWithKey (\part kn1 _ -> kn1 * (map2 DM.! (dualPartition part))) map1 map2 + b_lambda_mu :: [Int] -> [Int] -> Int -b_lambda_mu lambda mu = sum $ DM.elems wholeMap -- zipWith (*) k1 k2 +b_lambda_mu lambda mu = sum $ DM.elems wholeMap where - parts = partitions (sum lambda) - zeros = DM.fromList (zip parts (repeat 0)) - map1 = DM.union (GT.kostkaNumbersWithGivenMu (mkPartition lambda)) zeros - map2 = DM.union (GT.kostkaNumbersWithGivenMu (mkPartition mu)) zeros - wholeMap = DM.unionWithKey (\part kn1 _ -> kn1 * (map2 DM.! (dualPartition part))) map1 map2 - -- k1 = map ((flip kostkaNumber) (mkPartition lambda)) parts - -- k2 = map (((flip kostkaNumber) (mkPartition mu)) . dualPartition) parts + map1 = GT.kostkaNumbersWithGivenMu (mkPartition lambda) + map2 = DM.mapKeys dualPartition (GT.kostkaNumbersWithGivenMu (mkPartition mu)) + wholeMap = DM.intersectionWith (*) map1 map2 a_lambda_mu :: [Int] -> [Int] -> Int a_lambda_mu lambda mu = sum $ zipWith (*) k1 k2 @@ -123,6 +135,9 @@ k1 = map ((flip kostkaNumber) (mkPartition lambda)) parts k2 = map ((flip kostkaNumber) (mkPartition mu)) parts +conjugatePartition :: [Int] -> [Int] +conjugatePartition = fromPartition . dualPartition . toPartition + main :: IO () main = defaultMain $ testGroup @@ -130,8 +145,71 @@ [ - testCase "Skew Kostka numbers are numbers of skew Gelfand-Tsetlin patterns" $ do + testCase "A Hall polynomial (comparison with Sage)" $ do let + hallPolys = hallPolynomials [3, 1, 1] [2, 1] + hallPoly = hallPolys DM.! [4, 2, 1, 1] + t = qlone 1 + expected = 2 *^ t^**^3 ^+^ t^**^2 ^-^ t ^-^ unitSpray + assertEqual "" hallPoly expected + + , testCase "Leading coefficient of Hall polynomial is Littlewood-Richardson" $ do + let + mu = [3, 1] + nu = [2, 1] + _n :: Partition -> Int + _n lambda = sum (zipWith (*) [1 .. ] (drop 1 lambda)) + _n_mu_nu = _n mu + _n nu + _degree :: Partition -> Int + _degree lambda = _n lambda - _n_mu_nu + lrCoeffs = + DM.mapKeys fromPartition + (DM.map toRational (lrMult (toPartition mu) (toPartition nu))) + leadingCoeffs = + DM.mapWithKey + (\lambda poly -> getCoefficient [_degree lambda] poly) + (hallPolynomials mu nu) + assertEqual "" lrCoeffs leadingCoeffs + + , testCase "Jack polynomial for alpha=0" $ do + let + n = 4 + lambda = [3, 1] + which = 'P' + jackPoly = jackPol' n lambda 0 which + jackSymPoly = jackSymbolicPol' n lambda which + assertEqual "" + jackPoly + (substituteParameters jackSymPoly [0]) + + , testCase "Kostka-Jack numbers for alpha=0 and elementary symmetric polynomial" $ do + let + lambda = [3, 3] + lambda' = [2, 2, 2] -- dual partitition + kNumbers = kostkaNumbersWithGivenLambda lambda 0 + esPoly = esPolynomial 6 lambda' + combo = msCombination esPoly + mus = DM.keys kNumbers + b_lambda_mus = map (toRational . (b_lambda_mu lambda')) mus + assertEqual "" + (kNumbers, DM.elems kNumbers) + (combo, b_lambda_mus) + + , testCase "Skew Jack with alpha=0 is same as skew Macdonald with q=1" $ do + -- I don't know why. In particular, skew Macdonald with q=1 does not depend on t + let + n = 4 + lambda = [4, 2] + mu = [1, 1] + which = 'P' + skJackPoly = + changeParameters (skewJackSymbolicPol' n lambda mu which) [zeroSpray] + skMacPoly = + changeParameters (skewMacdonaldPolynomial' n lambda mu which) [unitSpray, qlone 2] + assertEqual "" skJackPoly skMacPoly + + , testCase "Skew Kostka numbers are numbers of skew Gelfand-Tsetlin patterns" $ do + let lambda = [5, 4, 3, 2, 1] mu = [2, 2, 2, 1] skNumbers = skewKostkaNumbers 1 lambda mu @@ -802,6 +880,14 @@ ] assertEqual "" p (sumOfSprays sprays) + + , testCase "Jack-P combination with alpha=0 is dual es combination" $ do + let + poly = 3*^esPolynomial 4 [2, 1, 1] ^-^ 7*^skewSchurPol' 4 [3, 2, 1, 1] [2, 1] + esCombo = DM.mapKeys conjugatePartition (esCombination poly) + jackCombo = jackCombination 0 'P' poly + assertEqual "" + esCombo jackCombo , testCase "jackSymbolicCombination" $ do let