{-|
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 :: Partition -> Rational -> Map Partition Rational
kostkaNumbersWithGivenLambda Partition
lambda Rational
alpha 
  | Bool -> Bool
not (Partition -> Bool
_isPartition Partition
lambda) = 
      [Char] -> Map Partition Rational
forall a. HasCallStack => [Char] -> a
error [Char]
"kostkaNumbersWithGivenLambda: invalid integer partition."
  | Partition -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Partition
lambda =
      Partition -> Rational -> Map Partition Rational
forall k a. k -> a -> Map k a
DM.singleton [] Rational
1
  | Bool
otherwise =
      Int -> Partition -> Rational -> Char -> Map Partition Rational
forall a. C a => Int -> Partition -> a -> Char -> Map Partition a
_kostkaNumbersWithGivenLambda (Partition -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum Partition
lambda) Partition
lambda Rational
alpha Char
'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 :: Int -> Rational -> Map Partition (Map Partition Rational)
kostkaNumbers Int
weight Rational
alpha 
  | Int
weight Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = 
      [Char] -> Map Partition (Map Partition Rational)
forall a. HasCallStack => [Char] -> a
error [Char]
"kostkaNumbers: negative weight."
  | Int
weight Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 =
      Partition
-> Map Partition Rational -> Map Partition (Map Partition Rational)
forall k a. k -> a -> Map k a
DM.singleton [] (Partition -> Rational -> Map Partition Rational
forall k a. k -> a -> Map k a
DM.singleton [] Rational
1)
  | Bool
otherwise =
      Int
-> Int
-> Rational
-> Char
-> Map Partition (Map Partition Rational)
forall a.
C a =>
Int -> Int -> a -> Char -> Map Partition (Map Partition a)
_kostkaNumbers Int
weight Int
weight Rational
alpha Char
'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 :: Int -> Map Partition (Map Partition RatioOfQSprays)
symbolicKostkaNumbers Int
weight
  | Int
weight Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = 
      [Char] -> Map Partition (Map Partition RatioOfQSprays)
forall a. HasCallStack => [Char] -> a
error [Char]
"symbolicKostkaNumbers: negative weight."
  | Int
weight Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 =
      Partition
-> Map Partition RatioOfQSprays
-> Map Partition (Map Partition RatioOfQSprays)
forall k a. k -> a -> Map k a
DM.singleton [] (Partition -> RatioOfQSprays -> Map Partition RatioOfQSprays
forall k a. k -> a -> Map k a
DM.singleton [] RatioOfQSprays
forall a. (C a, Eq a) => RatioOfSprays a
unitRatioOfSprays)
  | Bool
otherwise =
      Int -> Int -> Char -> Map Partition (Map Partition RatioOfQSprays)
forall a.
(Eq a, C a) =>
Int
-> Int -> Char -> Map Partition (Map Partition (RatioOfSprays a))
_symbolicKostkaNumbers Int
weight Int
weight Char
'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 :: Partition -> Map Partition RatioOfQSprays
symbolicKostkaNumbersWithGivenLambda Partition
lambda 
  | Bool -> Bool
not (Partition -> Bool
_isPartition Partition
lambda) = 
      [Char] -> Map Partition RatioOfQSprays
forall a. HasCallStack => [Char] -> a
error [Char]
"symbolicKostkaNumbersWithGivenLambda: invalid integer partition."
  | Partition -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Partition
lambda =
      Partition -> RatioOfQSprays -> Map Partition RatioOfQSprays
forall k a. k -> a -> Map k a
DM.singleton [] RatioOfQSprays
forall a. (C a, Eq a) => RatioOfSprays a
unitRatioOfSprays
  | Bool
otherwise =
      Int -> Partition -> Char -> Map Partition RatioOfQSprays
forall a.
(Eq a, C a) =>
Int -> Partition -> Char -> Map Partition (RatioOfSprays a)
_symbolicKostkaNumbersWithGivenLambda (Partition -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum Partition
lambda) Partition
lambda Char
'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 :: Rational -> Partition -> Partition -> Map Partition Rational
skewKostkaNumbers Rational
alpha Partition
lambda Partition
mu 
  | Bool -> Bool
not (Partition -> Partition -> Bool
isSkewPartition Partition
lambda Partition
mu) =
      [Char] -> Map Partition Rational
forall a. HasCallStack => [Char] -> a
error [Char]
"skewKostkaNumbers: invalid skew partition."
  | Bool
otherwise = 
      ((Int, Rational) -> Rational)
-> Map Partition (Int, Rational) -> Map Partition Rational
forall a b k. (a -> b) -> Map k a -> Map k b
DM.map (Int, Rational) -> Rational
forall a b. (a, b) -> b
snd (Rational
-> Char -> Partition -> Partition -> Map Partition (Int, Rational)
forall a.
(Eq a, C a) =>
a -> Char -> Partition -> Partition -> Map Partition (Int, a)
skewJackInMSPbasis Rational
alpha Char
'P' Partition
lambda Partition
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 :: Partition -> Partition -> Map Partition RatioOfQSprays
symbolicSkewKostkaNumbers Partition
lambda Partition
mu 
  | Bool -> Bool
not (Partition -> Partition -> Bool
isSkewPartition Partition
lambda Partition
mu) =
      [Char] -> Map Partition RatioOfQSprays
forall a. HasCallStack => [Char] -> a
error [Char]
"symbolicSkewKostkaNumbers: invalid skew partition."
  | Bool
otherwise = 
      ((Int, RatioOfQSprays) -> RatioOfQSprays)
-> Map Partition (Int, RatioOfQSprays)
-> Map Partition RatioOfQSprays
forall a b k. (a -> b) -> Map k a -> Map k b
DM.map (Int, RatioOfQSprays) -> RatioOfQSprays
forall a b. (a, b) -> b
snd (Char
-> Partition -> Partition -> Map Partition (Int, RatioOfQSprays)
forall a.
(Eq a, C a) =>
Char
-> Partition -> Partition -> Map Partition (Int, RatioOfSprays a)
skewSymbolicJackInMSPbasis Char
'P' Partition
lambda Partition
mu)