# Tools for manipulating sparse matrices. # A matrix is a list of linear polynomials in the variables e1,e2,... # The i-th polynomial represents the i-th row of the matrix. # Example: e3-2*e5 represents the row vector [0,0,1,0,-2,...] # Compute the matrix product a * b. fast_prod:=proc(a,b) local i; map(expand,subs({seq(cat('e',i)=b[i],i=1..nops(b))},a)) end; # Note: If a and b are matrices in this format, then versions of Maple # starting with V.4 automatically "do the right thing" with linear # combinations such as 3*a-2*b. ######################## # transpose a *square* matrix in sparse format fast_transpose:=proc(a) local i,j,N,b,res,co,tm,v,q; N:=nops(a); res:=table([seq(i=0,i=1..N)]); b:=subs({seq(cat('e',i)=q^i,i=1..N)},a); for i to N do co:=[coeffs(b[i],[q],'tm')]; tm:=map(degree,[tm],q); v:=cat('e',i); for j to nops(tm) do res[tm[j]]:=res[tm[j]]+co[j]*v od; od; res:=[seq(res[i],i=1..N)]; end; ######################## # test whether sparse matrix a is symmetric is_sym:=proc(a) local b,j,q,k,co,tm; b:=subs({seq(cat('e',j)=q^j,j=1..nops(a))},a); for j to nops(a) do co:=[coeffs(b[j],[q],'tm')]; tm:=[tm]; co:={seq(coeff(b[degree(tm[k],q)],q,j)-co[k],k=1..nops(co))}; if simplify(co,'sqrt')<>{0} then RETURN(false) fi od; true end; ######################## # Given symmetric matrices a and b and an integer m>=1, compute the # set of matrix entries of the braid difference (a*b*a*...)-(b*a*b*...) # (each product having m terms). Since the difference is symmetric (m odd) # or skew-symmetric (m even), we only extract coefficients on or above the # main diagonal. # If there is a fourth argument (i.e., a flag), don't assume that a and b # are symmetric, and return *all* coefficients of the braid difference. # Note: to build hereditary irreps relative to the standard chains, # we never need to apply the braid relations with m=4 for matrices larger # than 3x3, and m=6 cases are never larger than 2x2. braid_eqns:=proc(m,a,b) local u,co,i,vars; u:=[a,b]; co:=table(); for i to m-1 do u:=[fast_prod(u[2],a),fast_prod(u[1],b)] od; u:=zip((x,y)->x-y,u[1],u[2]); vars:={seq(cat('e',i),i=1..nops(a))}; if nargs>3 then RETURN(map(coeffs,{op(u)},vars)) fi; for i to nops(a) do co[i]:={coeffs(u[1],vars)}; vars:=subs(cat('e',i)=NULL,vars); u:=subs(cat('e',i)=0,subsop(1=NULL,u)); od; {seq(op(co[i]),i=1..nops(a))} end; ##################### # Given a group element w=[i_1,...,i_l] of para-Coxeter type (i.e., a # product of *distinct* simple reflections), evaluate the trace of w in # the i-th irrep of the Weyl group of rank n in the database. # # Requires the diagonal of the matrix representing w to be the product # of the diagonals of its factors. (True for graceful parabolic chains.) cheap_trace:=proc(w,i,n) local tr,rg,k,T; tr:=listchains(i,0,n); rg:=[seq(Rep[0,k]+1..k+1,k=1..n)]; tr:=[seq(convert([seq(coeff( Rep[[op(rg[k],T)],k],e[op(rg[k],T)]),k=w)],`*`),T=tr)]; convert(tr,`+`); end; # Compute the trace of w in the i-th irrep in an honest way. # We unpack a full matrix for each term appearing in w, so if w has # repetitions and the dimension is large, this is grossly inefficient. slow_trace:=proc(w,i,n) local a,j,ch; if nops(w)=0 then RETURN(Rep[n][i][1]) fi; ch:=listchains(i,0,n); a:=restore(w[1],n,ch); for j from 2 to nops(w) do a:=fast_prod(a,restore(w[j],n,ch)) od; convert([seq(coeff(a[j],cat('e',j)),j=1..nops(a))],`+`) end;