jackpolynomials-1.4.0.0: src/Math/Algebra/JackSymbolicPol.hs
{-|
Module : Math.Algebra.JackSymbolicPol
Description : Jack polynomials with symbolic Jack parameter.
Copyright : (c) Stéphane Laurent, 2024
License : GPL-3
Maintainer : laurent_step@outlook.fr
Computation of Jack polynomials with a symbolic Jack parameter.
See README for examples and references.
-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Math.Algebra.JackSymbolicPol
( jackSymbolicPol, jackSymbolicPol' )
where
import Prelude
hiding ((*), (+), (-), (/), (^), (*>), product, sum, fromIntegral, fromInteger, recip)
import Algebra.Additive ( (+), (-), sum )
import Algebra.Ring ( (*), product )
import Algebra.Field ( recip )
import qualified Algebra.Field as AlgField
import Control.Lens ( (.~), element )
import Data.Array ( Array, (!), (//), listArray )
import Data.Maybe ( fromJust, isJust )
import Math.Algebra.Jack.Internal ( _betaRatioOfSprays
, jackSymbolicCoeffC
, jackSymbolicCoeffPinv
, jackSymbolicCoeffQinv
, _N, _isPartition, Partition )
import Math.Algebra.Hspray ( FunctionLike (..), (.^)
, lone, lone'
, ParametricSpray, ParametricQSpray
, Spray, asRatioOfSprays
, RatioOfSprays, unitRatioOfSprays
, zeroSpray, unitSpray )
-- | Jack polynomial with symbolic Jack parameter
jackSymbolicPol'
:: Int -- ^ number of variables
-> Partition -- ^ partition of integers
-> Char -- ^ which Jack polynomial, @'J'@, @'C'@, @'P'@ or @'Q'@
-> ParametricQSpray
jackSymbolicPol' = jackSymbolicPol
-- | Jack polynomial with symbolic Jack parameter
jackSymbolicPol :: forall a. (Eq a, AlgField.C a)
=> Int -- ^ number of variables
-> Partition -- ^ partition of integers
-> Char -- ^ which Jack polynomial, @'J'@, @'C'@, @'P'@ or @'Q'@
-> ParametricSpray a
jackSymbolicPol n lambda which =
case _isPartition lambda of
False -> error "jackSymbolicPol: invalid integer partition"
True -> case which of
'J' -> resultJ
'C' -> jackSymbolicCoeffC lambda *^ resultJ
'P' -> recip (asRatioOfSprays (jackSymbolicCoeffPinv lambda)) *^ resultJ
'Q' -> recip (asRatioOfSprays (jackSymbolicCoeffQinv lambda)) *^ resultJ
_ -> error
"jackSymbolicPol: please use 'J', 'C', 'P' or 'Q' for last argument"
where
alpha = lone 1 :: Spray a
resultJ = jac n 0 lambda lambda arr0 unitRatioOfSprays
nll = _N lambda lambda
-- x = map lone [1 .. n] :: [ParametricSpray a]
arr0 = listArray ((1, 1), (nll, n)) (replicate (nll * n) Nothing)
theproduct :: Int -> RatioOfSprays a
theproduct nu0 = if nu0 <= 1
then unitRatioOfSprays
else asRatioOfSprays $ product $ map
(\i -> i .^ alpha ^+^ unitSpray)
[1 .. nu0-1]
jac :: Int -> Int -> Partition -> Partition
-> Array (Int,Int) (Maybe (ParametricSpray a))
-> RatioOfSprays a -> ParametricSpray a
jac m k mu nu arr beta
| null nu || nu !! 0 == 0 || m == 0 = unitSpray
| length nu > m && nu !! m > 0 = zeroSpray
| m == 1 =
theproduct (nu !! 0) *^ (lone' 1 (nu !! 0))
| k == 0 && isJust (arr ! (_N lambda nu, m)) =
fromJust $ arr ! (_N lambda nu, m)
| otherwise = s
where
s = go (beta *^ (jac (m-1) 0 nu nu arr unitRatioOfSprays ^*^
(lone' m (sum mu - sum nu)))) (max 1 k)
go :: ParametricSpray a -> Int -> ParametricSpray a
go !ss ii
| length nu < ii || nu!!(ii-1) == 0 = ss
| otherwise =
let u = nu!!(ii-1) in
if length nu == ii && u > 0 || u > nu !! ii
then
let nu' = (element (ii-1) .~ u-1) nu in
let gamma = _betaRatioOfSprays mu nu ii * beta in
if u > 1
then
go (ss ^+^ jac m ii mu nu' arr gamma) (ii + 1)
else
if nu' !! 0 == 0
then
go (ss ^+^ (gamma *^ (lone' m (sum mu))))
(ii + 1)
else
let arr' = arr // [((_N lambda nu, m), Just ss)] in
let jck =
jac (m-1) 0 nu' nu' arr' unitRatioOfSprays in
let jck' = gamma *^ (jck ^*^
(lone' m (sum mu - sum nu'))) in
go (ss ^+^ jck') (ii + 1)
else
go ss (ii + 1)