jackpolynomials 1.2.0.0 → 1.2.1.0
raw patch · 9 files changed
+243/−37 lines, 9 filesdep ~hsprayPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: hspray
API changes (from Hackage documentation)
+ Math.Algebra.Jack.SymmetricPolynomials: isSymmetricSpray :: (C a, Eq a) => Spray a -> Bool
+ Math.Algebra.Jack.SymmetricPolynomials: msCombination :: C a => Spray a -> Map Partition a
+ Math.Algebra.Jack.SymmetricPolynomials: msPolynomial :: (C a, Eq a) => Int -> Partition -> Spray a
+ Math.Algebra.Jack.SymmetricPolynomials: prettySymmetricNumSpray :: (Num a, Ord a, Show a, C a) => Spray a -> String
+ Math.Algebra.Jack.SymmetricPolynomials: prettySymmetricQSpray :: QSpray -> String
+ Math.Algebra.Jack.SymmetricPolynomials: prettySymmetricQSpray' :: QSpray' -> String
+ Math.Algebra.Jack.SymmetricPolynomials: prettySymmetricSymbolicQSpray :: String -> SymbolicQSpray -> String
Files
- CHANGELOG.md +7/−1
- README.md +61/−15
- jackpolynomials.cabal +4/−3
- src/Math/Algebra/Jack.hs +2/−4
- src/Math/Algebra/Jack/HypergeoPQ.hs +2/−1
- src/Math/Algebra/Jack/Internal.hs +0/−3
- src/Math/Algebra/Jack/SymmetricPolynomials.hs +136/−0
- src/Math/Algebra/JackPol.hs +1/−3
- tests/Main.hs +30/−7
CHANGELOG.md view
@@ -34,4 +34,10 @@ * it is now possible to choose which Jack polynomial to get or evaluate, `J`, `C`, `P` or `Q` (the previous versions returned `J` only) -* it is now possible to get Jack polynomials with a symbolic Jack parameter+* it is now possible to get Jack polynomials with a symbolic Jack parameter + +1.2.1.0 +------- +* a new module provides some stuff to deal with symmetric polynomials, mainly +some functions to print them as a linear combination of the monomial symmetric +polynomials, and a function to check the symmetry
README.md view
@@ -14,43 +14,89 @@ ___ +Evaluation of the Jack polynomial with parameter `2` associated to the integer +partition `[3, 1]` at `x1 = 1` and `x2 = 1`: + ```haskell import Math.Algebra.Jack jack' [1, 1] [3, 1] 2 'J' -- 48 % 1 ``` +The non-evaluated Jack polynomial: + ```haskell import Math.Algebra.JackPol import Math.Algebra.Hspray jp = jackPol' 2 [3, 1] 2 'J' -putStrLn $ prettySpray' jp --- (18 % 1) x1^3x2 + (12 % 1) x1^2x2^2 + (18 % 1) x1x2^3 +putStrLn $ prettyQSpray jp +-- 18*x^3.y + 12*x^2.y^2 + 18*x.y^3 evalSpray jp [1, 1] -- 48 % 1 ``` -As of version `1.2.0.0`, it is possible to get Jack polynomials with a symbolic Jack parameter: +The first argument, here `2`, is the number of variables of the polynomial. + +### Symbolic (or parametric) Jack polynomial + +As of version `1.2.0.0`, it is possible to get Jack polynomials with a +symbolic Jack parameter: + ```haskell import Math.Algebra.JackSymbolicPol import Math.Algebra.Hspray jp = jackSymbolicPol' 2 [3, 1] 'J' putStrLn $ prettySymbolicQSpray "a" jp --- ((2) + (4)a + (2)a^2)*x1^3x2 + ((4) + (4)a)*x1^2x2^2 + ((2) + (4)a + (2)a^2)*x1x2^3 -putStrLn $ prettySpray' $ evalSymbolicSpray jp 2 --- (18 % 1) x1^3x2 + (12 % 1) x1^2x2^2 + (18 % 1) x1x2^3 +-- { 2*a^2 + 4*a + 2 }*x^3.y + { 4*a + 4 }*x^2.y^2 + { 2*a^2 + 4*a + 2 }*x.y^3 +putStrLn $ prettyQSpray' $ evalSymbolicSpray jp 2 +-- 18*x^3.y + 12*x^2.y^2 + 18*x.y^3 ``` -From the definition of Jack polynomials, as well as from their implementation in this package, -the coefficients of the Jack polynomials are fractions of polynomials in the Jack parameter. -However, in the above example, one can see that the coefficients of the Jack polynomial `jp` -are *polynomials* in the Jack parameter `a`. -This fact actually is always true for the $J$-Jack polynomials (not for $C$, $P$ and $Q$). -This is a consequence of the Knop & Sahi combinatorial formula. -But be aware that in spite of this fact, the coefficients of the polynomials returned by -Haskell are *fractions* of polynomials (the type of these polynomials is `SymbolicSpray`, -defined in the **hspray** package). +From the definition of Jack polynomials, as well as from their implementation +in this package, the coefficients of the Jack polynomials are fractions of +polynomials in the Jack parameter. However, in the above example, one can see +that the coefficients of the Jack polynomial `jp` are *polynomials* in the +Jack parameter `a`. This fact actually is always true for the $J$-Jack +polynomials (not for $C$, $P$ and $Q$). This is a consequence of the Knop & +Sahi combinatorial formula. But be aware that in spite of this fact, the +coefficients of the polynomials returned by Haskell are *fractions* of +polynomials. The type of these polynomials is `SymbolicSpray`, defined in +the **hspray** package (which will be possibly renamed to `ParametricSpray` +in the future). + + +### Showing symmetric polynomials + +As of version 1.2.1.0, there is a module providing some functions to print a +symmetric polynomial as a linear combination of the monomial symmetric +polynomials. This can considerably shorten the expression of a symmetric +polynomial as compared to its expression in the canonical basis, and the +motivation to add this module to the package is that any Jack polynomial is +a symmetric polynomial. Here is an example: + +```haskell +import Math.Algebra.JackPol +import Math.Algebra.Jack.SymmetricPolynomials +jp = jackPol' 3 [3, 1, 1] 2 'J' +putStrLn $ prettySymmetricQSpray jp +-- 42*M[3,1,1] + 28*M[2,2,1] +``` + +And another example, with a symbolic Jack polynomial: + +```haskell +import Math.Algebra.JackSymbolicPol +import Math.Algebra.Jack.SymmetricPolynomials +jp = jackSymbolicPol' 3 [3, 1, 1] 'J' +putStrLn $ prettySymmetricSymbolicQSpray "a" jp +-- { 4*a^2 + 10*a + 6 }*M[3,1,1] + { 8*a + 12 }*M[2,2,1] +``` + +Of course you can use these functions for other polynomials, but carefully: +they do not check the symmetry. This new module provides the function +`isSymmetricSpray` to check the symmetry of a polynomial, much more efficient +than the function with the same name in the **hspray** package. ## References
jackpolynomials.cabal view
@@ -1,5 +1,5 @@ name: jackpolynomials -version: 1.2.0.0 +version: 1.2.1.0 synopsis: Jack, zonal, Schur and skew Schur polynomials description: This library can evaluate Jack polynomials, zonal polynomials, Schur and skew Schur polynomials. It is also able to compute them in symbolic form. homepage: https://github.com/stla/jackpolynomials#readme @@ -17,6 +17,7 @@ library hs-source-dirs: src exposed-modules: Math.Algebra.Jack.HypergeoPQ + , Math.Algebra.Jack.SymmetricPolynomials , Math.Algebra.Jack , Math.Algebra.JackPol , Math.Algebra.JackSymbolicPol @@ -25,7 +26,7 @@ , ilist >= 0.4.0.1 && < 0.4.1 , array >= 0.5.4.0 && < 0.6 , lens >= 5.0.1 && < 5.3 - , hspray >= 0.2.5.0 && < 1 + , hspray >= 0.2.6.0 && < 1 , numeric-prelude >= 0.4.4 && < 0.5 , combinat >= 0.2.10 && < 0.3 , containers >= 0.6.4.1 && < 0.8 @@ -50,7 +51,7 @@ , tasty >= 1.4 && < 1.6 , tasty-hunit >= 0.10 && < 0.11 , jackpolynomials - , hspray >= 0.2.5.0 && < 1 + , hspray >= 0.2.6.0 && < 1 , hypergeomatrix >= 1.1.0.2 && < 2 Default-Language: Haskell2010 ghc-options: -Wall
src/Math/Algebra/Jack.hs view
@@ -95,7 +95,7 @@ go (ss + gamma * x!!(m-1)^ (fromIntegral $ sum mu)) (ii + 1) else let arr' = arr // [((_N lambda nu, m), Just ss)] in - let jck = jac (m-1) 0 nu' nu' arr' one in + let jck = jac (m-1) 0 nu' nu' arr' one in let jck' = jck * gamma * x!!(m-1) ^ (fromIntegral $ sum mu - sum nu') in go (ss + jck') (ii + 1) @@ -114,9 +114,7 @@ => [a] -- ^ values of the variables -> Partition -- ^ partition of integers -> a -zonal x lambda = jackCoeffC lambda alpha * jack x lambda alpha 'J' - where - alpha = fromInteger 2 +zonal x lambda = jack x lambda (fromInteger 2) 'C' -- | Evaluation of Schur polynomial schur'
src/Math/Algebra/Jack/HypergeoPQ.hs view
@@ -1,7 +1,8 @@ module Math.Algebra.Jack.HypergeoPQ ( hypergeoPQ ) where -import Prelude hiding ((*), (+), (-), (/), (^), (*>), product, sum, fromIntegral, fromInteger) +import Prelude + hiding ( (*), (+), (-), (/), (^), (*>), product, sum, fromIntegral, fromInteger ) import Algebra.Additive import Algebra.Field import Algebra.Ring
src/Math/Algebra/Jack/Internal.hs view
@@ -194,9 +194,6 @@ den2 = product v num3 = product $ map (\p -> p + x) w den3 = product w - -- prod1 = product $ map (\x -> x / (x + alpha - one)) u - -- prod2 = product $ map (\x -> (x + alpha) / x) v - -- prod3 = product $ map (\x -> (x + alpha) / x) w (.^) :: AlgAdd.C a => Int -> a -> a (.^) k x = if k >= 0
+ src/Math/Algebra/Jack/SymmetricPolynomials.hs view
@@ -0,0 +1,136 @@+{-| +Module : Math.Algebra.Jack.SymmetricPolynomials +Description : Some utilities for Jack polynomials. +Copyright : (c) Stéphane Laurent, 2024 +License : GPL-3 +Maintainer : laurent_step@outlook.fr + +A Jack polynomial can have a very long expression which can be considerably +reduced if the polynomial is written in the basis formed by the monomial +symmetric polynomials instead. This is the motivation of this module. +-} + +module Math.Algebra.Jack.SymmetricPolynomials + ( isSymmetricSpray + , msPolynomial + , msCombination + , prettySymmetricNumSpray + , prettySymmetricQSpray + , prettySymmetricQSpray' + , prettySymmetricSymbolicQSpray + ) where +import qualified Algebra.Ring as AlgRing +import qualified Data.Foldable as DF +import Data.List ( foldl1', nub ) +import Data.Map.Strict ( Map ) +import qualified Data.Map.Strict as DM +import Data.Sequence ( Seq ) +import Math.Algebra.Hspray ( + (^+^) + , (*^) + , Spray + , QSpray + , QSpray' + , SymbolicQSpray + , fromList + , getCoefficient + , numberOfVariables + , prettyRatioOfQPolynomials + , showNumSpray + , showQSpray + , showQSpray' + , showSpray + , toList + , zeroSpray + ) +import Math.Algebra.Jack.Internal ( Partition , _isPartition ) +import Math.Combinat.Permutations ( permuteMultiset ) +import Math.Combinat.Partitions.Integer ( fromPartition, mkPartition ) + +-- | Monomial symmetric polynomials +-- +-- >>> putStrLn $ prettySpray' (msPolynomial 3 [2, 1]) +-- (1) x1^2.x2 + (1) x1^2.x3 + (1) x1.x2^2 + (1) x1.x3^2 + (1) x2^2.x3 + (1) x2.x3^2 +msPolynomial :: (AlgRing.C a, Eq a) + => Int -- ^ number of variables + -> Partition -- ^ integer partition + -> Spray a +msPolynomial n lambda + | n < 0 = error "msPolynomial: negative number of variables." + | not (_isPartition lambda) = error "msPolynomial: invalid partition." + | llambda > n = zeroSpray + | otherwise = fromList $ zip permutations coefficients + where + llambda = length lambda + permutations = permuteMultiset (lambda ++ replicate (n-llambda) 0) + coefficients = repeat AlgRing.one + +-- | Checks whether a spray defines a symmetric polynomial; this is useless for +-- Jack polynomials because they always are symmetric, but this module contains +-- everything needed to build this function and it can be useful in another context +isSymmetricSpray :: (AlgRing.C a, Eq a) => Spray a -> Bool +isSymmetricSpray spray = spray == spray' + where + assocs = msCombination' spray + n = numberOfVariables spray + spray' = foldl1' (^+^) + ( + map (\(lambda, x) -> x *^ msPolynomial n lambda) assocs + ) + +-- | Symmetric polynomial as a linear combination of monomial symmetric polynomials +msCombination :: AlgRing.C a => Spray a -> Map Partition a +msCombination spray = DM.fromList (msCombination' spray) + +msCombination' :: AlgRing.C a => Spray a -> [(Partition, a)] +msCombination' spray = + map (\lambda -> (lambda, getCoefficient lambda spray)) lambdas + where + lambdas = nub $ map (fromPartition . mkPartition . fst) (toList spray) + +-- helper function for the showing stuff +makeMSpray :: (Eq a, AlgRing.C a) => Spray a -> Spray a +makeMSpray = fromList . msCombination' + +-- show symmetric monomial like M[3,2,1] +showSymmetricMonomials :: [Seq Int] -> [String] +showSymmetricMonomials = map showSymmetricMonomial + where + showSymmetricMonomial :: Seq Int -> String + showSymmetricMonomial lambda = 'M' : show (DF.toList lambda) + +-- | Prints a symmetric spray as a linear combination of monomial symmetric polynomials +-- +-- >>> putStrLn $ prettySymmetricNumSpray $ schurPol' 3 [3, 1, 1] +-- M[3, 1, 1] + M[2, 2, 1] +prettySymmetricNumSpray :: (Num a, Ord a, Show a, AlgRing.C a) => Spray a -> String +prettySymmetricNumSpray spray = + showNumSpray showSymmetricMonomials show mspray + where + mspray = makeMSpray spray + +-- | Prints a symmetric spray as a linear combination of monomial symmetric polynomials +-- +-- >>> putStrLn $ prettySymmetricQSpray $ jackPol' 3 [3, 1, 1] 2 'J' +-- 42*M[3,1,1] + 28*M[2,2,1] +prettySymmetricQSpray :: QSpray -> String +prettySymmetricQSpray spray = showQSpray showSymmetricMonomials mspray + where + mspray = makeMSpray spray + +-- | Same as `prettySymmetricQSpray` but for a `QSpray'` symmetric spray +prettySymmetricQSpray' :: QSpray' -> String +prettySymmetricQSpray' spray = showQSpray' showSymmetricMonomials mspray + where + mspray = makeMSpray spray + +-- | Prints a symmetric symbolic spray as a linear combination of monomial symmetric polynomials +-- +-- >>> putStrLn $ prettySymmetricSymbolicQSpray "a" $ jackSymbolicPol' 3 [3, 1, 1] 'J' +-- { 4*a^2 + 10*a + 6 }*M[3,1,1] + { 8*a + 12 }*M[2,2,1] +prettySymmetricSymbolicQSpray :: String -> SymbolicQSpray -> String +prettySymmetricSymbolicQSpray a spray = + showSpray (prettyRatioOfQPolynomials a) ("{ ", " }") + showSymmetricMonomials mspray + where + mspray = makeMSpray spray
src/Math/Algebra/JackPol.hs view
@@ -119,9 +119,7 @@ -> Partition -- ^ partition of integers -> Spray a zonalPol n lambda = - jackCoeffC lambda alpha *> jackPol n lambda alpha 'J' - where - alpha = fromInteger 2 + jackPol n lambda (fromInteger 2) 'C' -- | Symbolic Schur polynomial schurPol'
tests/Main.hs view
@@ -1,12 +1,15 @@ module Main where import Data.Ratio ( (%) ) import Math.Algebra.Hspray ( (^+^), (*^), (^*^), (^**^), Spray, lone - , evalSpray, isSymmetricSpray + , evalSpray , evalSymbolicSpray, evalSymbolicSpray' , Rational' ) +import qualified Math.Algebra.Hspray as Hspray import Math.Algebra.Jack ( schur, skewSchur , jack', zonal' ) import Math.Algebra.Jack.HypergeoPQ ( hypergeoPQ ) +import Math.Algebra.Jack.SymmetricPolynomials ( isSymmetricSpray + , prettySymmetricSymbolicQSpray ) import Math.Algebra.JackPol ( zonalPol, zonalPol', jackPol' , schurPol, schurPol', skewSchurPol' ) import Math.Algebra.JackSymbolicPol ( jackSymbolicPol' ) @@ -36,14 +39,34 @@ p = evalSymbolicSpray jp 2 assertEqual "" zp p + , testCase "jackSymbolicPol Q is symmetric" $ do + let jp = jackSymbolicPol' 4 [3, 1] 'Q' + assertBool "" (isSymmetricSpray jp) + + , testCase "jackSymbolicPol P is symmetric" $ do + let jp = jackSymbolicPol' 5 [3, 2, 1] 'P' + assertBool "" (isSymmetricSpray jp) + + , testCase "prettySymmetricSymbolicQSpray - jack J" $ do + let jp = jackSymbolicPol' 3 [3, 1, 1] 'J' + assertEqual "" + (prettySymmetricSymbolicQSpray "a" jp) + ("{ 4*a^2 + 10*a + 6 }*M[3,1,1] + { 8*a + 12 }*M[2,2,1]") + + , testCase "prettySymmetricSymbolicQSpray - jack C" $ do + let jp = jackSymbolicPol' 3 [3, 1, 1] 'C' + assertEqual "" + (prettySymmetricSymbolicQSpray "a" jp) + ("{ [ 20*a^2 ] %//% [ a^2 + (5/3)*a + (2/3) ] }*M[3,1,1] + { [ 40*a^2 ] %//% [ a^3 + (8/3)*a^2 + (7/3)*a + (2/3) ] }*M[2,2,1]") + , testCase "jackPol" $ do let jp = jackPol' 2 [3, 1] (2 % 1) 'J' v = evalSpray jp [1, 1] assertEqual "" v 48 - , testCase "jackPol is symmetric" $ do + , testCase "jackPol is symmetric (Gröbner)" $ do let jp = jackPol' 3 [3, 2, 1] (2 % 1) 'J' - assertBool "" (isSymmetricSpray jp) + assertBool "" (Hspray.isSymmetricSpray jp) , testCase "jack" $ do assertEqual "" (jack' [1, 1] [3, 1] (2 % 1) 'J') 48 @@ -57,9 +80,9 @@ v = evalSpray (sp1 ^+^ 3 *^ sp2 ^+^ 2 *^ sp3 ^+^ 3 *^ sp4 ^+^ sp5) [2, 2, 2, 2] assertEqual "" v 4096 - , testCase "schurPol is symmetric" $ do + , testCase "schurPol is symmetric (Gröbner)" $ do let sp = schurPol' 3 [3, 2, 1] - assertBool "" (isSymmetricSpray sp) + assertBool "" (Hspray.isSymmetricSpray sp) , testCase "schur" $ do let sp1 = schur [1, 1, 1, 1] [4] @@ -82,9 +105,9 @@ ^+^ x ^*^ z^**^2 ^+^ y^**^2 ^*^ z ^+^ y ^*^ z^**^2 assertEqual "" skp p - , testCase "skewSchurPol is symmetric" $ do + , testCase "skewSchurPol is symmetric (Gröbner)" $ do let skp = skewSchurPol' 3 [3, 2, 1] [1, 1] - assertBool "" (isSymmetricSpray skp) + assertBool "" (Hspray.isSymmetricSpray skp) , testCase "zonalPol" $ do let zp1 = zonalPol' 4 [3]