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 )
msPolynomial :: (AlgRing.C a, Eq a)
=> Int
-> Partition
-> Spray a
msPolynomial :: forall a. (C a, Eq a) => Int -> [Int] -> Spray a
msPolynomial Int
n [Int]
lambda
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = [Char] -> Spray a
forall a. HasCallStack => [Char] -> a
error [Char]
"msPolynomial: negative number of variables."
| Bool -> Bool
not ([Int] -> Bool
_isPartition [Int]
lambda) = [Char] -> Spray a
forall a. HasCallStack => [Char] -> a
error [Char]
"msPolynomial: invalid partition."
| Int
llambda Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
n = Spray a
forall a. (Eq a, C a) => Spray a
zeroSpray
| Bool
otherwise = [([Int], a)] -> Spray a
forall a. (C a, Eq a) => [([Int], a)] -> Spray a
fromList ([([Int], a)] -> Spray a) -> [([Int], a)] -> Spray a
forall a b. (a -> b) -> a -> b
$ [[Int]] -> [a] -> [([Int], a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [[Int]]
permutations [a]
coefficients
where
llambda :: Int
llambda = [Int] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
lambda
permutations :: [[Int]]
permutations = [Int] -> [[Int]]
forall a. (Eq a, Ord a) => [a] -> [[a]]
permuteMultiset ([Int]
lambda [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ Int -> Int -> [Int]
forall a. Int -> a -> [a]
replicate (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
llambda) Int
0)
coefficients :: [a]
coefficients = a -> [a]
forall a. a -> [a]
repeat a
forall a. C a => a
AlgRing.one
isSymmetricSpray :: (AlgRing.C a, Eq a) => Spray a -> Bool
isSymmetricSpray :: forall a. (C a, Eq a) => Spray a -> Bool
isSymmetricSpray Spray a
spray = Spray a
spray Spray a -> Spray a -> Bool
forall a. Eq a => a -> a -> Bool
== Spray a
spray'
where
assocs :: [([Int], a)]
assocs = Spray a -> [([Int], a)]
forall a. C a => Spray a -> [([Int], a)]
msCombination' Spray a
spray
n :: Int
n = Spray a -> Int
forall a. Spray a -> Int
numberOfVariables Spray a
spray
spray' :: Spray a
spray' = (Spray a -> Spray a -> Spray a) -> [Spray a] -> Spray a
forall a. HasCallStack => (a -> a -> a) -> [a] -> a
foldl1' Spray a -> Spray a -> Spray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
(^+^)
(
(([Int], a) -> Spray a) -> [([Int], a)] -> [Spray a]
forall a b. (a -> b) -> [a] -> [b]
map (\([Int]
lambda, a
x) -> a
x a -> Spray a -> Spray a
forall a. (C a, Eq a) => a -> Spray a -> Spray a
*^ Int -> [Int] -> Spray a
forall a. (C a, Eq a) => Int -> [Int] -> Spray a
msPolynomial Int
n [Int]
lambda) [([Int], a)]
assocs
)
msCombination :: AlgRing.C a => Spray a -> Map Partition a
msCombination :: forall a. C a => Spray a -> Map [Int] a
msCombination Spray a
spray = [([Int], a)] -> Map [Int] a
forall k a. Ord k => [(k, a)] -> Map k a
DM.fromList (Spray a -> [([Int], a)]
forall a. C a => Spray a -> [([Int], a)]
msCombination' Spray a
spray)
msCombination' :: AlgRing.C a => Spray a -> [(Partition, a)]
msCombination' :: forall a. C a => Spray a -> [([Int], a)]
msCombination' Spray a
spray =
([Int] -> ([Int], a)) -> [[Int]] -> [([Int], a)]
forall a b. (a -> b) -> [a] -> [b]
map (\[Int]
lambda -> ([Int]
lambda, [Int] -> Spray a -> a
forall a. C a => [Int] -> Spray a -> a
getCoefficient [Int]
lambda Spray a
spray)) [[Int]]
lambdas
where
lambdas :: [[Int]]
lambdas = [[Int]] -> [[Int]]
forall a. Eq a => [a] -> [a]
nub ([[Int]] -> [[Int]]) -> [[Int]] -> [[Int]]
forall a b. (a -> b) -> a -> b
$ (([Int], a) -> [Int]) -> [([Int], a)] -> [[Int]]
forall a b. (a -> b) -> [a] -> [b]
map (Partition -> [Int]
fromPartition (Partition -> [Int])
-> (([Int], a) -> Partition) -> ([Int], a) -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> Partition
mkPartition ([Int] -> Partition)
-> (([Int], a) -> [Int]) -> ([Int], a) -> Partition
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Int], a) -> [Int]
forall a b. (a, b) -> a
fst) (Spray a -> [([Int], a)]
forall a. Spray a -> [([Int], a)]
toList Spray a
spray)
makeMSpray :: (Eq a, AlgRing.C a) => Spray a -> Spray a
makeMSpray :: forall a. (Eq a, C a) => Spray a -> Spray a
makeMSpray = [([Int], a)] -> Spray a
forall a. (C a, Eq a) => [([Int], a)] -> Spray a
fromList ([([Int], a)] -> Spray a)
-> (Spray a -> [([Int], a)]) -> Spray a -> Spray a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Spray a -> [([Int], a)]
forall a. C a => Spray a -> [([Int], a)]
msCombination'
showSymmetricMonomials :: [Seq Int] -> [String]
showSymmetricMonomials :: [Seq Int] -> [[Char]]
showSymmetricMonomials = (Seq Int -> [Char]) -> [Seq Int] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map Seq Int -> [Char]
showSymmetricMonomial
where
showSymmetricMonomial :: Seq Int -> String
showSymmetricMonomial :: Seq Int -> [Char]
showSymmetricMonomial Seq Int
lambda = Char
'M' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Int] -> [Char]
forall a. Show a => a -> [Char]
show (Seq Int -> [Int]
forall a. Seq a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
DF.toList Seq Int
lambda)
prettySymmetricNumSpray :: (Num a, Ord a, Show a, AlgRing.C a) => Spray a -> String
prettySymmetricNumSpray :: forall a. (Num a, Ord a, Show a, C a) => Spray a -> [Char]
prettySymmetricNumSpray Spray a
spray =
([Seq Int] -> [[Char]]) -> (a -> [Char]) -> Spray a -> [Char]
forall a.
(Num a, Ord a) =>
([Seq Int] -> [[Char]]) -> (a -> [Char]) -> Spray a -> [Char]
showNumSpray [Seq Int] -> [[Char]]
showSymmetricMonomials a -> [Char]
forall a. Show a => a -> [Char]
show Spray a
mspray
where
mspray :: Spray a
mspray = Spray a -> Spray a
forall a. (Eq a, C a) => Spray a -> Spray a
makeMSpray Spray a
spray
prettySymmetricQSpray :: QSpray -> String
prettySymmetricQSpray :: QSpray -> [Char]
prettySymmetricQSpray QSpray
spray = ([Seq Int] -> [[Char]]) -> QSpray -> [Char]
showQSpray [Seq Int] -> [[Char]]
showSymmetricMonomials QSpray
mspray
where
mspray :: QSpray
mspray = QSpray -> QSpray
forall a. (Eq a, C a) => Spray a -> Spray a
makeMSpray QSpray
spray
prettySymmetricQSpray' :: QSpray' -> String
prettySymmetricQSpray' :: QSpray' -> [Char]
prettySymmetricQSpray' QSpray'
spray = ([Seq Int] -> [[Char]]) -> QSpray' -> [Char]
showQSpray' [Seq Int] -> [[Char]]
showSymmetricMonomials QSpray'
mspray
where
mspray :: QSpray'
mspray = QSpray' -> QSpray'
forall a. (Eq a, C a) => Spray a -> Spray a
makeMSpray QSpray'
spray
prettySymmetricSymbolicQSpray :: String -> SymbolicQSpray -> String
prettySymmetricSymbolicQSpray :: [Char] -> SymbolicQSpray -> [Char]
prettySymmetricSymbolicQSpray [Char]
a SymbolicQSpray
spray =
(RatioOfQPolynomials -> [Char])
-> ([Char], [Char])
-> ([Seq Int] -> [[Char]])
-> SymbolicQSpray
-> [Char]
forall a.
(a -> [Char])
-> ([Char], [Char]) -> ([Seq Int] -> [[Char]]) -> Spray a -> [Char]
showSpray ([Char] -> RatioOfQPolynomials -> [Char]
prettyRatioOfQPolynomials [Char]
a) ([Char]
"{ ", [Char]
" }")
[Seq Int] -> [[Char]]
showSymmetricMonomials SymbolicQSpray
mspray
where
mspray :: SymbolicQSpray
mspray = SymbolicQSpray -> SymbolicQSpray
forall a. (Eq a, C a) => Spray a -> Spray a
makeMSpray SymbolicQSpray
spray