#
# A Maple Package for Symmetric Functions, Version 1            6/26/89
#   Slightly modified to accomodate new '.m' formats            4/27/90
# 
# COPYRIGHT NOTICE:
# Copyright (c) 1989 by John Reese Stembridge.
#  
# Permission is granted to anyone to to use, modify, or redistribute this
# software freely, subject to the following restrictions:
# 
# 1. The author accepts no responsibility for any consequences of this
# software and makes no guarantee that the software is free of defects.
# 2. The origin of this software must not be misrepresented, either by
# explicit claim or by omission.
# 3. This notice and the copyright must be included in all copies or
# altered versions of this software.
# 4. This software may not be included or redistributed as part of any
# package to be sold for profit unless the author has given explicit written
# permission to do so.
# 
# John Stembridge
# Department of Mathematics
# University of Michigan
# Ann Arbor, MI 48109-1003
# Internet:  jrs@polymnia.math.lsa.umich.edu
#
#############################################################################

#
# Par(n) returns a list of all partitions of n.
# Par(n,l) returns the partitions of n with length <=l.
# Par(n,k,l) returns the partitions of n with parts <=k, length <=l.
#
`SF/Par`:=proc() local n;
  option remember;
  n:=args[1];
  if nargs=1 then `SF/Par/sub`(n,n,n)
    elif nargs=2 then `SF/Par/sub`(n,n,args[2])
    else `SF/Par/sub`(args)
  fi;
end:
`SF/Par/sub`:=proc(n,row,col) local i,newstuff,result;
  if n=0 then RETURN([[]]) fi;
  if row=0 or col=0  then RETURN([]) fi;
  result:=NULL;
  for i from min(row,n) by -1 to iquo(n,col) do
    newstuff:=`SF/Par/sub`(n-i,i,col-1);
    result:=result,op(map(proc(x,y) [y,op(x)] end,newstuff,i));
  od;
  [result];
end:


#
# ch2p(<classfn>) will apply the characteristic map to <classfn>, producing
# a p-polynomial as the output. <classfn> must be expressed as a linear
# combination of characteristic functions cl[<mu>] for various partitions <mu>.
#
`SF/ch2p`:=proc(char) local res,supp,term,mu;
  res:=0; supp:=SF['varset'](char,'cl[]');
  for mu in supp do;
    term:=convert(map(proc(x) p.x end,mu),`*`);
    res:=res+coeff(char,cl[op(mu)])*term/SF['zee'](mu);
  od;
  res;
end: 


#
# conjugate(lambda) returns the conjugate of partition lambda.
# lambda must be a list in decreasing order.
#
`SF/conjugate`:=proc(mu) local i,l,nu;
  l:=nops(mu);
  if l=0 then RETURN([]) else nu:=l$mu[l] fi;
  for i from l-1 by -1 to 1 do;
    nu:=nu,i$(mu[i]-mu[i+1]);
  od;
  [nu];
end:


#
# evalsf(f,<expr>) will apply a substitution to f based on <expr> as
# follows: let <expr>(j) denote the result obtained by substituting x=x^j for
# each variable x appearing in <expr>. Then evalsf(f,<expr>) is obtained
# by substituting p.j=<expr>(j) in f for j=1,2,3,...
#
`SF/evalsf`:=proc() local poly,d,vars,expr,j,i;
  poly:=SF['top'](args[1]);
  d:=SF['varset'](poly,'p');
  vars:=indets(args[2]);
  expr:=subs({'vars[i]=vars[i]^j'$i=1..nops(vars)},args[2]);
  subs({('p.j'=expr)$j=1..d},poly);
end:


#
# ibocaj(<lambda>)      will compute the e-function expansion of s[<lambda>].
# ibocaj(<lambda>,<mu>) will do the same for a skew function s[<lambda>/<mu>].
#
`SF/ibocaj`:=proc() local lambda,mu;
  lambda:=SF['conjugate'](args[1]);
  if nargs=1 then
    SF['omega'](SF['jacobi'](lambda));
  else
    mu:=SF['conjugate'](args[2]);
    SF['omega'](SF['jacobi'](lambda,mu));
  fi;
end:


#
# itensor(f,g)    computes the inner tensor product of the symmetric
#                 functions f and g (a.k.a. the internal product).
# itensor(f,g,b)  does the same, but converts the output to base b.
#                  (b=s[],e,h,p, or m[]). Default is base p.
#
`SF/itensor`:=proc() local d,i,j,k,f,cfs,term,res,vars,mu;
  f:=map(SF['top'],[args[1..2]]);
  d:=SF['varset'](f[1]*f[2],'p');
  vars:=[p.(d-i)$i=0..d-1];
  f:=map(collect,f,vars,'distributed');
  for i from 1 to 2 do;
    cfs[i]:=[coeffs(f[i],vars,evaln(term[i]))];
    term[i]:=[term[i]];
  od;
  res:=0;
  for i to nops(term[1]) do;
    if member(term[1][i],term[2],'j') then
      mu:=['(d-k)$(degree(term[1][i],p.(d-k)))'$k=0..d-1];
      res:=res+SF['zee'](mu)*cfs[1][i]*cfs[2][j]*term[1][i];
    fi;
  od;
  if nargs>2 then 
    if type(args[3],'indexed') then op(0,args[3]) else args[3] fi;
    res:=SF[cat(`to`,'"')](res,'p'); 
  fi;
  res;
end:


#
# jacobi(<lambda>)      will compute the h-function expansion of s[<lambda>].
# jacobi(<lambda>,<mu>) will do the same for a skew function s[<lambda>/<mu>].
#
`SF/jacobi`:=proc() local n,i,j,lambda,mu;
  lambda:=args[1]; n:=nops(lambda);
  if nargs>1 then mu:=[op(args[2]),0$n] else mu:=[0$n] fi;
  if n=0 and nops(mu)=0 then RETURN(1) 
    elif 2*n<nops(mu) then RETURN(0)
  fi;
  array(['map(`SF/jacobi/ent`,['lambda[i]-i+j-mu[j]'$j=1..n])'$i=1..n]);
  linalg['det'](");
end:
`SF/jacobi/ent`:=proc(x) if x>0 then h.x elif x=0 then 1 else 0 fi end:


#
# omega(poly) applies the omega-automorphism to poly, assuming poly is
# expressed in terms of the bases e, h, p, and s[].
#
`SF/omega`:=proc(poly) local sp, n, res, j;
  sp:=SF['varset'](poly);
  if sp['m']<>[] then ERROR(`must use an m-free basis`) fi;
  n:=max(sp['e'],sp['h']);
  res:=subs({'e.j=h.j'$j=1..n,'h.j=e.j'$j=1..n},poly);
  res:=subs({'p.j=(-1)^(j-1)*p.j'$j=1..sp['p']},res);
  subs({'s[op(sp['s'][j])]=
    s[op(SF['conjugate'](sp['s'][j]))]'$j=1..nops(sp['s'])},res);
end:


#
# p2ch(<poly>) will apply the (inverse) characteristic map to a p-polynomial
# <poly>. The result is expressed as a linear combination of characteristic
# functions cl[<mu>] for various partitions <mu>.
#
`SF/p2ch`:=proc(poly) local i,j,d,res,inds,cee,term,mu;
  d:=SF['varset'](poly,'p'); res:=0;
  inds:=[p.(d-i)$i=0..d-1];
  cee:=[coeffs(collect(poly,inds,'distributed'),inds,'term')];
  term:=[term];
  for i from 1 to nops(cee) do;
    mu:='(d-j)$(degree(term[i],p.(d-j)))'$j=0..d-1;
    res:=res+SF['zee']([mu])*cee[i]*cl[mu];
  od;
  res;
end: 


#
# plethysm(f,g)      computes the plethysm f[g] for symmetric functions f,g.
# plethysm(f,g,'b')  does the same, but converts the output to base b.
#                    (b=e, h, p, s[], or m[]). The default is base p.
#
`SF/plethysm`:=proc() local d,i,j,f,g,t;
  f:=SF['top'](args[1]); g:=SF['top'](args[2]);
  d:=SF['varset'](f,'p');
  if f=p.d then 
    subs({'p.j=p.(d*j)'$j=1..SF['varset'](g,'p')},g);
  else
    subs({'p.i=SF['plethysm'](p.i,g)'$i=1..d},f);
  fi;
  if nargs=2 then RETURN(") fi;
  if type(args[3],`indexed`) then t:=op(0,args[3]) else t:=args[3] fi;
  SF[`to`.t]("",'p')
end:


#
# scalar(f,g) computes the scalar product of the symmetric functions f and g
# with respect to the form for which the power sums are orthogonal and
# <p[mu],p[mu]>=zee[mu].
#
# Options: scalar(f,g,'b1','b2') will compute scalar(f,g) under the
# assumption that f is in base b1 and g is in base b2. Currently, b1 and b2
# must be one of p, h, e, m[] or s[]. (In case of m[], the function must be
# linear).
#
# If the the last argument (the third or fifth) is a procedure that accepts
# partitions as arguments, say 'Z', then the scalar product will be
# computed with respect to the form for which power sums are orthogonal and
# <p[mu],p[mu]>=Z(mu).
#
`SF/scalar`:=proc() local f,form,b,d,vars,terms,cfs,mu,trm,i,j,k,res;
  f[1]:=args[1]; f[2]:=args[2]; res:=0;
  if nargs=3 or nargs=5 then form:=args[nargs] else form:=SF['zee'] fi;
  if nargs>3 then b:=[args[3..4]] else b[1]:=NULL; b[2]:=NULL fi;
  if b[1]='m[]' and modp(nargs,2)=0 then 
    f[2]:=SF['toh'](f[2],b[2]); d:=SF['varset'](f[2],'h');
    vars:=[h.(d-i)$i=0..d-1];
    cfs:=[coeffs(collect(f[2],vars,'distributed'),vars,'terms')];
    terms:=[terms]; 
    for mu in SF['varset'](f[1],'m[]') do;
      trm:=convert(map(proc(x) h.x end,mu),`*`);
      if member(trm,terms,'j') then res:=res+coeff(f[1],m[op(mu)])*cfs[j] fi;
    od;
  else
    f[1]:=SF['top'](f[1],b[1]); f[2]:=SF['top'](f[2],b[2]);
    d:=SF['varset'](f[1]*f[2],'p');
    vars:=[p.(d-i)$i=0..d-1];
    cfs[1]:=[coeffs(collect(f[1],vars,'distributed'),vars,'terms[1]')];
    cfs[2]:=[coeffs(collect(f[2],vars,'distributed'),vars,'terms[2]')];
    terms[1]:=[terms[1]]; terms[2]:=[terms[2]];
    for i to nops(terms[1]) do;
      if member(terms[1][i],terms[2],'j') then
        mu:=['(d-k)$(degree(terms[1][i],p.(d-k)))'$k=0..d-1];
        res:=res+form(mu)*cfs[1][i]*cfs[2][j];
      fi;
    od;
  fi;
  res;
end:


#
# stdeg(poly,b) determines the degree of poly with respect to the standard
# grading: if b is a multiplicative basis, then deg(b.i)=i. If b is linear,
# then deg(b[mu])=|mu|.
#
`SF/stdeg`:=proc(poly,b) local B,i,sp,t;
  sp:=SF['varset'](poly,b);
  if type(b,'indexed') then
    B:=op(0,b);
    degree(subs({`SF/stdeg/eqn`(sp[i],B,t)$i=1..nops(sp)},poly),t);
  else
    degree(subs({'evaln(b.i)=t^i*evaln(b.i)'$i=1..sp},poly),t);
  fi;
end:
`SF/stdeg/eqn`:=proc(x,b,t) 'b[op(x)]=t^convert(x,`+`)*b[op(x)]' end:


#
# toe(poly) converts a symmetric function <poly> into an e-polynomial.
# <poly> may be expressed in terms of the bases p, h, s[], and m[].
#
# toe(poly,<base>), where <base> is one of the names p, h, s[], or m[], will
# assume that poly is expressed  only in terms of the variables of <base>.
# In case the 'm[]' option is selected, poly must be linear.
#
`SF/toe`:=proc() local poly,bases,sp,i,j,mu;
  poly:=args[1];
  if nargs=1 then bases:={'m[]','s[]','p','h'} else bases:={args[2]} fi;
  if bases={'m[]'} then
    poly:=SF['top'](poly,'m[]'); bases:={'p'};
  elif member('m[]',bases) then
    sp['m']:=SF['varset'](poly,'m[]');
    for mu in sp['m'] do;
      poly:=subs(m[op(mu)]=SF['top'](m[op(mu)],'m[]'),poly);
    od;
  fi;
  sp:=SF['varset'](poly,bases);
  if member('p',bases) then
    for i from sp['p'] by -1 to 1 do;
      poly:=subs(p.i=i*(-1)^(i-1)*e.i-sum('(-1)^j*p.(i-j)*e.j',j=1..i-1),poly);
    od;
  fi;
  if member('h',bases) then 
    for i from sp['h'] by -1 to 1 do; 
      poly:=subs(h.i=(-1)^(i-1)*e.i-sum('(-1)^j*e.j*h.(i-j)',j=1..i-1),poly); 
    od;
  fi;
  if member('s[]',bases) then
    for mu in sp['s'] do;
      poly:=subs(s[op(mu)]=SF['ibocaj'](mu),poly);
    od;
  fi;
  poly;
end: 


#
# toh(poly) converts a symmetric function <poly> into an h-polynomial.
# <poly> may be expressed in terms of the bases e, p, s[], or m[].
#
# toh(poly,<base>), where <base> is one of the names e, h, s[], or m[], will
# assume that poly is expressed  only in terms of the variables of <base>.
# In case the 'm[]' option is selected, poly must be linear.
#
`SF/toh`:=proc() local poly,bases,sp,i,j,mu;
  poly:=args[1];
  if nargs=1 then bases:={'m[]','s[]','p','e'} else bases:={args[2]} fi;
  if bases={'m[]'} then
    poly:=SF['top'](poly,'m[]'); bases:={'p'};
  elif member('m[]',bases) then
    for mu in SF['varset'](poly,'m[]') do;
      poly:=subs(m[op(mu)]=SF['top'](m[op(mu)],'m[]'),poly);
    od;
  fi;
  sp:=SF['varset'](poly,bases);
  if member('p',bases) then
    for i from sp['p'] by -1 to 1 do;
      poly:=subs(p.i=i*h.i-sum('p.j*h.(i-j)',j=1..i-1),poly);
    od
  fi;
  if member('e',bases) then 
    for i from sp['e'] by -1 to 1 do; 
      poly:=subs(e.i=(-1)^(i-1)*h.i-sum('(-1)^j*h.j*e.(i-j)',j=1..i-1),poly); 
    od
  fi;
  if member('s[]',bases) then
    for mu in sp['s'] do;
      poly:=subs(s[op(mu)]=SF['jacobi'](mu),poly);
    od
  fi;
  poly;
end: 


#
# tom(poly) converts a symmetric function <poly> into a linear combination
# of monomial symmetric functions m[lambda].
#
# tom(poly,<base>), where <base> is one of the names p,h,e, or s[], will
# assume that poly is expressed in terms of the variables of <base>.
#
`SF/tom`:=proc() local poly,d,terms,i,n,degs,supp,res,c;
  poly:=SF['top'](args);
  d:=SF['varset'](poly,'p');
  poly:=collect(poly,[p.(d-i)$i=0..d-1],'distributed');
  coeffs(poly,[p.(d-i)$i=0..d-1],'terms'); 
  degs:=map(degree,subs({'p.i=c^i'$i=1..d},{terms}),c);
  supp:=map(proc(x) op(SF['Par'](x)) end,[op(degs)]);
  n:=nops(supp);
  res:=sum('c[i]*convert(map(proc(x) h.x end,supp[i]),`*`)',i=1..n);
  res:=SF['scalar'](poly,res,'p','h');
  subs({'c[i]=m[op(supp[i])]'$i=1..n},res);
end: 


#
# top(poly) converts a symmetric function <poly> into a p-polynomial.
# top(poly,'b'), where 'b' is one of the names h,e,s[], or m[], will
# assume that poly is expressed in base b.
#
# In case b='m[]' is specified, poly must be a linear function of the m[mu]'s. 
#
`SF/top`:=proc() local poly,bases,sp,i,j,degs,supp,dual,c,mu;
  poly:=args[1];
  if nargs=1 then bases:={'m[]','s[]','h','e'} else bases:={args[2]} fi;
  if member('s[]',bases) then poly:=SF['toh'](poly,'s[]');
    bases:=bases minus {'s[]'} union {'h'}
  fi;
  sp:=SF['varset'](poly,bases);
  if member('h',bases) then
    for i from sp['h'] by -1 to 1 do;
      poly:=subs(h.i=(p.i+sum('p.j*h.(i-j)',j=1..i-1))/i,poly);
    od;
  fi;
  if member('e',bases) then 
    for i from sp['e'] by -1 to 1 do; 
      poly:=subs(e.i=
        ((-1)^(i-1)*p.i-sum('(-1)^j*p.j*e.(i-j)',j=1..i-1))/i,poly); 
    od;
  fi;
  if bases={'m[]'} and sp['m']<>[] then 
    degs:={op(map(convert,sp['m'],`+`))}; dual:=0;
    supp:=[op(map(proc(x) op(SF['Par'](x)) end,degs))];
    for i from 1 to nops(supp) do;
      dual:=dual+c[i]*`SF/top/sub`(supp[i])/SF['zee'](supp[i]);
    od;
    dual:=SF['scalar'](poly,dual,'m[]','p');
    poly:=subs({'c[j]=`SF/top/sub`(supp[j])'$j=1..nops(supp)},dual);
  elif member('m[]',bases) then
    for mu in sp['m'] do;
      poly:=subs(m[op(mu)]=SF['top'](m[op(mu)],'m[]'),poly)
    od;
  fi;
  poly;
end: 
`SF/top/sub`:=proc(mu) convert(map(proc(x) p.x end,mu),`*`) end:


#
# tos(poly,<options>) will convert a symmetric function poly into a sum of
# Schur functions. <options> is a sequence of zero or more of the
# following expressions (in any order):
# (1) a list of partitions that support the Schur expansion of poly.
# (2) an equation 'nrows=<integer>', where <integer> is a positive integer
#     that specifies that all calculations should take place in the ring
#     spanned by Schur functions with at most <integer> rows.
# (3) a name 'b' that indicates what basis poly is expressed in. 
#     'b'= one of h, e, p, s[], or m[]. (If m[], then poly must be linear). 
#
# Warning: poly must be homogeneous. 
#
`SF/tos`:=proc() local c,j,d,poly,supp,eqns,res,n,nrows,inpt,opt,inds;
  inpt:=args[1]; nrows:=0; supp:=[];
  for opt in [args[2..nargs]] do;
    if type(opt,'list') then supp:=opt
    elif type(opt,`=`) then nrows:=op(2,opt)
    elif type(opt,'name') then inpt:=inpt,opt
    fi;
  od;
  if nrows>0 then
    poly:=SF['toe'](inpt);
    n:=SF['varset'](poly,'e');
    poly:=subs({'e.j=0'$j=nrows+1..n},poly);
    d:=SF['stdeg'](poly,'e');
    inds:={'e.j'$j=1..min(nrows,d)};
    if supp=[] then supp:=SF['Par'](d,min(nrows,d)) fi;
    n:=nops(supp);
    poly:=-poly+sum('c[j]*`SF/tos/det`(supp[j],nrows)',j=1..n);
  else
    poly:=SF['toh'](inpt);
    d:=SF['stdeg'](poly,'h');
    inds:={'h.j'$j=1..d};
    if supp=[] then supp:=SF['Par'](d,degree(poly,inds)) fi;
    n:=nops(supp);
    poly:=-poly+sum('c[j]*SF['jacobi'](supp[j])',j=1..n);
  fi;
  res:=sum('c[j]*s[op(supp[j])]',j=1..n);
  eqns:={coeffs(collect(poly,inds,'distributed'),inds)};
  subs(solve(eqns,{c[j]$j=1..n}),res);
end:
`SF/tos/det`:=proc(lambda,r) local mu,n,i,j;
  mu:=SF['conjugate'](lambda); n:=nops(mu);
  if n=0 then RETURN(1) fi;
  array(['map(`SF/tos/ent`,['mu[i]-i+j'$j=1..n],r)'$i=1..n]);
  linalg['det'](");
end:
`SF/tos/ent`:=proc(x,r) if x=0 then 1 elif x<0 or x>r then 0 else e.x fi end:


#
# varset(poly,<bases>) will return a table whose entries describe the sets of
# variables from <bases> that occur in poly. 
#
# <bases> may be a list or set of string names and indexed names. For each
# indexed name (e.g., 's[]'), there will be a table entry indexed by 's'
# consisting of a list of partitions that indicate the support of this basis
# in poly. For each string name (e.g.,'p'), there will be a table
# entry indexed by 'p' equal to the largest n s.t. p.n occurs in poly.
#
# If <bases> is a single name (not a list or set), then the entry of the
# above table corresponding to this name, not the table itself, is returned.
# If the second argument is omitted, the default is <bases>={s[],m[],h,e,p}.
#
`SF/varset`:=proc() local poly,inds,strs,one_base,b,x,res;
  poly:=args[1]; inds:={}; strs:={};
  res:=table(); one_base:=`false`;
  if nargs=1 then
    inds:={'s','m'};
    strs:={'h','e','p'};
  elif type(args[2],'name') then
    one_base:=`true`;
    if type(args[2],'indexed') then inds:={op(0,args[2])}; 
      else strs:={args[2]};
    fi;
  else 
    for x in args[2] do;
      if type(x,'indexed') then inds:=inds union {op(0,x)}
        else strs:=strs union {x}
      fi;
    od;
  fi;
  if inds<>{} then
    for x in inds do res[x]:=NULL od; 
    for x in indets(poly,'indexed') do;
      b:=op(0,x);
      if member(b,inds) then res[b]:=res[b],[op(x)] fi;
    od;
    for x in inds do res[x]:=[res[x]] od;
    if one_base then RETURN(res[x]) fi;
  fi;
  if strs<>{} then
    for x in strs do res[x]:=0 od;
    for x in indets(poly,'string') do;
      b:=substring(x,1..1);
      if member(b,strs) then res[b]:=max(res[b],`SF/varset/deg`(x,b)) fi; 
    od;
    if one_base then RETURN(res[op(strs)]) fi;
  fi;
  op(res);
end:
`SF/varset/digits`:=[`0`,`1`,`2`,`3`,`4`,`5`,`6`,`7`,`8`,`9`]:
`SF/varset/deg`:=proc(var,b) local i,n,pos;
  n:=0;
  for i from length(b)+1 to length(var) while 
    member(substring(var,i..i),`SF/varset/digits`,'pos') do;
    n:=10*n+pos-1;
  od;
  if i>length(var) then n else 0 fi;
end:  


#
# zee(lambda)=the order of the centralizer in S_n of a permutation of
# cycle type lambda  =  1^(m1)*m1!*2^(m2)*m2!*...
#
# zee(lambda,a)=zee(lambda)*a^nops(lambda) 
# zee(lambda,q,t)= zee(lambda)*prod((1-q^(lambda_i))/(1-t^(lambda_i)))
#
`SF/zee`:=proc() local res,m,i,mu;
  mu:=args[1]; res:=convert(mu,`*`);
  if nargs=2 then
    res:=res*args[2]^nops(mu)
  elif nargs=3 then 
    res:=res*product('(1-args[2]^mu[i])/(1-args[3]^mu[i])',i=1..nops(mu))
  fi;
  if nops(mu)<2 then RETURN(res) else  m:=1 fi;
  for i from 2 to nops(mu) do;
    if mu[i]<mu[i-1] then m:=1 else m:=m+1 fi;
    res:=res*m;
  od;
  res;
end:


#
# Symmetric Function package.
#
# Calling sequence:	SF[<funcname>](<arguments>)
#
SF[conjugate]:=eval(`SF/conjugate`):
SF[evalsf]:=eval(`SF/evalsf`):
SF[ibocaj]:=eval(`SF/ibocaj`):
SF[itensor]:=eval(`SF/itensor`):
SF[jacobi]:=eval(`SF/jacobi`):
SF[omega]:=eval(`SF/omega`):
SF[p2ch]:=eval(`SF/p2ch`):
SF[ch2p]:=eval(`SF/ch2p`):
SF[Par]:=eval(`SF/Par`):
SF[plethysm]:=eval(`SF/plethysm`):
SF[scalar]:=eval(`SF/scalar`):
SF[stdeg]:=eval(`SF/stdeg`):
SF[toe]:=eval(`SF/toe`):
SF[toh]:=eval(`SF/toh`):
SF[tom]:=eval(`SF/tom`):
SF[top]:=eval(`SF/top`):
SF[tos]:=eval(`SF/tos`):
SF[varset]:=eval(`SF/varset`):
SF[zee]:=eval(`SF/zee`):
`combinat/SF` := eval(SF):

`help/text/SF` := TEXT(
`HELP FOR: The symmetric functions package`,
`         `,
`CALLING SEQUENCES:`,
`   <function>(args)`,
`   SF[<function>](args)`,
`         `,
`SYNOPSIS:   `,
`      `,
`- To use <function>, either use the long notation SF[<function>](...);`,
`  or first define the posets functions by doing  with(SF);  then use`,
`  the short notation  <function>(...);`,
`         `,
`- The functions in the posets package are:`,
`         `,
`        Par        evalsf     jacobi     plethysm   toe        top`,
`        ch2p       ibocaj     omega      scalar     toh        tos`,
`        conjugate  itensor    p2ch       stdeg      tom        varset`,
`	zee      `,
`   `,
`- This package makes use of the global variables`,
`   `,
`	p1, p2, p3, ..., h1, h2, h3, ..., e1, e2, e3, ...`,
`   `,
`  and the subscripted variables`,
`   `,
`	m[...], s[...], cl[...]`,
`      `,
`- Help for any of these functions can be obtained with ?<function>`
):

`help/text/Par` := TEXT(
`FUNCTION : Par - list partitions`,
`    `,
`CALLING SEQUENCE : Par(n);  Par(n,l);  Par(n,k,l);`,
`    `,
`PARAMETERS :  n = the number to partition (nonnegative integer)`,
`              l = the maximum number of rows allowed (optional)`,
`              k = the maximum part size allowed (optional)`,
`   `,
`SYNOPSIS :   `,
`   Par(n) returns a list of all partitions of n.`,
`   Par(n,l) returns the partitions of n with length <=l.`,
`   Par(n,k,l) returns the partitions of n with parts <=k, length <=l.`,
`   The list is ordered lexicographically by the part sizes (a refinement of`,
`   dominance). Option remember is used.`,
`    `,
`EXAMPLES :   `,
`   Par(4);        yields   [[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]]`,
`   Par(7,2);      yields   [[7], [6, 1], [5, 2], [4, 3]]`,
`   Par(9,4,2);    yields   []`,
`   `,
`SEE  ALSO :  conjugate,  zee`
):
`help/text/ch2p` := TEXT(
`FUNCTION : ch2p - convert a class function to a p-polynomial`,
`    `,
`CALLING SEQUENCE :  ch2p(<classfn>);`,
`    `,
`PARAMETERS :  <classfn> = a linear combination of the characteristic `,
`  functions cl[<lambda>] for various partitions <lambda>.`,
`   `,
`SYNOPSIS :   `,
`  ch2p will apply the characteristic map to the given class function,`,
`  thereby producing a polynomial in the power sums p.i, i=1,2,...`,
`    `,
`EXAMPLES :   `,
`  ch2p(cl[3,2,2,1]);              yields   1/24*p3*p2^2*p1`,
`  ch2p(cl[1,1,1]+cl[3]+cl[2,1]);  yields   1/6*p1^3+1/2*p2*p1+1/3*p3`,
`    `,
`SEE  ALSO : p2ch`
):
`help/text/conjugate` := TEXT(
`FUNCTION :  conjugate - conjugate a partition`,
`    `,
`CALLING SEQUENCE :  conjugate(<lambda>);`,
`    `,
`PARAMETERS :  <lambda> = a partition`,
`    `,
`SYNOPSIS :   `,
`   conjugate() returns the partition whose diagram is the transpose of the`,
`   given partition. The parts must be listed in decreasing order.`,
`    `,
`EXAMPLES : `,
`   conjugate([7,7,3,2,2,2,1]);   yields   [7, 6, 3, 2, 2, 2, 2]`,
`   conjugate([]);                yields   []`,
`    `,
`SEE  ALSO : Par`
):
`help/text/evalsf` := TEXT(
`FUNCTION : evalsf - evaluate symmetric functions`,
`    `,
`CALLING SEQUENCE : evalsf(f,<expr>);`,
`    `,
`PARAMETERS :    f    = a symmetric function`,
`              <expr> = any expression`,
`   `,
`SYNOPSIS :   `,
`  Let <expr>(j) denote the result obtained by substituting x=x^j for each`,
`  variable x appearing in <expr>. The procedure evalsf(f,<expr>) is`,
`  computed by converting f to a p-polynomial, and then substituting`,
`  p.j=<expr>(j) into f for j=1,2,3,....`,
`  For example, evalsf(f,x+y+z) has the effect of expressing f as a`,
`  symmetric function of the variables x,y, and z.  Also, evalsf(f,1/(1-q))`,
`  is equivalent to substituting 1,q,q^2,... into the variables of f.`,
`   `,
`EXAMPLES :   `,
`  evalsf(e3,x+y+z+w);`,
`  expand(");                  yields   x*y*z+x*y*w+x*z*w+y*z*w`,
`  evalsf(s[2,1],1/(1-q));`,
`  factor(");                  yields   -q/(-1+q)^3/(q^2+q+1)`,
`  evalsf(h2,(a-b)/(1-q));`,
`  factor(");                  yields   (a-b)*(-q*b+a)/(-1+q)^2/(1+q)`,
`    `,
`SEE  ALSO :  top`
):
`help/text/ibocaj` := TEXT(
`FUNCTION :  ibocaj - Schur determinant via elementary symmetric functions`,
`    `,
`CALLING SEQUENCE : ibocaj(<lambda>);  ibocaj(<lambda>,<mu>);`,
`    `,
`PARAMETERS :  <lambda> = a partition`,
`              <mu>     = a partition (optional)`,
`SYNOPSIS :   `,
`   ibocaj(<lambda>) will compute the expansion of s[<lambda>] as an e-poly.`,
`   ibocaj(<lambda>,<mu>) will do the same for the skew Schur function`,
`     s[<lambda>/<mu>].`,
`    `,
`EXAMPLES :   `,
`   ibocaj([2,1,1]);          yields   e3*e1-e4`,
`   ibocaj([5,3,2],[3,2]);    yields   e1^5-2*e1^3*e2+e2^2*e1`,
`    `,
`SEE  ALSO : jacobi`
):
`help/text/itensor` := TEXT(
`FUNCTION :  itensor - inner tensor product of symmetric functions`,
`    `,
`CALLING SEQUENCE :  itensor(f,g);  itensor(f,g,'b');`,
`    `,
`PARAMETERS :  f, g  =  symmetric functions`,
`               'b'  =  one of the names e, h, p, s[] or m[]`,
`SYNOPSIS :   `,
`  itensor(f,g) is the symmetric function operation that corresponds`,
`  to (inner) tensor products of symmetric group characters. (It is also`,
`  known as the inner or internal product. If the third argument is present,`,
`  it will convert the output to base 'b'. However, beware that `,
`  tos(expand(itensor(f,g,'h'))) is often faster than itensor(f,g,'s[]').`,
`  The default base used for the output is 'p'.`,
`    `,
`EXAMPLES :   `,
`  itensor(s[2,1],s[2,1],'s[]');    yields    s[3]+s[2,1]+s[1,1,1]`,
`  expand(itensor(s[2,2],h2*e2));   yields    1/2*p1^4-1/2*p2^2`
):
`help/text/jacobi` := TEXT(
`FUNCTION :  jacobi - the Jacobi-Trudi determinant for Schur functions`,
`    `,
`CALLING SEQUENCE : jacobi(<lambda>);  jacobi(<lambda>,<mu>);`,
`    `,
`PARAMETERS :  <lambda> = a partition`,
`              <mu>     = a partition (optional)`,
`SYNOPSIS :   `,
`   jacobi(<lambda>) will compute the determinantal expansion of s[<lambda>]`,
`   as an h-poly.`,
`   jacobi(<lambda>,<mu>) will do the same for the skew Schur function`,
`   s[<lambda>/<mu>].`,
`    `,
`EXAMPLES :   `,
`   jacobi([2,1,1]);          yields   h2*h1^2-h2^2-h3*h1+h4`,
`   jacobi([5,3,2],[3,2]);    yields   h2^2*h1`,
`    `,
`SEE  ALSO : ibocaj`
):
`help/text/omega` := TEXT(
`FUNCTION : omega - apply the omega automorphism`,
`    `,
`CALLING SEQUENCE : omega(<poly>);`,
`    `,
`PARAMETERS :  <poly>  = a symmetric function`,
`   `,
`SYNOPSIS :   `,
`  Assuming <poly> is expressed in terms of the bases e, h, p, and s[],`,
`  omega(<poly>) will apply the omega automorphism to <poly>. (Note that`,
`  the m[]-basis is not supported).`,
`  The omega automorphism is computed via the substitutions h.i=e.i,`,
`  e.i=h.i, p.i=(-1)^(i-1)*p.i (i=1,2,...), and s[mu]=s[conjugate(mu)].  `,
`   `,
`EXAMPLES :   `,
`  omega(h3*p4+e2);           yields    -e3*p4+h2`,
`  f:=top(m[3,2],'m[]');`,
`  tom(omega(f),'p');         yields    -m[3,2]-2*m[5]`,
`    `,
`SEE  ALSO :  conjugate`
):
`help/text/p2ch` := TEXT(
`FUNCTION :  p2ch - convert a p-polynomial to a class function`,
`    `,
`CALLING SEQUENCE :  p2ch(<poly>);`,
`    `,
`PARAMETERS :  <poly> = a p-polynomial`,
`   `,
`SYNOPSIS :   `,
`   p2ch will apply the inverse characteristic map to the given <poly>,`,
`   thereby producing a linear combination of characteristic functions`,
`   cl[<mu>] for various partitions <mu>.`,
`   The term cl[<mu>] refers to the class function that takes on the value 1`,
`   for permutations of cycle-type <mu>, and zero otherwise.`,
`    `,
`EXAMPLES :   `,
`   p2ch((p1+p2)^2);         yields   4*cl[2,1]+2*cl[1,1]+8*cl[2,2]`,
`   f:=top(s[3,1]);`,
`   p2ch(f);                 yields   3*cl[1,1,1,1]+cl[2,1,1]-cl[2,2]-cl[4]`,
`    `,
`SEE  ALSO : ch2p`
):
`help/text/plethysm` := TEXT(
`FUNCTION :  plethysm - plethysm of symmetric functions`,
`    `,
`CALLING SEQUENCE :  plethysm(f,g);  plethysm(f,g,'b');`,
`    `,
`PARAMETERS :  f, g  =  symmetric functions`,
`               'b'  =  one of the names e, h, p, s[] or m[]`,
`SYNOPSIS :   `,
`  plethysm(f,g) is the symmetric function operation that corresponds`,
`  to composition of representations of the general linear group. (Sometimes`,
`  denoted f[g] or f o g). It also corresponds to the induction of `,
`  characters from wreath-product subgroups of symmetric groups.`,
`  The first argument is the outer operand of the plethysm, and the second`,
`  argument is the inner operand.`,
`  If a third argument is present, the output will be converted to base 'b'.`,
`  Beware that tos(expand(plethysm(f,g,'h'))) is often faster than`,
`  plethysm(f,g,'s[]').  The default base used for the output is 'p'.`,
`    `,
`EXAMPLES :   `,
`  plethysm(h2,h3,'s[]');  yields   s[6]+s[4,2]`,
`  plethysm(p3,s[2,1]);    yields   2/3*p3*(1/2*p6+1/2*p3^2)-1/3*p9-1/3*p6*p3`
):
`help/text/scalar` := TEXT(
`FUNCTION :  scalar - scalar product of symmetric functions`,
`    `,
`CALLING SEQUENCE :  scalar(f,g);         scalar(f,g,'b1','b2');`,
`                    scalar(f,g,<form>);  scalar(f,g,'b1',b2',<form>);`,
`    `,
`PARAMETERS :  f,g       = symmetric functions`,
`              'b1','b2' = names chosen from p, h, e, s[], or m[].`,
`              <form>    = a procedure that takes a partition as input.`,
`   `,
`SYNOPSIS :   `,
`  scalar(f,g) computes the scalar product of f and g with respect to the`,
`  form for which the power sums are orthogonal and <p[mu],p[mu]>=zee(mu).`,
`  If the names 'b1' and 'b2' are specified, then scalar will assume that`,
`  f is in base b1 and g is in base b2. (When 'm[]' is specified, the`,
`  polynomial must be a linear function of the m[mu]'s).`,
`  If the the last argument (the third or fifth) is a procedure <form>,`,
`  then the scalar product will be computed with respect to the bilinear`,
`  form in which the power sums are orthogonal and <p[mu],p[mu]>=<form>(mu).`,
`  In case b1='m[]' and no <form> is specified, then scalar(f,g) is computed`,
`  by applying toh() to g and using the duality of the h- and m[]-bases.`,
`   `,
`EXAMPLES :   `,
`  scalar(s[3,2],h2*h1^3);                    yields           3`,
`  scalar(m[3,1,1],e3*e2,'m[]','e');          yields           1`,
`  Zee:=proc(mu) z^nops(mu)*zee(mu) end;`,
`  scalar(s[2,1],s[2,1],Zee);                 yields     1/3*z+2/3*z^3`,
`  scalar(m[3,1],s[3,1],'m[]','s[]',Zee);     yields           z`,
`    `,
`SEE  ALSO :  zee`
):
`help/text/stdeg` := TEXT(
`FUNCTION : stdeg - degree with respect to standard grading`,
`    `,
`CALLING SEQUENCE :  stdeg(f,'b');`,
`    `,
`PARAMETERS :  f  = a symmetric function`,
`             'b' = a name (string or indexed).`,
`   `,
`SYNOPSIS :   `,
`  stdeg() determines the degree of the polynomial f in base 'b' with`,
`  respect to the standard grading. If 'b' is an indexed name, then b`,
`  is assumed to be a linear basis indexed by partitions and deg(b[mu])=`,
`  the size of mu. Otherwise, b is assumed to be a multiplicative basis`,
`  and deg(b.i)=i, i=1,2,...`,
`  All other terms appearing in f are given degree 0.`,
`   `,
`EXAMPLES :   `,
`  stdeg((p1+p3)^3+p7,'p');             yields    9`,
`  stdeg(s[3,2]*s[2]+s[3,1],'s[]');     yields    7`,
`  stdeg(h4*h2*e3-h5,'h');              yields    6`,
`    `,
`SEE  ALSO :  varset`
):
`help/text/toe` := TEXT(
`FUNCTION : toe - convert a symmetric function to the e-basis.`,
`    `,
`CALLING SEQUENCE :  toe(<poly>);  toe(<poly>,'b');`,
`    `,
`PARAMETERS :  <poly> = a symmetric function`,
`                'b'  = one of the names p, h, s[], or m[]`,
`   `,
`SYNOPSIS :   `,
`  toe() will convert <poly> into elementary symmetric functions.`,
`  If 'b' is specified, then <poly> is assumed to be expressed in base b.`,
`  In case b='m[]', <poly> must be a linear function of the m[mu]'s.`,
`    `,
`EXAMPLES :   `,
`  toe(h1*e2*p2+s[2,1]*m[2]);`,
`  expand(");                  yields   -4*e1*e2^2+2*e1^3*e2+2*e3*e2-e3*e1^2`,
`  toe(m[3],'m[]');`,
`  expand(");                  yields    3*e3-3*e1*e2+e1^3`,
`    `,
`SEE  ALSO :  toh,  top,  tos,  tom`
):
`help/text/toh` := TEXT(
`FUNCTION : toh - convert a symmetric function to the h-basis.`,
`    `,
`CALLING SEQUENCE :  toh(<poly>);  toh(<poly>,'b');`,
`    `,
`PARAMETERS :  <poly> = a symmetric function`,
`                'b'  = one of the names p, e, s[], or m[]`,
`   `,
`SYNOPSIS :   `,
`  toh() will convert <poly> into the homogeneous symmetric functions h.i.`,
`  If 'b' is specified, then <poly> is assumed to be expressed in base b.`,
`  In case b='m[]', <poly> must be a linear function of the m[mu]'s.`,
`    `,
`EXAMPLES :   `,
`  toh(s[2,2]*e2);              yields  (h2^2-h3*h1)*(-h2+h1^2)`,
`  toh(p3,'p');`,
`  expand(");                   yields  3*h3-3*h1*h2+h1^3`,
`    `,
`SEE  ALSO :  toe,  top,  tos,  tom`
):
`help/text/tom` := TEXT(
`FUNCTION : tom - convert a symmetric function to the monomial basis`,
`    `,
`CALLING SEQUENCE :  tom(<poly>);  tom(<poly>,'b');`,
`    `,
`PARAMETERS :  <poly> = a symmetric function`,
`                'b'  = one of the names e, p, h, or s[]`,
`   `,
`SYNOPSIS :   `,
`  tom() will convert <poly> into a linear combination of monomial symmetric`,
`  functions.  If 'b' is specified, then <poly> is assumed to be expressed in`,
`  base b.   `,
`    `,
`EXAMPLES :   `,
`  tom(m[3,2]*p2);            yields   m[5,2]+m[4,3]+2*m[3,2,2]  `,
`  tom(s[2]*s[1,1],'s[]');    yields   m[2,2]+3*m[2,1,1]+6*m[1,1,1,1]+m[3,1]`,
`    `,
`SEE  ALSO :  toe,  toh,  top,  tos`
):
`help/text/top` := TEXT(
`FUNCTION : top - convert a symmetric function to the p-basis.`,
`    `,
`CALLING SEQUENCE :  top(<poly>);  top(<poly>,'b');`,
`    `,
`PARAMETERS :  <poly> = a symmetric function`,
`                'b'  = one of the names e, h, s[], or m[]`,
`   `,
`SYNOPSIS :   `,
`  top() will convert <poly> into power-sum symmetric functions.`,
`  If 'b' is specified, then <poly> is assumed to be expressed in base b.`,
`  In case b='m[]', <poly> must be a linear function of the m[mu]'s.`,
`    `,
`EXAMPLES :   `,
`  top(m[3,1]*e2);           yields    (-p4+p3*p1)*(-1/2*p2+1/2*p1^2)`,
`  top(s[3,1],'s[]');`,
`  expand(");                yields    1/4*p2*p1^2+1/8*p1^4-1/4*p4-1/8*p2^2`,
`    `,
`SEE  ALSO :  toe,  toh,  tos,  tom`
):
`help/text/tos` := TEXT(
`############################################################################`,
`   `,
`FUNCTION : tos - express a symmetric function in terms of Schur functions`,
`    `,
`CALLING SEQUENCE :  tos(f);  tos(f,<options>);`,
`    `,
`PARAMETERS :     f    = a symmetric function`,
`            <options> = one or more of the following (in any order):`,
`                 1) one of the names e, h, p, s[], or m[]`,
`                 2) a list of partitions`,
`                 3) an equation of the form 'nrows=<integer>'`,
`   `,
`SYNOPSIS :   `,
`  tos() will convert a symmetric function into a linear combination of`,
`  Schur functions. If a name 'b' (optional) is specified, then f is`,
`  assumed to be in base b. If b='m[]', then f must be a linear function`,
`  of the m[lambda]'s.`,
`  If a list of partitions is specified, it will be assumed that this list`,
`  includes all of the partitions that will appear in the Schur functions`,
`  of the result. (This can significantly improve the speed of tos()).`,
`  If an equation 'nrows=k' is specified, where k is a positive integer,`,
`  then tos() will be applied in the subring spanned by Schur functions`,
`  with at most k rows.`,
`   `,
`  Warning: In the present implementation, f must be homogeneous with`,
`     respect to the standard grading.`,
`   `,
`    `,
`EXAMPLES :   `,
`  tos(h3*p2);                      yields   s[5]+s[3,2]-s[3,1,1]`,
`  tos(s[2,1]*s[2,2],Par(7,4,4));   yields`,
`                   s[4,3]+s[4,2,1]+s[3,3,1]+s[3,2,2]+s[3,2,1,1]+s[2,2,2,1]`,
`  tos(e2*e2,nrows=2,'e');          yields   s[2,2]`,
`  jacobi([5,4,2,1],[3,2]);`,
`  tos(",'h',nrows=3,Par(7,3));     yields`,
`                 s[5,2]+s[5,1,1]+2*s[4,3]+3*s[4,2,1]+2*s[3,3,1]+2*s[3,2,2]`,
`    `,
`SEE  ALSO :  toe,  toh,  top,  tom`,
`   `
):
`help/text/varset` := TEXT(
`############################################################################`,
`    `,
`FUNCTION :  varset - variable set of a symmetric function`,
`    `,
`CALLING SEQUENCE :  varset(f);  varset(f,<bases>);`,
`    `,
`PARAMETERS :    f    = a symmetric function`,
`             <bases> = a name (string or indexed), or a list or set`,
`                       of such names`,
`   `,
`SYNOPSIS :   `,
`  varset() returns a table whose entries describe the sets of variables`,
`  that occur in f. For each indexed name (e.g., 's[]') there will be a`,
`  table entry indexed by 's' consisting of a list of partitions mu that `,
`  appear as indices of the form s[mu] in f. For each string name (e.g., 'p'),`,
`  there will be a table entry indexed by 'p' whose value is the largest`,
`  integer n such that p.n occurs in f (n=0 if none occur).`,
`  If varset() is called with only one argument, the default <bases>=`,
`  {s[],m[],h,e,p} is used.`,
`  If <bases> is a single name (not a list or set), then the table entry`,
`  corresponding to this name, not the table itself, is returned.`,
`  String names must be single letters.`,
`   `,
`EXAMPLES :   `,
`  varset((p1+p3)^3+p7,'p');               yields    7`,
`  varset(s[3,2]*m[2]+h3*h1);              yields `,
`                           table([(s)=[[3, 2]],(m)=[[2]],(h)=3,(e)=0,(p)=0])`,
`  f:=P[2,1]+q2^2*P[1,1];`,
`  t:=varset(f,{'q','P[]'}); `,
`  t[P],t[q];                              yields   [[2,1], [1,1]] , 2`,
`    `,
`SEE  ALSO :  stdeg`,
`   `
):
`help/text/zee` := TEXT(
`############################################################################`,
`    `,
`FUNCTION : zee - order of centralizer of a permutation`,
`    `,
`CALLING SEQUENCE : zee(<lambda>);  zee(<lambda>,a);  zee(<lambda>,q,t);`,
`    `,
`PARAMETERS :  <lambda>  = a partition`,
`               a,q,t    = arbitrary names or expressions`,
`   `,
`SYNOPSIS :   `,
`  If <lambda> is a partition with m.i terms of size i, then zee(<lambda>)`,
`  is defined to be 1^(m1)*m1!*2^(m2)*m2!*..., which is the order of the`,
`  centralizer of any permutation of cycle-type <lambda>.`,
`  zee(<lambda>,a) is defined to be a^nops(<lambda>)*zee(<lambda>)`,
`  zee(<lambda>,q,t) is defined to be`,
`     zee(<lambda>)*prod((1-q^lambda[i])/(1-t^lambda[i])).`,
`   `,
`EXAMPLES :   `,
`  zee([]);                   yields    1`,
`  zee([3,3,2]);              yields    36`,
`  zee([3,3,2],x);            yields    36*x^3`,
`  zee([3,3,2],z^2,z);        `,
`  normal(");                 yields    36*(z^3+1)^2*(z^2+1)`,
`    `,
`SEE  ALSO :  scalar`,
`   `
):

#save `SF.m`;
#quit
