{-# LANGUAGE BangPatterns        #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Math.Algebra.Jack.Internal
  (Partition
  , jackCoeffP
  , jackCoeffQ
  , jackCoeffC
  , jackSymbolicCoeffC
  , jackSymbolicCoeffPinv
  , jackSymbolicCoeffQinv
  , _betaratio
  , _betaRatioOfPolynomials
  , _isPartition
  , _N
  , (.^)
  , _fromInt
  , skewSchurLRCoefficients
  , isSkewPartition)
  where
import           Prelude 
  hiding ((*), (+), (-), (/), (^), (*>), product, sum, fromIntegral, fromInteger, recip)
import           Algebra.Additive                            ( (+), (-), sum )
import           Algebra.Field                               ( (/), recip )
import           Algebra.Ring                                ( (*), product, one, (^), fromInteger )
import           Algebra.ToInteger                           ( fromIntegral )
import qualified Algebra.Additive                            as AlgAdd
import qualified Algebra.Field                               as AlgField
import qualified Algebra.Ring                                as AlgRing
import           Data.List.Index                             ( iconcatMap )
import qualified Data.Map.Strict                             as DM
import           Math.Algebra.Hspray                         ( 
                                                               RatioOfPolynomials
                                                             , Polynomial
                                                             , soleParameter
                                                             , constPoly
                                                             )
import qualified Math.Combinat.Partitions.Integer            as MCP
import           Math.Combinat.Tableaux.LittlewoodRichardson ( _lrRule )
import           Number.Ratio                                ( T( (:%) ) )

type Partition = [Int]

_isPartition :: Partition -> Bool
_isPartition :: Partition -> Bool
_isPartition []           = Bool
True
_isPartition [Int
x]          = Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
_isPartition (Int
x:xs :: Partition
xs@(Int
y:Partition
_)) = (Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
y) Bool -> Bool -> Bool
&& Partition -> Bool
_isPartition Partition
xs

_diffSequence :: [Int] -> [Int]
_diffSequence :: Partition -> Partition
_diffSequence = Partition -> Partition
forall {a}. C a => [a] -> [a]
go where
  go :: [a] -> [a]
go (a
x:ys :: [a]
ys@(a
y:[a]
_)) = (a
xa -> a -> a
forall a. C a => a -> a -> a
-a
y) a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a] -> [a]
go [a]
ys 
  go [a
x]          = [a
x]
  go []           = []

_dualPartition :: Partition -> Partition
_dualPartition :: Partition -> Partition
_dualPartition [] = []
_dualPartition Partition
xs = Int -> Partition -> Partition -> Partition
forall {t}. (C t, Num t) => t -> Partition -> Partition -> [t]
go Int
0 (Partition -> Partition
_diffSequence Partition
xs) [] where
  go :: t -> Partition -> Partition -> [t]
go !t
i (Int
d:Partition
ds) Partition
acc = t -> Partition -> Partition -> [t]
go (t
it -> t -> t
forall a. C a => a -> a -> a
+t
1) Partition
ds (Int
dInt -> Partition -> Partition
forall a. a -> [a] -> [a]
:Partition
acc)
  go t
n  []     Partition
acc = t -> Partition -> [t]
forall {t}. (C t, Num t) => t -> Partition -> [t]
finish t
n Partition
acc 
  finish :: t -> Partition -> [t]
finish !t
j (Int
k:Partition
ks) = Int -> t -> [t]
forall a. Int -> a -> [a]
replicate Int
k t
j [t] -> [t] -> [t]
forall a. [a] -> [a] -> [a]
++ t -> Partition -> [t]
finish (t
jt -> t -> t
forall a. C a => a -> a -> a
-t
1) Partition
ks
  finish t
_  []     = []

_ij :: Partition -> ([Int], [Int])
_ij :: Partition -> (Partition, Partition)
_ij Partition
lambda =
  (
    (Int -> Int -> Partition) -> Partition -> Partition
forall a b. (Int -> a -> [b]) -> [a] -> [b]
iconcatMap (\Int
i Int
a ->  Int -> Int -> Partition
forall a. Int -> a -> [a]
replicate Int
a (Int
i Int -> Int -> Int
forall a. C a => a -> a -> a
+ Int
1)) Partition
lambda,
    (Int -> Partition) -> Partition -> Partition
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\Int
a -> [Int
1 .. Int
a]) ((Int -> Bool) -> Partition -> Partition
forall a. (a -> Bool) -> [a] -> [a]
filter (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
0) Partition
lambda)
  )

_convParts :: AlgRing.C b => [Int] -> ([b], [b])
_convParts :: forall b. C b => Partition -> ([b], [b])
_convParts Partition
lambda =
  ((Int -> b) -> Partition -> [b]
forall a b. (a -> b) -> [a] -> [b]
map Int -> b
forall a b. (C a, C b) => a -> b
fromIntegral Partition
lambda, (Int -> b) -> Partition -> [b]
forall a b. (a -> b) -> [a] -> [b]
map Int -> b
forall a b. (C a, C b) => a -> b
fromIntegral (Partition -> Partition
_dualPartition Partition
lambda))

_N :: [Int] -> [Int] -> Int
_N :: Partition -> Partition -> Int
_N Partition
lambda Partition
mu = Partition -> Int
forall a. C a => [a] -> a
sum (Partition -> Int) -> Partition -> Int
forall a b. (a -> b) -> a -> b
$ (Int -> Int -> Int) -> Partition -> Partition -> Partition
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> Int -> Int
forall a. C a => a -> a -> a
(*) Partition
mu Partition
prods
  where
  prods :: Partition
prods = (Int -> Int) -> Partition -> Partition
forall a b. (a -> b) -> [a] -> [b]
map (\Int
i -> Partition -> Int
forall a. C a => [a] -> a
product (Partition -> Int) -> Partition -> Int
forall a b. (a -> b) -> a -> b
$ Int -> Partition -> Partition
forall a. Int -> [a] -> [a]
drop Int
i ((Int -> Int) -> Partition -> Partition
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Int -> Int
forall a. C a => a -> a -> a
+Int
1) Partition
lambda)) [Int
1 .. Partition -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Partition
lambda]

hookLengths :: AlgRing.C a => Partition -> a -> ([a], [a])
hookLengths :: forall a. C a => Partition -> a -> ([a], [a])
hookLengths Partition
lambda a
alpha = ([a]
lower, [a]
upper)
  where
    (Partition
i, Partition
j) = Partition -> (Partition, Partition)
_ij Partition
lambda
    ([a]
lambda', [a]
lambdaConj') = Partition -> ([a], [a])
forall b. C b => Partition -> ([b], [b])
_convParts Partition
lambda
    upper :: [a]
upper = (Int -> Int -> a) -> Partition -> Partition -> [a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ([a] -> [a] -> Int -> Int -> a
fup [a]
lambdaConj' [a]
lambda') Partition
i Partition
j
      where
        fup :: [a] -> [a] -> Int -> Int -> a
fup [a]
x [a]
y Int
ii Int
jj =
          [a]
x[a] -> Int -> a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
jjInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) a -> a -> a
forall a. C a => a -> a -> a
- Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
ii a -> a -> a
forall a. C a => a -> a -> a
+ a
alpha a -> a -> a
forall a. C a => a -> a -> a
* ([a]
y[a] -> Int -> a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
iiInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) a -> a -> a
forall a. C a => a -> a -> a
- Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral (Int
jj Int -> Int -> Int
forall a. C a => a -> a -> a
- Int
1))
    lower :: [a]
lower = (Int -> Int -> a) -> Partition -> Partition -> [a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ([a] -> [a] -> Int -> Int -> a
flow [a]
lambdaConj' [a]
lambda') Partition
i Partition
j
      where
        flow :: [a] -> [a] -> Int -> Int -> a
flow [a]
x [a]
y Int
ii Int
jj =
          [a]
x[a] -> Int -> a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
jjInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) a -> a -> a
forall a. C a => a -> a -> a
- (Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral (Int -> a) -> Int -> a
forall a b. (a -> b) -> a -> b
$ Int
ii Int -> Int -> Int
forall a. C a => a -> a -> a
- Int
1) a -> a -> a
forall a. C a => a -> a -> a
+ a
alpha a -> a -> a
forall a. C a => a -> a -> a
* ([a]
y[a] -> Int -> a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
iiInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) a -> a -> a
forall a. C a => a -> a -> a
- Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
jj)

_productHookLengths :: AlgRing.C a => Partition -> a -> a
_productHookLengths :: forall a. C a => Partition -> a -> a
_productHookLengths Partition
lambda a
alpha = [a] -> a
forall a. C a => [a] -> a
product [a]
lower a -> a -> a
forall a. C a => a -> a -> a
* [a] -> a
forall a. C a => [a] -> a
product [a]
upper
  where
    ([a]
lower, [a]
upper) = Partition -> a -> ([a], [a])
forall a. C a => Partition -> a -> ([a], [a])
hookLengths Partition
lambda a
alpha

jackCoeffC :: AlgField.C a => Partition -> a -> a
jackCoeffC :: forall a. C a => Partition -> a -> a
jackCoeffC Partition
lambda a
alpha = 
  a
alphaa -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
k a -> a -> a
forall a. C a => a -> a -> a
* Integer -> a
forall a. C a => Integer -> a
fromInteger ([Integer] -> Integer
forall a. C a => [a] -> a
product [Integer
2 .. Integer
k]) a -> a -> a
forall a. C a => a -> a -> a
* a -> a
forall a. C a => a -> a
recip a
jlambda
  where
    k :: Integer
k = Int -> Integer
forall a b. (C a, C b) => a -> b
fromIntegral (Partition -> Int
forall a. C a => [a] -> a
sum Partition
lambda)
    jlambda :: a
jlambda = Partition -> a -> a
forall a. C a => Partition -> a -> a
_productHookLengths Partition
lambda a
alpha

jackCoeffP :: AlgField.C a => Partition -> a -> a
jackCoeffP :: forall a. C a => Partition -> a -> a
jackCoeffP Partition
lambda a
alpha = a
forall a. C a => a
one a -> a -> a
forall a. C a => a -> a -> a
/ [a] -> a
forall a. C a => [a] -> a
product [a]
lower
  where
    ([a]
lower, [a]
_) = Partition -> a -> ([a], [a])
forall a. C a => Partition -> a -> ([a], [a])
hookLengths Partition
lambda a
alpha

jackCoeffQ :: AlgField.C a => Partition -> a -> a
jackCoeffQ :: forall a. C a => Partition -> a -> a
jackCoeffQ Partition
lambda a
alpha = a
forall a. C a => a
one a -> a -> a
forall a. C a => a -> a -> a
/ [a] -> a
forall a. C a => [a] -> a
product [a]
upper
  where
    ([a]
_, [a]
upper) = Partition -> a -> ([a], [a])
forall a. C a => Partition -> a -> ([a], [a])
hookLengths Partition
lambda a
alpha

symbolicHookLengthsProducts :: forall a. AlgRing.C a 
  => Partition -> (Polynomial a, Polynomial a)
symbolicHookLengthsProducts :: forall a. C a => Partition -> (Polynomial a, Polynomial a)
symbolicHookLengthsProducts Partition
lambda = ([Polynomial a] -> Polynomial a
forall a. C a => [a] -> a
product [Polynomial a]
lower, [Polynomial a] -> Polynomial a
forall a. C a => [a] -> a
product [Polynomial a]
upper)
  where
    alpha :: Polynomial a
alpha = Polynomial a
forall a. C a => Polynomial a
soleParameter :: Polynomial a
    (Partition
i, Partition
j) = Partition -> (Partition, Partition)
_ij Partition
lambda
    ([a]
lambda', [a]
lambdaConj') = Partition -> ([a], [a])
forall b. C b => Partition -> ([b], [b])
_convParts Partition
lambda
    upper :: [Polynomial a]
upper = (Int -> Int -> Polynomial a)
-> Partition -> Partition -> [Polynomial a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ([a] -> [a] -> Int -> Int -> Polynomial a
fup [a]
lambdaConj' [a]
lambda') Partition
i Partition
j
      where
        fup :: [a] -> [a] -> Int -> Int -> Polynomial a
fup [a]
x [a]
y Int
ii Int
jj =
          a -> Polynomial a
forall a. a -> Polynomial a
constPoly ([a]
x[a] -> Int -> a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
jjInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) a -> a -> a
forall a. C a => a -> a -> a
- Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
ii) 
            Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
+ a -> Polynomial a
forall a. a -> Polynomial a
constPoly ([a]
y[a] -> Int -> a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
iiInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) a -> a -> a
forall a. C a => a -> a -> a
- Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral (Int
jj Int -> Int -> Int
forall a. C a => a -> a -> a
- Int
1)) Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
* Polynomial a
alpha
    lower :: [Polynomial a]
lower = (Int -> Int -> Polynomial a)
-> Partition -> Partition -> [Polynomial a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ([a] -> [a] -> Int -> Int -> Polynomial a
flow [a]
lambdaConj' [a]
lambda') Partition
i Partition
j
      where
        flow :: [a] -> [a] -> Int -> Int -> Polynomial a
flow [a]
x [a]
y Int
ii Int
jj =
          a -> Polynomial a
forall a. a -> Polynomial a
constPoly ([a]
x[a] -> Int -> a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
jjInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) a -> a -> a
forall a. C a => a -> a -> a
- Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral (Int
ii Int -> Int -> Int
forall a. C a => a -> a -> a
- Int
1)) 
            Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
+ a -> Polynomial a
forall a. a -> Polynomial a
constPoly ([a]
y[a] -> Int -> a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
iiInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) a -> a -> a
forall a. C a => a -> a -> a
- Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
jj) Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
* Polynomial a
alpha

symbolicHookLengthsProduct :: AlgRing.C a => Partition -> Polynomial a
symbolicHookLengthsProduct :: forall a. C a => Partition -> Polynomial a
symbolicHookLengthsProduct Partition
lambda = (Polynomial a, Polynomial a) -> Polynomial a
forall a b. (a, b) -> a
fst (Polynomial a, Polynomial a)
hlproducts Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
* (Polynomial a, Polynomial a) -> Polynomial a
forall a b. (a, b) -> b
snd (Polynomial a, Polynomial a)
hlproducts
  where
    hlproducts :: (Polynomial a, Polynomial a)
hlproducts = Partition -> (Polynomial a, Polynomial a)
forall a. C a => Partition -> (Polynomial a, Polynomial a)
symbolicHookLengthsProducts Partition
lambda

jackSymbolicCoeffC :: forall a. AlgField.C a => Partition -> RatioOfPolynomials a
jackSymbolicCoeffC :: forall a. C a => Partition -> RatioOfPolynomials a
jackSymbolicCoeffC Partition
lambda = 
  (a -> Polynomial a
forall a. a -> Polynomial a
constPoly (Integer -> a
forall a. C a => Integer -> a
fromInteger Integer
factorialk) Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
* Polynomial a
alphaPolynomial a -> Integer -> Polynomial a
forall a. C a => a -> Integer -> a
^Integer
k) Polynomial a -> Polynomial a -> T (Polynomial a)
forall a. a -> a -> T a
:% Polynomial a
jlambda
  where
    alpha :: Polynomial a
alpha      = Polynomial a
forall a. C a => Polynomial a
soleParameter :: Polynomial a
    k :: Integer
k          = Int -> Integer
forall a b. (C a, C b) => a -> b
fromIntegral (Partition -> Int
forall a. C a => [a] -> a
sum Partition
lambda)
    factorialk :: Integer
factorialk = [Integer] -> Integer
forall a. C a => [a] -> a
product [Integer
2 .. Integer
k]
    jlambda :: Polynomial a
jlambda    = Partition -> Polynomial a
forall a. C a => Partition -> Polynomial a
symbolicHookLengthsProduct Partition
lambda

jackSymbolicCoeffPinv :: AlgField.C a => Partition -> Polynomial a
jackSymbolicCoeffPinv :: forall a. C a => Partition -> Polynomial a
jackSymbolicCoeffPinv Partition
lambda = (Polynomial a, Polynomial a) -> Polynomial a
forall a b. (a, b) -> a
fst ((Polynomial a, Polynomial a) -> Polynomial a)
-> (Polynomial a, Polynomial a) -> Polynomial a
forall a b. (a -> b) -> a -> b
$ Partition -> (Polynomial a, Polynomial a)
forall a. C a => Partition -> (Polynomial a, Polynomial a)
symbolicHookLengthsProducts Partition
lambda

jackSymbolicCoeffQinv :: AlgField.C a => Partition -> Polynomial a 
jackSymbolicCoeffQinv :: forall a. C a => Partition -> Polynomial a
jackSymbolicCoeffQinv Partition
lambda = (Polynomial a, Polynomial a) -> Polynomial a
forall a b. (a, b) -> b
snd ((Polynomial a, Polynomial a) -> Polynomial a)
-> (Polynomial a, Polynomial a) -> Polynomial a
forall a b. (a -> b) -> a -> b
$ Partition -> (Polynomial a, Polynomial a)
forall a. C a => Partition -> (Polynomial a, Polynomial a)
symbolicHookLengthsProducts Partition
lambda

_betaratio :: AlgField.C a => Partition -> Partition -> Int -> a -> a
_betaratio :: forall a. C a => Partition -> Partition -> Int -> a -> a
_betaratio Partition
kappa Partition
mu Int
k a
alpha = a
alpha a -> a -> a
forall a. C a => a -> a -> a
* a
prod1 a -> a -> a
forall a. C a => a -> a -> a
* a
prod2 a -> a -> a
forall a. C a => a -> a -> a
* a
prod3
  where
    mukm1 :: Int
mukm1 = Partition
mu Partition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!! (Int
kInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1)
    t :: a
t = Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
k a -> a -> a
forall a. C a => a -> a -> a
- a
alpha a -> a -> a
forall a. C a => a -> a -> a
* Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
mukm1
    u :: [a]
u = (Int -> Int -> a) -> Partition -> Partition -> [a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Int
s Int
kap -> a
t a -> a -> a
forall a. C a => a -> a -> a
+ a
forall a. C a => a
one a -> a -> a
forall a. C a => a -> a -> a
- Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
s a -> a -> a
forall a. C a => a -> a -> a
+ a
alpha a -> a -> a
forall a. C a => a -> a -> a
* Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
kap)
                [Int
1 .. Int
k] Partition
kappa 
    v :: [a]
v = (Int -> Int -> a) -> Partition -> Partition -> [a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Int
s Int
m -> a
t a -> a -> a
forall a. C a => a -> a -> a
- Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
s a -> a -> a
forall a. C a => a -> a -> a
+ a
alpha a -> a -> a
forall a. C a => a -> a -> a
* Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
m)
                [Int
1 .. Int
kInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1] Partition
mu 
    w :: [a]
w = (Int -> Int -> a) -> Partition -> Partition -> [a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Int
s Int
m -> Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
m a -> a -> a
forall a. C a => a -> a -> a
- a
t a -> a -> a
forall a. C a => a -> a -> a
- a
alpha a -> a -> a
forall a. C a => a -> a -> a
* Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
s)
                [Int
1 .. Int
mukm1Int -> Int -> Int
forall a. C a => a -> a -> a
-Int
1] (Partition -> Partition
_dualPartition Partition
mu)
    prod1 :: a
prod1 = [a] -> a
forall a. C a => [a] -> a
product ([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$ (a -> a) -> [a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (\a
x -> a
x a -> a -> a
forall a. C a => a -> a -> a
/ (a
x a -> a -> a
forall a. C a => a -> a -> a
+ a
alpha a -> a -> a
forall a. C a => a -> a -> a
- a
forall a. C a => a
one)) [a]
u
    prod2 :: a
prod2 = [a] -> a
forall a. C a => [a] -> a
product ([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$ (a -> a) -> [a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (\a
x -> (a
x a -> a -> a
forall a. C a => a -> a -> a
+ a
alpha) a -> a -> a
forall a. C a => a -> a -> a
/ a
x) [a]
v
    prod3 :: a
prod3 = [a] -> a
forall a. C a => [a] -> a
product ([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$ (a -> a) -> [a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (\a
x -> (a
x a -> a -> a
forall a. C a => a -> a -> a
+ a
alpha) a -> a -> a
forall a. C a => a -> a -> a
/ a
x) [a]
w

_betaRatioOfPolynomials :: forall a. AlgField.C a
  => Partition -> Partition -> Int -> RatioOfPolynomials a
_betaRatioOfPolynomials :: forall a.
C a =>
Partition -> Partition -> Int -> RatioOfPolynomials a
_betaRatioOfPolynomials Partition
kappa Partition
mu Int
k = 
  ((Polynomial a
x Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
* Polynomial a
num1 Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
* Polynomial a
num2 Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
* Polynomial a
num3) Polynomial a -> Polynomial a -> T (Polynomial a)
forall a. a -> a -> T a
:% (Polynomial a
den1 Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
* Polynomial a
den2 Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
* Polynomial a
den3))
  where
    mukm1 :: Int
mukm1 = Partition
mu Partition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!! (Int
kInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1)
    x :: Polynomial a
x = Polynomial a
forall a. C a => Polynomial a
soleParameter :: Polynomial a
    t :: Polynomial a
t = a -> Polynomial a
forall a. a -> Polynomial a
constPoly (Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
k) Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
- a -> Polynomial a
forall a. a -> Polynomial a
constPoly (Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
mukm1) Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
* Polynomial a
x
    u :: [Polynomial a]
u = (Int -> Int -> Polynomial a)
-> Partition -> Partition -> [Polynomial a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith 
        (
        \Int
s Int
kap -> 
          Polynomial a
t Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
- a -> Polynomial a
forall a. a -> Polynomial a
constPoly (Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral (Int -> a) -> Int -> a
forall a b. (a -> b) -> a -> b
$ Int
sInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
+ a -> Polynomial a
forall a. a -> Polynomial a
constPoly (Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
kap) Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
* Polynomial a
x
        )
        [Int
1 .. Int
k] Partition
kappa 
    v :: [Polynomial a]
v = (Int -> Int -> Polynomial a)
-> Partition -> Partition -> [Polynomial a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith 
        (
        \Int
s Int
m -> Polynomial a
t Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
- a -> Polynomial a
forall a. a -> Polynomial a
constPoly (Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
s) Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
+ a -> Polynomial a
forall a. a -> Polynomial a
constPoly (Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
m) Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
* Polynomial a
x
        )
        [Int
1 .. Int
kInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1] Partition
mu 
    w :: [Polynomial a]
w = (Int -> Int -> Polynomial a)
-> Partition -> Partition -> [Polynomial a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith 
        (
        \Int
s Int
m -> a -> Polynomial a
forall a. a -> Polynomial a
constPoly (Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
m) Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
- Polynomial a
t Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
- a -> Polynomial a
forall a. a -> Polynomial a
constPoly (Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
s) Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
* Polynomial a
x
        )
        [Int
1 .. Int
mukm1Int -> Int -> Int
forall a. C a => a -> a -> a
-Int
1] (Partition -> Partition
_dualPartition Partition
mu)
    num1 :: Polynomial a
num1 = [Polynomial a] -> Polynomial a
forall a. C a => [a] -> a
product [Polynomial a]
u
    den1 :: Polynomial a
den1 = [Polynomial a] -> Polynomial a
forall a. C a => [a] -> a
product ([Polynomial a] -> Polynomial a) -> [Polynomial a] -> Polynomial a
forall a b. (a -> b) -> a -> b
$ (Polynomial a -> Polynomial a) -> [Polynomial a] -> [Polynomial a]
forall a b. (a -> b) -> [a] -> [b]
map (\Polynomial a
p -> Polynomial a
p Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
+ Polynomial a
x Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
- a -> Polynomial a
forall a. a -> Polynomial a
constPoly a
forall a. C a => a
one) [Polynomial a]
u
    num2 :: Polynomial a
num2 = [Polynomial a] -> Polynomial a
forall a. C a => [a] -> a
product ([Polynomial a] -> Polynomial a) -> [Polynomial a] -> Polynomial a
forall a b. (a -> b) -> a -> b
$ (Polynomial a -> Polynomial a) -> [Polynomial a] -> [Polynomial a]
forall a b. (a -> b) -> [a] -> [b]
map (\Polynomial a
p -> Polynomial a
p Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
+ Polynomial a
x) [Polynomial a]
v
    den2 :: Polynomial a
den2 = [Polynomial a] -> Polynomial a
forall a. C a => [a] -> a
product [Polynomial a]
v
    num3 :: Polynomial a
num3 = [Polynomial a] -> Polynomial a
forall a. C a => [a] -> a
product ([Polynomial a] -> Polynomial a) -> [Polynomial a] -> Polynomial a
forall a b. (a -> b) -> a -> b
$ (Polynomial a -> Polynomial a) -> [Polynomial a] -> [Polynomial a]
forall a b. (a -> b) -> [a] -> [b]
map (\Polynomial a
p -> Polynomial a
p Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
+ Polynomial a
x) [Polynomial a]
w
    den3 :: Polynomial a
den3 = [Polynomial a] -> Polynomial a
forall a. C a => [a] -> a
product [Polynomial a]
w

infixr 7 .^
-- | scale by an integer (I do not find this operation in __numeric-prelude__)

(.^) :: (AlgAdd.C a, Eq a) => Int -> a -> a
Int
k .^ :: forall a. (C a, Eq a) => Int -> a -> a
.^ a
x = if Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
  then (a -> a -> a) -> a -> a -> Int -> a
forall {t} {t}. Integral t => (t -> t -> t) -> t -> t -> t -> t
powerOperation a -> a -> a
forall a. C a => a -> a -> a
(AlgAdd.+) a
forall a. C a => a
AlgAdd.zero a
x Int
k
  else Int -> a -> a
forall a. (C a, Eq a) => Int -> a -> a
(.^) (-Int
k) (a -> a
forall a. C a => a -> a
AlgAdd.negate a
x)
  where 
    powerOperation :: (t -> t -> t) -> t -> t -> t -> t
powerOperation t -> t -> t
op =
      let go :: t -> t -> t -> t
go t
acc t
_ t
0 = t
acc
          go t
acc t
a t
n = t -> t -> t -> t
go (if t -> Bool
forall a. Integral a => a -> Bool
even t
n then t
acc else t -> t -> t
op t
acc t
a) (t -> t -> t
op t
a t
a) (t -> t -> t
forall a. Integral a => a -> a -> a
div t
n t
2)
      in t -> t -> t -> t
forall {t}. Integral t => t -> t -> t -> t
go

_fromInt :: (AlgRing.C a, Eq a) => Int -> a
_fromInt :: forall a. (C a, Eq a) => Int -> a
_fromInt Int
k = Int
k Int -> a -> a
forall a. (C a, Eq a) => Int -> a -> a
.^ a
forall a. C a => a
AlgRing.one

skewSchurLRCoefficients :: Partition -> Partition -> DM.Map Partition Int
skewSchurLRCoefficients :: Partition -> Partition -> Map Partition Int
skewSchurLRCoefficients Partition
lambda Partition
mu = 
  (Partition -> Partition) -> Map Partition Int -> Map Partition Int
forall k2 k1 a. Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a
DM.mapKeys Partition -> Partition
toPartition (Partition -> Partition -> Map Partition Int
_lrRule Partition
lambda' Partition
mu')
  where
    toPartition :: MCP.Partition -> Partition
    toPartition :: Partition -> Partition
toPartition (MCP.Partition Partition
part) = Partition
part 
    fromPartition :: Partition -> MCP.Partition
    fromPartition :: Partition -> Partition
fromPartition Partition
part = Partition -> Partition
MCP.Partition Partition
part
    lambda' :: Partition
lambda' = Partition -> Partition
fromPartition Partition
lambda
    mu' :: Partition
mu'     = Partition -> Partition
fromPartition Partition
mu

isSkewPartition :: Partition -> Partition -> Bool
isSkewPartition :: Partition -> Partition -> Bool
isSkewPartition Partition
lambda Partition
mu = 
  Partition -> Bool
_isPartition Partition
lambda Bool -> Bool -> Bool
&& Partition -> Bool
_isPartition Partition
mu Bool -> Bool -> Bool
&& (Int -> Bool) -> Partition -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) ((Int -> Int -> Int) -> Partition -> Partition -> Partition
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (-) Partition
lambda Partition
mu)