---*- coding: utf-8 -*-
--------------------------------------------------------------------------------
-- Copyright 2007, 2011 Michael Stillman
--
-- This program is free software: you can redistribute it and/or modify it under
-- the terms of the GNU General Public License as published by the Free Software
-- Foundation, either version 3 of the License, or (at your option) any later
-- version.
--
-- This program is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-- details.
--
-- You should have received a copy of the GNU General Public License along with
-- this program. If not, see .
--------------------------------------------------------------------------------
newPackage(
"SchurRings",
Version => "1.1",
Date => "August 24, 2011",
Authors => {
{Name => "Michael Stillman", Email => "mike@math.cornell.edu", HomePage => "http://www.math.cornell.edu/~mike/"},
{Name => "Hal Schenck"},
{Name => "Claudiu Raicu", Email => "claudiu@math.berkeley.edu", HomePage => "http://math.berkeley.edu/~claudiu/"}
},
Headline => "representation rings of general linear groups and of symmetric groups",
DebuggingMode => true,
AuxiliaryFiles => true
)
export {schurRing, SchurRing, symmRing,
symmetricRingOf, schurRingOf,
toS, toE, toP, toH,
jacobiTrudi, plethysm,
centralizerSize, classFunction, symmetricFunction,
scalarProduct, internalProduct,
SchurRingIndexedVariableTable, EHPVariables, SVariable,
ClassFunction, schurLevel,
schurResolution,
Memoize, Schur, EorH, GroupActing,
eVariable, pVariable, hVariable
}
debug Core
protect symbol symRingForE;
protect symbol mapToE;
protect symbol symRingForP;
protect symbol mapToP;
protect symbol mapFromP;
protect symbol grbE
protect symbol PtoETable
protect symbol HtoETable
protect symbol grbH
protect symbol PtoHTable
protect symbol EtoHTable
protect symbol grbP
protect symbol EtoPTable
protect symbol HtoPTable
--protect symbol plethysmMaps
protect symbol mapFromE
protect symbol sFunction
SchurRing = new Type of EngineRing
SchurRing.synonym = "Schur ring"
ClassFunction = new Type of HashTable
ClassFunction.synonym = "Class function"
expression SchurRing := S -> new FunctionApplication from { schurRing, (expression last S.baseRings, S.Symbol, S.numgens ) }
undocumented (expression, SchurRing)
toExternalString SchurRing := R -> toString expression R
undocumented (toExternalString, SchurRing),
toString SchurRing := R -> (
if hasAttribute(R,ReverseDictionary) then toString getAttribute(R,ReverseDictionary)
else toString expression R)
undocumented (toString, SchurRing)
net SchurRing := R -> (
if hasAttribute(R,ReverseDictionary) then toString getAttribute(R,ReverseDictionary)
else net expression R)
undocumented (net, SchurRing)
rawmonom2partition = (m) -> (
reverse splice apply(rawSparseListFormMonomial m, (x,e) -> e:x)
)
--various ways of addressing elements of a Schur ring
SchurRing _ List := (SR, L) -> new SR from rawSchurFromPartition(raw SR, L)
SchurRing _ Sequence := (SR, L) -> new SR from rawSchurFromPartition(raw SR, L)
SchurRing _ ZZ := (SR, L) -> new SR from rawSchurFromPartition(raw SR, 1:L)
--
coefficientRing SchurRing := Ring => R -> last R.baseRings
numgens SchurRing := Ring => R -> R.numgens
--constructs the symmetric ring of a Schur ring
--if the Schur ring has dimension n, its symmetric ring is the polynomial ring
--in the variables e_1,...,e_n,p_1,...,p_n,h_1,...,h_n, i.e. the other types of
--symmetric functions (besides the Schur functions) that the package implements
symmetricRingOf = method()
symmetricRingOf (Ring) := R -> (
if R.?symmRing then R.symmRing else
if class R === SchurRing then
(
if numgens R === infinity then
error"symmetric ring expects finite schurRings";
if coefficientRing R === ZZ then
error"base ring has to be QQ";
R.symmRing = symmRing(symmetricRingOf coefficientRing R,numgens R,EHPVariables => R.EHPVariables, SVariable => R.Symbol, GroupActing => R.GroupActing);
R.symmRing.Schur = R;
R.symmRing
)
else R
)
--constructs the Schur ring of a symmetric ring R
--this is a ring with basis consisting of s-polynomials (Schur functions) that
--is abstractly isomorphic to R
schurRingOf = method()
schurRingOf (Ring) := R -> (
if R.?Schur then R.Schur else
if schurLevel R > 0 then
(
if instance(R, SchurRing) then R else
(
s := R.SVariable;
if schurLevel R == 1 then R.Schur = schurRing(coefficientRing R,s,R.dim,EHPVariables => R.EHPVariables, GroupActing => R.GroupActing)
else R.Schur = schurRing(schurRingOf coefficientRing R,s,R.dim,EHPVariables => R.EHPVariables, GroupActing => R.GroupActing); --symmetricRingOf is wrong, right?
R.Schur.symmRing = R;
R.Schur
)
)
else error"Expected ring to have a Schur Ring"
)
--n = schurLevel R is the number of iterations of the schurRing/symmetricRing function
--used in the construction of R
schurLevel = method()
schurLevel (Ring) := R -> if R.?schurLevel then R.schurLevel else 0
--Construction of Schur rings
newSchur2 = method()
newSchur2(Ring,Symbol) := (A,p) -> newSchur2(A,p,-1)
newSchur2(Ring,Symbol,ZZ) := (A,p,n) -> (
if not (A.?Engine and A.Engine)
then error "expected coefficient ring handled by the engine";
SR := new SchurRing from rawSchurRing1(raw A,n);
SR.Symbol = p;
SR.baseRings = append(A.baseRings,A);
SR.generators = {};
SR.numgens = if n < 0 then infinity else n;
SR.degreeLength = 0;
--the basic features of SR are coded at the engine level
commonEngineRingInitializations SR;
ONE := SR#1;
if A.?char then SR.char = A.char;
toExternalString SR := r -> toString expression r;
expression SR := f -> (
(coeffs,monoms) -> sum(
coeffs,monoms,
(a,m) -> expression (if a == 1 then 1 else new A from a) *
new Subscript from {p, (
t1 := toSequence rawmonom2partition m;
if #t1 === 1 then t1#0 else t1
)})
) rawPairs(raw A, raw f);
listForm SR := (f) -> (
n := numgens SR;
(cc,mm) := rawPairs(raw A, raw f);
toList apply(cc, mm, (c,m) -> (rawmonom2partition m, new A from c)));
if (A.?schurLevel) then SR.schurLevel = A.schurLevel + 1
else SR.schurLevel = 1;
SR
)
schurRing = method(Options => {EHPVariables => (getSymbol"e",getSymbol"h",getSymbol"p"), SVariable => getSymbol"s", GroupActing => "GL"})
schurRing(Ring,Thing,ZZ) := SchurRing => opts -> (A,p,n) -> (
try p = baseName p else error "schurRing: can't use provided thing as variable";
if class p === Symbol then schurRing(A,p,n,opts)
else error "schurRing: can't use provided thing as variable"
);
schurRing(Ring,Thing) := SchurRing => opts -> (A,p) -> (
try p = baseName p else error "schurRing: can't use provided thing as variable";
if class p === Symbol then schurRing(A,p,opts)
else error "schurRing: can't use provided thing as variable"
);
schurRing(Ring,Symbol) := opts -> (R,p) -> schurRing(R,p,infinity,opts)
schurRing(Ring,Symbol,InfiniteNumber) :=
schurRing(Ring,Symbol,ZZ) := SchurRing => opts -> (R,p,n) -> (
S := local S;
if n == infinity then S = newSchur2(R,p,-1) else S = newSchur2(R,p,n);
S.EHPVariables = opts.EHPVariables;
--S.SVariable = opts.SVariable;
S.GroupActing = opts.GroupActing;
dim S := s -> dimSchur(s);
dim(Thing,S) := (n,s) -> dimSchur(n, s);
S @ RingElement := RingElement @ S := (f1,f2) -> plethysm(f1,f2);
S^ZZ := (f,n) -> product apply(n,i->f);
symmetricPower(ZZ,S) := (n,s) -> plethysm({n},s);
exteriorPower(ZZ,S) := opts -> (n,s) -> plethysm(splice{n:1},s);
--define the multiplication on S
--in the case when the group acting is a general linear group
if opts.GroupActing == "GL" then
(
oldmult := method();
oldmult(S,S) := (f1,f2) -> new S from raw f1 * raw f2;
oldmult(RingElement, S) := (f1,f2) -> if member(ring f1,S.baseRings | {S}) then oldmult(promote(f1,S),f2);
oldmult(S, RingElement) := (f1,f2) -> if member(ring f2,S.baseRings | {S}) then oldmult(f1,promote(f2,S));
oldmult(Number, S) := (f1,f2) -> if member(ring f1,S.baseRings | {S}) then oldmult(promote(f1,S),f2);
oldmult(S, Number) := (f1,f2) -> if member(ring f2,S.baseRings | {S}) then oldmult(f1,promote(f2,S));
S * S := (f1,f2) ->
if schurLevel S == 1 then oldmult(f1,f2)
else
(
lF1 := listForm f1;
lF2 := listForm f2;
sum flatten for p1 in lF1 list
for p2 in lF2 list
(
oldmult((last p1) * (last p2), oldmult(S_(first p1),S_(first p2)))
)
);
)
--define the multiplication on S
--in the case when the group acting is a symmetric group
else if opts.GroupActing == "Sn" then
(
S ** S := (f1,f2) -> new S from raw f1 * raw f2;
-- RingElement ** S := (f,g) -> if member(ring f,S.baseRings | {S}) then promote(f,S) ** g;
-- S ** RingElement := (f,g) -> if member(ring g,S.baseRings | {S}) then f ** promote(g,S);
RingElement ** S := (f,g) -> if member(ring f,S.baseRings | {S}) then promote(f,S) ** g
else if member(S,(ring f).baseRings | {ring f}) then f ** promote(g,S);
Number ** S := (f,g) -> if member(ring f,S.baseRings | {S}) then promote(f,S) ** g;
S ** Number := (f,g) -> if member(ring g,S.baseRings | {S}) then f ** promote(g,S);
S * S := (f1,f2) ->
if schurLevel S == 1 then
(
cS := coefficientRing S;
if liftable(f1,cS) or liftable(f2,cS) then f1 ** f2 else
if f1 == 0 or f2 == 0 then 0_S else
internalProduct(f1,f2)
)
else
(
lF1 := listForm f1;
lF2 := listForm f2;
sum flatten for p1 in lF1 list
for p2 in lF2 list
(
((last p1) * (last p2)) ** internalProduct(S_(first p1),S_(first p2))
)
);
);
t := new SchurRingIndexedVariableTable from p;
t.SchurRing = S;
t#symbol _ = a -> ( S _ a);
S.use = S -> (globalAssign(p,t); S);
S.use S;
S)
schurRing(Thing,ZZ) := opts -> (s,n) -> schurRing(QQ,s,n,opts)
schurRing(Thing,InfiniteNumber) := opts -> (s,n) -> schurRing(QQ,s,n,opts)
schurRing(Thing) := opts -> (s) -> schurRing(QQ,s,-1,opts)
undocumented (schurRing,Ring,Symbol,InfiniteNumber)
undocumented (schurRing,Thing,InfiniteNumber)
--a new type that indexes the elements in the s-basis of a Schur ring
SchurRingIndexedVariableTable = new Type of IndexedVariableTable
SchurRingIndexedVariableTable _ Thing := (x,i) -> x#symbol _ i
--construction of symmetric rings
symmRing = method(Options => options schurRing)
symmRing (Ring,ZZ) := opts -> (A,n) -> (
(e,h,p) := opts.EHPVariables;
R := A[e_1..e_n,p_1..p_n,h_1..h_n,
Degrees => toList(1..n,1..n,1..n), MonomialSize => 8];
R.EHPVariables = opts.EHPVariables;
R.SVariable = opts.SVariable;
R.eVariable = (i) -> if 1 <= i and i <= n then R_(i-1) else error"Invalid index";
R.pVariable = (i) -> if 1 <= i and i <= n then R_(n+i-1) else error"Invalid index";
R.hVariable = (i) -> if 1 <= i and i <= n then R_(2*n+i-1) else error"Invalid index";
R.GroupActing = opts.GroupActing;
R.dim = n;
R ** R := (f1,f2) -> internalProduct(f1,f2); --internal product of symmetric functions
R @ RingElement := RingElement @ R := (f1,f2) -> plethysm(f1,f2);
symmetricPower(ZZ,R) := (n,r) -> plethysm({n},r);
exteriorPower(ZZ,R) := opts -> (n,r) -> plethysm(splice{n:1},r);
--the degrees of e_i,p_i,h_i are equal to i
degsEHP := toList(1..n);
--blocks#0 are indeces for e-variables
--blocks#1 are indeces for p-variables
--blocks#2 are indeces for h-variables
blocks := {toList(0..(n-1)),toList(n..(2*n-1)),toList(2*n..(3*n-1))};
--new variables for the E,H,P polynomials
vrs := symbol vrs;
locVarsE := apply(blocks#0,i->vrs_i);
locVarsP := apply(blocks#1,i->vrs_i);
locVarsH := apply(blocks#2,i->vrs_i);
--new rings used for conversion to E- and P- polynomials
--they differ from R in the order of the variables
--R is used by default for conversion to H-polynomials
R.symRingForE = A[locVarsH | locVarsP | locVarsE ,Degrees=>flatten toList(3:degsEHP),MonomialOrder=>GRevLex, MonomialSize => 8];
R.mapToE = map(R.symRingForE,R,apply(blocks#2|blocks#1|blocks#0,i->(R.symRingForE)_i));
R.mapFromE = map(R,R.symRingForE,apply(blocks#2|blocks#1|blocks#0,i->R_i));
R.symRingForP = A[locVarsH | locVarsE | locVarsP,Degrees=>flatten toList(3:degsEHP),MonomialOrder=>GRevLex, MonomialSize => 8];
R.mapToP = map(R.symRingForP,R,apply(blocks#1|blocks#2|blocks#0,i->(R.symRingForP)_i));
R.mapFromP = map(R,R.symRingForP,apply(blocks#2|blocks#0|blocks#1,i->R_i));
--compute conversion tables
--between E-,H- and P- polynomials
EtoP(n,R);
PtoE(n,R);
HtoE(n,R);
EtoH(n,R);
PtoH(n,R);
HtoP(n,R);
--define Groebner bases used for conversion between E-,H- and P- polynomials
R.grbE = forceGB matrix{flatten apply(splice{1..n},i->{R.mapToE(R_(n-1+i))-R.PtoETable#i,R.mapToE(R_(2*n-1+i))-R.HtoETable#i})};
R.grbH = forceGB matrix{flatten apply(splice{1..n},i->{R_(n-1+i)-R.PtoHTable#i,R_(-1+i)-R.EtoHTable#i})};
R.grbP = forceGB matrix{flatten apply(splice{1..n},i->{R.mapToP(R_(-1+i))-R.EtoPTable#i,R.mapToP(R_(2*n-1+i))-R.HtoPTable#i})};
collectGarbage();
--construct maps that convert a polynomial in the E-,H-,P- variables
--into one involving only one of the three variables
R.mapSymToE = (f) -> R.mapFromE(R.mapToE(f)%R.grbE);
R.mapSymToP = (f) -> R.mapFromP(R.mapToP(f)%R.grbP);
R.mapSymToH = (f) -> f%R.grbH;
--the Schur level of R is one more than that of its base ring
if (A.?schurLevel) then R.schurLevel = A.schurLevel + 1
else R.schurLevel = 1;
R)
symmRing(ZZ) := opts -> n -> symmRing(QQ,n,opts)
---------------------------------------------------------------
--------------Jacobi-Trudi-------------------------------------
---------------------------------------------------------------
----local variables for jacobiTrudi
----they are used in the recursive function jT
auxR = local auxR;
auxn = local auxn;
auxEH = local auxEH;
----
jacobiTrudi = method(Options => {Memoize => true, EorH => "E"})
jacobiTrudi(BasicList,Ring) := opts -> (lambda,R) ->
(
lam := new Partition from lambda;
rez := local rez;
local u;
if opts.EorH == "H" then u = R.hVariable else (u = R.eVariable;lam = conjugate lam;);
if opts.Memoize then
(
if not R.?sFunction then R.sFunction = new MutableHashTable;
if opts.EorH == "E" then
(
-----sFunction#0 records s-polynomials in terms of the e-variables
if not R.sFunction#?0 then R.sFunction#0 = new MutableHashTable;
auxEH = 0;
)
else
(
-----sFunction#1 records s-polynomials in terms of the h-variables
if not R.sFunction#?1 then R.sFunction#1 = new MutableHashTable;
auxEH = 1;
);
auxR = R;
auxn = R.dim;
rez = jT(lam);
)
else
(
n := #lam;
rez = det(map(R^n, n, (i,j) ->
(
aux := lam#i-i+j;
if aux < 0 or aux>R.dim then 0_R
else if aux == 0 then 1_R else u aux)
),
Strategy => Cofactor);
);
rez
)
--computes the Jacobi-Trudi determinant recursively
jT = (lambda) ->
(
lambda = toList lambda;
rez := local rez;
if auxR.sFunction#auxEH#?lambda then rez = auxR.sFunction#auxEH#lambda
else
(
ll := #lambda;
if ll == 0 or lambda#0 == 0 then rez = 1_auxR else
if ll == 1 then rez = auxR_(2*auxEH*auxn-1+lambda#0) else
(
l1 := drop(lambda,-1);
l2 := {};
rez = 0;
sgn := 1;
for i from 0 to ll-1 do
(
if lambda#(ll-1-i)+i<=auxn then --just added, won't work for h-polynomials
rez = rez + sgn*auxR_(2*auxEH*auxn-1+lambda#(ll-1-i)+i)*jT(l1|l2);
sgn = - sgn;
l1 = drop(l1,-1);
if lambda#(ll-1-i)>1 then
l2 = {lambda#(ll-1-i)-1} | l2;
);
);
auxR.sFunction#auxEH#lambda = rez;
);
rez
)
---------------------------------------------------------------
--------------End Jacobi-Trudi---------------------------------
---------------------------------------------------------------
---------------------------------------------------------------
--------------Plethysm-----------------------------------------
---------------------------------------------------------------
--the cycle type of the k-th power of any permutation of cycle type cyc
powerCycleType := method()
powerCycleType(ZZ,List) := (k,cyc) ->
(
rsort(flatten (for i in cyc list (g := gcd(i,k);splice{g:i//g})))
)
-- d is an integer
-- R is symmRing n
-- returns the plethysm map p_d : R --> R
-- which sends p_i to p_(i*d).
plethysmMap = (d,maxg,R) -> (
nS := R.dim;
nSd := nS // d;
fs := splice{nS:0_R};
topf := min(maxg,nSd);
fs = join(fs, apply(1..topf, j -> R.pVariable(d*j)));
if maxg > nSd then
fs = join(fs, apply(topf+1..maxg,j-> R.mapFromE R.PtoETable#(d*j)));
fs = join(fs, 2*nS-maxg:0_R);
map(R,R,fs)
)
-- exterior plethysm (corresponding to composition
-- of Schur functors of GL-representations)
-- f is a polynomial in symmRing / SchurRing SA
-- g is a polynomial in symmRing / SchurRing SB
-- result is in symmRing / SchurRing SB
plethysmGL = method()
plethysmGL(RingElement,RingElement) := (f,g) -> (
Rg := ring g;
Rf := ring f;
if schurLevel Rf > 1 then error"Undefined plethysm operation";
issy := not instance(Rg,SchurRing);
pg := toP g;
pf := toP f;
SRg := ring pg; --symmetric ring of Rg
SRf := ring pf; --symmetric ring of Rf
nf := SRf.dim;
--maxf is the maximum i for which the variable p_i appears in the expression of pf
maxf := max(support(pf)/index//max-nf+1,0);
auxS := SRg;
nS := auxS.dim;
lev := schurLevel auxS;
spg := support(pg)/index;
--maxg is the maximum i for which the variable p_i appears in the expression of pg
maxg := max(select(spg,i->i<3*nS)//max-nS+1,0);
--if p_(maxf*maxg) hasn't been computed in terms of E-polynomial, then compute it
if maxf*maxg >= #auxS.PtoETable then PtoE(maxf*maxg,auxS);
--phi is the map that sends p_i to the plethystic composition p_i\circ pg
--so that phi(f) = f \circ pg (plethysm of f and pg)
phi := map(SRg,SRf,flatten splice {nf:0_SRg,
apply(1..nf, j -> (if j<=maxf then (plethysmMap(j,maxg,SRg))pg else 0_SRg)),
nf:0_SRg});
pl := phi pf;
if issy then pl else toS pl
)
-- interior plethysm (corresponding to the result of
-- the application of a Schur functor to an S_n-representation)
-- f is a polynomial in symmRing N / SchurRing SA
-- g is a polynomial in symmRing n / SchurRing SB
-- result is in symmRing n / SchurRing SB
plethysmSn = method()
plethysmSn(RingElement,RingElement) := (f,g) ->
(
symmetricFunction(plethysm(f,classFunction g), ring g)
)
-- plethysm of symmetric functions
plethysm = method()
-- this function is not exported
-- it is used to compute the plethysm of f and g
-- when f is a power-sum symmetric polynomial
auxplet = method()
auxplet(RingElement,RingElement) := (f,g) ->
(
Rg := ring g;
pl := local pl;
if Rg.GroupActing == "GL" then pl = plethysmGL else
if Rg.GroupActing == "Sn" then pl = plethysmSn;
sLg := schurLevel Rg;
if sLg == 1 then return pl(f,g) else
(
lF := listForm g;
return sum for t in lF list auxplet(f,last t) * pl(f,Rg_(first t))
);
)
-- the most general form of plethysm
-- f is an arbitrary symmetric functions
-- g is an element of a representation ring of a product of general linear and/or symmetric groups
plethysm(RingElement,RingElement) := (f,g) ->
(
pf := toP f;
Rf := ring pf;
if schurLevel Rf > 1 then error"Undefined plethysm operation";
pls := new MutableHashTable from {};
lpf := listForm pf;
m := (ring pf).dim;
isSchur := instance(ring g,SchurRing);
auxg := local auxg;
if isSchur then auxg = g else auxg = toS g;
pl := sum for t in lpf list ((last t) * product select(apply(splice{0..m-1}, i -> (ex := (first t)#(m+i);
if ex > 0 then (if pls#?i then (pls#i)^ex else
(pls#i = auxplet(Rf.pVariable(i+1),auxg);(pls#i)^ex)))),j -> j =!= null)); -- this is bad when g is not in a SchurRing
if isSchur then pl else toSymm pl
)
-- plethysm of s_lambda and g
plethysm(BasicList,RingElement) := (lambda,g) -> (
d := sum toList lambda;
Rf := symmRing(QQ,d);
f := jacobiTrudi(lambda,Rf);
plethysm(f,g)
)
-- (inner) plethysm of symmetric function f with the class function cF (the character of a certain S_n-representation)
plethysm(RingElement,ClassFunction) := (f,cF) ->
(
R := ring(cF#(first keys cF));
pf := toP f;
n := degree cF;
k := (ring pf).dim;
pvars := (ring pf).pVariable;
parsn := toList \ partitions(n);
newHT := new MutableHashTable;
for sig in parsn do
(
sublist := for i from 1 to k list
(
pct := powerCycleType(i,sig);
if cF#?pct then cF#pct else 0
);
newHT#sig = (map(R,ring pf,splice{k:0} | sublist | splice{k:0})) pf;
);
new ClassFunction from newHT
)
-- (inner) plethysm of s_lambda with the class function cF (the character of a certain S_n-representation)
plethysm(BasicList,ClassFunction) := (lambda,cF) -> (
d := sum toList lambda;
Rf := symmRing(QQ,d);
f := jacobiTrudi(lambda,Rf);
plethysm(f,cF))
{*
-- degree of a polynomial in a SchurRing
-- this is no longer used
degSchurPol = method()
degSchurPol(RingElement) := ps -> (
tms := listForm ps;
tms/first/sum//max
)
*}
---------------------------------------------------------------
-----------End plethysm----------------------------------------
---------------------------------------------------------------
---------------------------------------------------------------
----Transition between various types of symmetric functions----
---------------------------------------------------------------
-- toSymm
toSymm = method()
-- if ps is an element of a schurRing R
-- toSymm returns the symmetric function corresponding to ps, as an element of a symmRing, the symmetricRingOf R;
-- otherwise ps is returned;
toSymm(RingElement) := (ps) ->
(
S := ring ps;
if instance(S, SchurRing) then
(
R := symmetricRingOf S;
tms := listForm ps;
--each term s_lambda in ps is transformed into an element of R using the jacobiTrudi routine
sum apply(tms,(p,a)->(
(try b:=jacobiTrudi(p,R) then b else error"Need symmetric ring of higher dimension")*
toSymm(lift(a,coefficientRing S))))
)
else return ps
)
-- this is the base case of the recursive operation in the general case
-- needed when ps is an element of ZZ or QQ, because ZZ, QQ don't have
-- RingElement as an ancestor
toSymm(Number) := (ps) -> ps
mapSymToE = method()
-- writes the symmetric functions of maximal schurLevel in f (i.e. those
-- not contained in the coefficient ring of R) in terms of the e-polynomials
mapSymToE (RingElement) := (f) -> (
R:=ring f;
if R.?mapSymToE then R.mapSymToE f else f
)
mapSymToH = method()
-- writes the symmetric functions of maximal schurLevel in f (i.e. those
-- not contained in the coefficient ring of R) in terms of the h-polynomials
mapSymToH (RingElement) := (f) -> (
R:=ring f;
if R.?mapSymToH then R.mapSymToH f else f
)
mapSymToP = method()
-- writes the symmetric functions of maximal schurLevel in f (i.e. those
-- not contained in the coefficient ring of R) in terms of the p-polynomials
mapSymToP (RingElement) := (f) -> (
R:=ring f;
if R.?mapSymToP then R.mapSymToP f else f
)
toE = method()
-- writes a symmetric function (possibly in a ring
-- with schurLevel larger than one) in terms of
-- elementary symmetric polynomials
toE (RingElement) := (f) -> (
R := ring f;
if class R === SchurRing then toE toSymm f
else
(
if not R.?schurLevel then f else
if R.schurLevel>1 then terms f/(i->(toE leadCoefficient i*(mapSymToE leadMonomial i)))//sum
else mapSymToE f
)
)
toP = method()
-- writes a symmetric function (possibly in a ring
-- with schurLevel larger than one) in terms of
-- power sums
toP (RingElement) := (f) -> (
R := ring f;
if class R === SchurRing then toP toSymm f
else
(
if not R.?schurLevel then f else
if R.schurLevel>1 then terms f/(i->(toP leadCoefficient i*(mapSymToP leadMonomial i)))//sum
else mapSymToP f
)
)
toH = method()
-- writes a symmetric function (possibly in a ring
-- with schurLevel larger than one) in terms of
-- complete symmetric polynomials
toH (RingElement) := (f) -> (
R := ring f;
if class R === SchurRing then toH toSymm f
else
(
if not R.?schurLevel then f else
if R.schurLevel>1 then terms f/(i->(toH leadCoefficient i*(mapSymToH leadMonomial i)))//sum
else mapSymToH f
)
)
-- auxiliary functions to be used in
-- the recTrans routine
leadTermFcn := local leadTermFcn;
retFcn := local retFcn;
mappingFcn := local mappingFcn;
toS = method()
toS(RingElement) := (f) -> (
R := ring f;
if (schurLevel R == 0 or class R === SchurRing) then f else
(
S := schurRingOf R;
local hf;
n := R.dim;
d := first degree f;
ngS := numgens S;
--mappingFcn v is used when v = h_i for some i; it returns the Schur polynomial s_i, in the correct Schur ring
mappingFcn = (v) -> (schurRingOf ring v)_{index v-2*(ring v).dim+1};
--leadTermFcn takes as input a polynomial pl in the h-variables,
--and returns the variable h_i, with i maximal, such that h_i appears in the expression of pl
leadTermFcn = (pl) -> (
R := ring pl;
spl := select(support pl,i->index i toS lift(pl,(coefficientRing ring pl));
promote(recTrans(toH f),S)
)
)
toS(Thing) := (f) -> f
undocumented(toS,Thing)
toS(Thing,Ring) := (f,T) -> try(lift(f,T)) else f
undocumented(toS,Thing,Ring)
toS(RingElement,SchurRing) := (f, T) ->
(
R := ring f;
if schurLevel R == 0 then
(
U := T;
while schurLevel U > 0 do U = coefficientRing U;
toS(f,U)
)
else
(
fS := toS f;
dimT := numgens T;
(listForm fS)/(i-> if #i#0<=dimT then T_(i#0)*toS(i#1,coefficientRing T) else 0_T)//sum
)
)
--recTrans is a recursive routine that transforms an h-polynomial (in a symmRing of positive schurLevel)
--into an s-polynomial, by proceeding one level at a time
recTrans = method()
recTrans (RingElement) := (pl) ->
(
--lead = leading variable = h_i with i maximal
lead := leadTermFcn pl;
isSn := (ring pl).GroupActing == "Sn";
if lead === null then retFcn pl else
(
--monomials/coefficients with respect to the leading variable lead
(mon,coe) := coefficients(pl,Variables=>{lead});
mon = flatten entries mon;
coe = flatten entries coe;
rez := 0;
cdeg := degree(lead,mon#0)+1;
for i from 0 to #mon-1 do
(
fdeg := degree(lead,mon#i);
while (cdeg>fdeg+1) do
(
cdeg = cdeg - 1;
--if the group acting at a given level is the symmetric group
--use internal multiplication of symmetric functions
--otherwise use usual multiplication
if isSn then rez = rez**mappingFcn(lead) else
rez = rez*mappingFcn(lead);
);
if isSn then rez = rez**mappingFcn(lead)+recTrans(coe#i)
else rez = rez*mappingFcn(lead)+recTrans(coe#i);
cdeg = cdeg - 1;
);
while cdeg>0 do
(
cdeg = cdeg - 1;
--if the group acting at a given level is the symmetric group
--use internal multiplication of symmetric functions
--otherwise use usual multiplication
if isSn then rez = rez**mappingFcn(lead) else
rez = rez*mappingFcn(lead);
);
rez
)
)
recTrans(Thing) := p -> p
--------
--------
--given a recursive relation for a sequence a_n, given by a convolution of (a_n) with (L_n)
--convolve computes formulas for a_n in terms of L_n
--the main routine is coded in the engine
--the value of conv is used to indicate one of several types of convolution
convolve = method()
convolve(List,ZZ) := (L,conv) -> (
A := ring L_0;
toList drop(apply(rawConvolve(L/raw//toSequence, conv), f -> new A from f),1)
)
--a_n = p_n
--L_n = e_n
PtoE = (m,R) -> (
n := R.dim;
A := R.symRingForE;
p2e := prepend(1_A, for i from 1 to n list ((-1)^(i+1) * A_(2*n+i-1)));
if m>n then p2e = join(p2e,toList((m-n):0_A));
R.PtoETable = {1_A} | (- convolve(p2e,2));
)
--a_n = h_n
--L_n = e_n
HtoE = (m,R) -> (
n := R.dim;
A := R.symRingForE;
h2e := prepend(1_A, for i from 1 to n list (-1)^(i+1)*A_(2*n+i-1));
R.HtoETable = {1_A} | convolve(h2e,0);
)
--a_n = h_n
--L_n = p_n
HtoP = (m,R) -> (
n := R.dim;
A := R.symRingForP;
h2p := prepend(1_A, for i from 1 to n list A_(2*n+i-1));
R.HtoPTable = {1_A} | convolve(h2p,1);
)
--a_n = e_n
--L_n = p_n
EtoP = (m,R) -> (
n := R.dim;
A := R.symRingForP;
e2p := prepend(1_A, for i from 1 to n list (-1)^(i+1)*A_(2*n+i-1));
R.EtoPTable = {1_A} | convolve(e2p,1);
)
--a_n = p_n
--L_n = h_n
PtoH = (m,R) -> (
n := R.dim;
A := R;
p2h := prepend(1_A, for i from 1 to n list (- A_(2*n+i-1)));
R.PtoHTable = {1_A} | convolve(p2h,2);
)
--a_n = e_n
--L_n = h_n
EtoH = (m,R) -> (
n := R.dim;
A := R;
e2h := prepend(1_A, for i from 1 to n list (-1)^(i+1)*A_(2*n+i-1));
R.EtoHTable = {1_A} | convolve(e2h,0);
)
---------------------------------------------------------------
--------------End transition-----------------------------------
---------------------------------------------------------------
---------------------------------------------------------------
-------------Schur Resolutions---------------------------------
---------------------------------------------------------------
--recsyz is a recursive method that takes as input an element el of a SchurRing of positive schurLevel
--and returns the sum of the terms having negative coefficients
--it is used in the routine schurRes to determine representations that are forced to be generators
--of syzygy modules in an equivariant resolution
recsyz = method()
recsyz (Thing) := (el) -> min(el,0)
recsyz (RingElement) := (el) ->
(
T := ring el;
listForm el/((u,v)->T_u*recsyz(v))//sum
)
schurResolution = method(Options => {DegreeLimit => 0, SyzygyLimit => 0})
schurResolution(RingElement,List) := opts -> (rep,M) ->
(
d := opts.DegreeLimit;
if d == 0 then d = #M-1;
c := opts.SyzygyLimit;
T := ring rep;
n := schurLevel T;
--plets is the list of symmetric powers of the representation rep, from 0 to d
plets := new MutableList;
plets#0 = 1_T;
for i from 1 to d do plets#i = symmetricPower(i,rep);
schurRes(rep,M,new List from plets,DegreeLimit => d,SyzygyLimit => c)
)
schurResolution(RingElement,List,List) := opts -> (rep,M,plets) ->
(
d := opts.DegreeLimit;
if d == 0 then d = #M-1;
c := opts.SyzygyLimit;
schurRes(rep,M,plets,DegreeLimit => d,SyzygyLimit => c)
)
schurRes = method(Options => options schurResolution)
schurRes(RingElement,List,List) := opts -> (rep,M,plets) ->
(
T := ring rep;
d := opts.DegreeLimit;
c := opts.SyzygyLimit;
mods := new MutableList from (M | toList((d+1-#M):0));
notdone := true;
k := 0;
--syzy is the list of the characters of the generators of the syzygy modules
syzy := new MutableList;
syzy#k = {};
local mo;
local newsyz;
--syzygy modules are constructed step by step
--the stopping condition is either reaching the limit c of syzygy modules that are computed
--or not finding any new syzygies at a given step
while notdone do
(
for i from 0 to d do
(
mo = 0_T;
for sy in syzy#k do
if sy#0 <= i then mo = mo + plets#(i-sy#0) * sy#1
else break;
--mods is a sequence of representations, mods#i being the degree i of a module that needs to be ``covered''
--by the differential in the equivariant complex
--mo is the degree i part of the new syzygy module
--it needs to ``cover'' mods#i, i.e. there has to exist a surjective map of representations from
--mo to mods#i
mo = mo - mods#i;
--if there are representations with negative coefficients in mo-mods#i, it means that mo doesn't cover mods#i
--the representations with negative signs must be ``covered'' by new syzygies
newsyz = recsyz(mo);
if newsyz != 0 then syzy#k = syzy#k | {(i,-newsyz)};
mods#i = mo - newsyz;
);
if c == 0 then notdone = not (syzy#k == {})
else notdone = (k i != {})
)
---------------------------------------------------------------
-------------end Schur Resolutions-----------------------------
---------------------------------------------------------------
---------------------------------------------------------------
--------------Characters of Symmetric Group--------------------
---------------------------------------------------------------
--given a partition lambda as a nonincreasing sequence of positive integers
--seqToMults returns the representation of this partition as a sequence
--of multiplicities: rez#i is the number of parts of lambda of size (i+1)
seqToMults = method()
seqToMults(List) := (lambda) ->
(
lam := new Partition from lambda;
aux := toList(conjugate lam)|{0};
rez := {};
for j from 0 to #aux-2 do
(
dif := aux#j-aux#(j+1);
rez = rez | {dif};
);
rez
)
--given a partition lambda represented in as a sequence of multiplicities mults
--where mults#i is the number of parts of lambda of size (i+1)
--multsToSeq represents lambda as a nonincreasing sequence of positive integers
multsToSeq = method()
multsToSeq(List) := (mults) ->
(
n := #mults;
par := {};
for i from 0 to n-1 do
par = par | splice{mults#i:(i+1)};
reverse par
)
--the size of the centralizer of a permutation of cycle type lambda
centralizerSize = method()
centralizerSize(List) := lambda ->
(
product for i from 0 to #lambda-1 list((i+1)^(lambda#i)*(lambda#i)!)
)
keysCF := method()
keysCF(ClassFunction) := (cF) -> keys cF
degree(ClassFunction) := ch ->
(
ke := keysCF ch;
if #ke == 0 then -1 else sum(first ke)
)
--go from symmetric functions to class functions
classFunction = method()
classFunction(RingElement) := (f)->
(
Rf := ring f;
R := symmetricRingOf Rf;
pf := toP f;
n := R.dim;
if (degree pf)#0 > n then error"Can't interpret ring element as a symmetric function";
(mon,coe) := apply(coefficients pf,i->flatten entries i);
ch := new MutableHashTable;
for j from 0 to #mon-1 do
(
degs := (flatten exponents mon#j)_{(n)..(2*n-1)};
par := multsToSeq(degs);
ch#par = lift(coe#j,coefficientRing R) * centralizerSize(degs);
);
new ClassFunction from ch
)
classFunction(BasicList) := (lambda)->
(
lam := toList(lambda);
s := symbol s;
R := schurRing(QQ,s,sum lam);
classFunction(R_lam)
)
ClassFunction + ClassFunction := (ch1,ch2)->
(
clSum := new MutableHashTable;
l1 := sum((keysCF ch1)#0);
l2 := sum((keysCF ch2)#0);
if l1 != l2 then error("The symmetric functions/characters must have the same degree");
for i in unique(keysCF(ch1)|keysCF(ch2)) do
(
a := b := 0;
if ch1#?i then a = ch1#i;
if ch2#?i then b = ch2#i;
if (a+b != 0) then clSum#i = a + b;
);
new ClassFunction from clSum
)
RingElement * ClassFunction := Number * ClassFunction := (n,ch) ->
(
clProd := new MutableHashTable;
for i in keysCF ch do clProd#i = n*ch#i;
new ClassFunction from clProd
)
ClassFunction * RingElement := ClassFunction * Number := (ch,n) -> n*ch;
ClassFunction - ClassFunction := (ch1,ch2)-> ch1 + (-1)*ch2;
ClassFunction == ClassFunction := (ch1,ch2) ->
(
equ := true;
for i in unique(keysCF ch1 | keysCF ch2) do
if not ((not ch1#?i and not ch2#?i) or (ch1#?i and ch2#?i and ch1#i == ch2#i)) then
(
equ = false;
break;
);
equ
)
--go from class functions to symmetric functions
symmetricFunction = method()
symmetricFunction(ClassFunction,Ring) := (ch,S)->
(
R := symmetricRingOf S;
rez := 0_R;
n := R.dim;
for lam in keysCF ch do
rez = rez + ch#lam * (product for i from 0 to #lam-1 list R.pVariable(lam#i)) / centralizerSize(seqToMults lam);
if instance(S, SchurRing) then toS rez else rez
)
scalarProduct = method()
scalarProduct(ClassFunction,ClassFunction) := (ch1,ch2)->
(
scProd := 0;
chProd := internalProduct(ch1,ch2);
for i in keysCF(chProd) do
scProd = scProd + chProd#i / centralizerSize(seqToMults i);
scProd
)
scalarProduct(RingElement,RingElement) := (f1,f2)->
(
ch1 := classFunction f1;
ch2 := classFunction f2;
scalarProduct(ch1,ch2)
)
internalProduct = method()
ClassFunction * ClassFunction :=
internalProduct(ClassFunction,ClassFunction) := (ch1,ch2)->
(
iProd := new MutableHashTable;
l1 := sum((keysCF ch1)#0);
l2 := sum((keysCF ch2)#0);
if l1 == 0 then return(ch1#{} * ch2);
if l2 == 0 then return(ch2#{} * ch1);
if l1 != l2 then error("The symmetric functions/characters must have the same degree");
for i in keysCF(ch1) do
if ch2#?i then iProd#i = ch1#i * ch2#i;
new ClassFunction from iProd
)
internalProduct(RingElement,RingElement) := (f1,f2)->
(
R2 := ring f2;
R := local R;
issy := false;
if (class R2 =!= SchurRing) then issy = true;
R = symmetricRingOf ring f2;
ch1 := classFunction f1;
ch2 := classFunction f2;
rez := symmetricFunction(internalProduct(ch1,ch2),R);
if issy then rez else
toS rez
)
{*
chi(BasicList,BasicList) := (lambda, rho) ->
(
la := toList lambda;
rh := toList rho;
ll := sum la;
if ll != sum(rh) then error"Partitions must have the same size.";
R := symmRing(QQ,ll);
sl := jacobiTrudi(la,R);
pr := 1_R;
for i from 0 to #rh-1 do pr = pr * R_(ll-1+rh#i);
scalarProduct(sl,pr)
)
*}
---------------------------------------------------------------
--------------End characters-----------------------------------
---------------------------------------------------------------
--------------------------------
-- Dimension -------------------
--------------------------------
-- Function to compute the dimension of a virtual representation
hooklengths = (lambda) -> (
mu := conjugate lambda;
product for i from 0 to #lambda-1 list (
product for j from 0 to lambda#i-1 list (
lambda#i + mu#j - i - j -1
))
)
dimSchur = method(Options => {GroupActing => "GL"})
dimSchur(Thing,List) := opts -> (n,lambda) -> dimSchur(n, new Partition from lambda)
dimSchur(Thing,Partition) := opts -> (n, lambda) -> (
-- lambda is a list {a0,a1,...,a(r-1)}, a0 >= a1 >= ... >= a(r-1) > 0
-- n can be a number or a symbol
-- powers := new MutableList from toList(lambda#0 + #lambda - 1 : 0);
powers := new MutableList from toList((if lambda#?0 then lambda#0 else 0) + #lambda - 1 : 0);
base := 1 - #lambda;
for i from 0 to #lambda-1 do
for j from 0 to lambda#i-1 do
powers#(j-i-base) = powers#(j-i-base) + 1;
if not instance(n,ZZ) then n = hold n;
-- now get the hook lengths
answer := local answer;
if opts.GroupActing == "GL" then
(
num := product for s from 0 to #powers-1 list (n + (base+s))^(powers#s);
answer = num/hooklengths lambda;
)
else if opts.GroupActing == "Sn" then answer = n! / hooklengths lambda;
-- if instance(answer,QQ) then lift(answer,ZZ) else answer
answer
)
dimSchur(Thing,RingElement) := opts -> (n, F) -> (
-- assumption: F is an element in a SchurRing
L := listForm F;
sum apply(L, p -> (
lambda := new Partition from p#0;
if p#1 == 1 then dimSchur(n,lambda,opts) else p#1 * dimSchur(n,lambda,opts)))
)
dimSchur(List,List,RingElement) := opts -> (ns, ng, F) -> (
-- assumption: F is an element in a SchurRing
L := listForm F;
n := ns#0;
gr := ng#0;
lev := schurLevel ring F;
if lev =!= #ns then error ("expected Schur ring of level "|lev);
if lev > 1 then (
n1 := drop(ns,1);
ng1 := drop(ng,1);
L = apply(L, p -> (p#0, dimSchur(n1,ng1,p#1)));
);
sum apply(L, p -> (
lambda := new Partition from p#0;
if gr == "GL" then (if p#1 === 1 then dimSchur(n,lambda,GroupActing=>gr) else p#1 * dimSchur(n,lambda,GroupActing=>gr))
else (if p#1 === 1 then dimSchur(sum toList lambda,lambda,GroupActing=>gr) else p#1 * dimSchur(sum toList lambda,lambda,GroupActing=>gr))))
)
dimSchur(RingElement) := opts -> (F) -> (
schurdims := (S) -> (
if schurLevel S === 0 then {}
else prepend(numgens S, schurdims coefficientRing S));
groupsacting := (S) -> (
if schurLevel S === 0 then {}
else prepend(S.GroupActing, groupsacting coefficientRing S));
ns := schurdims ring F;
ng := groupsacting ring F;
if any(ns, i -> not instance(i,ZZ))
then error "expected finitely generated Schur rings";
dS := dimSchur(ns,ng,F);
if liftable(dS,ZZ) then lift(dS,ZZ) else dS
)
---------------------------------------------------------------
--------End dimension----------------------------------------------
---------------------------------------------------------------
---------------------------------------------------------------
-----------Partitions-related functions------------------------
---------------------------------------------------------------
--this part might have to be moved elsewhere
--since it's not directly connected to the package
parts := (d, n) -> (
-- d is an integer >= 0
-- n is an integer >= 1
-- returns a list of all of the partitions of d
-- having <= n parts.
x := partitions(d);
select(x, xi -> #xi <= n))
-------Generate all the partitions of a set
-------with a given shape
locS = local locS;
locL = local locL;
locLengthL = local locLengthL;
locParts = local locParts;
locPartitions = local locPartitions;
locind = local locind;
genPartitions = local genPartitions;
genPartitions = method()
genPartitions(ZZ) := (k)->
(
if k==length locS then (locind = locind + 1;locPartitions#locind = set toList locParts) else
(
for i from 0 to locLengthL-1 do
if (i==0 and #locParts#0 < locL#0) or (((locL#(i-1)>locL#i) or (#locParts#(i-1)>0)) and (#locParts#i
(
locS = toList S;
locL = L;
locLengthL = #L;
locParts = new MutableList;
for i from 0 to locLengthL-1 do locParts#i = set{};
locPartitions = new MutableList;
locind = -1;
genPartitions(0);
toList locPartitions
)
--------end generate partitions
---------------------------------------------------------------
--------End partitions-related functions-----------------------
---------------------------------------------------------------
beginDocumentation()
undocumented {Schur}
doc ///
Key
SchurRings
Headline
Rings representing irreducible representations of general linear or symmetric groups
Description
Text
This package makes computations in the representation rings of general linear groups
and symmetric groups possible.
Given a positive integer {\tt n} we may define a polynomial ring in {\tt n}
variables over an arbitrary base ring , whose monomials correspond to the irreducible
representations of {\tt GL(n)}, and where multiplication is given by the decomposition of
the tensor product of representations. We create such a ring in Macaulay2 using the
@TO schurRing@ function.
Example
S = schurRing(QQ,s,4)
R = schurRing(r,infinity)
Text
Note that in the above, {\tt n} is allowed to be equal to {\tt \infty}. However, in this
version of the package, many of the features from the case {\tt n} finite are missing
from the infinite case, so the user is advised to use large values for {\tt n} as a
substitute, whenever necessary.
We determine the relative dimension of a SchurRing over its base using the @TO numgens@ function:
Example
numgens S
numgens R
Text
For {\tt k\leq n}, one may interpret the degree
{\tt k} homogeneous component of a @TO SchurRing@ as the representation ring of the symmetric
group {\tt S_k}. In this ring, the multiplication is different than the one in
the representation ring of {\tt GL(n)}. By default, the elements of a @TO SchurRing@ are
interpreted as (virtual) characters of
a general linear group. This interpretation is controlled by the option @TO GroupActing@,
whose default value is "GL". To indicate that the elements of a Schur ring should
be interpreted as characters of the symmetric group, one has to set the option @TO GroupActing@
to "Sn".
Example
Q = schurRing(q,4,GroupActing => "Sn")
Text
A monomial in {\tt S} represents the irreducible representation with a given highest weight.
The standard {\tt GL(4)}-representation is
Example
V = s_1
Text
We may see the dimension of the corresponding irreducible representation using @TO dim@:
Example
dim V
Text
Multiplication of elements corresponds to tensor product of representations. The
value is computed using a variant of the Littlewood-Richardson rule.
Example
V * V
V^3
Text
The third symmetric power of {\tt V} is obtained by
Example
W = s_{3}
dim W
Text
and the third exterior power of {\tt V} can be obtained using
Example
U = s_{1,1,1}
dim U
Text
Alternatively, one can use the functions @TO symmetricPower@ and @TO exteriorPower@:
Example
W = symmetricPower(3,V)
U = exteriorPower(3,V)
Text
We can in fact take symmetric powers and exterior powers of any representation:
Example
exteriorPower(2,W)
symmetricPower(2,U)
Text
and compute even more general forms of @TO plethysm@:
Example
plethysm(W+U,W+U)
Text
Alternatively, we can use the binary operator @TO symbol \@ @ to compute plethysm:
Example
s_2 @ s_3
(W+U) @ (W+U)
Text
All the above calculations assume that we're dealing with representations of {\tt GL(4)}.
But as symmetric functions of degree three, {\tt W} and {\tt U}, can be thought of as characters of the
symmetric group {\tt S_3}. Let us first ``move'' these symmetric functions into a Schur ring
designed to deal with characters of symmetric groups (like the ring {\tt Q} defined
above):
Example
W' = toS(W,Q)
U' = toS(U,Q)
Text
Now {\tt W'} corresponds to the trivial representation of {\tt S_3},
and {\tt U'} to the sign representation. As such, we can tensor them together using the
function @TO internalProduct@, or the binary operator @TO symbol *@.
Example
W' * U'
Text
We can generate the class function corresponding to an {\tt S_n}-representation, using
the function @TO classFunction@:
Example
cfW = classFunction(W')
cfU = classFunction(U')
Text
We can multiply class functions together, and transform class functions into symmetric
functions using the function @TO symmetricFunction@:
Example
cfWU = cfW * cfU
symmetricFunction(cfWU,Q)
Text
The result of the previous computation is of course the same as that of taking the product
of {\tt W'} and {\tt U'}.
We can take exterior and symmetric powers of {\tt S_n}-representations, just as for
{\tt GL}-modules (compare to {\tt o16} and {\tt o17}):
Example
exteriorPower(2,W')
symmetricPower(2,U')
Text
We can write any symmetric function in terms of the standard {\tt e}- (elementary
symmetric), {\tt h}- (complete) and {\tt p}- (power sum) bases, using the functions
@TO toE@, @TO toH@, @TO toP@ respectively:
Example
toE U
toH U
toP W
Text
These expressions live in the Symmetric ring associated to {\tt S}, which can be obtained
using the function @TO symmetricRingOf@:
Example
A = symmetricRingOf S
Text
Similarly, any Symmetric ring has a Schur ring attached to it, which can be obtained using
the function @TO schurRingOf@:
Example
schurRingOf A === S
Text
We construct tensor products of Schur rings iteratively by allowing Schur rings over
base rings that are also Schur rings:
Example
T = schurRing(S,t,3)
Text
The Schur ring {\tt T} can thus be thought of as the representation ring of
{\tt GL(V)\times GL(V')}, where {\tt V} is as before a vector space of dimension
{\tt 4}, and {\tt V'} is a vector space of dimension {\tt 3}. The representation
corresponding to {\tt V'} is
Example
V' = t_1
Text
The function @TO schurLevel@ indicates the number of Schur rings that have been
tensored together to obtain any given ring:
Example
schurLevel T
schurLevel S
schurLevel QQ
Text
We can now check Cauchy's formula for decomposing symmetric/exterior powers of a
tensor product:
Example
symmetricPower(3,V*V')
exteriorPower(3,V*V')
Text
We end with the computation of the {\tt GL(n)}- and {\tt S_n}-equivariant resolutions
of the residue field of a polynomial ring in {\tt n} variables. The function that does
this calculation, @TO schurResolution@, is based on an empirical method, which gives
the correct answer in surprisingly many situations.
In the {\tt GL(n)} situation, we are resolving the residue field which as a representation
has character {\tt 1_S}. The space of linear forms in the polynomial ring
considered as a {\tt GL}-representation has character {\tt V = s_1}.
Example
n = 4
M = {1_S}
schurResolution(V,M,DegreeLimit => n)
Text
Not surprisingly, the syzygy modules are generated by the exterior powers of {\tt V}.
The residue field as a representation of the symmetric group {\tt S_n}
has character {\tt s_n}. The space of linear forms in the polynomial ring
considered as an {\tt S_n}-representation coincides with the permutation representation
of {\tt S_n}, thus has character {\tt s_n + s_{n-1,1}}.
Example
rep = q_n + q_(n-1,1)
M = {q_n}
sR = schurResolution(rep,M,DegreeLimit => n)
Text
We can check that the second syzygy module is generated by the second exterior power of the permutation
representation.
Example
eP2rep = exteriorPower(2,rep)
eP2rep == last sR#2#0
///
doc ///
Key
SchurRing
(symbol _,SchurRing,List)
(symbol _,SchurRing,Sequence)
(symbol _,SchurRing,ZZ)
Headline
The class of all Schur rings
Description
Text
A Schur ring is the representation ring for the general linear group of {\tt n\times n}
matrices, and one can be constructed with @TO schurRing@.
Example
S = schurRing(QQ,s,4)
Text
Alternatively, its elements can be interpreted as virtual characters of symmetric groups,
by setting the value of the option @TO GroupActing@ to {\tt "Sn"}.
Example
Q = schurRing(QQ,q,4,GroupActing => "Sn")
Text
The element corresponding to the Young diagram {\tt \{3,2,1\}}, is obtained as follows.
Example
s_{3,2,1}
Text
Alternatively, we can use a @TO Sequence@ instead of a @TO List@ as the index of a Schur
function.
Example
s_(3,2,1)
Text
For Young diagrams with only one row one can use positive integers as subscripts.
Example
q_4
Text
The name of the Schur ring can be used with a subscript to describe a symmetric
function.
Example
Q_{2,2}
S_5
Text
The dimension of the underlying virtual {\tt GL}-representation can be obtained
with @TO dim@.
Example
dim s_{3,2,1}
Text
Multiplication in the ring comes from tensor product of representations.
Example
s_{3,2,1} * s_{1,1}
q_{2,1} * q_{2,1}
SeeAlso
schurRing
///
doc ///
Key
schurRing
(schurRing,Ring,Symbol,ZZ)
(schurRing,Ring,Thing,ZZ)
(schurRing,Ring,Symbol)
(schurRing,Ring,Thing)
(schurRing,Thing,ZZ)
(schurRing,Thing)
Headline
Make a SchurRing
Description
Text
{\tt S = schurRing(A,s,n)} creates a Schur ring of degree {\tt n} over the base ring
{\tt A}, with variables based on the symbol {\tt s}. This is the representation ring
for the general linear group of {\tt n} by {\tt n} matrices, tensored with the ring
{\tt A}. If {\tt s} is already assigned a value as a variable in a ring, its base
symbol will be used, if it is possible to determine.
Example
S = schurRing(QQ[x],s,3);
(x*s_{2,1}+s_3)^2
Text
Alternatively, the elements of a Schur ring may be interpreted as characters of
symmetric groups. To indicate this interpretation, one has to set the value of the option
@TO GroupActing@ to "Sn".
Example
S = schurRing(s,4,GroupActing => "Sn");
exteriorPower(2,s_(3,1))
Text
If the dimension {\tt n} is not specified, then one should think of {\tt S} as the
full ring of symmetric functions over the base {\tt A}, i.e. there is no restriction
on the number of parts of the partitions indexing the generators of {\tt S}.
Example
S = schurRing(ZZ/5,t)
(t_(2,1)-t_3)^2
Text
If the base ring {\tt A} is not specified, then @TO QQ@ is used instead.
Example
S = schurRing(r,2,EHPVariables => (re,rh,rp))
toH r_(2,1)
SeeAlso
SchurRing
symmRing
///
doc ///
Key
(coefficientRing, SchurRing)
Headline
Coefficient ring of a Schur ring
Usage
coefficientRing S
Inputs
S:SchurRing
Description
Text
Given a Schur ring {\tt S}, the function returns its coefficient ring.
Example
S = schurRing(ZZ[x],s,4);
coefficientRing S
A = schurRing(QQ,a,3);
B = schurRing(A,b,2);
coefficientRing B
///
document {
Key => {SchurRingIndexedVariableTable,(symbol _,SchurRingIndexedVariableTable,Thing)},
"This class is used as part of the implementation of a type of indexed variable used just for Schur rings.",
SeeAlso => { IndexedVariableTable }
}
doc ///
Key
symmRing
(symmRing,Ring,ZZ)
(symmRing,ZZ)
Headline
Make a Symmetric ring
Usage
symmRing(A,n)
symmRing n
Inputs
A:Ring
n:ZZ
Description
Text
The method {\tt symmRing} creates a Symmetric ring of dimension {\tt n} over a base ring
{\tt A}. This is the subring of the ring of symmetric functions over the base {\tt A}
consisting of polynomials in the first {\tt n} elementary (or complete, or power sum)
symmetric functions. If {\tt A} is not specified, then it is assumed to be @TO QQ@.
Example
R = symmRing(QQ[x,y,z],4)
e_2*x+y*p_3+h_2
toS oo
Text
The elements of a Symmetric ring can be interpreted as characters of either symmetric or
general linear groups. This is controlled by the value of the option @TO GroupActing@, whose
default value is "GL" (general linear group). The other possibility for its value is
"Sn" (symmetric group).
Example
R = symmRing(QQ,3,GroupActing => "Sn")
toE symmetricPower(2,e_2)
SeeAlso
SchurRing
///
doc ///
Key
eVariable
Headline
Elementary symmetric functions in a Symmetric ring
Description
Text
For a Symmetric ring {\tt R} of dimension {\tt n}, {\tt R.eVariable} is a function
which assigns to each index {\tt 1\leq i\leq n} the {\tt i}-th elementary symmetric
function. If {\tt i} is outside the given bounds, an error is returned.
Example
R = symmRing(QQ,5,EHPVariables => (a,b,c));
R.eVariable 3
SeeAlso
hVariable
pVariable
///
doc ///
Key
hVariable
Headline
Complete symmetric functions in a Symmetric ring
Description
Text
For a Symmetric ring {\tt R} of dimension {\tt n}, {\tt R.hVariable} is a function
which assigns to each index {\tt 1\leq i\leq n} the {\tt i}-th complete symmetric
function. If {\tt i} is outside the given bounds, an error is returned.
Example
R = symmRing(QQ,2,EHPVariables => (x,y,z));
R.hVariable 2
SeeAlso
eVariable
pVariable
///
doc ///
Key
pVariable
Headline
Power-sum symmetric functions in a Symmetric ring
Description
Text
For a Symmetric ring {\tt R} of dimension {\tt n}, {\tt R.pVariable} is a function
which assigns to each index {\tt 1\leq i\leq n} the {\tt i}-th power-sum symmetric
function. If {\tt i} is outside the given bounds, an error is returned.
Example
R = symmRing(QQ,4);
R.pVariable 2
SeeAlso
eVariable
hVariable
///
doc ///
Key
(numgens,SchurRing)
Headline
Number of generators of Schur ring.
Description
Text
Given a Schur ring {\tt S}, the function {\tt numgens} outputs the number
of generators of {\tt S}. This is equal to the relative dimension of {\tt S}
over its base ring, and also to the maximal number of parts of a partition
allowed as an index for the elements of {\tt S}.
Example
R = schurRing(QQ,r,6);
numgens R
S = schurRing(s);
numgens S
///
doc ///
Key
schurRingOf
(schurRingOf,Ring)
Headline
The Schur ring corresponding to a given Symmetric ring.
Usage
S = schurRingOf R
Inputs
R:Ring
Outputs
S:SchurRing
Description
Text
Given a ring {\tt R}, the function {\tt schurRingOf} attempts to return a
Schur ring {\tt S} that is associated to {\tt R} in a natural way. Namely, if
the attribute {\tt R.Schur} points to a Schur ring, then the function returns
that ring. If {\tt R} is already a Schur ring, then the ring {\tt R} is returned.
Otherwise, if the Schur level of {\tt R} is at least one, then the function
constructs a Schur ring over the base ring {\tt A} of {\tt R}, having the same
relative dimension over {\tt A} as {\tt R}. If the Schur level of {\tt R} is zero, then
an error is returned.
Example
R = schurRing(QQ,r,6);
schurRingOf R
Q = symmRing(QQ,3);
A = schurRingOf Q;
schurRingOf Q
SeeAlso
symmetricRingOf
///
doc ///
Key
symmetricRingOf
(symmetricRingOf,Ring)
Headline
The Symmetric ring corresponding to a given (Schur) ring.
Usage
R = symmetricRingOf S
Inputs
S:Ring
Outputs
R:Ring
Description
Text
Given a (Schur) ring {\tt S}, the function {\tt symmetricRingOf} returns a
(Symmetric) ring {\tt R} that is associated to {\tt S} in a natural way. Namely, if
the attribute {\tt S.symmRing} points to a ring, then the function returns
that ring. If {\tt S} is not a Schur ring, then the function returns {\tt S}.
Otherwise, if {\tt S} is a Schur ring, then the function
constructs a polynomial ring over the Symmetric ring {\tt R_A} of the base ring {\tt A} of
{\tt R}, having the same relative dimension over {\tt R_A} as {\tt S} over {\tt A}.
Example
A = schurRing(QQ,a,6);
B = schurRing(A,b,3);
symmetricRingOf B
symmetricRingOf ZZ
SeeAlso
schurRingOf
///
doc ///
Key
toS
(toS,RingElement)
(toS,RingElement,SchurRing)
Headline
Schur (s-) basis representation
Usage
fs = toS f
fs = toS(f,S)
Description
Text
Given a symmetric function {\tt f}, the function
{\tt toS} yields a representation of {\tt f} as a linear
combination of Schur functions.
If {\tt f} is an element of a Symmetric ring {\tt R} and the output Schur ring {\tt S}
is not specified, then the output {\tt fs} is an element of the Schur ring
associated to {\tt R} (see @TO schurRingOf@).
Example
R = symmRing(QQ,4);
fs = toS(e_1*h_2+p_3)
S = schurRing(s,2);
toS(fs,S)
Text
This also works over tensor products of Symmetric/Schur rings.
Example
R = symmRing(4, EHPVariables => (a,b,c), SVariable => r);
S = symmRing(R, 2, EHPVariables => (x,y,z), SVariable => s);
T = symmRing(S, 3, SVariable => t);
A = schurRingOf T;
f = a_3*x_2*e_1 - b_1*z_2*p_3
toS f
SeeAlso
toH
toE
toP
///
doc ///
Key
toE
(toE,RingElement)
Headline
Elementary symmetric (e-) basis representation
Usage
fe = toE f
Inputs
f:RingElement
element of a Symmetric or Schur ring
Outputs
fe:RingElement
element of a Symmetric ring
Description
Text
Given a symmetric function {\tt f}, the function
{\tt toE} yields a representation of {\tt f} as a polynomial
in the elementary symmetric functions.
If {\tt f} is an element of a Schur ring {\tt S} then the output {\tt fe} is an
element of the Symmetric ring associated to {\tt S} (see @TO symmetricRingOf@).
Example
R = symmRing 7;
toE(h_3*e_3)
S = schurRing(s,4)
toE S_{3,2,1}
Text
This also works over tensor products of Symmetric/Schur rings.
Example
R = schurRing(r, 4, EHPVariables => (a,b,c));
S = schurRing(R, s, 2, EHPVariables => (x,y,z));
T = schurRing(S, t, 3);
A = symmetricRingOf T;
f = (r_1+s_1+t_1)^2
toE f
SeeAlso
toH
toS
toP
///
doc ///
Key
toH
(toH,RingElement)
Headline
Complete symmetric (h-) basis representation
Usage
fh = toH f
Inputs
f:RingElement
element of a Symmetric or Schur ring
Outputs
fh:RingElement
element of a Symmetric ring
Description
Text
Given a symmetric function {\tt f}, the function
{\tt toH} yields a representation of {\tt f} as a polynomial
in the complete symmetric functions.
If {\tt f} is an element of a Schur ring {\tt S} then the output {\tt fh} is an
element of the Symmetric ring associated to {\tt S} (see @TO symmetricRingOf@).
Example
R = symmRing 7;
toH(h_3*e_3)
S = schurRing(s,4)
toH S_{3,2,1}
Text
This also works over tensor products of Symmetric/Schur rings.
Example
R = schurRing(r, 4, EHPVariables => (a,b,c));
S = schurRing(R, s, 2, EHPVariables => (x,y,z));
T = schurRing(S, t, 3);
A = symmetricRingOf T;
f = (r_1+s_1+t_1)^2
toH f
SeeAlso
toE
toS
toP
///
doc ///
Key
toP
(toP,RingElement)
Headline
Power-sum (p-) basis representation
Usage
fp = toP f
Inputs
f:RingElement
element of a Symmetric or Schur ring
Outputs
fp:RingElement
element of a Symmetric ring
Description
Text
Given a symmetric function {\tt f}, the function
{\tt toP} yields a representation of {\tt f} as a polynomial
in the power-sum symmetric functions.
If {\tt f} is an element of a Schur ring {\tt S} then the output {\tt fp} is an
element of the Symmetric ring associated to {\tt S} (see @TO symmetricRingOf@).
Example
R = symmRing 7;
toP(h_3*e_3)
S = schurRing(s,4)
toP S_{3,2,1}
Text
This also works over tensor products of Symmetric/Schur rings.
Example
R = schurRing(r, 4, EHPVariables => (a,b,c));
S = schurRing(R, s, 2, EHPVariables => (x,y,z));
T = schurRing(S, t, 3);
A = symmetricRingOf T;
f = (r_1+s_1+t_1)^2
toP f
SeeAlso
toH
toS
toE
///
doc ///
Key
jacobiTrudi
(jacobiTrudi,BasicList,Ring)
Headline
Jacobi-Trudi determinant
Usage
f = jacobiTrudi(lambda,R)
Inputs
lambda:BasicList
a nonincreasing list of integers, or a partition
R:Ring
a Symmetric ring
Outputs
f:RingElement
an element of a Symmetric ring
Description
Text
Given a partition {\tt lambda} and Symmetric ring {\tt R},
the method evaluates the Jacobi-Trudi determinant corresponding
to the partition {\tt lambda}, yielding a representation of
the Schur function {\tt s_{lambda}} as a symmetric function
in {\tt R}. The default option is to represent this symmetric
function in terms of {\tt e-}polynomials.
Example
R = symmRing(QQ,10);
jacobiTrudi({3,2,2,1},R)
jacobiTrudi(new Partition from {4,4,1},R,EorH => "H")
toS oo
///
doc///
Key
EorH
[jacobiTrudi,EorH]
Headline
e- or h- representation of Jacobi-Trudi determinant
Usage
EorH => s
Inputs
s:String
either "E" or "H"
Description
Text
This option allows one to choose between evaluating the
Jacobi-Trudi determinant in the {\tt e}- or {\tt h}- basis.
If the length of the conjugate partition {\tt lambda'} is
larger than the length of {\tt lambda}, then it is
computationally less expensive to set the option {\tt EorH}
to {\tt "H"}. Otherwise, the default value {\tt "E"} is more
efficient.
///
doc///
Key
[jacobiTrudi,Memoize]
Headline
Store values of the jacobiTrudi function.
Usage
Memoize => b
Inputs
b:Boolean
Description
Text
If the option is set to {\tt true} then all the values of the jacobiTrudi
function that are computed are recorded into a special hash table attached
to the symmetric ring inside which the computations are done.
///
doc ///
Key
plethysm
(plethysm,RingElement,RingElement)
Headline
Plethystic operations on representations
Usage
pl = plethysm(f,g)
pl = f @ g
Inputs
f:RingElement
element of Symmetric ring or Schur ring
g:RingElement
element of Symmetric ring or Schur ring
Outputs
pl:RingElement
element of the ring of {\tt g}
Description
Text
Given a symmetric functions {\tt f} and the character {\tt g} of a virtual representation of a product
of general linear and symmetric groups, the method computes the character of the
plethystic composition of {\tt f} and {\tt g}. The result of this operation will be an element of
the ring of {\tt g}. We use the binary operator @TO symbol \@ @ as a synonym for the plethysm function.
Example
R = symmRing(QQ,5);
pl = plethysm(h_2,h_3)
toS pl
S = schurRing(QQ,q,3);
h_2 @ q_{2,1}
plethysm(q_{2,1},q_{2,1})
T = schurRing(S,t,2,GroupActing => "Sn");
plethysm(q_{1,1,1}-q_{2,1}+q_{3},q_{2,1}*t_2-t_{1,1})
p_3 @ (q_{2,1}*t_2-t_{1,1})
///
doc ///
Key
(plethysm,BasicList,RingElement)
Headline
Plethystic operations on representations
Usage
pl = plethysm(lambda,g)
Inputs
lambda:BasicList
nonincreasing sequence of positive integers, or partition
g:RingElement
element of Symmetric ring or Schur ring
Outputs
pl:RingElement
element of the ring of {\tt g}
Description
Text
The method computes the character of the representation obtained by applying the Schur functor
{\tt S_{\lambda}} to the representation with character {\tt g}, where
{\tt \lambda} is a partition.
Example
R = symmRing(QQ,3);
S = schurRing(QQ,q,3);
toE plethysm({2,1},e_1*e_2-e_3)
plethysm({2,1,1},q_{1,1})
T = schurRing(S,t,4,GroupActing => "Sn");
plethysm({1,1},q_1*t_{3,1})
///
doc ///
Key
(plethysm,RingElement,ClassFunction)
(plethysm,BasicList,ClassFunction)
Headline
Plethystic operations on class functions
Usage
pl = plethysm(f,cF)
pl = plethysm(lambda,cF)
Description
Text
These methods describe the result of applying plethystic operations to a virtual
character of a symmetric group. These operations are described either via a symmetric
function {\tt f}, or a partition {\tt lambda}. Since {\tt cF} corresponds to an {\tt S_n}-
representation, the option @TO GroupActing@ is irrelevant in this case.
Example
cF = new ClassFunction from {{2} => 1, {1,1} => -1};
pl1 = plethysm({1,1},cF)
R = symmRing 5;
pl2 = plethysm(e_1+e_2,cF)
S = schurRingOf R;
symmetricFunction(cF,S)
symmetricFunction(pl1,S)
symmetricFunction(pl2,S)
///
{*doc ///
Key
(exteriorPower,ZZ,RingElement)
Headline
Exterior power of a representation
Usage
ep = exteriorPower(n,rep)
Inputs
n:ZZ
rep:RingElement
an element of a SchurRing
Outputs
ep:RingElement
Description
Text
Given a representation {\tt rep} of a product of general linear
groups, and a positive integer {\tt n}, the function returns the
{\tt n}-th exterior power of this representation.
Example
S = schurRing(QQ,s,2)
T = schurRing(S,t,3)
exteriorPower(4,s_{1}+t_{1})
///
doc ///
Key
(symmetricPower,ZZ,RingElement)
Headline
Symmetric power of a representation
Usage
ep = symmetricPower(n,rep)
Inputs
n:ZZ
rep:RingElement
an element of a SchurRing
Outputs
ep:RingElement
Description
Text
Given a representation {\tt rep} of a product of general linear
groups, and a positive integer {\tt n}, the function returns the
{\tt n}-th symmetric power of this representation.
Example
S = schurRing(QQ,s,2)
T = schurRing(S,t,3)
symmetricPower(4,s_{1}+t_{1})
///
*}
doc ///
Key
schurResolution
(schurResolution,RingElement,List,List)
(schurResolution,RingElement,List)
Headline
Compute an ``approximate'' equivariant resolution of a module.
Usage
resol = schurResolution(rep,M,lS)
resol = schurResolution(rep,M)
Inputs
rep:RingElement
element of a SchurRing
M:List
list of representations, corresponding to the homogeneous components of a module {\tt M}.
lS:List
list of representations, corresponding to the homogeneous components of a polynomial ring {\tt S}.
Outputs
resol:List
Description
Text
Given a representation {\tt rep} of a (product of) general linear
or symmetric group(s) {\tt G}, we consider the symmetric algebra {\tt S = Sym(rep)}
and an {\tt S}-module {\tt M} which is also a {\tt G}-module in such
a way that the {\tt S}-module structure on {\tt M} respects the
{\tt G}-action. More generally, {\tt S} can be any graded ring, of which one inputs only
finitely many homogeneous components as a list {\tt lS} of characters of {\tt G}. The main reason
why we allow this generality is because most of the time it is computationally expensive to calculate
the symmetric powers of the representation {\tt rep}, so we give the user the option to compute these
symmetric powers by different methods and use the results as input for the schurResolution routine.
We are interested in computing an equivariant
resolution of {\tt M}. This depends on both the {\tt G}- and {\tt S}-module structure
of {\tt M} in general, but in many examples that occur in practice, it turns out that
the differentials in the resolution have maximal rank among all
{\tt G}-module homomorphisms between the free modules in the resolution.
We will therefore assume that this is the case for the module {\tt M} that we are
trying to resolve, and thus disregard its {\tt S}-module structure.
More precisely, the assumptions that we make about {\tt M} are as follows: {\tt M} is
a graded {\tt S}-module, with {\tt M_i = 0} for {\tt i<0}, where the grading on {\tt S} is standard,
given by setting the degrees of the elements of {\tt rep} equal to 1. Since we assumed
that the {\tt G}-structure of {\tt M} determines the syzygies, all the relevant
information is concentrated in finitely many homogeneous components of {\tt M} (namely
up to {\tt reg(M)+pd(M)}, the sum of the regularity and the projective dimension of
{\tt M}). We will thus assume that {\tt M}
is given as a list of {\tt G}-representations, corresponding to (a subset of) the
relevant homogeneous components. The function {\tt schurResolution} takes as
inputs the representation {\tt rep}, the module {\tt M}, and as optional arguments a {\tt DegreeLimit}
{\tt d}, and a {\tt SyzygyLimit} {\tt c}. The ring {\tt S} itself can occur as input data, being
described as a list of {\tt G}-representations, just like {\tt M}.
The routine outputs the generators of degree at most {\tt d} of the
first {\tt c+1} syzygy modules (from {\tt 0} to {\tt c}). They are listed as a
sequence of pairs, consisting of the degree of the generators of the syzygy modules
together with the characters of the {\tt G}-representations they correspond to.
If the syzygy bound {\tt c} is not given,
then all syzygy modules are computed. If the degree bound {\tt d} is not given, then
it is assumed to be equal to the largest degree among the homogeneous components of
{\tt M} in the input, i.e. one less than the length of the @TO List@ {\tt M}.
The example below computes the resolution of the quadratic Veronese
surface in {\tt P^5}.
Example
S = schurRing(QQ,s,3)
rep = s_{2}
M = {1_S,s_{2},s_{4},s_{6},s_{8},s_{10},s_{12}}
schurResolution(rep,M)
Text
Next, we compute the syzygies of degree at most {\tt 7} in the resolution
of the cubic Veronese embedding of {\tt P^2}.
Example
rep = s_{3}
M = {1_S,s_{3},s_{6},s_{9},s_{12},s_{15},s_{18},s_{21},s_{24},s_{27}}
d = 7
schurResolution(rep,M,DegreeLimit => d)
Text
We can compute the resolution of the ideal of {\tt 2\times 2} minors of a {\tt 3\times 4}
matrix, which corresponds to the Segre embedding of {\tt P^2\times P^3}:
Example
T = schurRing(S,t,4)
rep = s_1 * t_1
M = {1_T} | apply(splice{1..8},i -> s_i * t_i)
schurResolution(rep,M)
Text
The following example computes the equivariant resolution of the residue field of a
polynomial ring in {\tt n=5} variables, with respect to the action of the symmetric
group {\tt S_n}.
Example
n = 5;
S = schurRing(QQ,s,n,GroupActing => "Sn");
rep = s_n + s_{n-1,1};
M = {s_n}
schurResolution(rep,M,DegreeLimit => n)
Text
Generalizing this, we can compute the equivariant resolution of the quotient of the
polynomial ring in {\tt n=5} variables by the ideal of square-free monomials of
degree two, with respect to the action of the symmetric group {\tt S_n}.
Example
M = {s_n} | splice{n:rep};
schurResolution(rep,M)
///
doc ///
Key
[schurResolution,DegreeLimit]
Headline
Specifies the maximal degree of syzygies to be computed
Description
Text
This is an optional argument for the @TO schurResolution@ routine. It specifies an upper bound for the
degrees of the generators of the syzygy modules in the equivariant resolution of an equivariant module {\tt M}
to be computed by the routine. If a {\tt DegreeLimit} is not specified, then it is assumed to be equal to the
maximal degree in which the module {\tt M} is specified as a representation.
Example
A = schurRing(a,3,GroupActing => "Sn");
B = schurRing(A,b,2);
rep = (a_3 + a_{2,1}) * b_1
d = dim rep
M = {a_3 * 1_B};
sR = schurResolution(rep,M,DegreeLimit => d)
SeeAlso
[schurResolution,SyzygyLimit]
///
doc ///
Key
[schurResolution,SyzygyLimit]
Headline
Specifies the number of syzygy modules to be computed
Description
Text
This is an optional argument for the @TO schurResolution@ routine. It specifies an upper bound for the
number of syzygy modules in the equivariant resolution of an equivariant module {\tt M} to be computed
by the routine. If a {\tt SyzygyLimit} is not specified, then all syzygy modules are computed.
The example below computes the {\tt 0}-th to {\tt 3}-rd syzygy modules of the {\tt 5}-th Veronese embedding
of {\tt P^2}.
Example
S = schurRing(s,3);
rep = s_{5};
M = {1_S,s_{5},s_{10},s_{15},s_{20},s_{25},s_{30}};
schurResolution(rep,M,SyzygyLimit => 3)
SeeAlso
[schurResolution,DegreeLimit]
///
doc ///
Key
schurLevel
(schurLevel,Ring)
Headline
Number of SchurRings the ring is a tensor product of.
Usage
lev = schurLevel(R)
Inputs
R:Ring
Outputs
lev:ZZ
Description
Text
For the representation ring {\tt R} of a product of {\tt lev}
general linear groups, the function returns {\tt lev}. If {\tt R}
is not a representation ring, then the function returns 0.
Example
R = schurRing(QQ,r,3);
S = schurRing(R,s,5);
T = schurRing(S,t,2);
schurLevel R
schurLevel S
schurLevel T
schurLevel QQ
///
doc ///
Key
(partitions,Set,BasicList)
Headline
Partitions of a set
Usage
par = partitions(S,L)
Inputs
S:Set
L:BasicList
a nonincreasing list of integers, or a partition
Outputs
par:List
Description
Text
Given a set {\tt S} and a partition {\tt L=\{l_1\geq l_2\cdots\}}, the method
returns the list of partitions of the set {\tt S} of type
{\tt L}, i.e. representations of {\tt S} as {\tt S=S_1\cup S_2\cup\cdots}, where
the {\tt S_i}'s are disjoint subsets of {\tt S} having {\tt t_i} elements.
Example
partitions(set{1,2,3,4},{2,1,1})
partitions(set{a,b,c,d,e},new Partition from {3,2})
///
{*
doc ///
Key
(chi,BasicList,BasicList)
Headline
Irreducible character of symmetric group
Usage
v = chi(lambda,rho)
Inputs
lambda:BasicList
a nondecreasing list of positive integers, or a partition
rho:BasicList
a nondecreasing list of positive integers, or a partition
Outputs
v:QQ
Description
Text
Given two partitions {\tt lambda} and {\tt rho} of the integer {\tt N}, this method
computes the value of the irreducible character of the symmetric group
corresponding to the partition {\tt lambda} evaluated on
any permutation of cycle-type {\tt rho}.
The character of the trivial representation takes the value
1 on any permutation:
Example
chi({4},{2,1,1})
Text
The character of the sign representation takes the value -1 on
a cycle of length 4:
Example
chi({1,1,1,1},{4})
SeeAlso
symmetricFunction
classFunction
///
*}
doc ///
Key
ClassFunction
(symbol +,ClassFunction,ClassFunction)
(symbol -,ClassFunction,ClassFunction)
(symbol *,ClassFunction,ClassFunction)
(symbol *,ClassFunction,RingElement)
(symbol *,RingElement,ClassFunction)
(symbol *,ClassFunction,Number)
(symbol *,Number,ClassFunction)
(symbol ==,ClassFunction,ClassFunction)
Headline
The class of all Class functions
Description
Text
A class function (or virtual character of a symmetric group {\tt S_n}) is a function that is constant
on the conjugacy classes of {\tt S_n}. Class functions for {\tt S_n} are in one to one
correspondence with symmetric functions of degree {\tt n}. The class functions corresponding
to actual representations of {\tt S_n} are called {\tt characters}.
The character of the standard representation of {\tt S_3} is
Example
S = schurRing(QQ,s,3);
classFunction(s_{2,1})
Text
The character of the sign representation of {\tt S_5} is
Example
S = schurRing(QQ,s,5);
classFunction(s_{1,1,1,1,1})
Text
We can go back and forth between class functions and symmetric functions.
Example
R = symmRing(QQ,3);
cF = new ClassFunction from {{1,1,1} => 2, {3} => -1};
sF = symmetricFunction(cF,R)
toS sF
classFunction sF
Text
We can add, subtract, multiply, scale class functions:
Example
S = schurRing(QQ,s,4);
c1 = classFunction(S_{2,1,1}-S_{4});
c2 = classFunction(S_{3,1});
c1 + c2
c1 * c2
3*c1 - c2*2
///
doc ///
Key
(degree,ClassFunction)
Headline
Degree of virtual character
Description
Text
For a virtual character {\tt ch} of a symmetric group on {\tt n} letters, the degree
of {\tt ch} is {\tt n}.
Example
S = schurRing(s,5);
ch = classFunction s_(3,1,1)
degree ch
///
doc ///
Key
symmetricFunction
(symmetricFunction,ClassFunction,Ring)
Headline
Converts class function to symmetric function
Usage
f = symmetricFunction(ch,S)
Inputs
ch:ClassFunction
S:Ring
a Symmetric or Schur ring
Outputs
f:RingElement
element of a Symmetric or Schur ring
Description
Text
Given a virtual character {\tt cF} of a
symmetric group, and given a Symmetric ring {\tt S},
the method computes the corresponding symmetric function
as an element of {\tt S}.
Example
S = symmRing(QQ,4);
cF = new ClassFunction from {{1,1,1,1}=>24};
symmetricFunction(cF,S)
symmetricFunction(cF,schurRingOf S)
SeeAlso
classFunction
-- chi
///
doc ///
Key
classFunction
(classFunction,RingElement)
Headline
Converts symmetric function to class function
Usage
ch = classFunction(f)
Inputs
f:RingElement
element of a Symmetric ring
Outputs
ch:ClassFunction
Description
Text
Given a symmetric function {\tt f}, homogeneous of degree {\tt N},
the method computes the corresponding virtual character
of the symmetric group {\tt S_N}.
The character of the standard representation of {\tt S_5} is
Example
R = symmRing(QQ,5);
classFunction(jacobiTrudi({4,1},R))
Text
The character of the second exterior power of the standard representation of {\tt S_5} is
Example
R = symmRing(QQ,5);
classFunction(jacobiTrudi({3,1,1},R))
SeeAlso
symmetricFunction
-- chi
///
doc ///
Key
(classFunction,BasicList)
Headline
Character of irreducible representation of symmetric group
Usage
ch = classFunction(l)
Inputs
l:BasicList
partition
Outputs
ch:ClassFunction
Description
Text
Given a partition {\tt l} of {\tt N}, the method computes the character of the irreducible
{\tt S_N}-representation corresponding to the partition {\tt l}.
Example
R = symmRing(QQ,7);
cF = classFunction({3,2,1})
toS(symmetricFunction(cF,R))
SeeAlso
symmetricFunction
///
doc ///
Key
scalarProduct
Headline
Standard pairing on symmetric functions/class functions
Description
Text
This method computes the standard scalar product on the ring {\tt \Lambda}
of symmetric functions. One way to define this product is by imposing
that the collection of Schur functions {\tt s_{\lambda}} form
an orthonormal basis.
Alternatively, by the correspondence between symmetric functions
and virtual characters of symmetric groups, this scalar product
coincides with the standard scalar product on class functions.
The number of standard tableaux of shape {\tt \{4,3,2,1\}} is:
Example
R = symmRing(QQ,10);
S = schurRing(QQ,s,10);
scalarProduct(h_1^10,s_{4,3,2,1})
SeeAlso
internalProduct
///
doc ///
Key
(scalarProduct,RingElement,RingElement)
Headline
Standard scalar product of symmetric functions
Usage
sp = scalarProduct(f1,f2)
Inputs
f1:RingElement
element of a Symmetric Ring
f2:RingElement
element of a Symmetric Ring
Outputs
sp:QQ
Description
Text
Given symmetric functions {\tt f1} and {\tt f2}, the method
computes the standard pairing between {\tt f1} and {\tt f2}.
Example
R = symmRing(QQ,5);
S = schurRingOf R
scalarProduct(h_5,p_5)
scalarProduct(S_{4,1},p_5)
Text
Indeed, the coefficients of {\tt s_5} and {\tt s_{4,1}} in the
s-basis expansion of {\tt h_5} are as computed above:
Example
R = symmRing(QQ,5);
toS p_5
///
doc ///
Key
(scalarProduct,ClassFunction,ClassFunction)
Headline
Standard scalar product of class functions
Usage
sp = scalarProduct(ch1,ch2)
Inputs
ch1:ClassFunction
ch2:ClassFunction
Outputs
sp:QQ
Description
Text
Given virtual characters {\tt ch1} and {\tt ch2}, the method
computes the standard pairing between {\tt ch1} and {\tt ch2}.
Example
ch1 = new ClassFunction from {{3,2} => 2, {2,2,1} => -2, {3,1,1} => 2, {5} => 1};
ch2 = new ClassFunction from {{2,2,1} => -2, {5} => 1, {1,1,1,1,1} => 5, {3,2} => 3, {4,1} => -2};
scalarProduct(ch1,ch2)
///
doc ///
Key
internalProduct
Headline
Internal product of symmetric functions/class functions
Description
Text
This method computes the internal (Kronecker) product of two homogeneous symmetric
functions of the same degree. If we think of these functions as being
virtual characters of some symmetric group, then their internal product
is just the character of the tensor product of the corresponding virtual
representations. We use the binary operator @TO symbol **@ as a shorthand for
@TO internalProduct@.
The complete symmetric function of degree {\tt n} corresponds
to the trivial {\tt S_n}-representation and is therefore
the unit of the representation ring of {\tt S_n}:
Example
R = symmRing(QQ,5);
S = schurRing(QQ,s,3);
internalProduct(h_3,s_{2,1})
toE(h_3 ** e_3)
Text
The square of the sign representation is the trivial representation:
Example
R = symmRing(QQ,5);
toH internalProduct(e_3,e_3)
SeeAlso
scalarProduct
///
doc ///
Key
(internalProduct,RingElement,RingElement)
Headline
Kronecker product of symmetric functions
Usage
ip = internalProduct(f1,f2)
Inputs
f1:RingElement
element of a Symmetric ring or a Schur ring
f2:RingElement
element of a Symmetric ring or a Schur ring
Outputs
ip:Ring
a Symmetric ring or a Schur Ring
Description
Text
Given symmetric functions {\tt f1} and {\tt f2}, the method
computes the Kronecker product {\tt ip} between {\tt f1} and {\tt f2}.
The output {\tt ip} is an element in the ring of {\tt f2}.
Example
R = symmRing(QQ,6);
S = schurRing(QQ,s,6);
toE(h_3**e_3)
Q = schurRing(QQ,q,6);
internalProduct(s_{3,3},q_{4,2})
Text
An error is returned if {\tt f1} and {\tt f2} don't have the
same degree.
///
doc ///
Key
(internalProduct,ClassFunction,ClassFunction)
Headline
Tensor product of virtual representations
Usage
ip = internalProduct(ch1,ch2)
Inputs
ch1:ClassFunction
ch2:ClassFunction
Outputs
ip:ClassFunction
Description
Text
Given virtual characters {\tt ch1} and {\tt ch2}, the method
computes the character of the tensor product of corresponding
virtual representations of the symmetric group.
Example
ch1 = new ClassFunction from {{4,4} => 2, {8} => -1, {5,2,1} => 2, {3,2,2,1} => 1};
ch2 = new ClassFunction from {{2,2,2,2} => -4, {5,2,1} => 1, {3,2,2,1} => 3};
internalProduct(ch1,ch2)
ch1 * ch2
///
doc ///
Key
centralizerSize
(centralizerSize,List)
Headline
Size of the centralizer of a permutation
Usage
n = centralizerSize(rho)
Inputs
rho:List
Outputs
n:ZZ
Description
Text
{\tt rho} is a list representing the cycle type of some permutation: the i-th entry in {\tt rho} is the number of cycles of length i of the permutation.
The output of the function {\tt centralizerSize} is the size of the centralizer in the symmetric group of any permutation of cycle type {\tt rho}. The cycle type {\tt rho}
corresponds to a partition {\tt lambda}, in which case {\tt centralizerSize(rho)} is also the value of the square norm of the symmetric function {\tt p_{lambda}}.
Example
centralizerSize{1,1,1}
R = symmRing(QQ,6);
u = p_1 * p_2 * p_3;
scalarProduct(u,u)
///
doc ///
Key
Memoize
Headline
Option to record values of the jacobiTrudi function
Description
Text
This is an optional argument for the @TO jacobiTrudi@
function, allowing one to store its values
in order to speed up computations.
///
doc ///
Key
SVariable
[schurRing,SVariable]
[symmRing,SVariable]
Headline
Specifies symbol representing s-functions
Description
Text
This is an optional argument for the constructor of a Symmetric ring. It indicates the
symbol to be used to denote s-functions in the associated Schur ring. The default value
is {\tt s}.
Example
R = symmRing(QQ,5,SVariable => getSymbol"s");
S = schurRingOf R
s_2^2
SeeAlso
EHPVariables
///
doc ///
Key
EHPVariables
[schurRing,EHPVariables]
[symmRing,EHPVariables]
Headline
Specifies sequence of symbols representing e-, h-, and p-functions
Description
Text
This is an optional argument for the constructor of a Symmetric or Schur ring. It indicates the
symbols to be used to denote e-, h-, and p-functions in the associated Symmetric ring. The
default values are {\tt (e,h,p)}.
Example
S = schurRing(QQ,s,4,EHPVariables => (getSymbol"a",getSymbol"b",getSymbol"c"));
R = symmetricRingOf S
epol = toE s_{2,2,2}
toS epol
SeeAlso
SVariable
///
doc ///
Key
GroupActing
[schurRing,GroupActing]
[symmRing,GroupActing]
Headline
Specifies the group that is acting
Description
Text
This is an optional argument for the @TO schurRing@ and @TO symmRing@ functions.
When the exterior or symmetric powers of a symmetric function {\tt g} are computed, the result
depends on whether {\tt g} is interpreted as a virtual representation of a general
linear or symmetric group. The option {\tt GroupActing} specifies the interpretation
to be considered. Its possible values are {\tt "GL"} and {\tt "Sn"}, with the former
being the default.
Example
S = schurRing(s,2);
exteriorPower(3,s_2)
T = schurRing(t,2,GroupActing => "Sn");
symmetricPower(2,t_{1,1})
Text
The first example computes the decomposition of {\tt \Lambda^3(Sym^2(V))} into irreducible
{\tt GL(V)}-representations, while the second one computes the
second symmetric power of the sign representation of the symmetric group {\tt S_2}.
///
--------------------
-- test Jacobi-Trudi
--------------------
TEST ///
E = symmRing(QQ,5)
f = jacobiTrudi({4,1},E)
g = toS f
G = ring g
assert (g == G_{4,1})
///
TEST ///
E = symmRing(QQ,5)
f = jacobiTrudi({2,1},E)
g = toS f
G = ring g
assert (g == G_{2,1})
///
TEST ///
E = symmRing(QQ,13)
f = jacobiTrudi({7,4,2},E)
g = toS f
G = ring g
assert (toS f == G_{7,4,2})
///
TEST ///
P = symmRing(QQ,6)
f = toS plethysm(jacobiTrudi({2},P), jacobiTrudi({2},P))
G = ring f
assert(f == G_{4}+G_{2,2})
///
TEST ///
Q = symmRing(QQ,5)
--S = schurRing(QQ,q,4)
S = schurRingOf Q
f = toS(plethysm(jacobiTrudi({3},Q), jacobiTrudi({2},Q)))
--assert(dim f == 220)
assert(dim(4,f) == 220)
///
------------------------
-- end test Jacobi-Trudi
------------------------
-----------
-- test dim
-----------
TEST ///
R = schurRing(r,3,GroupActing => "Sn")
S = schurRing(R,s,2)
T = schurRing(S,t,4,GroupActing => "Sn")
assert( (dim(r_1)) == 1 )
assert( (dim(s_2)) == 3 )
assert( (dim(s_3)) == 4 )
assert( (dim(t_4)) == 1 )
assert( (dim(r_1 * s_2 * t_3)) == 3 )
assert( (dim(r_1 * s_3 + t_4)) == 5 )
///
---------------
-- end test dim
---------------
---------------------
-- test plethysm, toS
---------------------
TEST ///
R = symmRing(QQ,4)
pl = plethysm({1,1},jacobiTrudi({2},R))
G = schurRingOf ring pl
assert(toS pl == G_{3,1})
///
TEST ///
R = symmRing(QQ,12)
pl = plethysm({1,1,1},jacobiTrudi({4},R))
assert(#listForm(toS pl) == 7)
///
TEST ///
R = symmRing(QQ, 9)
S = schurRing(QQ,q,3)
pl = plethysm(h_3,q_{2,1})
assert (dim(pl) == 120)
///
TEST ///
R = symmRing(QQ,3)
S = schurRingOf R
assert(toS(h_3 @ e_3) == S_{3,3,3})
///
TEST ///
S = schurRing(QQ,q,4)
assert(plethysm(q_{2,1},q_{1,1,1}) == q_{3,3,2,1})
///
TEST ///
R = symmRing(QQ, 12)
f = e_4
lambda = new Partition from {3}
assert(plethysm(lambda,f) == h_3 @ e_4)
///
TEST ///
schurRing(QQ,s,2)
assert(dim(plethysm(s_{2,1}+s_{3},s_{3})) == 40)
///
TEST ///
R = symmRing(QQ,20)
assert(#listForm(toS plethysm(h_5,h_4)) == 95)
///
TEST ///
R = symmRing(QQ, 10)
S = schurRingOf R
sch = toS(plethysm({2,1},h_3))
assert(dim(5,sch) == 14280)
///
TEST ///
R = symmRing 5
S = schurRing(s,3)
assert( ((h_2 + p_2) @ s_{2,1}) == 2*s_(4,2)-s_(4,1,1)-s_(3,3)+s_(3,2,1)+2*s_(2,2,2) )
///
TEST ///
S = schurRing(s,3)
T = schurRing(S,t,4,GroupActing => "Sn")
Q = schurRing(T,q,2)
assert( (s_2 @ q_{2,1}) == q_(4,2) )
assert( (s_{2,1} - s_{1,1,1} @ (t_3 + t_(2,1))) == -s_()*t_(1,1,1)+s_(2,1)*t_() )
assert( (plethysm({3},s_1 * t_1 * q_1)) == s_3*t_1*q_3+s_(2,1)*t_1*q_(2,1) )
assert( (plethysm({2,1},s_1 + t_1 + q_1)) == q_(2,1)+(t_1+s_1*t_())*q_2+(t_1+s_1*t_())*q_(1,1)+((2*s_1+s_())*t_1+(s_2+s_(1,1))*t_())*q_1+((s_2+s_(1,1)+s_1)*t_1+s_(2,1)*t_())*q_() )
assert( toH plethysm({2,1},s_1 + t_1 + q_1) == toH plethysm({2,1},toE(s_1 + t_1 + q_1)) )
///
----------------------------
-- end test of plethysm, toS
----------------------------
------------------------------------
----- symmetricPower & exteriorPower
------------------------------------
TEST ///
S = schurRing(s,5)
T = schurRing(S,t,3,GroupActing => "Sn")
assert( (symmetricPower(2,s_3)) == s_6+s_(4,2) )
assert( (symmetricPower(2,t_2)) == t_2 )
assert( (symmetricPower(2,s_3+t_2)) == (s_3+s_())*t_2+(s_6+s_(4,2))*t_() )
assert( (exteriorPower(3,s_3 * t_{2,1} - t_3)) == (s_(7,1,1)+s_(6,3)+s_(5,3,1)-s_(5,1)+s_(3,3,3)-s_(3,3)-s_())*t_3+(s_(8,1)+s_(7,2)+s_(7,1,1)+2*s_(6,3)+s_(6,2,1)+s_(5,4)+2*s_(5,3,1)-s_(5,1)+s_(4,3,2)+s_(3,3,3)-s_(3,3)+s_3)*t_(2,1)+(s_(7,1,1)+s_(6,3)-s_6+s_(5,3,1)-s_(4,2)+s_(3,3,3))*t_(1,1,1) )
assert( (exteriorPower(5,s_1 * t_1)) == s_(1,1,1,1,1)*t_1 )
///
TEST ///
R = symmRing(3,GroupActing => "Sn")
S = symmRing(R,4)
T = symmRing(S,2,GroupActing => "Sn")
a = R.hVariable 3
b = S.eVariable 4
c = T.pVariable 2
assert (toS(symmetricPower(3,a*b*c)) == symmetricPower(3,toS(a*b*c)))
assert (toS(exteriorPower(3,a*b*c)) == exteriorPower(3,toS(a*b*c)))
assert (toS(symmetricPower(3,a+b-c)) == symmetricPower(3,toS(a+b-c)))
assert (toS(exteriorPower(3,a*b-c)) == exteriorPower(3,toS(a*b-c)))
///
----------------------------------------
----- end symmetricPower & exteriorPower
----------------------------------------
-------------------------------------------------------------------
----- test characters of symmetric groups, scalarProd, internalProd
-------------------------------------------------------------------
TEST ///
R = symmRing(QQ,20)
S = schurRing(QQ,o,20)
assert(scalarProduct(o_{6,4,3,2,1},jacobiTrudi({3,3,3},symmetricRingOf S)*toP(o_{4,2,1})) == 2)
assert(scalarProduct(jacobiTrudi({6,4,3,2,1},R),jacobiTrudi({4,3,3,3,2,1},R)) == 0)
assert(scalarProduct(jacobiTrudi({6,4,3,2,1},R),o_{4,3,3,3,2,1}) == 0)
///
TEST ///
R = symmRing(QQ,5)
A = schurRing(QQ,a,4)
assert(internalProduct(e_2+h_2,a_{2}) == a_{2}+a_{1,1})
assert(toE internalProduct(a_{2},e_2+h_2) == toE p_1^2)
assert(dim internalProduct(a_{2,1}*a_{1},a_{2,2}) == 176)
///
TEST ///
R = symmRing(QQ,10)
ch1 = new ClassFunction from {{4,4} => 2, {8} => -1, {5,2,1} => 2, {3,2,2,1} => 1};
ch2 = new ClassFunction from {{2,2,2,2} => -4, {5,2,1} => 1, {3,2,2,1} => 3};
assert(toP symmetricFunction(internalProduct(ch1,ch2),R) == 1/8*p_1*p_2^2*p_3+1/5*p_1*p_2*p_5)
assert(toP symmetricFunction(ch1*ch2,R) == 1/8*p_1*p_2^2*p_3+1/5*p_1*p_2*p_5)
///
TEST ///
R = symmRing(QQ,4)
f = p_2^2
g = (e_2+h_2)^2
ch1 = classFunction(f)
ch2 = classFunction(g)
assert(symmetricFunction(internalProduct(ch1,ch2),R) == 0)
assert(internalProduct(f,g) == 0)
///
---------------------------------------------------------------------
--- end test characters of symmetric groups, scalarProd, internalProd
---------------------------------------------------------------------
---------------------------
--- test toS, toP, toE, toH
---------------------------
TEST ///
R = symmRing(QQ,6)
assert(toE(toS(e_1*e_2*e_3)) == e_1*e_2*e_3)
///
TEST ///
R = symmRing(QQ,5)
S = schurRing(QQ,q,3)
assert(toE(q_{2}) + e_2 == e_1^2)
///
TEST///
R = symmRing(QQ, 4)
assert(toP toE toH toE toH toP toE toE toP toH (p_1+p_2+p_3) == p_1+p_2+p_3)
///
TEST ///
R = symmRing(QQ,6)
S = schurRingOf R
toSf = map(S, R, apply(gens R, x -> toS(x)))
assert(toSf(e_1*e_2*e_3) == S_(3,2,1)+S_(3,1,1,1)+S_(2,2,2)+2*S_(2,2,1,1)+2*S_(2,1,1,1,1)+S_(1,1,1,1,1,1))
assert(toSf(h_1*h_2*h_3) == S_{1}*S_{2}*S_{3})
///
TEST ///
R = symmRing(QQ,7)
assert(toH toP toE (toS (jacobiTrudi({2,1},R))^2) == (h_1*h_2-h_3)^2)
///
TEST ///
S = schurRing(s,5,GroupActing => "Sn")
R = symmetricRingOf S
T = schurRing(S,t,3,EHPVariables => (getSymbol "eT", getSymbol "hT", getSymbol "pT"))
Q = symmetricRingOf T
a = toS((R.pVariable 2) * (R.eVariable 3))
b = a * (t_3 - t_{2,1})
c = toH(a + b)
d = toE(a - b)
f = toP b
assert( (a) == s_(3,1,1)-s_(2,2,1)-s_(1,1,1,1,1) )
assert( (b) == (s_(3,1,1)-s_(2,2,1)-s_(1,1,1,1,1))*t_3+(-s_(3,1,1)+s_(2,2,1)+s_(1,1,1,1,1))*t_(2,1) )
assert( (c) == (h_1^5-4*h_1^3*h_2+4*h_1*h_2^2+h_1^2*h_3-2*h_2*h_3)*hT_1*hT_2+(-2*h_1^5+8*h_1^3*h_2-8*h_1*h_2^2-2*h_1^2*h_3+4*h_2*h_3)*hT_3-h_1^5+4*h_1^3*h_2-4*h_1*h_2^2-h_1^2*h_3+2*h_2*h_3 )
assert( (d) == (-e_1^2*e_3+2*e_2*e_3)*eT_1^3+(3*e_1^2*e_3-6*e_2*e_3)*eT_1*eT_2+(-2*e_1^2*e_3+4*e_2*e_3)*eT_3+e_1^2*e_3-2*e_2*e_3 )
assert( (f) == (-(1/36)*p_1^3*p_2+(1/12)*p_1*p_2^2-(1/18)*p_2*p_3)*pT_1^3+((1/12)*p_1^3*p_2-(1/4)*p_1*p_2^2+(1/6)*p_2*p_3)*pT_1*pT_2+((1/9)*p_1^3*p_2-(1/3)*p_1*p_2^2+(2/9)*p_2*p_3)*pT_3 )
assert( (toH(c - d - 2*f)) == 0 )
assert( (toE(c - d - 2*f)) == 0 )
assert( (toP(c - d - 2*f)) == 0 )
///
-------------------------------
--- end test toS, toP, toE, toH
-------------------------------
-------------------------------------------------
--- test schurLevel, symmetricRingOf, schurRingOf
-------------------------------------------------
TEST ///
R = symmRing 5
S = schurRingOf R
S1 = schurRing(R,s1,3,GroupActing => "Sn")
R1 = symmetricRingOf S1
R2 = symmRing(R1,3,GroupActing => "Sn")
S2 = schurRingOf R2
assert( (schurLevel QQ) == 0 )
assert( schurLevel (ZZ/5) == 0 )
assert( (schurLevel R) == 1 )
assert( (schurLevel R1) == 2 )
assert( (schurLevel R2) == 3 )
assert( (schurLevel S) == 1 )
assert( (schurLevel S1) == 2 )
assert( (schurLevel S2) == 3 )
///
-----------------------------------------------------
--- end test schurLevel, symmetricRingOf, schurRingOf
-----------------------------------------------------
-----------------------
-- test centralizerSize
-----------------------
TEST ///
assert( (centralizerSize{3,2,1}) === 144 )
assert( (centralizerSize{1,1,1}) === 6 )
assert( (centralizerSize{3}) === 6 )
assert( (centralizerSize{5,2,1,1,1}) === 57600 )
assert( (centralizerSize{5,5,5}) === 13436928000 )
assert( (centralizerSize{4,4,2,2}) === 5308416 )
assert( (centralizerSize{1}) === 1 )
///
---------------------------
-- end test centralizerSize
---------------------------
-----------------------
-- test schurResolution
-----------------------
TEST ///
S = schurRing(QQ,s,3)
rep = s_{2}
M = {1_S,s_{2},s_{4},s_{6},s_{8},s_{10},s_{12}}
sR = schurResolution(rep,M)
assert( (#sR) == 4 )
assert( (sR#2#0#1) == s_(3,2,1) )
assert( (last last sR) == (4,s_(3,3,2)) )
rep = s_{3}
M = {1_S,s_{3},s_{6},s_{9},s_{12},s_{15},s_{18},s_{21},s_{24},s_{27}}
d = 7
sR = schurResolution(rep,M,DegreeLimit => d)
assert( (#sR) == 7 )
assert( (sR#2#0#0) == 3 )
l = apply(sR,i -> i / (j -> dim last j))
assert( (l) == {{1}, {27}, {105}, {189}, {189}, {105}, {27}} )
T = schurRing(S,t,4)
rep = s_1 * t_1
M = {1_T} | apply(splice{1..8},i -> s_i * t_i)
sR = schurResolution(rep,M)
assert( (last last sR) == (8,s_(3,3,2)*t_(2,2,2,2)) )
assert( (first first sR) == (0,t_()) )
assert( (sR#1#0) == (2,s_(1,1)*t_(1,1)) )
assert( (sR#4#1) == (6,s_(2,2,2)*t_(2,2,2)) )
l = apply(sR,i -> i / (j -> dim last j))
assert( (l) == {{1},{18},{52},{60},{24,10},{12},{3}} )
n = 5;
S = schurRing(QQ,s,n,GroupActing => "Sn");
rep = s_n + s_{n-1,1};
M = {s_n}
sR = schurResolution(rep,M,DegreeLimit => n)
assert( (last sR#2) == (2,s_(4,1)+s_(3,1,1)) )
assert( (first sR#3) == (3,s_(3,1,1)+s_(2,1,1,1)) )
assert( (last last sR) == (5,s_(1,1,1,1,1)) )
l = apply(sR,i -> i / (j -> dim last j))
assert( (l) == {{1},{5},{10},{10},{5},{1}} )
M = {s_n} | splice{n:rep};
sR = schurResolution(rep,M)
assert( (last sR#2) == (3,s_(4,1)+s_(3,2)+s_(3,1,1)+s_(2,2,1)) )
assert( (first sR#3) == (4,s_(3,1,1)+s_(2,2,1)+s_(2,1,1,1)) )
assert( (last last sR) == (5,s_(2,1,1,1)) )
l = apply(sR,i -> i / (j -> dim last j))
assert( (l) == {{1},{10},{20},{15},{4}} )
///
---------------------------
-- end test schurResolution
---------------------------
end
restart
loadPackage"SchurRings"
d = 11
mul = method()
mul(List,List,List,List) := (lam,mu,nu,del) ->
(
m := sum lam;
(llam,lmu,lnu,ldel) := (lam,mu,nu,del);
if not llam#?1 then llam = llam | {0};
if not lmu#?1 then lmu = lmu | {0};
if not lnu#?1 then lnu = lnu | {0};
if not ldel#?1 then ldel = ldel | {0};
e := llam#1 + lmu#1 + lnu#1 + ldel#1;
f := max(llam#1, lmu#1, lnu#1, ldel#1);
local rez;
if e>=m-1 then
(
rez = m//2 - f + 1;
if e%2 == 1 and m%2 == 0 then rez = rez - 1;
)
else
(
rez = (e+1)//2 - f + 1;
if e%2 == 1 then rez = rez - 1;
);
max(0,rez)
)
T_1 = schurRing(QQ,t1,2);
l = {(T_1)_{1}}
for i from 2 to 4 do
(
T_i = schurRing(T_(i-1),value concatenate("t",toString i),2);
l = l | {(T_i)_{1}};
)
rep = product l
mods = new MutableList;
mods#0 = 1_(T_4)
for i from 1 to d do
(
pars = {{i}} | apply(splice{1..(i//2)},j->{i-j,j});
mods#i = sum (for p in (toList (set pars)^**4) list
mul(p#0,p#1,p#2,p#3)*(T_1)_(p#0)*(T_2)_(p#1)*(T_3)_(p#2)*(T_4)_(p#3));
)
M = toList mods
resol = schurResolution(rep,M,DegreeLimit => d)
resol/(i->(sum apply(i,j->dim(last j))))
restart
uninstallPackage"SchurRings"
installPackage"SchurRings"
check SchurRings
viewHelp SchurRings
restart
loadPackage"SchurRings"
S = schurRing(QQ,s,3)
T = schurRing(S,t,4)
rep = s_1 * t_1
symmetricPower(8,rep)
restart
loadPackage"SchurRings"
S = schurRing(QQ,s,4)
d = 4
rep = s_d
degl = 3*d
syzl = degl - 2
M = {1_S} | apply(splice{1..degl},i->s_{i*d})
schurResolution(rep,M,DegreeLimit => degl, SyzygyLimit => syzl)
-- Local Variables:
-- compile-command: "make -C $M2BUILDDIR/Macaulay2/packages PACKAGES=SchurRings pre-install"
-- End: