local poly* decompose_character(poly* ch) { wt_init(ch->ncols); /* for building result */ while (ch->coef[0]->size!=0) /* i.e., |while (ch!=0)| */ { bigint* c=ch->coef[0]; if (c->size<0) { cmpfn=sav_cmpfn; defaultgrp=sav_dfgrp; error ("Non-virtual decomposition failed.\n"); } { wt_ins(ch->elm[0],c,false); /* contribute weight to result */ c=copybigint(c,NULL); c->size= -c->size; ch=Addmul_pol_pol_bin(ch,Domchar_irr(ch->elm[0],NULL),c); } } { poly* result=wt_collect(); { cmpfn=sav_cmpfn; defaultgrp=sav_dfgrp; clrsorted(result); } return result; } }
local void add_decomp_wt(entry* mu) { lie_Index i,r=the_g->lierank; boolean neg; for (i=0; i<r; ++i) cur_expon[i]=mu[i]+1; neg=simp_make_dominant(cur_expon,the_g)%2!=0; /* apply |alt_dom| action */ for (i=0; i<r; ++i) if (--(cur_expon[i])<0) return; /* subtract $\rho$ and quit unless result is dominant */ wt_ins(cur_expon,one,neg); /* and insert into result */ }
poly* LR_tensor_irr(entry* lambda,entry * mu, _index n) { _index i,j; entry* nu; entry** T; if (n==0) return poly_one(0); { nu=&mkintarray(n+1)[1]; copyrow(lambda,nu,n); nu[-1]=lambda[0]+mu[0]; T=alloc_array(entry*,n+1); for (i=0;i<=n;++i) /* allocate row |T[i]| and place sentinel before it */ { T[i]= &mkintarray(mu[i==0?0:i-1]+1)[1]; T[i][-1]=n-1-i; } for (i=0,j=mu[0]-1; j>=0; --j) { while (i<n && mu[i]>j) ++i; /* find first |i| with |mu[i]<=j| */ T[i][j]=-1; /* place sentinel at bottom of column |j| */ } } wt_init(n); /* prepare to collect terms with exponents of size~|n| */ { j=-1; for (i=n-1; i>0 && mu[i]==0; --i) {} /* move to initial position */ recurse: /* recursive starting point; */ if (++j>=mu[i] &&(j=0,--i<0)) /* move to next empty position, if any */ wt_ins(nu,one,false); /* if not, |T| is full; contribute |nu| once */ else { _index k= T[i+1][j]; entry prev= nu[k]; do { while (nu[++k]==prev) {} /* find next |k| with |nu[k]<nu[@t$k'$@>]| */ ++nu[T[i][j]=k]; goto recurse; /* insert |k| into |T| and extend partition |nu|; recurse */ resume: prev= --nu[k=T[i][j]]; /* restore |k| and |nu|; set |prev=nu[k]| */ } while (prev>nu[T[i][j-1]]); /* if so, there are still corners of |nu| to try */ } if (j==0) j= ++i<n?mu[i]:0; /* return to end of row below if necessary */ if (--j>=0) goto resume; /* do return jump unless empty row is reached */ } { --nu; freearr(nu); for (i=0;i<=n;i++) { entry* t=&T[i][-1]; freearr(t); } freearr(T); } return wt_collect(); /* return sum of all contributed terms */ }
poly* MN_char(entry* lambda, lie_Index l) { lie_Index n=check_part(lambda,l); if (n==0) return poly_one(0); /* the character of $\Sym0$ */ while (lambda[l-1]==0) --l; /* minimise |l| */ wt_init(n); /* get ready for accumulating contributions to the character */ { entry* mu=mkintarray(3*n),* save=mu+n,* lambda_prime=save+n; int i, j, r, d=lambda[0]+l, k=0; /* sum of leg lengths */ boolean* edge=alloc_array(boolean,2*d-2),* candidate=edge+d-2; /* lie_Index |2<=r<d| */ enum {hor, vert}; /* values used for |edge| */ for (i=0; i<n; ++i) mu[i]=0; { int r=l-1,c=0; /* current column number */ for (j=0; r>=0; --r) { while (c<lambda[r]) { edge[j++]=hor; ++c; } /* columns of length |r| */ edge[j++]=vert; /* row |r|, of length |c==lambda[r]| */ } } for (r=2; r<d; ++r) { for (j=0; j+r<d; ++j) if (edge[j]==hor && edge[j+r]==vert) break; candidate[r]= j+r<d; } { i=0; /* index of last entry that was set in~|mu| */ for (r=d-1; r>1; --r) /* try hooks of size |r| */ if (candidate[r]) { recurse: /* recursive starting point */ { for (j=1; j<r; ++j) k+=edge[j]; /* leg length of hook first tried */ for (j=0; j<d-r; ++j) { if (edge[j]==hor && edge[j+r]==vert) { edge[j]=vert; edge[j+r]=hor; mu[i]=r; save[i++]=j; goto recurse; resume: j=save[--i]; r=mu[i]; mu[i]=0; edge[j]=hor; edge[j+r]=vert; } k+= edge[j+r]-edge[j+1]; /* adjust |k| for hook tried next */ } while (++j<d) k-= edge[j]; /* restore |k| */ } } } { int r=l,c=0,s=0; /* size of |lambda_prime| */ for (j=0; r>0; ) if (edge[j++]==vert) s+=lambda_prime[--r]=c; else ++c; /* build |lambda_prime| from edges */ for (j=0; j<s; ++j) mu[i++]=1; /* extend |mu| with |s| ones */ wt_ins(mu,n_tableaux(lambda_prime,l),k%2); for (j=0; j<s; ++j) mu[--i]=0; /* remove the ones again */ } if (i>0) goto resume; { freearr(edge); freearr(mu); } } return wt_collect(); }