jackpolynomials 1.2.1.0 → 1.2.2.0
raw patch · 10 files changed
+160/−64 lines, 10 filesdep +miniteriondep ~hsprayPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: miniterion
Dependency ranges changed: hspray
API changes (from Hackage documentation)
- Math.Algebra.Jack.SymmetricPolynomials: prettySymmetricSymbolicQSpray :: String -> SymbolicQSpray -> String
+ Math.Algebra.Jack.SymmetricPolynomials: prettySymmetricOneParameterQSpray :: String -> OneParameterQSpray -> String
- Math.Algebra.Jack: jack :: forall a. C a => [a] -> Partition -> a -> Char -> a
+ Math.Algebra.Jack: jack :: forall a. (Eq a, C a) => [a] -> Partition -> a -> Char -> a
- Math.Algebra.Jack: skewSchur :: forall a. C a => [a] -> Partition -> Partition -> a
+ Math.Algebra.Jack: skewSchur :: forall a. (Eq a, C a) => [a] -> Partition -> Partition -> a
- Math.Algebra.Jack: zonal :: C a => [a] -> Partition -> a
+ Math.Algebra.Jack: zonal :: (Eq a, C a) => [a] -> Partition -> a
- Math.Algebra.Jack.HypergeoPQ: hypergeoPQ :: C a => Int -> [a] -> [a] -> [a] -> a
+ Math.Algebra.Jack.HypergeoPQ: hypergeoPQ :: (Eq a, C a) => Int -> [a] -> [a] -> [a] -> a
- Math.Algebra.JackSymbolicPol: jackSymbolicPol :: forall a. (Eq a, C a) => Int -> Partition -> Char -> SymbolicSpray a
+ Math.Algebra.JackSymbolicPol: jackSymbolicPol :: forall a. (Eq a, C a) => Int -> Partition -> Char -> OneParameterSpray a
- Math.Algebra.JackSymbolicPol: jackSymbolicPol' :: Int -> Partition -> Char -> SymbolicQSpray
+ Math.Algebra.JackSymbolicPol: jackSymbolicPol' :: Int -> Partition -> Char -> OneParameterQSpray
Files
- CHANGELOG.md +7/−3
- README.md +30/−16
- benchmarks/Main.hs +48/−0
- jackpolynomials.cabal +22/−4
- src/Math/Algebra/Jack.hs +3/−3
- src/Math/Algebra/Jack/HypergeoPQ.hs +1/−1
- src/Math/Algebra/Jack/Internal.hs +16/−9
- src/Math/Algebra/Jack/SymmetricPolynomials.hs +14/−11
- src/Math/Algebra/JackSymbolicPol.hs +11/−9
- tests/Main.hs +8/−8
CHANGELOG.md view
@@ -31,8 +31,8 @@ 1.2.0.0 ------- -* 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 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 @@ -40,4 +40,8 @@ ------- * 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+polynomials, and a function to check the symmetry + +1.2.2.0 +------- +* slight modifications due to the upgrade of **hspray**
README.md view
@@ -1,6 +1,6 @@ # jackpolynomials -*Jack, zonal, Schur and skew Schur polynomials.* +***Jack, zonal, Schur and skew Schur polynomials.*** <!-- badges: start --> [](https://github.com/stla/jackpolynomials/actions/workflows/Stack-lts.yml) @@ -10,12 +10,12 @@ 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 -allows to evaluate these polynomials. It can also compute their symbolic form. +allows to evaluate these polynomials and to compute them in symbolic form. ___ Evaluation of the Jack polynomial with parameter `2` associated to the integer -partition `[3, 1]` at `x1 = 1` and `x2 = 1`: +partition `[3, 1]`, at `x1 = 1` and `x2 = 1`: ```haskell import Math.Algebra.Jack @@ -47,25 +47,39 @@ import Math.Algebra.JackSymbolicPol import Math.Algebra.Hspray jp = jackSymbolicPol' 2 [3, 1] 'J' -putStrLn $ prettySymbolicQSpray "a" jp +putStrLn $ prettyOneParameterQSpray "a" jp -- { 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 +putStrLn $ prettyQSpray' $ evalOneParameterSpray jp 2 -- 18*x^3.y + 12*x^2.y^2 + 18*x.y^3 ``` +This is possible thanks to an upgrade of the **hspray** package which now +provides the type `OneParameterSpray` (and more). An object of this type +represents a multivariate polynomial whose coefficients depend on a parameter +which is symbolically treated. The type of the Jack polynomial returned by +the `jackSymbolicPol` function is `OneParameterSpray a`, and it is +`OneParameterQSpray` for the `jackSymbolicPol'` function. The type +`OneParameterQSpray` is an alias of `OneParameterSpray Rational'` where +`Rational'` is a type defined in the **numeric-prelude** package, +analogous to the well known `Rational` type. + 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). +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, in the sense that this is the nature of the `OneParameterQSpray` +objects. +Note that if you use the function `jackSymbolicPol` to get a +`OneParameterSpray Double` object in the output, it is not guaranted that you +will visually get some polynomials in the Jack parameter for the coefficients, +because the arithmetic operations are not exact with the `Double` type + ### Showing symmetric polynomials As of version 1.2.1.0, there is a module providing some functions to print a @@ -89,7 +103,7 @@ import Math.Algebra.JackSymbolicPol import Math.Algebra.Jack.SymmetricPolynomials jp = jackSymbolicPol' 3 [3, 1, 1] 'J' -putStrLn $ prettySymmetricSymbolicQSpray "a" jp +putStrLn $ prettySymmetricOneParameterQSpray "a" jp -- { 4*a^2 + 10*a + 6 }*M[3,1,1] + { 8*a + 12 }*M[2,2,1] ```
+ benchmarks/Main.hs view
@@ -0,0 +1,48 @@+module Main (main) where +import Math.Algebra.Hspray ( evalSymbolicSpray + , Rational' + , QSpray + , QSpray' + , SymbolicQSpray + ) +import Math.Algebra.JackPol ( jackPol' + ) +import Math.Algebra.JackSymbolicPol ( jackSymbolicPol' ) +import Miniterion ( bench + , bgroup + , defaultMain + , whnf ) + +nT :: Int +nT = 5 + +lambdaT :: [Int] +lambdaT = [4, 2, 2, 1] + +alphaT :: Rational +alphaT = 2 + +alphaT' :: Rational' +alphaT' = 2 + +jP :: (Int, [Int], Rational) -> QSpray +jP (n, lambda, alpha) = jackPol' n lambda alpha 'J' + +jSP :: (Int, [Int]) -> SymbolicQSpray +jSP (n, lambda) = jackSymbolicPol' n lambda 'J' + +jSPeval :: (Int, [Int], Rational') -> QSpray' +jSPeval (n, lambda, alpha') = evalSymbolicSpray (jackSymbolicPol' n lambda 'J') alpha' + +main :: IO () +main = + defaultMain + [ bgroup "Jack" + [ bench "jackPol with the given alpha" $ + whnf jP (nT, lambdaT, alphaT) + , bench "jackSymbolicPol" $ + whnf jSP (nT, lambdaT) + , bench "jackSymbolicPol evaluated at alpha" $ + whnf jSPeval (nT, lambdaT, alphaT') + ] + ]
jackpolynomials.cabal view
@@ -1,5 +1,5 @@ name: jackpolynomials -version: 1.2.1.0 +version: 1.2.2.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 @@ -7,7 +7,7 @@ license-file: LICENSE author: Stéphane Laurent maintainer: laurent_step@outlook.fr -copyright: 2022 Stéphane Laurent +copyright: 2022-2024 Stéphane Laurent category: Math, Algebra build-type: Simple extra-source-files: README.md @@ -26,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.6.0 && < 1 + , hspray >= 0.3.0.0 && < 0.4.0.0 , numeric-prelude >= 0.4.4 && < 0.5 , combinat >= 0.2.10 && < 0.3 , containers >= 0.6.4.1 && < 0.8 @@ -51,8 +51,26 @@ , tasty >= 1.4 && < 1.6 , tasty-hunit >= 0.10 && < 0.11 , jackpolynomials - , hspray >= 0.2.6.0 && < 1 + , hspray >= 0.3.0.0 && < 0.4.0.0 , hypergeomatrix >= 1.1.0.2 && < 2 + Default-Language: Haskell2010 + ghc-options: -Wall + -Wcompat + -Widentities + -Wincomplete-record-updates + -Wincomplete-uni-patterns + -Wmissing-home-modules + -Wpartial-fields + -Wredundant-constraints + +benchmark benchmarks + type: exitcode-stdio-1.0 + main-is: Main.hs + hs-source-dirs: benchmarks/ + Build-Depends: base >= 4.7 && < 5 + , miniterion >= 0.1.1.0 && < 0.2 + , jackpolynomials + , hspray >= 0.3.0.0 && < 0.4.0.0 Default-Language: Haskell2010 ghc-options: -Wall -Wcompat
src/Math/Algebra/Jack.hs view
@@ -41,7 +41,7 @@ jack' = jack -- | Evaluation of Jack polynomial -jack :: forall a. AlgField.C a +jack :: forall a. (Eq a, AlgField.C a) => [a] -- ^ values of the variables -> Partition -- ^ partition of integers -> a -- ^ Jack parameter @@ -110,7 +110,7 @@ zonal' = zonal -- | Evaluation of zonal polynomial -zonal :: AlgField.C a +zonal :: (Eq a, AlgField.C a) => [a] -- ^ values of the variables -> Partition -- ^ partition of integers -> a @@ -176,7 +176,7 @@ skewSchur' = skewSchur -- | Evaluation of a skew Schur polynomial -skewSchur :: forall a. AlgRing.C a +skewSchur :: forall a. (Eq a, AlgRing.C a) => [a] -- ^ values of the variables -> Partition -- ^ the outer partition of the skew partition -> Partition -- ^ the inner partition of the skew partition
src/Math/Algebra/Jack/HypergeoPQ.hs view
@@ -33,7 +33,7 @@ parts n = [n] : [ x : p | x <- [1 .. n], p <- ps !! (n - x), x <= p!!0 ] -- | Inefficient hypergeometric function of a matrix argument (for testing purpose) -hypergeoPQ :: AlgField.C a => Int -> [a] -> [a] -> [a] -> a +hypergeoPQ :: (Eq a, AlgField.C a) => Int -> [a] -> [a] -> [a] -> a hypergeoPQ m a b x = sum $ map (\kappa -> coeff kappa * zonal x kappa) kappas where kappas = filter (\kap -> length kap <= length x) (_allPartitions m)
src/Math/Algebra/Jack/Internal.hs view
@@ -31,7 +31,7 @@ import Math.Algebra.Hspray ( RatioOfPolynomials , Polynomial - , outerVariable + , soleParameter , constPoly ) import qualified Math.Combinat.Partitions.Integer as MCP @@ -115,7 +115,7 @@ => Partition -> (Polynomial a, Polynomial a) symbolicHookLengthsProducts lambda = (product lower, product upper) where - alpha = outerVariable :: Polynomial a + alpha = soleParameter :: Polynomial a (i, j) = _ij lambda (lambda', lambdaConj') = _convParts lambda upper = zipWith (fup lambdaConj' lambda') i j @@ -138,7 +138,7 @@ jackSymbolicCoeffC lambda = (constPoly (fromInteger factorialk) * alpha^k) :% jlambda where - alpha = outerVariable :: Polynomial a + alpha = soleParameter :: Polynomial a k = fromIntegral (sum lambda) factorialk = product [2 .. k] jlambda = symbolicHookLengthsProduct lambda @@ -170,7 +170,7 @@ ((x * num1 * num2 * num3) :% (den1 * den2 * den3)) where mukm1 = mu !! (k-1) - x = outerVariable :: Polynomial a + x = soleParameter :: Polynomial a t = constPoly (fromIntegral k) - constPoly (fromIntegral mukm1) * x u = zipWith ( @@ -195,12 +195,19 @@ num3 = product $ map (\p -> p + x) w den3 = product w -(.^) :: AlgAdd.C a => Int -> a -> a -(.^) k x = if k >= 0 - then AlgAdd.sum (replicate k x) - else AlgAdd.negate $ AlgAdd.sum (replicate (-k) x) +infixr 7 .^ +-- | scale by an integer (I do not find this operation in __numeric-prelude__) +(.^) :: (AlgAdd.C a, Eq a) => Int -> a -> a +k .^ x = if k >= 0 + then powerOperation (AlgAdd.+) AlgAdd.zero x k + else (.^) (-k) (AlgAdd.negate x) + where + powerOperation op = + let go acc _ 0 = acc + go acc a n = go (if even n then acc else op acc a) (op a a) (div n 2) + in go -_fromInt :: AlgRing.C a => Int -> a +_fromInt :: (AlgRing.C a, Eq a) => Int -> a _fromInt k = k .^ AlgRing.one skewSchurLRCoefficients :: Partition -> Partition -> DM.Map Partition Int
src/Math/Algebra/Jack/SymmetricPolynomials.hs view
@@ -5,9 +5,11 @@ 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. +A Jack polynomial can have a very long expression in the canonical basis. +A considerably shorter expression is obtained by writing the polynomial as +a linear combination of the monomial symmetric polynomials instead, which is +always possible since Jack polynomials are symmetric. This is the motivation +of this module. -} module Math.Algebra.Jack.SymmetricPolynomials @@ -17,7 +19,7 @@ , prettySymmetricNumSpray , prettySymmetricQSpray , prettySymmetricQSpray' - , prettySymmetricSymbolicQSpray + , prettySymmetricOneParameterQSpray ) where import qualified Algebra.Ring as AlgRing import qualified Data.Foldable as DF @@ -31,7 +33,7 @@ , Spray , QSpray , QSpray' - , SymbolicQSpray + , OneParameterQSpray , fromList , getCoefficient , numberOfVariables @@ -67,7 +69,7 @@ -- | 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 +-- everything needed to build this function which can be useful in another context isSymmetricSpray :: (AlgRing.C a, Eq a) => Spray a -> Bool isSymmetricSpray spray = spray == spray' where @@ -102,7 +104,7 @@ -- | 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] +-- 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 @@ -124,12 +126,13 @@ where mspray = makeMSpray spray --- | Prints a symmetric symbolic spray as a linear combination of monomial symmetric polynomials +-- | Prints a symmetric one-parameter spray as a linear combination of monomial +-- symmetric polynomials -- --- >>> putStrLn $ prettySymmetricSymbolicQSpray "a" $ jackSymbolicPol' 3 [3, 1, 1] 'J' +-- >>> putStrLn $ prettySymmetricOneParameterQSpray "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 = +prettySymmetricOneParameterQSpray :: String -> OneParameterQSpray -> String +prettySymmetricOneParameterQSpray a spray = showSpray (prettyRatioOfQPolynomials a) ("{ ", " }") showSymmetricMonomials mspray where
src/Math/Algebra/JackSymbolicPol.hs view
@@ -29,8 +29,8 @@ , jackSymbolicCoeffQinv , _N, _isPartition, Partition ) import Math.Algebra.Hspray ( (*^), (^**^), (^*^), (^+^) - , lone, SymbolicSpray, SymbolicQSpray - , Polynomial, outerVariable + , lone, OneParameterSpray, OneParameterQSpray + , Polynomial, soleParameter , constPoly, RatioOfPolynomials , zeroSpray, unitSpray ) import Number.Ratio ( fromValue, recip ) @@ -40,7 +40,7 @@ :: Int -- ^ number of variables -> Partition -- ^ partition of integers -> Char -- ^ which Jack polynomial, @'J'@, @'C'@, @'P'@ or @'Q'@ - -> SymbolicQSpray + -> OneParameterQSpray jackSymbolicPol' = jackSymbolicPol -- | Jack polynomial with symbolic Jack parameter @@ -48,7 +48,7 @@ => Int -- ^ number of variables -> Partition -- ^ partition of integers -> Char -- ^ which Jack polynomial, @'J'@, @'C'@, @'P'@ or @'Q'@ - -> SymbolicSpray a + -> OneParameterSpray a jackSymbolicPol n lambda which = case _isPartition lambda of False -> error "jackSymbolicPol: invalid integer partition" @@ -57,12 +57,13 @@ 'C' -> jackSymbolicCoeffC lambda *^ resultJ 'P' -> recip (fromValue (jackSymbolicCoeffPinv lambda)) *^ resultJ 'Q' -> recip (fromValue (jackSymbolicCoeffQinv lambda)) *^ resultJ - _ -> error "jackSymbolicPol: please use 'J', 'C', 'P' or 'Q' for last argument" + _ -> error + "jackSymbolicPol: please use 'J', 'C', 'P' or 'Q' for last argument" where - alpha = outerVariable :: Polynomial a + alpha = soleParameter :: Polynomial a resultJ = jac (length x) 0 lambda lambda arr0 one nll = _N lambda lambda - x = map lone [1 .. n] :: [SymbolicSpray a] + x = map lone [1 .. n] :: [OneParameterSpray a] arr0 = listArray ((1, 1), (nll, n)) (replicate (nll * n) Nothing) theproduct :: Int -> RatioOfPolynomials a theproduct nu0 = if nu0 <= 1 @@ -71,7 +72,8 @@ (\i -> constPoly (fromIntegral i) * alpha + constPoly one) [1 .. nu0-1] jac :: Int -> Int -> Partition -> Partition - -> Array (Int,Int) (Maybe (SymbolicSpray a)) -> RatioOfPolynomials a -> SymbolicSpray a + -> Array (Int,Int) (Maybe (OneParameterSpray a)) + -> RatioOfPolynomials a -> OneParameterSpray a jac m k mu nu arr beta | null nu || nu!!0 == 0 || m == 0 = unitSpray | length nu > m && nu!!m > 0 = zeroSpray @@ -82,7 +84,7 @@ where s = go (beta *^ (jac (m-1) 0 nu nu arr one ^*^ ((x!!(m-1)) ^**^ (sum mu - sum nu)))) (max 1 k) - go :: SymbolicSpray a -> Int -> SymbolicSpray a + go :: OneParameterSpray a -> Int -> OneParameterSpray a go !ss ii | length nu < ii || nu!!(ii-1) == 0 = ss | otherwise =
tests/Main.hs view
@@ -2,14 +2,14 @@ import Data.Ratio ( (%) ) import Math.Algebra.Hspray ( (^+^), (*^), (^*^), (^**^), Spray, lone , evalSpray - , evalSymbolicSpray, evalSymbolicSpray' + , evalOneParameterSpray, evalOneParameterSpray' , 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 ) + , prettySymmetricOneParameterQSpray ) import Math.Algebra.JackPol ( zonalPol, zonalPol', jackPol' , schurPol, schurPol', skewSchurPol' ) import Math.Algebra.JackSymbolicPol ( jackSymbolicPol' ) @@ -30,13 +30,13 @@ [ testCase "jackSymbolicPol" $ do let jp = jackSymbolicPol' 3 [3, 1] 'J' - v = evalSymbolicSpray' jp 2 [-3, 4, 5] + v = evalOneParameterSpray' jp 2 [-3, 4, 5] assertEqual "" v 1488 , testCase "jackSymbolicPol C" $ do let jp = jackSymbolicPol' 4 [3, 1] 'C' zp = zonalPol 4 [3, 1] :: Spray Rational' - p = evalSymbolicSpray jp 2 + p = evalOneParameterSpray jp 2 assertEqual "" zp p , testCase "jackSymbolicPol Q is symmetric" $ do @@ -47,16 +47,16 @@ let jp = jackSymbolicPol' 5 [3, 2, 1] 'P' assertBool "" (isSymmetricSpray jp) - , testCase "prettySymmetricSymbolicQSpray - jack J" $ do + , testCase "prettySymmetricOneParameterQSpray - jack J" $ do let jp = jackSymbolicPol' 3 [3, 1, 1] 'J' assertEqual "" - (prettySymmetricSymbolicQSpray "a" jp) + (prettySymmetricOneParameterQSpray "a" jp) ("{ 4*a^2 + 10*a + 6 }*M[3,1,1] + { 8*a + 12 }*M[2,2,1]") - , testCase "prettySymmetricSymbolicQSpray - jack C" $ do + , testCase "prettySymmetricOneParameterQSpray - jack C" $ do let jp = jackSymbolicPol' 3 [3, 1, 1] 'C' assertEqual "" - (prettySymmetricSymbolicQSpray "a" jp) + (prettySymmetricOneParameterQSpray "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