Last active
February 29, 2024 02:27
-
-
Save stla/f0aca12a91fe61dde05138165800d53b to your computer and use it in GitHub Desktop.
Littlewood-Richardson rule for skew Schur
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
insertWith <- function(f, mp, key, value) { | |
if(key %in% names(mp)) { | |
mp[[key]] <- f(value, mp[[key]]) | |
} else { | |
mp[[key]] <- value | |
} | |
mp | |
} | |
zip3 <- function(v1, v2, v3) { | |
lapply(1L:length(v1), function(i) { | |
c(v1[i], v2[i], v3[i]) | |
}) | |
} | |
# _lrRule :: Partition -> Partition -> Map Partition Int | |
# _lrRule plam@(Partition lam) pmu@(Partition mu0) = | |
# if not (pmu `isSubPartitionOf` plam) | |
# then Map.empty | |
# else foldl' f Map.empty [ nu | (nu,_) <- fillings n diagram ] | |
# where | |
# f old nu = Map.insertWith (+) (Partition nu) 1 old | |
# diagram = [ (i,j) | (i,a,b) <- reverse (zip3 [1..] lam mu) , j <- [b+1..a] ] | |
# mu = mu0 ++ repeat 0 | |
# n = sum' $ zipWith (-) lam mu | |
lrRule <- function(lambda, mu) { | |
f <- function(old, nu) { | |
insertWith(`+`, old, toString(nu), 1L) | |
} | |
l <- length(lambda) | |
mu <- c(mu, rep(0L, l - length(mu))) | |
Liab <- rev(zip3(seq_len(l), lambda, mu)) | |
diagram <- do.call(rbind, do.call(c, lapply(Liab, function(iab) { | |
i <- iab[1L] | |
a <- iab[2L] | |
b <- iab[3L] | |
jvec <- if(b + 1L <= a) (b + 1L):a else integer(0L) | |
lapply(jvec, function(j) { | |
c(i, j) | |
}) | |
}))) | |
n <- sum(lambda - mu) | |
Lnu <- lapply(fillings(n, diagram), `[[`, 1L) | |
Reduce(f, Lnu, init = integer(0L)) | |
} | |
# fillings :: Int -> Diagram -> [Filling] | |
# fillings _ [] = [ ([],[]) ] | |
# fillings n diagram@((x,y):rest) = concatMap (nextLetter lower upper) (fillings (n-1) rest) where | |
# upper = case findIndex (==(x ,y+1)) diagram of { Just j -> n-j ; Nothing -> 0 } | |
# lower = case findIndex (==(x-1,y )) diagram of { Just j -> n-j ; Nothing -> 0 } | |
fillings <- function(n, diagram) { | |
if(nrow(diagram) == 0L) { | |
list(list(integer(0L), integer(0L))) | |
} else { | |
xy <- diagram[1L, ] | |
x <- xy[1L] | |
y <- xy[2L] | |
rest <- diagram[-1L, , drop = FALSE] | |
diagram <- apply(diagram, 1L, toString) | |
upper <- n - (match(toString(c(x, y + 1L)), diagram, nomatch = n + 1L) - 1L) | |
lower <- n - (match(toString(c(x - 1L, y)), diagram, nomatch = n + 1L) - 1L) | |
L <- lapply(fillings(n - 1L, rest), function(filling) { | |
nextLetter(lower, upper, filling) | |
}) | |
do.call(c, L) | |
} | |
} | |
# nextLetter :: Int -> Int -> Filling -> [Filling] | |
# nextLetter lower upper (nu,lpart) = stuff where | |
# stuff = [ ( incr i shape , lpart++[i] ) | i<-nlist ] | |
# shape = nu ++ [0] | |
# lb = if lower>0 | |
# then lpart !! (lower-1) | |
# else 0 | |
# ub = if upper>0 | |
# then min (length shape) (lpart !! (upper-1)) | |
# else length shape | |
# | |
# nlist = filter (>0) $ map f [lb+1..ub] | |
# f j = if j==1 || shape!!(j-2) > shape!!(j-1) then j else 0 | |
nextLetter <- function(lower, upper, filling) { | |
nu <- filling[[1L]] | |
lpart <- filling[[2L]] | |
shape <- c(nu, 0L) | |
lb <- if(lower > 0L) lpart[lower] else 0L | |
ub <- if(upper > 0L) min(length(shape), lpart[upper]) else length(shape) | |
f <- function(j) { | |
if(j == 1L || shape[j-1L] > shape[j]) j else 0L | |
} | |
v <- vapply((lb+1L):ub, f, integer(1L)) | |
nlist <- v[v > 0L] | |
lapply(nlist, function(i) { | |
list(incr(i, shape), c(lpart, i)) | |
}) | |
} | |
# incr :: Int -> [Int] -> [Int] | |
# incr i (x:xs) = case i of | |
# 0 -> finish (x:xs) | |
# 1 -> (x+1) : finish xs | |
# _ -> x : incr (i-1) xs | |
# incr _ [] = [] | |
incr <- function(i, xxs) { | |
if(length(xxs) == 0L) { | |
integer(0L) | |
} else { | |
if(i == 0L) { | |
finish(xxs) | |
} else if(i == 1L) { | |
c(xxs[1L] + 1L, finish(xxs[-1L])) | |
} else { | |
c(xxs[1L], incr(i - 1L, xxs[-1L])) | |
} | |
} | |
} | |
# finish :: [Int] -> [Int] | |
# finish (x:xs) = if x>0 then x : finish xs else [] | |
# finish [] = [] | |
finish <- function(xxs) { | |
if(length(xxs) == 0L) { | |
integer(0L) | |
} else { | |
x <- xxs[1L] | |
if(x > 0L) { | |
c(x, finish(xxs[-1L])) | |
} else { | |
integer(0L) | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment