{-|
Module      : Math.Algebra.JackPol
Description : Symbolic Jack polynomials.
Copyright   : (c) Stéphane Laurent, 2024
License     : GPL-3
Maintainer  : laurent_step@outlook.fr

Computation of symbolic Jack polynomials, zonal polynomials, and Schur polynomials. 
See README for examples and references.
-}

{-# LANGUAGE BangPatterns        #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Math.Algebra.JackPol
  (jackPol, zonalPol, schurPol)
  where
import qualified Algebra.Ring               as AR
import           Control.Lens               ( (.~), element )
import           Data.Array                 ( Array, (!), (//), listArray )
import           Data.Maybe                 ( fromJust, isJust )
import           Math.Algebra.Jack.Internal ( _betaratio, hookLengths, _N
                                            , _isPartition, Partition )
import           Math.Algebra.Hspray        ( (*^), (^**^), (^*^), (^+^)
                                            , lone, Spray
                                            , zeroSpray, unitSpray )
import           Numeric.SpecFunctions      ( factorial )

-- | Symbolic Jack polynomial

jackPol :: forall a. (Fractional a, Ord a, AR.C a) 
  => Int       -- ^ number of variables

  -> Partition -- ^ partition of integers

  -> a         -- ^ alpha parameter

  -> Spray a
jackPol :: forall a.
(Fractional a, Ord a, C a) =>
Int -> Partition -> a -> Spray a
jackPol Int
n Partition
lambda a
alpha =
  case Partition -> Bool
_isPartition Partition
lambda Bool -> Bool -> Bool
&& a
alpha a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
0 of
    Bool
False -> if Partition -> Bool
_isPartition Partition
lambda
      then [Char] -> Spray a
forall a. HasCallStack => [Char] -> a
error [Char]
"jackPol: alpha must be strictly positive"
      else [Char] -> Spray a
forall a. HasCallStack => [Char] -> a
error [Char]
"jackPol: invalid integer partition"
    Bool
True -> Int
-> Int
-> Partition
-> Partition
-> Array (Int, Int) (Maybe (Spray a))
-> a
-> Spray a
jac ([Spray a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Spray a]
x) Int
0 Partition
lambda Partition
lambda Array (Int, Int) (Maybe (Spray a))
forall {a}. Array (Int, Int) (Maybe a)
arr0 a
1
      where
      nll :: Int
nll = Partition -> Partition -> Int
_N Partition
lambda Partition
lambda
      x :: [Spray a]
x = (Int -> Spray a) -> Partition -> [Spray a]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Spray a
forall a. C a => Int -> Spray a
lone [Int
1 .. Int
n] :: [Spray 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. Num a => a -> a -> a
* Int
n) Maybe a
forall a. Maybe a
Nothing)
      theproduct :: Int -> a
      theproduct :: Int -> a
theproduct Int
nu0 = if Int
nu0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
1
        then a
1
        else [a] -> a
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product ([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$ (Int -> a) -> Partition -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (\Int
i -> a
alpha a -> a -> a
forall a. Num a => a -> a -> a
* Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i a -> a -> a
forall a. Num a => a -> a -> a
+ a
1) [Int
1 .. Int
nu0Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1]
      jac :: Int -> Int -> Partition -> Partition -> Array (Int,Int) (Maybe (Spray a)) -> a -> Spray a
      jac :: Int
-> Int
-> Partition
-> Partition
-> Array (Int, Int) (Maybe (Spray a))
-> a
-> Spray a
jac Int
m Int
k Partition
mu Partition
nu Array (Int, Int) (Maybe (Spray a))
arr 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 = Spray 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 = Spray 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 -> a
theproduct (Partition
nuPartition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!!Int
0) a -> Spray a -> Spray a
forall a. (C a, Eq a) => a -> Spray a -> Spray a
*^ ([Spray a]
x[Spray a] -> Int -> Spray a
forall a. HasCallStack => [a] -> Int -> a
!!Int
0 Spray a -> Int -> Spray 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 (Spray a) -> Bool
forall a. Maybe a -> Bool
isJust (Array (Int, Int) (Maybe (Spray a))
arr Array (Int, Int) (Maybe (Spray a)) -> (Int, Int) -> Maybe (Spray a)
forall i e. Ix i => Array i e -> i -> e
! (Partition -> Partition -> Int
_N Partition
lambda Partition
nu, Int
m)) =
                      Maybe (Spray a) -> Spray a
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (Spray a) -> Spray a) -> Maybe (Spray a) -> Spray a
forall a b. (a -> b) -> a -> b
$ Array (Int, Int) (Maybe (Spray a))
arr Array (Int, Int) (Maybe (Spray a)) -> (Int, Int) -> Maybe (Spray a)
forall i e. Ix i => Array i e -> i -> e
! (Partition -> Partition -> Int
_N Partition
lambda Partition
nu, Int
m)
        | Bool
otherwise = Spray a
s
          where
            s :: Spray a
s = Spray a -> Int -> Spray a
go (a
beta a -> Spray a -> Spray a
forall a. (C a, Eq a) => a -> Spray a -> Spray a
*^ (Int
-> Int
-> Partition
-> Partition
-> Array (Int, Int) (Maybe (Spray a))
-> a
-> Spray a
jac (Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
0 Partition
nu Partition
nu Array (Int, Int) (Maybe (Spray a))
arr a
1 Spray a -> Spray a -> Spray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^*^ (([Spray a]
x[Spray a] -> Int -> Spray a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)) Spray a -> Int -> Spray a
forall a. (C a, Eq a) => Spray a -> Int -> Spray a
^**^ (Partition -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum Partition
mu 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
nu))))
                (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
k)
            go :: Spray a -> Int -> Spray a
            go :: Spray a -> Int -> Spray a
go !Spray 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. Num a => a -> a -> a
-Int
1) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Spray a
ss
              | Bool
otherwise =
                let u :: Int
u = Partition
nuPartition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!!(Int
iiInt -> Int -> Int
forall a. Num 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. Num 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. Num a => a -> a -> a
-Int
1) Partition
nu in
                    let gamma :: a
gamma = a
beta a -> a -> a
forall a. Num a => a -> a -> a
* Partition -> Partition -> Int -> a -> a
forall a. Fractional a => Partition -> Partition -> Int -> a -> a
_betaratio Partition
mu Partition
nu Int
ii a
alpha in
                    if Int
u Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1
                      then
                        Spray a -> Int -> Spray a
go (Spray a
ss Spray a -> Spray a -> Spray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^+^ Int
-> Int
-> Partition
-> Partition
-> Array (Int, Int) (Maybe (Spray a))
-> a
-> Spray a
jac Int
m Int
ii Partition
mu Partition
nu' Array (Int, Int) (Maybe (Spray a))
arr a
gamma) (Int
ii Int -> Int -> Int
forall a. Num 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
                            Spray a -> Int -> Spray a
go (Spray a
ss Spray a -> Spray a -> Spray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^+^ (a
gamma a -> Spray a -> Spray a
forall a. (C a, Eq a) => a -> Spray a -> Spray a
*^ ([Spray a]
x[Spray a] -> Int -> Spray a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Spray a -> Int -> Spray a
forall a. (C a, Eq a) => Spray a -> Int -> Spray a
^**^ Partition -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum Partition
mu))) (Int
ii Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
                          else
                            let arr' :: Array (Int, Int) (Maybe (Spray a))
arr' = Array (Int, Int) (Maybe (Spray a))
arr Array (Int, Int) (Maybe (Spray a))
-> [((Int, Int), Maybe (Spray a))]
-> Array (Int, Int) (Maybe (Spray a))
forall i e. Ix i => Array i e -> [(i, e)] -> Array i e
// [((Partition -> Partition -> Int
_N Partition
lambda Partition
nu, Int
m), Spray a -> Maybe (Spray a)
forall a. a -> Maybe a
Just Spray a
ss)] in
                            let jck :: Spray a
jck = Int
-> Int
-> Partition
-> Partition
-> Array (Int, Int) (Maybe (Spray a))
-> a
-> Spray a
jac (Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
0 Partition
nu' Partition
nu' Array (Int, Int) (Maybe (Spray a))
arr' a
1 in
                            let jck' :: Spray a
jck' = a
gamma a -> Spray a -> Spray a
forall a. (C a, Eq a) => a -> Spray a -> Spray a
*^ (Spray a
jck Spray a -> Spray a -> Spray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^*^ 
                                        ([Spray a]
x[Spray a] -> Int -> Spray a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Spray a -> Int -> Spray a
forall a. (C a, Eq a) => Spray a -> Int -> Spray a
^**^ (Partition -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum Partition
mu 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
nu'))) in
                            Spray a -> Int -> Spray a
go (Spray a
ss Spray a -> Spray a -> Spray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^+^ Spray a
jck') (Int
iiInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
                  else
                    Spray a -> Int -> Spray a
go Spray a
ss (Int
iiInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)

-- | Symbolic zonal polynomial

zonalPol :: (Fractional a, Ord a, AR.C a) 
  => Int       -- ^ number of variables

  -> Partition -- ^ partition of integers

  -> Spray a
zonalPol :: forall a. (Fractional a, Ord a, C a) => Int -> Partition -> Spray a
zonalPol Int
n Partition
lambda = a
c a -> Spray a -> Spray a
forall a. (C a, Eq a) => a -> Spray a -> Spray a
*^ Spray a
jck
  where
    k :: Int
k = Partition -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum Partition
lambda
    jlambda :: a
jlambda = [a] -> a
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product (Partition -> a -> [a]
forall a. Fractional a => Partition -> a -> [a]
hookLengths Partition
lambda a
2)
    c :: a
c = a
2a -> Int -> a
forall a b. (Num a, Integral b) => a -> b -> a
^Int
k a -> a -> a
forall a. Num a => a -> a -> a
* Double -> a
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Int -> Double
factorial Int
k) a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
jlambda
    jck :: Spray a
jck = Int -> Partition -> a -> Spray a
forall a.
(Fractional a, Ord a, C a) =>
Int -> Partition -> a -> Spray a
jackPol Int
n Partition
lambda a
2

-- | Symbolic Schur polynomial

schurPol :: forall a. (Ord a, AR.C a)
  => Int       -- ^ number of variables

  -> Partition -- ^ partition of integers

  -> Spray a
schurPol :: forall a. (Ord a, C a) => Int -> Partition -> Spray a
schurPol Int
n Partition
lambda =
  case Partition -> Bool
_isPartition Partition
lambda of
    Bool
False -> [Char] -> Spray a
forall a. HasCallStack => [Char] -> a
error [Char]
"schurPol: invalid integer partition"
    Bool
True -> Int
-> Int
-> Partition
-> Array (Int, Int) (Maybe (Spray a))
-> Spray a
sch Int
n Int
1 Partition
lambda Array (Int, Int) (Maybe (Spray a))
forall {a}. Array (Int, Int) (Maybe a)
arr0
      where
        x :: [Spray a]
x = (Int -> Spray a) -> Partition -> [Spray a]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Spray a
forall a. C a => Int -> Spray a
lone [Int
1 .. Int
n] :: [Spray a]
        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)
        sch :: Int -> Int -> [Int] -> Array (Int,Int) (Maybe (Spray a)) -> Spray a
        sch :: Int
-> Int
-> Partition
-> Array (Int, Int) (Maybe (Spray a))
-> Spray a
sch Int
m Int
k Partition
nu Array (Int, Int) (Maybe (Spray a))
arr
          | 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 = Spray 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 = Spray a
forall a. (Eq a, C a) => Spray a
zeroSpray
          | Int
m Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = [Spray a]
x[Spray a] -> Int -> Spray a
forall a. HasCallStack => [a] -> Int -> a
!!Int
0 Spray a -> Int -> Spray a
forall a. (C a, Eq a) => Spray a -> Int -> Spray a
^**^ Partition
nuPartition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!!Int
0
          | Maybe (Spray a) -> Bool
forall a. Maybe a -> Bool
isJust (Array (Int, Int) (Maybe (Spray a))
arr Array (Int, Int) (Maybe (Spray a)) -> (Int, Int) -> Maybe (Spray a)
forall i e. Ix i => Array i e -> i -> e
! (Partition -> Partition -> Int
_N Partition
lambda Partition
nu, Int
m)) = Maybe (Spray a) -> Spray a
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (Spray a) -> Spray a) -> Maybe (Spray a) -> Spray a
forall a b. (a -> b) -> a -> b
$ Array (Int, Int) (Maybe (Spray a))
arr Array (Int, Int) (Maybe (Spray a)) -> (Int, Int) -> Maybe (Spray a)
forall i e. Ix i => Array i e -> i -> e
! (Partition -> Partition -> Int
_N Partition
lambda Partition
nu, Int
m)
          | Bool
otherwise = Spray a
s
            where
              s :: Spray a
s = Spray a -> Int -> Spray a
go (Int
-> Int
-> Partition
-> Array (Int, Int) (Maybe (Spray a))
-> Spray a
sch (Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
1 Partition
nu Array (Int, Int) (Maybe (Spray a))
arr) Int
k
              go :: Spray a -> Int -> Spray a
              go :: Spray a -> Int -> Spray a
go !Spray 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. Num a => a -> a -> a
-Int
1) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Spray a
ss
                | Bool
otherwise =
                  let u :: Int
u = Partition
nuPartition -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!!(Int
iiInt -> Int -> Int
forall a. Num 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
nu Partition -> 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. Num 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. Num a => a -> a -> a
-Int
1) Partition
nu in
                      if Int
u Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1
                        then
                          Spray a -> Int -> Spray a
go (Spray a
ss Spray a -> Spray a -> Spray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^+^ (([Spray a]
x[Spray a] -> Int -> Spray a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)) Spray a -> Spray a -> Spray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^*^ Int
-> Int
-> Partition
-> Array (Int, Int) (Maybe (Spray a))
-> Spray a
sch Int
m Int
ii Partition
nu' Array (Int, Int) (Maybe (Spray a))
arr)) (Int
ii Int -> Int -> Int
forall a. Num 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
                              Spray a -> Int -> Spray a
go (Spray a
ss Spray a -> Spray a -> Spray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^+^ ([Spray a]
x[Spray a] -> Int -> Spray a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1))) (Int
ii Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
                            else
                              let arr' :: Array (Int, Int) (Maybe (Spray a))
arr' = Array (Int, Int) (Maybe (Spray a))
arr Array (Int, Int) (Maybe (Spray a))
-> [((Int, Int), Maybe (Spray a))]
-> Array (Int, Int) (Maybe (Spray a))
forall i e. Ix i => Array i e -> [(i, e)] -> Array i e
// [((Partition -> Partition -> Int
_N Partition
lambda Partition
nu, Int
m), Spray a -> Maybe (Spray a)
forall a. a -> Maybe a
Just Spray a
ss)] in
                              Spray a -> Int -> Spray a
go (Spray a
ss Spray a -> Spray a -> Spray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^+^ (([Spray a]
x[Spray a] -> Int -> Spray a
forall a. HasCallStack => [a] -> Int -> a
!!(Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)) Spray a -> Spray a -> Spray a
forall a. (C a, Eq a) => Spray a -> Spray a -> Spray a
^*^ Int
-> Int
-> Partition
-> Array (Int, Int) (Maybe (Spray a))
-> Spray a
sch (Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
1 Partition
nu' Array (Int, Int) (Maybe (Spray a))
arr')) (Int
ii Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
                    else
                      Spray a -> Int -> Spray a
go Spray a
ss (Int
iiInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)