{-# 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, one )
import Algebra.ToInteger ( fromIntegral )
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 ( _betaRatioOfPolynomials
, jackSymbolicCoeffC
, jackSymbolicCoeffPinv
, jackSymbolicCoeffQinv
, _N, _isPartition, Partition )
import Math.Algebra.Hspray ( (*^), (^**^), (^*^), (^+^)
, lone, SymbolicSpray, SymbolicQSpray
, Polynomial, outerVariable
, constPoly, RatioOfPolynomials
, zeroSpray, unitSpray )
import Number.Ratio ( fromValue, recip )
jackSymbolicPol'
:: Int
-> Partition
-> Char
-> SymbolicQSpray
jackSymbolicPol' :: Int -> Partition -> Char -> SymbolicQSpray
jackSymbolicPol' = Int -> Partition -> Char -> SymbolicQSpray
forall a.
(Eq a, C a) =>
Int -> Partition -> Char -> SymbolicSpray a
jackSymbolicPol
jackSymbolicPol :: forall a. (Eq a, AlgField.C a)
=> Int
-> Partition
-> Char
-> SymbolicSpray a
jackSymbolicPol :: forall a.
(Eq a, C a) =>
Int -> Partition -> Char -> SymbolicSpray a
jackSymbolicPol Int
n Partition
lambda Char
which =
case Partition -> Bool
_isPartition Partition
lambda of
Bool
False -> [Char] -> SymbolicSpray a
forall a. HasCallStack => [Char] -> a
error [Char]
"jackSymbolicPol: invalid integer partition"
Bool
True -> case Char
which of
Char
'J' -> SymbolicSpray a
resultJ
Char
'C' -> Partition -> RatioOfPolynomials a
forall a. C a => Partition -> RatioOfPolynomials a
jackSymbolicCoeffC Partition
lambda RatioOfPolynomials a -> SymbolicSpray a -> SymbolicSpray a
forall a. (C a, Eq a) => a -> Spray a -> Spray a
*^ SymbolicSpray a
resultJ
Char
'P' -> RatioOfPolynomials a -> RatioOfPolynomials a
forall a. (C a, C a) => T a -> T a
recip (Polynomial a -> RatioOfPolynomials a
forall a. C a => a -> T a
fromValue (Partition -> Polynomial a
forall a. C a => Partition -> Polynomial a
jackSymbolicCoeffPinv Partition
lambda)) RatioOfPolynomials a -> SymbolicSpray a -> SymbolicSpray a
forall a. (C a, Eq a) => a -> Spray a -> Spray a
*^ SymbolicSpray a
resultJ
Char
'Q' -> RatioOfPolynomials a -> RatioOfPolynomials a
forall a. (C a, C a) => T a -> T a
recip (Polynomial a -> RatioOfPolynomials a
forall a. C a => a -> T a
fromValue (Partition -> Polynomial a
forall a. C a => Partition -> Polynomial a
jackSymbolicCoeffQinv Partition
lambda)) RatioOfPolynomials a -> SymbolicSpray a -> SymbolicSpray a
forall a. (C a, Eq a) => a -> Spray a -> Spray a
*^ SymbolicSpray a
resultJ
Char
_ -> [Char] -> SymbolicSpray a
forall a. HasCallStack => [Char] -> a
error [Char]
"jackSymbolicPol: please use 'J', 'C', 'P' or 'Q' for last argument"
where
alpha :: Polynomial a
alpha = Polynomial a
forall a. C a => Polynomial a
outerVariable :: Polynomial a
resultJ :: SymbolicSpray a
resultJ = Int
-> Int
-> Partition
-> Partition
-> Array (Int, Int) (Maybe (SymbolicSpray a))
-> RatioOfPolynomials a
-> SymbolicSpray a
jac ([SymbolicSpray a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [SymbolicSpray a]
x) Int
0 Partition
lambda Partition
lambda Array (Int, Int) (Maybe (SymbolicSpray a))
forall {a}. Array (Int, Int) (Maybe a)
arr0 RatioOfPolynomials a
forall a. C a => a
one
nll :: Int
nll = Partition -> Partition -> Int
_N Partition
lambda Partition
lambda
x :: [SymbolicSpray a]
x = (Int -> SymbolicSpray a) -> Partition -> [SymbolicSpray a]
forall a b. (a -> b) -> [a] -> [b]
map Int -> SymbolicSpray a
forall a. C a => Int -> Spray a
lone [Int
1 .. Int
n] :: [SymbolicSpray a]
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. C a => a -> a -> a
* Int
n) Maybe a
forall a. Maybe a
Nothing)
theproduct :: Int -> RatioOfPolynomials a
theproduct :: Int -> RatioOfPolynomials a
theproduct Int
nu0 = if Int
nu0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
1
then Polynomial a -> RatioOfPolynomials a
forall a. C a => a -> T a
fromValue (a -> Polynomial a
forall a. a -> Polynomial a
constPoly a
forall a. C a => a
one)
else Polynomial a -> RatioOfPolynomials a
forall a. C a => a -> T a
fromValue (Polynomial a -> RatioOfPolynomials a)
-> Polynomial a -> RatioOfPolynomials a
forall a b. (a -> b) -> a -> b
$ [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
$ (Int -> Polynomial a) -> Partition -> [Polynomial a]
forall a b. (a -> b) -> [a] -> [b]
map
(\Int
i -> a -> Polynomial a
forall a. a -> Polynomial a
constPoly (Int -> a
forall a b. (C a, C b) => a -> b
fromIntegral Int
i) Polynomial a -> Polynomial a -> Polynomial a
forall a. C a => a -> a -> a
* Polynomial a
alpha 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)
[Int
1 .. Int
nu0Int -> Int -> Int
forall a. C a => a -> a -> a
-Int
1]
jac :: Int -> Int -> Partition -> Partition
-> Array (Int,Int) (Maybe (SymbolicSpray a)) -> RatioOfPolynomials a -> SymbolicSpray a
jac :: Int
-> Int
-> Partition
-> Partition
-> Array (Int, Int) (Maybe (SymbolicSpray a))
-> RatioOfPolynomials a
-> SymbolicSpray a
jac Int
m Int
k Partition
mu Partition
nu Array (Int, Int) (Maybe (SymbolicSpray a))
arr RatioOfPolynomials a
beta
| Partition -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Partition
nu Bool -> Bool -> Bool
|| Partition
nuPartition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!!Int
0 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 = SymbolicSpray a
forall a. C a => Spray a
unitSpray
| Partition -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Partition
nu Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
m Bool -> Bool -> Bool
&& Partition
nuPartition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!!Int
m Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = SymbolicSpray a
forall a. (Eq a, C a) => Spray a
zeroSpray
| Int
m Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = Int -> RatioOfPolynomials a
theproduct (Partition
nuPartition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!!Int
0) RatioOfPolynomials a -> SymbolicSpray a -> SymbolicSpray a
forall a. (C a, Eq a) => a -> Spray a -> Spray a
*^ ([SymbolicSpray a]
x[SymbolicSpray a] -> Int -> SymbolicSpray a
forall a. HasCallStack => [a] -> Int -> a
!!Int
0 SymbolicSpray a -> Int -> SymbolicSpray a
forall a. (C a, Eq a) => Spray a -> Int -> Spray a
^**^ Partition
nuPartition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!!Int
0)
| Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
&& Maybe (SymbolicSpray a) -> Bool
forall a. Maybe a -> Bool
isJust (Array (Int, Int) (Maybe (SymbolicSpray a))
arr Array (Int, Int) (Maybe (SymbolicSpray a))
-> (Int, Int) -> Maybe (SymbolicSpray a)
forall i e. Ix i => Array i e -> i -> e
! (Partition -> Partition -> Int
_N Partition
lambda Partition
nu, Int
m)) =
Maybe (SymbolicSpray a) -> SymbolicSpray a
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (SymbolicSpray a) -> SymbolicSpray a)
-> Maybe (SymbolicSpray a) -> SymbolicSpray a
forall a b. (a -> b) -> a -> b
$ Array (Int, Int) (Maybe (SymbolicSpray a))
arr Array (Int, Int) (Maybe (SymbolicSpray a))
-> (Int, Int) -> Maybe (SymbolicSpray a)
forall i e. Ix i => Array i e -> i -> e
! (Partition -> Partition -> Int
_N Partition
lambda Partition
nu, Int
m)
| Bool
otherwise = SymbolicSpray a
s
where
s :: SymbolicSpray a
s = SymbolicSpray a -> Int -> SymbolicSpray a
go (RatioOfPolynomials a
beta RatioOfPolynomials a -> SymbolicSpray a -> SymbolicSpray a
forall a. (C a, Eq a) => a -> Spray a -> Spray a
*^ (Int
-> Int
-> Partition
-> Partition
-> Array (Int, Int) (Maybe (SymbolicSpray a))
-> RatioOfPolynomials a
-> SymbolicSpray a
jac (Int
mInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) Int
0 Partition
nu Partition
nu Array (Int, Int) (Maybe (SymbolicSpray a))
arr RatioOfPolynomials a
forall a. C a => a
one SymbolicSpray a -> SymbolicSpray a -> SymbolicSpray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^*^ (([SymbolicSpray a]
x[SymbolicSpray a] -> Int -> SymbolicSpray a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
mInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1)) SymbolicSpray a -> Int -> SymbolicSpray a
forall a. (C a, Eq a) => Spray a -> Int -> Spray a
^**^ (Partition -> Int
forall a. C a => [a] -> a
sum Partition
mu Int -> Int -> Int
forall a. C a => a -> a -> a
- Partition -> Int
forall a. C a => [a] -> a
sum Partition
nu))))
(Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
k)
go :: SymbolicSpray a -> Int -> SymbolicSpray a
go :: SymbolicSpray a -> Int -> SymbolicSpray a
go !SymbolicSpray a
ss Int
ii
| Partition -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Partition
nu Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
ii Bool -> Bool -> Bool
|| Partition
nuPartition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!!(Int
iiInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = SymbolicSpray a
ss
| Bool
otherwise =
let u :: Int
u = Partition
nuPartition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!!(Int
iiInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) in
if Partition -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Partition
nu 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
nuPartition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!!Int
ii
then
let nu' :: Partition
nu' = (Int -> IndexedTraversal' Int Partition Int
forall (t :: * -> *) a.
Traversable t =>
Int -> IndexedTraversal' Int (t a) a
element (Int
iiInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) ((Int -> Identity Int) -> Partition -> Identity Partition)
-> Int -> Partition -> Partition
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Int
uInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) Partition
nu in
let gamma :: RatioOfPolynomials a
gamma = Partition -> Partition -> Int -> RatioOfPolynomials a
forall a.
C a =>
Partition -> Partition -> Int -> RatioOfPolynomials a
_betaRatioOfPolynomials Partition
mu Partition
nu Int
ii RatioOfPolynomials a
-> RatioOfPolynomials a -> RatioOfPolynomials a
forall a. C a => a -> a -> a
* RatioOfPolynomials a
beta in
if Int
u Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1
then
SymbolicSpray a -> Int -> SymbolicSpray a
go (SymbolicSpray a
ss SymbolicSpray a -> SymbolicSpray a -> SymbolicSpray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^+^ Int
-> Int
-> Partition
-> Partition
-> Array (Int, Int) (Maybe (SymbolicSpray a))
-> RatioOfPolynomials a
-> SymbolicSpray a
jac Int
m Int
ii Partition
mu Partition
nu' Array (Int, Int) (Maybe (SymbolicSpray a))
arr RatioOfPolynomials a
gamma) (Int
ii Int -> Int -> Int
forall a. C a => a -> a -> a
+ Int
1)
else
if 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
then
SymbolicSpray a -> Int -> SymbolicSpray a
go (SymbolicSpray a
ss SymbolicSpray a -> SymbolicSpray a -> SymbolicSpray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^+^ (RatioOfPolynomials a
gamma RatioOfPolynomials a -> SymbolicSpray a -> SymbolicSpray a
forall a. (C a, Eq a) => a -> Spray a -> Spray a
*^ ([SymbolicSpray a]
x[SymbolicSpray a] -> Int -> SymbolicSpray a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
mInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) SymbolicSpray a -> Int -> SymbolicSpray a
forall a. (C a, Eq a) => Spray a -> Int -> Spray a
^**^ Partition -> Int
forall a. C a => [a] -> a
sum Partition
mu))) (Int
ii Int -> Int -> Int
forall a. C a => a -> a -> a
+ Int
1)
else
let arr' :: Array (Int, Int) (Maybe (SymbolicSpray a))
arr' = Array (Int, Int) (Maybe (SymbolicSpray a))
arr Array (Int, Int) (Maybe (SymbolicSpray a))
-> [((Int, Int), Maybe (SymbolicSpray a))]
-> Array (Int, Int) (Maybe (SymbolicSpray a))
forall i e. Ix i => Array i e -> [(i, e)] -> Array i e
// [((Partition -> Partition -> Int
_N Partition
lambda Partition
nu, Int
m), SymbolicSpray a -> Maybe (SymbolicSpray a)
forall a. a -> Maybe a
Just SymbolicSpray a
ss)] in
let jck :: SymbolicSpray a
jck = Int
-> Int
-> Partition
-> Partition
-> Array (Int, Int) (Maybe (SymbolicSpray a))
-> RatioOfPolynomials a
-> SymbolicSpray a
jac (Int
mInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) Int
0 Partition
nu' Partition
nu' Array (Int, Int) (Maybe (SymbolicSpray a))
arr' RatioOfPolynomials a
forall a. C a => a
one in
let jck' :: SymbolicSpray a
jck' = RatioOfPolynomials a
gamma RatioOfPolynomials a -> SymbolicSpray a -> SymbolicSpray a
forall a. (C a, Eq a) => a -> Spray a -> Spray a
*^ (SymbolicSpray a
jck SymbolicSpray a -> SymbolicSpray a -> SymbolicSpray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^*^
([SymbolicSpray a]
x[SymbolicSpray a] -> Int -> SymbolicSpray a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
mInt -> Int -> Int
forall a. C a => a -> a -> a
-Int
1) SymbolicSpray a -> Int -> SymbolicSpray a
forall a. (C a, Eq a) => Spray a -> Int -> Spray a
^**^ (Partition -> Int
forall a. C a => [a] -> a
sum Partition
mu Int -> Int -> Int
forall a. C a => a -> a -> a
- Partition -> Int
forall a. C a => [a] -> a
sum Partition
nu'))) in
SymbolicSpray a -> Int -> SymbolicSpray a
go (SymbolicSpray a
ss SymbolicSpray a -> SymbolicSpray a -> SymbolicSpray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^+^ SymbolicSpray a
jck') (Int
ii Int -> Int -> Int
forall a. C a => a -> a -> a
+ Int
1)
else
SymbolicSpray a -> Int -> SymbolicSpray a
go SymbolicSpray a
ss (Int
ii Int -> Int -> Int
forall a. C a => a -> a -> a
+ Int
1)