{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Math.Algebra.JackSymbolicPol
(
jackSymbolicPol
, jackSymbolicPol'
, skewJackSymbolicPol
, skewJackSymbolicPol'
)
where
import Prelude
hiding ((/), (^), (*>), product, fromIntegral, fromInteger, recip)
import Algebra.Field ( recip )
import qualified Algebra.Field as AlgField
import Control.Lens ( (.~), element )
import Data.Array ( Array, (!), (//), listArray )
import qualified Data.HashMap.Strict as HM
import qualified Data.Map.Strict as DM
import Data.Maybe ( fromJust, isJust )
import Math.Algebra.Jack.Internal ( _betaRatioOfSprays
, jackSymbolicCoeffC
, jackSymbolicCoeffPinv
, jackSymbolicCoeffQinv
, _N, _isPartition, Partition
, isSkewPartition
, skewSymbolicJackInMSPbasis )
import Math.Algebra.Hspray ( FunctionLike (..), (.^)
, lone, lone'
, ParametricSpray, ParametricQSpray
, Spray, asRatioOfSprays
, zeroSpray, unitSpray
, productOfSprays
, fromList )
import Math.Combinat.Permutations ( permuteMultiset )
jackSymbolicPol'
:: Int
-> Partition
-> Char
-> ParametricQSpray
jackSymbolicPol' :: Int -> Partition -> Char -> ParametricQSpray
jackSymbolicPol' = Int -> Partition -> Char -> ParametricQSpray
forall a.
(Eq a, C a) =>
Int -> Partition -> Char -> ParametricSpray a
jackSymbolicPol
jackSymbolicPol :: forall a. (Eq a, AlgField.C a)
=> Int
-> Partition
-> Char
-> ParametricSpray a
jackSymbolicPol :: forall a.
(Eq a, C a) =>
Int -> Partition -> Char -> ParametricSpray a
jackSymbolicPol Int
n Partition
lambda Char
which =
case Partition -> Bool
_isPartition Partition
lambda of
Bool
False -> [Char] -> ParametricSpray a
forall a. HasCallStack => [Char] -> a
error [Char]
"jackSymbolicPol: invalid integer partition."
Bool
True -> case Char
which of
Char
'J' -> ParametricSpray a
resultJ
Char
'C' -> Partition -> RatioOfSprays a
forall a. (Eq a, C a) => Partition -> RatioOfSprays a
jackSymbolicCoeffC Partition
lambda BaseRing (ParametricSpray a)
-> ParametricSpray a -> ParametricSpray a
forall b. FunctionLike b => BaseRing b -> b -> b
*^ ParametricSpray a
resultJ
Char
'P' -> RatioOfSprays a -> RatioOfSprays a
forall a. C a => a -> a
recip (Spray a -> RatioOfSprays a
forall a. C a => Spray a -> RatioOfSprays a
asRatioOfSprays (Partition -> Spray a
forall a. (Eq a, C a) => Partition -> Spray a
jackSymbolicCoeffPinv Partition
lambda)) BaseRing (ParametricSpray a)
-> ParametricSpray a -> ParametricSpray a
forall b. FunctionLike b => BaseRing b -> b -> b
*^ ParametricSpray a
resultJ
Char
'Q' -> RatioOfSprays a -> RatioOfSprays a
forall a. C a => a -> a
recip (Spray a -> RatioOfSprays a
forall a. C a => Spray a -> RatioOfSprays a
asRatioOfSprays (Partition -> Spray a
forall a. (Eq a, C a) => Partition -> Spray a
jackSymbolicCoeffQinv Partition
lambda)) BaseRing (ParametricSpray a)
-> ParametricSpray a -> ParametricSpray a
forall b. FunctionLike b => BaseRing b -> b -> b
*^ ParametricSpray a
resultJ
Char
_ -> [Char] -> ParametricSpray a
forall a. HasCallStack => [Char] -> a
error
[Char]
"jackSymbolicPol: please use 'J', 'C', 'P' or 'Q' for last argument."
where
alpha :: Spray a
alpha = Int -> Spray a
forall a. C a => Int -> Spray a
lone Int
1 :: Spray a
jck :: Int
-> Partition
-> Array (Int, Int) (Maybe (ParametricSpray a))
-> ParametricSpray a
jck Int
m Partition
kappa Array (Int, Int) (Maybe (ParametricSpray a))
arr = Int
-> Int
-> Partition
-> Partition
-> Array (Int, Int) (Maybe (ParametricSpray a))
-> ParametricSpray a
jac Int
m Int
0 Partition
kappa Partition
kappa Array (Int, Int) (Maybe (ParametricSpray a))
arr
resultJ :: ParametricSpray a
resultJ = Int
-> Partition
-> Array (Int, Int) (Maybe (ParametricSpray a))
-> ParametricSpray a
jck Int
n Partition
lambda Array (Int, Int) (Maybe (ParametricSpray a))
forall {a}. Array (Int, Int) (Maybe a)
arr0
nll :: Int
nll = Partition -> Partition -> Int
_N Partition
lambda Partition
lambda
arr0 :: Array (Int, Int) (Maybe a)
arr0 = ((Int, Int), (Int, Int)) -> [Maybe a] -> Array (Int, Int) (Maybe a)
forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray ((Int
1, Int
1), (Int
nll, Int
n)) (Int -> Maybe a -> [Maybe a]
forall a. Int -> a -> [a]
replicate (Int
nll Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n) Maybe a
forall a. Maybe a
Nothing)
jac :: Int -> Int -> Partition -> Partition
-> Array (Int,Int) (Maybe (ParametricSpray a))
-> ParametricSpray a
jac :: Int
-> Int
-> Partition
-> Partition
-> Array (Int, Int) (Maybe (ParametricSpray a))
-> ParametricSpray a
jac Int
m Int
k Partition
mu Partition
nu Array (Int, Int) (Maybe (ParametricSpray a))
arr
| Partition -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Partition
nu Bool -> Bool -> Bool
|| Int
nu0 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
|| Int
m Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = ParametricSpray a
forall a. C a => Spray a
unitSpray
| Int
ellNu Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
m Bool -> Bool -> Bool
&& Partition
nu Partition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!! Int
m Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = ParametricSpray a
forall a. (Eq a, C a) => Spray a
zeroSpray
| Int
m Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 =
if Int
nu0 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
then
Int -> ParametricSpray a
forall a. C a => Int -> Spray a
lone Int
1
else
let sprays :: [Spray a]
sprays = [Int
i Int -> Spray a -> Spray a
forall a. (C a, Eq a) => Int -> a -> a
.^ Spray a
alpha Spray a -> Spray a -> Spray a
forall b. (FunctionLike b, C b) => b -> b -> b
^+^ Spray a
forall a. C a => Spray a
unitSpray | Int
i <- [Int
1 .. Int
nu0Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1]] in
Spray a -> RatioOfSprays a
forall a. C a => Spray a -> RatioOfSprays a
asRatioOfSprays ([Spray a] -> Spray a
forall a. (Eq a, C a) => [Spray a] -> Spray a
productOfSprays [Spray a]
sprays) BaseRing (ParametricSpray a)
-> ParametricSpray a -> ParametricSpray a
forall b. FunctionLike b => BaseRing b -> b -> b
*^ Int -> ParametricSpray a
x Int
nu0
| Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
&& Maybe (ParametricSpray a) -> Bool
forall a. Maybe a -> Bool
isJust Maybe (ParametricSpray a)
maybe_pspray =
Maybe (ParametricSpray a) -> ParametricSpray a
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (ParametricSpray a) -> ParametricSpray a)
-> Maybe (ParametricSpray a) -> ParametricSpray a
forall a b. (a -> b) -> a -> b
$ Maybe (ParametricSpray a)
maybe_pspray
| Bool
otherwise = ParametricSpray a
s
where
nu0 :: Int
nu0 = Partition
nu Partition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!! Int
0
ellNu :: Int
ellNu = Partition -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Partition
nu
x :: Int -> ParametricSpray a
x = Int -> Int -> ParametricSpray a
forall a. C a => Int -> Int -> Spray a
lone' Int
m
_N_lambda_nu_m :: (Int, Int)
_N_lambda_nu_m = (Partition -> Partition -> Int
_N Partition
lambda Partition
nu, Int
m)
maybe_pspray :: Maybe (ParametricSpray a)
maybe_pspray = Array (Int, Int) (Maybe (ParametricSpray a))
arr Array (Int, Int) (Maybe (ParametricSpray a))
-> (Int, Int) -> Maybe (ParametricSpray a)
forall i e. Ix i => Array i e -> i -> e
! (Int, Int)
_N_lambda_nu_m
wMu :: Int
wMu = Partition -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum Partition
mu
jck' :: Partition
-> Array (Int, Int) (Maybe (ParametricSpray a))
-> ParametricSpray a
jck' Partition
kappa Array (Int, Int) (Maybe (ParametricSpray a))
array = Int
-> Partition
-> Array (Int, Int) (Maybe (ParametricSpray a))
-> ParametricSpray a
jck (Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Partition
kappa Array (Int, Int) (Maybe (ParametricSpray a))
array ParametricSpray a -> ParametricSpray a -> ParametricSpray a
forall b. (FunctionLike b, C b) => b -> b -> b
^*^ Int -> ParametricSpray a
x (Int
wMu Int -> Int -> Int
forall a. Num a => a -> a -> a
- Partition -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum Partition
kappa)
s :: ParametricSpray a
s = ParametricSpray a -> Int -> ParametricSpray a
go (Partition
-> Array (Int, Int) (Maybe (ParametricSpray a))
-> ParametricSpray a
jck' Partition
nu Array (Int, Int) (Maybe (ParametricSpray a))
arr) (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
k)
go :: ParametricSpray a -> Int -> ParametricSpray a
go :: ParametricSpray a -> Int -> ParametricSpray a
go !ParametricSpray a
ss Int
ii
| Int
ellNu Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
ii Bool -> Bool -> Bool
|| Int
u Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 =
ParametricSpray a
ss
| Int
ellNu Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ii Bool -> Bool -> Bool
&& Int
u Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
|| Int
u Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Partition
nu Partition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!! Int
ii =
ParametricSpray a -> Int -> ParametricSpray a
go (ParametricSpray a
ss ParametricSpray a -> ParametricSpray a -> ParametricSpray a
forall b. (FunctionLike b, C b) => b -> b -> b
^+^ ParametricSpray a
tt) (Int
ii Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
| Bool
otherwise =
ParametricSpray a -> Int -> ParametricSpray a
go ParametricSpray a
ss (Int
ii Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
where
jj :: Int
jj = Int
ii Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
u :: Int
u = Partition
nu Partition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!! Int
jj
nu' :: Partition
nu' = (Int -> IndexedTraversal' Int Partition Int
forall (t :: * -> *) a.
Traversable t =>
Int -> IndexedTraversal' Int (t a) a
element Int
jj ((Int -> Identity Int) -> Partition -> Identity Partition)
-> Int -> Partition -> Partition
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Int
u Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Partition
nu
gamma :: RatioOfSprays a
gamma = Partition -> Partition -> Int -> RatioOfSprays a
forall a.
(Eq a, C a) =>
Partition -> Partition -> Int -> RatioOfSprays a
_betaRatioOfSprays Partition
mu Partition
nu Int
ii
tt :: ParametricSpray a
tt = RatioOfSprays a
BaseRing (ParametricSpray a)
gamma BaseRing (ParametricSpray a)
-> ParametricSpray a -> ParametricSpray a
forall b. FunctionLike b => BaseRing b -> b -> b
*^ ParametricSpray a
pspray
where
pspray :: ParametricSpray a
pspray
| Int
u Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 =
Int
-> Int
-> Partition
-> Partition
-> Array (Int, Int) (Maybe (ParametricSpray a))
-> ParametricSpray a
jac Int
m Int
ii Partition
mu Partition
nu' Array (Int, Int) (Maybe (ParametricSpray a))
arr
| Partition
nu' Partition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!! Int
0 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 =
Int -> ParametricSpray a
x Int
wMu
| Bool
otherwise =
Partition
-> Array (Int, Int) (Maybe (ParametricSpray a))
-> ParametricSpray a
jck' Partition
nu' (Array (Int, Int) (Maybe (ParametricSpray a))
arr Array (Int, Int) (Maybe (ParametricSpray a))
-> [((Int, Int), Maybe (ParametricSpray a))]
-> Array (Int, Int) (Maybe (ParametricSpray a))
forall i e. Ix i => Array i e -> [(i, e)] -> Array i e
// [((Int, Int)
_N_lambda_nu_m, ParametricSpray a -> Maybe (ParametricSpray a)
forall a. a -> Maybe a
Just ParametricSpray a
ss)])
skewJackSymbolicPol ::
(Eq a, AlgField.C a)
=> Int
-> Partition
-> Partition
-> Char
-> ParametricSpray a
skewJackSymbolicPol :: forall a.
(Eq a, C a) =>
Int -> Partition -> Partition -> Char -> ParametricSpray a
skewJackSymbolicPol Int
n Partition
lambda Partition
mu Char
which
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 =
[Char] -> ParametricSpray a
forall a. HasCallStack => [Char] -> a
error [Char]
"skewJackSymbolicPol: negative number of variables."
| Bool -> Bool
not (Partition -> Partition -> Bool
isSkewPartition Partition
lambda Partition
mu) =
[Char] -> ParametricSpray a
forall a. HasCallStack => [Char] -> a
error [Char]
"skewJackSymbolicPol: invalid skew partition."
| Bool -> Bool
not (Char
which Char -> [Char] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char
'J', Char
'C', Char
'P', Char
'Q']) =
[Char] -> ParametricSpray a
forall a. HasCallStack => [Char] -> a
error [Char]
"skewJackSymbolicPol: please use 'J', 'C', 'P' or 'Q' for last argument."
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 =
if Partition
lambda Partition -> Partition -> Bool
forall a. Eq a => a -> a -> Bool
== Partition
mu then ParametricSpray a
forall a. C a => Spray a
unitSpray else ParametricSpray a
forall a. (Eq a, C a) => Spray a
zeroSpray
| Bool
otherwise =
[ParametricSpray a] -> ParametricSpray a
forall k v. Eq k => [HashMap k v] -> HashMap k v
HM.unions [ParametricSpray a]
sprays
where
msCombo :: Map Partition (Int, RatioOfSprays a)
msCombo =
((Int, RatioOfSprays a) -> Bool)
-> Map Partition (Int, RatioOfSprays a)
-> Map Partition (Int, RatioOfSprays a)
forall a k. (a -> Bool) -> Map k a -> Map k a
DM.filter
((Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
n) (Int -> Bool)
-> ((Int, RatioOfSprays a) -> Int)
-> (Int, RatioOfSprays a)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, RatioOfSprays a) -> Int
forall a b. (a, b) -> a
fst)
(Char
-> Partition -> Partition -> Map Partition (Int, RatioOfSprays a)
forall a.
(Eq a, C a) =>
Char
-> Partition -> Partition -> Map Partition (Int, RatioOfSprays a)
skewSymbolicJackInMSPbasis Char
which Partition
lambda Partition
mu)
sprays :: [ParametricSpray a]
sprays =
((Partition, (Int, RatioOfSprays a)) -> ParametricSpray a)
-> [(Partition, (Int, RatioOfSprays a))] -> [ParametricSpray a]
forall a b. (a -> b) -> [a] -> [b]
map (
\(Partition
kappa, (Int
l, RatioOfSprays a
rOS)) ->
[(Partition, RatioOfSprays a)] -> ParametricSpray a
forall a. (C a, Eq a) => [(Partition, a)] -> Spray a
fromList
([Partition] -> [RatioOfSprays a] -> [(Partition, RatioOfSprays a)]
forall a b. [a] -> [b] -> [(a, b)]
zip
(Partition -> [Partition]
forall a. (Eq a, Ord a) => [a] -> [[a]]
permuteMultiset (Partition
kappa Partition -> Partition -> Partition
forall a. [a] -> [a] -> [a]
++ Int -> Int -> Partition
forall a. Int -> a -> [a]
replicate (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l) Int
0))
(RatioOfSprays a -> [RatioOfSprays a]
forall a. a -> [a]
repeat RatioOfSprays a
rOS))
) (Map Partition (Int, RatioOfSprays a)
-> [(Partition, (Int, RatioOfSprays a))]
forall k a. Map k a -> [(k, a)]
DM.assocs Map Partition (Int, RatioOfSprays a)
msCombo)
skewJackSymbolicPol' ::
Int
-> Partition
-> Partition
-> Char
-> ParametricQSpray
skewJackSymbolicPol' :: Int -> Partition -> Partition -> Char -> ParametricQSpray
skewJackSymbolicPol' = Int -> Partition -> Partition -> Char -> ParametricQSpray
forall a.
(Eq a, C a) =>
Int -> Partition -> Partition -> Char -> ParametricSpray a
skewJackSymbolicPol