Pictographs for intertwiners of SU(n): honeycombs

Version 1.1
Robert Coquereaux
CPT, CNRS, Luminy, Marseille

WHAT THE PROGRAM DOES

A triple of irreducible representations (ω1, ω2, ω3) of SU(n) specified by their highest weights is admissible if ω1 ⊗ ω2 ⊗ ω3 contains ℂ (the scalars), or equivalently if the decomposition of ω1 ⊗ ω2 into a direct sum contains (OverBar[ω3]) (the conjugate of ω3). By definition an admissible triple has non-zero multiplicity,  i.e. the representation  (OverBar[ω3]) may occur once or several times in the decomposition of ω1 ⊗ ω2 into a direct sum.
If the multiplicity is equal to m one can associate m diagrams, generically called pictographs to the chosen triple.

There are several versions of pictographs: 
Chronologically the first version was introduced by A.D. Berenstein and A.Z. Zelevinsky in 1992; they are called BZ-triangles. 
Then we had the honeycombs introduced by A. Knutson and T. Tao in 1992; they are called KT-honeycomb  (actually they were introduced for the group GL(n)).
A kind of dual version of the latter was later introduced by A. Ocneanu (unpublished); they are called O-blades, or oblades, and were presented and used, together with an adapted SU(n) version of the KT-honeycomb (called SU(n) honeycombs, isometric honeycombs, or just honeycombs, for short)  in an article by R. Coquereaux and J.-B. Zuber,  in 2014.

The edges of a honeycomb carry integers : one can display this information with regular honeycombs, with edges labelled by the corresponding non-negative integers (but they may vanish).
One can also display the same information by using isometric honeycombs (which are discussed in the same paper by R.C. and J.-B. Zuber) where edges have precisely a length equal to the integer that they carry.
In the latter case some edges may have length 0 so that the hexagons of an isometric honeycomb can be degenerated.
The precise references can be found in the subsection DETAILS AND REFERENCES (see below).

Given an admissible triple, the present program determines its multiplicity and draws the corresponding isometric honeycombs.

A companion program (called obladesSUn)  draws the associated O-blades.

The present program can also determine the decomposition of a tensor product of irreducible representations (irreps) into a direct sum of irreps, although this is not is prime objective, as this is something that can be done separately by the function tensorproduct  contained in the notebook tensorProdIrrep.nb  (the function tensorproduct is defined in the package shorttensorProdIrrepPackage).  

A product of two irreps can contain a huge quantity of terms in its decomposition, whereas the functions multiplicity and plotOblades, defined below, assume that their three arguments are provided by the user, so that they do not need to use the function tensorproduct (but the user may call this latter function if needed).

Constraints obeyed by the relevant pictographs (here honeycombs) are summarized in the  subsection “The SU(N) game”.

Here, like in the program tensorProdIrrep, the decomposition of a tensor product of irreducible representations is done by using an improved hive technique developed by the author: in order to speed up the calculation we use a basis of elementary pictographs where syzygies (constraints) are eliminated before the actual reduction of the system of inequalities takes place.

What the program does can be explained in terms of representation theory or in a purely combinatorial way, read the next subsection :  “The SU(N) game”.

THE SU(N) GAME

External faces of the honeycombs (excluding corners) are given: for each direction (NW, NE, S) there are N-1 faces are labelled with N-1 arbitrary non-negative integers. 
Internal edges carry non-negative integers.

Problem: find all the pictographs obeying the following constraints: 

	Conservation of integers on each face (its label is equal to the sum of the two edges that bound the face).
	For each hexagon of the honeycomb,  pair of edges that are adjacent to directly opposite angles have the same sum.
	
A triple (three sides, i.e. three triplets of N-1 non-negative integers ) is called admissible if the above problem admits a solution. Arbitrary triples are usually not admissible. 
For SU(N), honeycombs have (N-1)(N-2)/2 internal hexagons, but they may be partially or totally degenerate (vanishing edges).
Given two sides, the set of admissible triples is finite : the third side has to be chosen in a specific list (the one returned by the  tensorproduct command).
A chosen admissible triple may have multiplicity (several pictographs with the same sides) : the various solutions differ by the values of internal edges.
The solutions are given by the pictographs. Here we study the honeycomb version (see also the O-blade version in the obladesSUn program).

Example
	
Consider SU(5)

{3,4,3,5} ⊗ {4,3,5,4} ⟶{3,4,4,7}
This is one of the 5223 possible branchings returned by the function tensorproduct.
Its multiplicity is 1427, which is then also the number of honeycombs with those given sides.
Among them, 37 are non degenerated (none of their internal sides vanishes).
Their positions in the list (count index) returned by the function nondegeneratedObladesMain (defined below in the section Examples) 
{168,169,172,252,255,256,259,286,287,290,486,487,496,497,574,577,584,587,588,591,598,601,617,625,626,629,637,717,720,729,732,755,758,766,769,790,799}
Here are two of them.

GraphicsRow[{plotHoneycombs[{3,4,3,5},{4,3,5,4},{3,4,4,7},168], plotHoneycombs[{3,4,3,5},{4,3,5,4},{3,4,4,7},169]},ImageSize->Full]

The dynamic interface: why two sections for the CDF Player ?

The main function is plotOblade -- see also the function multiplicity and, if needed, the function tensorproduct.
They are defined in the main program : the obladePackage, that, in turns, calls the adjmatPackage package (exported functions adjmatfct and adjmatgraph).
The user can directly call these functions from a Mathematica session.
See the section Examples.

The following section “Code for interface” contains commands that generate a dynamical interface (and a cdf file)
Now, why two versions ?

The first version of the interface code can be used in Mathematica and it was used to generate a cdf file that runs both in Mathematica and with the Wolfram CDF Player version for computers.
Unfortunately, some commands do not work well with the IOS version (iPad 2017 version) of the CDF Player, in particular the command that generates the reduction of a tensor product of representations. 
 Also the size of the graphics is not correct. This is the reason for the other version. 
With the second version of the cdf file (for the IOS CDF Player), the user has to rely on the other file tensorProdIrrep.cdf if he needs to determine the reduction of a tensor product of irreps into its simple components.

History

The package was written in 2014.
The code for the interface (dynamic module, cdf file) was written in August 2017.
It was made public on the R.C. web site in September 2017.

The decomposition of the tensor product of irreducible representations is done by using an improved hive technique. 
In order to speed up the calculation we use a basis of elementary pictographs where syzygies (constraints) are eliminated before the actual reduction of the system of inequalities takes place. 
See the subsection DETAILS.

Other related programs : see the program tensorProdIrrep (that only determines the reduction of a product of irreps into a direct sum), and the program SU(n) honeycombs.

Links

Related programs (notebooks) :

MouseOver 
MouseOver (this file)
MouseOver

CDF files :

MouseOver
MouseOver

MouseOver
MouseOver
MouseOver

MouseOver
MouseOver
MouseOver

Licence

MIT License
Copyright (c) 2017 RobertCoquereaux
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sub license, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

DETAILS AND REFERENCES

Irreducible representations (irreps) of the Lie group SU(n) are denoted by their highest weights. 
Their  n-1 components are given in a  particular basis called the Dynkin basis.

One starts from three irreps building an admissible triple.
Warning about the orientation of the last member of the triple... the triple obtained by conjugating the last member of an admissible triple is usually not admissible!
If the user only knows the first two members of the triple, he has  first to decomposes their tensor product ω1⊗ω2 as a sum of irreps, with multiplicities.

The user chooses one of them ((OverBar[ω3])), the program then draws the pictographs (O-blade version) associated with the coupling ω1⊗ω2 ⟶ (OverBar[ω3]).
Or, equivalently, with the coupling ω1⊗ω2 ⊗ω3 ⟶  1

The multiplicity of the coupling (aka Littlewood-Richardson coefficient) is equal to the number of pictographs.

Components of highest weights (non-negative integers) are read as follows:

ω1 : external vertices belonging to the left side of the triangle, bottom to top.
ω2 : external vertices belonging to the right side of the triangle, top to bottom.
ω3 : external vertices belonging to the bottom side of the triangle, right to left (equivalently (OverBar[ω3]) : left to right)

Internal edges carry non-negative integers.
They obey the following constraints : 

	Conservation of integers at each external vertex, 
	Equality of opposite angles at each internal vertex (the value of an angle being defined as the sum of its edges).

The displayed collection of pictographs, for a given triple  (ω1, ω2 ,  ω3), solves the above constraints.

Several types of pictographs can be used to display the same space of intertwiners (Subscript[Hom, SUn])(ω1⊗ω2, (OverBar[ω3])) :  BZ-triangles, KT-honeycombs, O-blades.
BZ stands for Berenstein-Zelevinski , KT for Knutsen-Tao, and O for Ocneanu.   The generic  term "pictographs" was introduced in [1] to denote these combinatorial objects.

Here we display isometric honeycombs (where edges have  a length precisely equal to the integer that they carry).

O-blades (also called “oblades”) are introduced and documented in [1][2][3]. 
Properties of Isometric honeycombs are also discussed in these references. 

[1] MouseOver
[2] MouseOver
[3] MouseOver

The decomposition of the tensor product of irreducible representations is done by using an improved hive technique developed by the author and inspired from [4], [5], [6]. 
In order to speed up the calculation we use a basis of elementary pictographs where syzygies (constraints) are eliminated before the actual reduction of the system of inequalities takes place.

[4] MouseOver
[5] MouseOver
[6] MouseOver

CAVEATS

Constraint on the values of weight components when using the  tensorproduct command :
In order to run the command  tensorproduct[la, mu], the components of the weights la and mu should obey the constraint Or[max(la) < 10, max(mu)] < 10 == True
This value of 10 comes from the default setting of the global system options for Reduce in Mathematica version 11.1
Strangely enough, the constraint was much less drastic -- it was 10^4 rather than 10^1 -- in Mathematica 6.0
This behavior will be “repaired” (hope so) in a later version of Mathematica.
Meanwhile,  If you need to manipulate simultaneously two weights that have components bigger than 10 (but smaller than 20, for instance),  quit the kernel, start it again, run the command 
SetSystemOptions[“ReduceOptions” -> {“DiscreteSolutionBound” -> 20}]
and evaluate the two packages adjmatPackage and obladePackage.

The dynamic interface: why two sections for the CDF Player ?

The main function is plotHoneycombs -- see also the function multiplicity,  and, if needed, the function tensorproduct.
They are defined in the main program : the honeycombPackage, that, in turns, calls the adjmatPackage package (exported functions adjmatfct and adjmatgraph).
The user can directly call these functions from a Mathematica session.
See the section Examples.

The section “Code for interface” contains commands that generate a dynamical interface (and a cdf file)
Now, why two versions ?

The first version of the interface code can be used in Mathematica and it was used to generate a cdf file that runs both in Mathematica and with the Wolfram CDF Player version for computers.
Unfortunately, some commands do not work well with the IOS version (iPad 2017 version) of the CDF Player.
This is the reason for the second version. 
Actually, this is indeed the case for the obladeSUn program, because of the pb with global orientation of graphs (choice of RandomSeed is different for different systems, and this is used by adjmatgraph),
 but at the moment (Sept 2017) the two cdf files for the computer and for IOS are the same.

HISTORY

A program drawing SU(3) honeycombs was written by the author in 2014.
A program drawing SU(4) honeycombs was written by my student D. Amankwah in December 2016.
The general code for SU(N) was written by the author during the spring 2017.
The code for the interface (dynamic module, cdf file) was written in August 2017.
It was made public on the R.C. web site in September 2017.

The decomposition of the tensor product of irreducible representations is done by using an improved hive technique. 
In order to speed up the calculation we use a basis of elementary pictographs where syzygies (constraints) are eliminated before the actual reduction of the system of inequalities takes place. 
See the subsection Details and References.

Other related programs : see the program tensorProdIrrep (that only determines the reduction of a product of irreps into a direct sum), and the program ObladesSUn.

LINKS

Related programs :

Notebooks (nb files, they also include the source code for the cdf version) 
(HyperlinkURL["Tensor product of SU(n) irreducible representations (Littlewood-Richardson coefficients)", http://www.cpt.univ-mrs.fr/~coque/Computer_programs/nb/tensorProdIrrep.nb])
(HyperlinkURL["Pictographs: oblades for SU(n)", http://www.cpt.univ-mrs.fr/~coque/Computer_programs/nb/obladesSUn.nb])
(HyperlinkURL["Pictographs: honeycombs for SU(n)", http://www.cpt.univ-mrs.fr/~coque/Computer_programs/nb/honeycombsSUn.nb])
(HyperlinkURL["Dimensions of irreps of SU(n)", http://www.cpt.univ-mrs.fr/~coque/Computer_programs/nb/dimensionsOfIrrepsSUn.nb])

CDF files (standalone)
for the Wolfram CDF Player
(HyperlinkURL["Tensor product of SU(n) irreducible representations (Littlewood-Richardson coefficients). CDF file", http://www.cpt.univ-mrs.fr/~coque/Computer_programs/cdf/tensorProdIrrep.cdf])
(HyperlinkURL["Pictographs: oblades for SU(n). CDF file", http://www.cpt.univ-mrs.fr/~coque/Computer_programs/cdf/obladesSUn.cdf])
(HyperlinkURL["Pictographs: honeycombs for SU(n). CDF file", http://www.cpt.univ-mrs.fr/~coque/Computer_programs/cdf/honeycombsSUn.cdf])
(HyperlinkURL["Dimensions of irreps of SU(n). CDF file", http://www.cpt.univ-mrs.fr/~coque/Computer_programs/cdf/dimensionsOfIrrepsSUn.cdf])

CDF files adapted to the first version of the CDF Player on IOS 
(when the latter is updated,  one should use the previous files instead):
(HyperlinkURL["Pictographs: oblades for SU(n). CDF file, IOS.", http://www.cpt.univ-mrs.fr/~coque/Computer_programs/cdf/obladesSUnForIOS.cdf])
(HyperlinkURL["Pictographs: honeycombs for SU(n). CDF file, IOS.", http://www.cpt.univ-mrs.fr/~coque/Computer_programs/cdf/honeycombsSUnForIOS.cdf])

Files for the cdf web plug-in 
(dying technology: the plug-in is incompatible with most recent browsers, these files will not be updated):
(HyperlinkURL["Tensor product of SU(n) irreducible representations (Littlewood-Richardson coefficients). CDF file for web plug-in", http://www.cpt.univ-mrs.fr/~coque/Computer_programs/cdf/tensorProdIrrepWeb.cdf])
(HyperlinkURL["Pictographs: oblades for SU(n). CDF file for web plug-in", http://www.cpt.univ-mrs.fr/~coque/Computer_programs/cdf/obladesSUnWeb.cdf])
(HyperlinkURL["Pictographs: honeycombs for SU(n). CDF file for web plug-in", http://www.cpt.univ-mrs.fr/~coque/Computer_programs/cdf/honeycombsSUnWeb.cdf])

CITATION

If you use this program in a scientific publication or talk, please give proper academic credit to the author :

MouseOver
MouseOver
September 2017

LICENCE

MIT License
Copyright (c) 2017 RobertCoquereaux
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sub license, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Main program: package (local copy) : use this to run the program with Mathematica

Code

adjmatPackage

BeginPackage["adjmatPackage`"];
(*usages go here*)

adjmatfct::usage="adjmatfct[n] returns the adjacency matrix of SU(3) at level n"

adjmatgraph::usage="adjmatgraph[n] returns the graphplot of the adjacency matrix of SU(3) at level n"

nntoseed::usage = "nntoseed is association list and nntoseed[NN] gives the RandomSeed to be used in GraphPlot in order to display correctly (orientation) the graph of adjacency matrices. The list nntoseed should be completed manually." 

Begin["Private`"];
(*Function definitions go here*)
adjmatfct[NN_]:=adjmatfct[NN]=Module[{levelplus,rk,One,iii,SparseAdjTens,normalAdjTens,lab,partlab,adjacencyMatrices},
levelplus = NN +1;
rk=(NN + 1)(NN +2)/2;
One = IdentityMatrix[rk];
SparseAdjTens=SparseArray[{{a_,b_,c_,d_} /;  c == a+1 &&  d == b ||c == a &&  d == b - 1 || c == a-1 && d == b + 1 -> 1},{levelplus,levelplus,levelplus,levelplus}];
normalAdjTens= Normal[SparseAdjTens];
lab={{0,0},{1,0},{0,1}};
Do[Do[iii=i+1;partlab[iii]={j-i,i},{i,0,j}];Do[lab=Append[lab,partlab[i]],{i,1,j+1}],{j,2,levelplus-1}];
adjacencyMatrices=Module[{v,crit0, crit1, crit2, indices0,indices1,indices2,indices,orderedindices,smallAdjTens, matbid,trisort,tritolab,permutritolab,permutritolabinverse,AdjMatTriality,AdjMatLevel},
indices = Flatten[Table[v[i,j],{i,1,levelplus},{j,1,levelplus-i+1}]];
crit0[v[p_,q_]] := Mod[p + 2q - 3,3] ==0; 
crit1[v[p_,q_]] := Mod[p + 2q - 3,3] ==1; 
crit2[v[p_,q_]] := Mod[p + 2q - 3,3] ==2; 
indices0=Select[indices,crit0];
indices1=Select[indices,crit1];
indices2=Select[indices,crit2];
orderedindices=Join[indices0,indices1,indices2];
smallAdjTens= Table[normalAdjTens[[i,j,k,l]],{i,1,levelplus},{j,1,levelplus-i+1},{k,1,levelplus},{l,1,levelplus-k+1}];
matbid[v[a_,b_],v[c_,d_]] :=smallAdjTens[[a,b,c,d]];
AdjMatTriality=Table[matbid[orderedindices[[i]],orderedindices[[j]]],{i,1,rk},{j,1,rk}];
(* Generator [1,0] with vertices sorted by triality blocks *)
trisort=(orderedindices /. {v->List})-ConstantArray[{1,1},rk];
tritolab=Table[Flatten[List[s,Position[lab,trisort[[s]]]]],{s,1,rk}];
permutritolab=SparseArray[MapThread[Rule,{tritolab, ConstantArray[1,rk]}],{rk,rk}];
permutritolabinverse=SparseArray[Inverse[permutritolab]];
 AdjMatLevel = permutritolabinverse.AdjMatTriality.permutritolab ;
(* Generator [1,0] with vertices sorted by increasing levels, like lab *)
{AdjMatTriality,AdjMatLevel}];
adjacencyMatrices[[2]]]
nntoseed=<|1->22,2->8,3->1,4->2,5->3,6->0,7->4,8->2,9->0,10->10,11->1,12->9|>;
(* nntoseed : to be completed *)
adjmatgraph[NN_]:= If[MissingQ[nntoseed[NN]]==True, Print["The a-list nntoseed should be completed for this argument"],
GraphPlot[adjmatfct[NN], VertexLabeling->True,Method->{Automatic,"RandomSeed"->nntoseed[NN]}]]
End[];(*private*)(*protect what you want*)EndPackage[];

Names["adjmatPackage`*"]

obladePackage

BeginPackage["obladePackage`", {"adjmatPackage`"}];
(*usages go here*)

oblade::usage=
"Evaluation of oblade[n] initializes all relevant data for SU(n). It returns n and set the variable currentgroup to n.";

tensorproduct::usage="tensorproduct[lambda,mu] returns the decomposition into irreducible components nu of a tensor product of two irreps lambda, mu, of the Lie group SU(n), given by the components of their highest weights along the basis of fundamental weights.  The last entry of each term is its multiplicity.";

multiplicity::usage="multiplicity[lambda,mu,nu] gives the multiplicity of the term nu in the decomposition into irreducible components of a tensor product lambda ⊗ mu of two irreps of the Lie group SU(n), given by the components of their highest weights along the basis of fundamental weights. This integer is also called Littlewood-Richardson coefficient. Equivalently it is the multiplicity of the trivial representation in the triple tensor product: lambda ⊗ mu ⊗ Conjugate[nu].";

pictographsCoordinates::usage =
"Assuming that the chosen triple has multiplicity m, the function pictographsCoordinates[lambda,mu,nu] gives the matrix
 of components of the m different pictographs along a basis of fundamental intertwiners. 
For SU(n) there are 3(n-1)+ (n-1)(n-2) fundamental intertwiners. A basis has only 3(n-1)+ (n-1)(n-2)/2 elements because of relations between fundamental intertwiners (syzygies). 
The rank of the matrix, minus 1, gives the dimension of the hive polytope, a rational polytope (not always integral) whose integral points are precisely the different pictographs. The dimension of the hive polytope is at most (n-1)(n-2)/2, with equality for the so-called generic triples."  


plotOblades::usage ="plotOblades[lambda,mu,nu] returns the list of drawings of all oblades with sides defined by the three highest weights lambda, mu, nu and describes the branching la ⊗ mu -> nu. To display this list as a tableform (with no braces) one can do as follows:  li = plotOblades[lambda,mu,nu];  GraphicsRow[li,ImageSize-> Length[li]*300]. The command admits and optional argument pos which is an integer chosen between 1 and multiplicity[lambda, mu, nu]; if specified, plotOblades[lambda,mu,nu, pos] displays only the particular oblade numbered pos.";

currentgroup::usage = "currentgroup returns the argument n of the group SU(n) currently in use.";

edgesEWvalues::usage = "edgesEWvalues[lambda,mu,nucc] returns the list of East-West edges values for the branching rule lambda ⊗ mu ⊗ nucc -> 1 or la ⊗ mu -> nu with nuc = Reverse[nu].";
edgesNESWvalues::usage = "edgesEWvalues[lambda,mu,nucc] returns the list of NorthEast-SouthWest edges values for the branching rule lambda ⊗ mu ⊗ nucc -> 1 or la ⊗ mu -> nu with nuc = Reverse[nu].";
edgesNWSEvalues::usage = "edgesEWvalues[lambda,mu,nucc] returns the list of NorthWest-SouthEast edges values for the branching rule lambda ⊗ mu ⊗ nucc -> 1 or la ⊗ mu -> nu with nuc = Reverse[nu].";

Begin["Private`"];
(*Function definitions go here*)

(* Sides,edges,components and equations *)
(* Sides *)
(* p will run from 1 to NN-1 *)
lambdalabel[n_,p_]:=1/2 (2+3 p+p^2);
mulabel[n_,p_]:=(n+1)(n+2)/2-p;
nulabel[n_,p_]:=1/2 (n+n^2-2 n p+(-1+p) p+2);

oblade[var_]:= With[{NN=var},
 
(* Equations on sides *)
(* conservation equations at the external vertices (weights) *)
lambdaequations = And[
Apply[And,Table[lambda[p,0,0]== Sum[ j[p,NN-(s+p),s] ,{s,0,NN-p}],{p,1,NN-1}]],
Apply[And,Table[lambda[0,p,0]== Sum[ j[s,p,NN-(s+p)] ,{s,0,NN-p}],{p,1,NN-1}]],
Apply[And,Table[lambda[0,0,p]== Sum[ j[s,NN-(s+p),p] ,{s,0,NN-p}],{p,1,NN-1}]]];
(* Edges values (in terms of fundamental pictographs)*)
edgesEW[NN]= Table[FoldList[Plus][Table[j[t,NN-s,s-t],{s,t,NN-1}]],{t,1,NN-1}];
edgesNESW[NN]= Table[FoldList[Plus][Table[j[s-p,p,NN-s],{s,p,NN-1}]],{p,1,NN-1}];
edgesNWSE[NN]= Table[FoldList[Plus][Table[j[NN-s,s-p,p],{s,p,NN-1}]],{p,1,NN-1}];
(* Edge labelling doublets *)
edgesEWlabels[lev_]:=Table[Take[Table[1/2 (4+p+p^2)+(lev-1),{p,lev,NN}],{z,z+1}],{z,1,NN-lev}];
edgesNESWlabels[lev_]:=Table[Take[Table[1/2 (3p+p^2)+1/2 (lev-1) (lev)+ (lev-1) p,{p,1,NN}],{z,z+1}],{z,1,NN-lev}];
edgesNWSElabels[lev_]:=Table[Take[Range[1+1/2 (-lev+NN) (1-lev+NN),1-lev+NN+1/2 (-lev+NN) (1-lev+NN)],{z,z+1}],{z,1,NN-lev}];

(* Fundamental pictographs and positivity constraints *)
components = Join[
Table[Table[ j[p,NN-(s+p),s] ,{s,0,NN-p}],{p,1,NN-1}],
Table[Table[ j[s,p,NN-(s+p)] ,{s,0,NN-p}],{p,1,NN-1}],
Table[Table[ j[s,NN-(s+p),p] ,{s,0,NN-p}],{p,1,NN-1}]];
fundamentalcomponents = Union[Flatten[components]];
positivityconstraints=And[
Apply[And,Map[# >= 0 &,Flatten@edgesEW[NN]]],
Apply[And,Map[# >= 0 &,Flatten@edgesNESW[NN]]],
Apply[And,Map[# >= 0 &,Flatten@edgesNWSE[NN]]]
];
buildlambdainput[{l1__},{l2__}]:=Flatten[{
MapThread[Rule,{Table[lambda[p,0,0],{p,1,NN-1}],{l1}}],
MapThread[Rule,{Table[lambda[0,p,0],{p,1,NN-1}],{l2}}]}];
buildlambdainput[{l1__},{l2__},{l3__}]:=Flatten[{
MapThread[Rule,{Table[lambda[p,0,0],{p,1,NN-1}],{l1}}],
MapThread[Rule,{Table[lambda[0,p,0],{p,1,NN-1}],{l2}}],
MapThread[Rule,{Table[lambda[0,0,p],{p,1,NN-1}],{l3}}]}];
fundamentalcomponentsLabels=ToString[fundamentalcomponents];

(* Values of edges if only lambda and mu are given *) 
componentsEdgesAndnuc[{lam__},{mu__}]:= componentsEdgesAndnuc[{lam},{mu}]= Module[{redsol,locrules,nuclist,fundcompval,edgesEWValues,edgesNESWValues,edgesNWSEValues},
redsol=Reduce[And[lambdaequations/. buildlambdainput[{lam},{mu}],positivityconstraints],fundamentalcomponents,Integers];
locrules=ToRules[redsol];
fundcompval=fundamentalcomponents/. {locrules} ;
nuclist=Table[lambda[0,0,p],{p,1,NN-1}]/. {locrules};
edgesEWValues = Table[edgesEW[NN]/.MapThread[Rule,{fundamentalcomponents, fundcompval[[s]]}],{s,1,Length[fundcompval]}];
edgesNESWValues = Table[edgesNESW[NN]/.MapThread[Rule,{fundamentalcomponents, fundcompval[[s]]}],{s,1,Length[fundcompval]}];
edgesNWSEValues = Table[edgesNWSE[NN]/.MapThread[Rule,{fundamentalcomponents, fundcompval[[s]]}],{s,1,Length[fundcompval]}];
{fundcompval,edgesEWValues ,edgesNESWValues,edgesNWSEValues,nuclist}];

(* Values of edges if lambda, mu and nu are given - Warning: nuc is reverse nu *) 
componentsEdgesAndnuc[{lam__},{mu__},{nuc__}]:= componentsEdgesAndnuc[{lam},{mu},{nuc}]= Module[{redsol,locrules,nuclist,fundcompval,edgesEWValues,edgesNESWValues,edgesNWSEValues},
redsol=Reduce[And[lambdaequations/. buildlambdainput[{lam},{mu},{nuc}],positivityconstraints],fundamentalcomponents,Integers];
redsol = And[redsol, Apply[And,Table[lambda[0,0,p]=={nuc}[[p]],{p,1,NN-1}]]];
(* If[redsol=!=False,locrules= ToRules[redsol], Print["Not an admissible intertwiner"];Return[{0,0,0,0,0}]];*)
If[redsol=!=False,locrules= ToRules[redsol],Return[{0,0,0,0,0}]];
fundcompval=fundamentalcomponents/. {locrules} ;
nuclist=Table[lambda[0,0,p],{p,1,NN-1}]/. {locrules};
edgesEWValues = Table[edgesEW[NN]/.MapThread[Rule,{fundamentalcomponents, fundcompval[[s]]}],{s,1,Length[fundcompval]}];
edgesNESWValues = Table[edgesNESW[NN]/.MapThread[Rule,{fundamentalcomponents, fundcompval[[s]]}],{s,1,Length[fundcompval]}];
edgesNWSEValues = Table[edgesNWSE[NN]/.MapThread[Rule,{fundamentalcomponents, fundcompval[[s]]}],{s,1,Length[fundcompval]}];
{fundcompval,edgesEWValues ,edgesNESWValues,edgesNWSEValues,nuclist}];

(* Plot oblades *)
(* Warning:GraphPlot uses RandomSeed to prevent global rotation of the graph layout *)
AdjMatbis=adjmatfct[NN]; (* this function is defined in a dependent package *)
rs = nntoseed[NN]; (* this a-list is defined in a dependent package *)
If[MissingQ[nntoseed[NN]], Print["The nntoseed A-list in the adjmatPackage should be extended for plotOblade to work with this rank"]];

plotSUNoblade[mytripleofweights_,loccoupling_]:=Module[{adj,vert=mytripleofweights,grid,gr2,grla,grmu,grnu,
grEW,grNESW,grNWSE},
(* Warning: mytripleofweights is a list of three weights *)
(* loccoupling is a positive integer that refers to the position in the list of coupling with fixed nu. *)
adj=AdjMatbis;
fullinfo=componentsEdgesAndnuc[mytripleofweights[[1]],mytripleofweights[[2]],
Reverse[mytripleofweights[[3]]]];
grid=GraphPlot[adj,Method->{Automatic,"RandomSeed"->rs}];
grla=GraphPlot[adj,VertexRenderingFunction->( Which@@Flatten[Table[{#2==lambdalabel[NN,s],{Text[Style[vert[[1,s]],Large,Blue],#,{Right,Bottom}],Disk[#,.03],{Black}}},{s,1,NN-1}],1]&)(* lambda side *),
Method->{Automatic,"RandomSeed"->rs}
];
grmu=GraphPlot[adj,VertexRenderingFunction->( Which@@Flatten[Table[{#2==mulabel[NN,s],{Text[Style[vert[[2,s]],Large,Blue],#,{Left,Bottom}],Disk[#,.03],{Black}}},{s,1,NN-1}],1]&)(* mu side *),
Method->{Automatic,"RandomSeed"->rs}
];
grnu=GraphPlot[adj,VertexRenderingFunction->( Which@@Flatten[Table[{#2==nulabel[NN,s],{Text[Style[vert[[3,NN-s]],Large,Blue],#,{Right,Top}],Disk[#,.03],{Black}}},{s,1,NN-1}],1]&)(* reversed nu side *),
Method->{Automatic,"RandomSeed"->rs}
];
grEW=GraphPlot[adj,EdgeRenderingFunction->
( Which@@Flatten[Table[Flatten[Table[{First[#2]==First[u] && Last[#2]==Last[u],{Text[Style[Reverse[fullinfo[[2,loccoupling]][[f]]][[First@Flatten[Position[edgesEWlabels[f],u]]]],20],(#1[[1]]+#1[[2]])/2]}},
{u,edgesEWlabels[f]}],1],{f,1,NN-1}],1]&),(* edges  EW *)
Method->{Automatic,"RandomSeed"->rs}
];
grNESW=GraphPlot[adj,EdgeRenderingFunction->
( Which@@Flatten[Table[Flatten[Table[{Last[#2]==First[u] && First[#2]==Last[u],{Text[Style[fullinfo[[3,loccoupling]][[f]][[First@Flatten[Position[edgesNESWlabels[f],u]]]],20],(#1[[1]]+#1[[2]])/2]}},
{u,edgesNESWlabels[f]}],1],{f,1,NN-1}],1]&),(* edges  NE-SW *)
Method->{Automatic,"RandomSeed"->rs}];
(* Very subtle in grNESW : we had to permute First and Last in #2 because of the orientation defined by the adjacency matrix !
At the same time we removed the Reverse in front of fullinfo because of the reversed convention between edgesNESWlabels and their values *)
grNWSE=GraphPlot[adj,EdgeRenderingFunction->
( Which@@Flatten[Table[Flatten[Table[{First[#2]==First[u] && Last[#2]==Last[u],{Text[Style[Reverse[fullinfo[[4,loccoupling]][[f]]][[First@Flatten[Position[edgesNWSElabels[f],u]]]],20],(#1[[1]]+#1[[2]])/2]}},
{u,edgesNWSElabels[f]}],1],{f,1,NN-1}],1]&),(* edges  NW-SE *)
Method->{Automatic,"RandomSeed"->rs}];
(* Modified Method everywhere in GraphPlot : Rotation ! For SU4 it was - Pi/3 *)
Show[grid,grla,grmu,grnu,grEW,grNESW,grNWSE]];

plotAllOblades[myweights_]:= 
Table[plotSUNoblade[myweights, pos],{pos,1,Apply[multiplicity,myweights]}];

(* OLD CODE WHERE POS REFERS TO GLOBAL POSITION IN TENSOR PRODUCT LIST
plotSUNobladeFromFullList[myweights_]:= Module[{fullinfo,tensp,couplingpositions,nums,listobld},(* Warning argument is a list of three lists :  weights {la,mu,nu} with la x mu -> nu *)
fullinfo=componentsEdgesAndnuc[myweights[[1]],myweights[[2]]];
tensp = fullinfo[[5]];
couplingpositions=Flatten@Position[tensp,Reverse@myweights[[3]]];(* warning third argument is reversed *)
(* Warning: coupling is a positive integer. WARNING this integer refers to the position in the global list of all couplings (for all nu's), not to the position in the list of coupling with fixed nu. *)
nums=Length[couplingpositions];
listobld=Table[plotSUNobladeOLD[myweights, coupl],{coupl,couplingpositions}]
(* One can display the above list of O-blades (without parens) for instance as follows : *)
(* GraphicsRow[listobld,ImageSize-> Length[listobld]*300] *)
]; To keep or not to keep ? *)
currentgroup=NN]

(* we add a CC at the end of tensorproduct to say that the rhs of the tensor product is reversed (complex conjugated) *)
componentsAlongFundPict[{lam__},{mu__}]:=componentsEdgesAndnuc[{lam},{mu}][[1]];
edgesEWvalues[{lam__},{mu__}]:=componentsEdgesAndnuc[{lam},{mu}][[2]];
edgesNESWvalues[{lam__},{mu__}]:=componentsEdgesAndnuc[{lam},{mu}][[3]];
edgesNWSEvalues[{lam__},{mu__}]:=componentsEdgesAndnuc[{lam},{mu}][[4]];
tensorproductCC[{lam__},{mu__}]:=componentsEdgesAndnuc[{lam},{mu}][[5]];
(* Getting only the weights nuc (ie conjugated nu),tallied,and their multiplicities *)

tensorproduct[{lam__},{mu__}]:=Switch[
ValueQ[currentgroup],False,oblade[Length[{lam}]+1];tensorproduct[{lam},{mu}],
True,If[
Length[{lam}]== currentgroup-1, 
SortBy[Tally[Map[Reverse,tensorproductCC[{lam},{mu}]]],Last], 
oblade[Length[{lam}]+1];
tensorproduct[{lam},{mu}]]];
(* Information for a given admissible triple:components along primitive pictographs,edges,multiplicity,etc. *)
(* Warning:the last component of the next command is a nu_conjugate *)
(* Getting part of the above information: *)
(* we add a CC at the end of tensorproduct to say that the rhs of the tensor product is reversed (complex conjugated) *)
(* Getting only the weights nuc (ie conjugated nu),tallied,and their multiplicities *)
componentsAlongFundPict[{lam__},{mu__},{nuc__}]:=componentsEdgesAndnuc[{lam},{mu},{nuc}][[1]];
edgesEWvalues[{lam__},{mu__},{nuc__}]:=componentsEdgesAndnuc[{lam},{mu},{nuc}][[2]];
edgesNESWvalues[{lam__},{mu__},{nuc__}]:=componentsEdgesAndnuc[{lam},{mu},{nuc}][[3]];
edgesNWSEvalues[{lam__},{mu__},{nuc__}]:=componentsEdgesAndnuc[{lam},{mu},{nuc}][[4]];
tensorproductCC[{lam__},{mu__},{nuc__}]:=componentsEdgesAndnuc[{lam},{mu},{nuc}][[5]];

multiplicity[{lam__},{mu__},{nu__}]:=Switch[
ValueQ[currentgroup],False,oblade[Length[{lam}]+1];multiplicity[{lam},{mu},{nu}],
True,If[Length[{lam}]== currentgroup-1, 
Length[tensorproductCC[{lam},{mu},Reverse[{nu}]]], 
oblade[Length[{lam}]+1];
multiplicity[{lam},{mu},{nu}]]];
(* multiplicityCC[{lam__},{mu__},{nuc__}]:=Length[tensorproductCC[{lam},{mu},{nuc}]]; *)

pictographsCoordinates[{lam__},{mu__},{nu__}]:=Switch[
ValueQ[currentgroup],False,oblade[Length[{lam}]+1];pictographsCoordinates[{lam},{mu},{nu}],
True,If[Length[{lam}]== currentgroup-1, 
componentsAlongFundPict[{lam},{mu},Reverse[{nu}]], 
oblade[Length[{lam}]+1];
pictographsCoordinates[{lam},{mu},{nu}]]];(* Warning: the third argument nu is not reversed *)

plotOblades[{lam__},{mu__},{nu__}]:=
Switch[ValueQ[currentgroup],
False,oblade[Length[{lam}]+1];plotOblades[{lam},{mu},{nu}],
True,If[Length[{lam}]==currentgroup-1,plotAllOblades[{{lam},{mu},{nu}}],
oblade[Length[{lam}]+1];plotOblades[{lam},{mu},{nu}]]]

plotOblades[{lam__},{mu__},{nu__},pos_]:=
Switch[ValueQ[currentgroup],
False,oblade[Length[{lam}]+1];plotOblades[{lam},{mu},{nu},pos],
True,If[Length[{lam}]==currentgroup-1,plotSUNoblade[{{lam},{mu},{nu}},pos],
oblade[Length[{lam}]+1];plotOblades[{lam},{mu},{nu},pos]]]

End[];(*private*)
(*protect what you want*)
EndPackage[];

Names["obladePackage`*"]

honeycombPackage

BeginPackage["honeycombPackage`", {"obladePackage`"}];
(*usages go here*)

plotHoneycombs::usage= "plotHoneycombs[lambda,mu,nu]returns the list of all honeycombs associated with the branching rule lambda,mu -> nu. To display this list as a tableform (with no braces) one can do as follows:  li = plotOblades[lambda,mu,nu];  GraphicsRow[li,ImageSize-> Length[li]*300]. The command admits and optional argument pos which is an integer chosen between 1 and multiplicity[lambda, mu, nu]; if specified, plotHoneycombs[lambda,mu,nu, pos] displays only the particular honeycomb numbered pos.";

Begin["Private`"];

(*Function definitions go here*)
u = {Sqrt[3]/2,1/2};v = {-(Sqrt[3]/2),1/2};w={0,-1};
sidespartsFct[lambda_,mu_,nu_,pos_]:= Module[{ew,nesw,nwse},
ew=edgesEWvalues[lambda,mu,Reverse[nu]][[pos]];
nesw=edgesNESWvalues[lambda,mu,Reverse[nu]][[pos]];
nwse=edgesNWSEvalues[lambda,mu,Reverse[nu]][[pos]];
List[ew,nesw,nwse]]
affineSegment[point_,vect_]:=Line[{point,point+vect}]
segmentLabel[txt_,color_,p_,q_,off_]:=Text[Style[txt,color, 15],(p+q)/2,Offset[off,{0,-1}]];
segmentLabel[txt_,color_,Bold,p_,q_,off_]:=Text[Style[txt,color,Bold, 24],(p+q)/2,Offset[off,{0,0}]];
segmentLabel[txt_,color_,"SemiBold",p_,q_,off_]:=Text[Style[txt,color,"SemiBold", 24],(p+q)/2,Offset[off,{0,0}]];

plotSUNhoneycomb[myweights_,pos_]:= Module[{la=myweights[[1]],mu=myweights[[2]],nu=myweights[[3]],NN,ptg,sidesparts,gra1,gra2},
(* Warning: myweights is a list of three weights *)(* pos is a positive integer that refers to the position in the list of coupling with fixed nu. *)
sidesparts=sidespartsFct[la,mu,nu,pos];
NN=currentgroup;(* for SU(NN) *)
(* Points coordinates for the floor f of the honeycomb *)
ptg[1,1]={0,0}; (* starting position: left bottom corner *)
ptg[1,s_]:=ptg[1,s-1]+ u sidesparts[[3,-s/2 ,-1]]  /; EvenQ[s];(* -1 special *)
ptg[1,s_]:=ptg[1,s-1]-v sidesparts[[2,(s-1)/2,1]] /; OddQ[s];
ptg[f_,1]:=ptg[f-1,2] - w sidesparts[[1,f-1,(NN)-(f-1)]];
ptg[f_,s_]:=ptg[f,s-1]+u  sidesparts[[3,-(s/2+f-1),s/2]]/; EvenQ[s]; 
ptg[f_,s_]:=ptg[f,s-1]- v sidesparts[[2,(s-1)/2,f]]/; OddQ[s];
(* Internal: points and edges*)
gra1=Graphics[Join[
Table[{Black,Point[Table[ptg[f,s],{s,1,2NN- 2f +1}]]},{f,1,NN}],
Table[{Blue, Line[Table[{ptg[f,j],ptg[f,j+1]},{j,1,2(NN-f)}]]},{f,1,NN-1}],
Table[{Blue,Line[Table[{ptg[f,j],ptg[f+1,j-1]},{j,2,2(NN-f),2}]]},{f,1,NN-1}],
Table[{Red,Table[affineSegment[ptg[f,j],2w],{j,1,2 NN-f,2}]},{f,1,1}],
Table[{Red,Table[affineSegment[ptg[f,j],2v],{j,1,1}]},{f,1,NN}],
Table[{Red,Table[affineSegment[ptg[f,j],2u],{j,2(NN-f)+1,2(NN-f)+1}]},{f,1,NN}]
],AspectRatio->Automatic];
(* External: outgoing edges *)
gra2=Graphics[{
Table[Table[segmentLabel[sidesparts[[1,f,-j]],Black,ptg[f,2j],ptg[f+1,2j-1],{5,0}],{j,1,NN-f}],{f,1,NN-1}],
Table[Table[segmentLabel[sidesparts[[2,f, j]],Black,ptg[j,2f],ptg[j,2f+1],{-6,-6}],{j,1,NN-f}],{f,1,NN-1}],
Table[Table[segmentLabel[sidesparts[[3,f, -j]],Black,ptg[j,2NN-2j-2f+1],ptg[j,2NN - 2j - 2f+1+1],{0,-6}],{j,1,NN-f}],{f,1,NN-1}],

Table[segmentLabel[la[[f]],Blue,Bold,ptg[f,1]-w,ptg[f+1,1]-w,{25,-10}],{f,1,NN-1}],
Table[segmentLabel[mu[[NN-f]],Blue,Bold,ptg[f,2NN-2f+1]-w,ptg[f+1,2NN-2f-1]-w,{-40,-10}],{f,1,NN-1}],
Table[segmentLabel[nu[[NN-f]],Blue,Bold,ptg[1,2NN-2f-1]-w,ptg[1,2NN-2f+1]-w,{-10,60}],{f,1,NN-1}]
},AspectRatio->Automatic];
Show[gra1,gra2]]

plotAllHoneycombs[myweights_]:= 
Table[plotSUNhoneycomb[myweights, pos],{pos,1,Apply[multiplicity,myweights]}];

plotHoneycombs[{lam__},{mu__},{nu__}]:=
Switch[ValueQ[currentgroup],
False,oblade[Length[{lam}]+1];plotHoneycombs[{lam},{mu},{nu}],
True,If[Length[{lam}]==currentgroup-1,plotAllHoneycombs[{{lam},{mu},{nu}}],
oblade[Length[{lam}]+1];plotHoneycombs[{lam},{mu},{nu}]]]

plotHoneycombs[{lamb__},{muu__},{nuu__},pos_]:=
Switch[ValueQ[currentgroup],
False,oblade[Length[{lamb}]+1];plotHoneycombs[{lamb},{muu},{nuu},pos],
True,If[Length[{lamb}]==currentgroup-1,plotSUNhoneycomb[{{lamb},{muu},{nuu}},pos],oblade[Length[{lamb}]+1];plotHoneycombs[{lamb},{muu},{nuu},pos]]]

End[];(*private*)(*protect what you want*)EndPackage[];

Names["honeycombPackage`*"]

Useful commands

Cf Comments in the section “An application: find the non degenerated pictographs....”

nondegeneratedObladesMain[λ_,μ_,ν_]:= 
Position[
Map[FreeQ[#,0]&,Map[Flatten,Transpose@{Map[Flatten,edgesEWvalues[λ,μ,Reverse[ν]]],Map[Flatten,edgesNESWvalues[λ,μ,Reverse[ν]]],Map[Flatten,edgesNWSEvalues[λ,μ,Reverse[ν]]]}]],True]

tensorproduct[mat_]:= Apply[tensorproduct,mat];(* it may be useful *)

Examples

Example with n=3 :  λ={3,1};μ={2,5};

Although this is not its principal interest, the present program can list all the possible ν  (with multiplicity) that appear in the decomposition of the product λ and μ.

λ={3,4};μ={2,5};

tensorproduct[λ,μ](* The irreducible representations that appear in the decomposition of λ⊗μ into a direct sum, with their multiplicity (the last entry of each sublist) *)

The program recognizes that the current group is SU(3)

currentgroup

The following example assumes that ν is given (it is chosen from the above list).

ν={3,7};

multiplicity[λ,μ,ν](* For :  la  mu -> nu. We knew the result already. *)

The multiplicity being 3, there are 3 oblades associated with this space of intertwiners (ie with this branching rule) :

plotHoneycombs[λ,μ,ν]

plotHoneycombs[λ,μ,ν, 2](* We only display the second one *)

Clear[λ,μ,ν]

An application: find the non degenerated pictographs corresponding to a given admissible triple

A pictograph is called non degenerated if none of its edges is equal to 0.

The following command was already introduced before

nondegeneratedObladesMain[λ_,μ_,ν_]:= 
Position[
Map[FreeQ[#,0]&,Map[Flatten,Transpose@{Map[Flatten,edgesEWvalues[λ,μ,Reverse[ν]]],Map[Flatten,edgesNESWvalues[λ,μ,Reverse[ν]]],Map[Flatten,edgesNWSEvalues[λ,μ,Reverse[ν]]]}]],True]

λ={21,13,5};μ={7,10,12};ν={20,10,11};

multiplicity[λ,μ,ν]

Flatten@nondegeneratedObladesMain[λ,μ,ν]

Among the 377 pictographs associated with this admissible triple, only 166 are non degenerated: in those cases the three hexagons of an SU(4) honeycomb are not degenerated.
The positions of these non degenerated pictographs in the list of all pictographs (the count index, see the user interface for O-blades or for honeycombs) are given by the previous list.

Length@%

For large multiplicities the number of non-degenerated pictographs can itself be quite large, and the above command may take some time; the used may be happy with a single example. 
The first non degenerated pictograph that appears in the above list (count index 16 in that example) can be found immediately as follows :

Module[{llist=Map[Flatten,Transpose@{Map[Flatten,edgesEWvalues[λ,μ,Reverse[ν]]],Map[Flatten,edgesNESWvalues[λ,μ,Reverse[ν]]],Map[Flatten,edgesNWSEvalues[λ,μ,Reverse[ν]]]}]},
Catch[Do[If[FreeQ[llist[[pos]],0],Throw[pos]],{pos,1,Length[llist]}]]]

GraphicsRow[{plotOblades[λ,μ,ν,16],plotHoneycombs[λ,μ,ν,16]},ImageSize->Full]

Clear[λ,μ,ν]

Another example:

{multiplicity[{21,13,5},{7,10,12},{19,2,2}],Flatten@nondegeneratedObladesMain[{21,13,5},{7,10,12},{19,2,2}]}

plotHoneycombs[{21,13,5},{7,10,12},{19,2,2},10]

Examples (continuation)

Example with n=6:  λ={2,1,1,1,1};μ={1,1,2,1,1};ν={2,2,3,2,1};

λ={2,1,1,1,1};μ={1,1,2,1,1};

?tensorproduct

tensorproduct[λ,μ]

currentgroup

The following example assumes that ν is given (it is chosen in the above list).

ν={2,2,3,2,1};

?multiplicity

multiplicity[λ,μ,ν](* For :  la  mu -> nu. We knew the result already. *)

The multiplicity being 16, there are 16 oblades associated with this space of intertwiners (ie with this branching rule):

?plotHoneycombs

plotHoneycombs[λ,μ,ν]

Show[plotHoneycombs[λ,μ,ν, 5],ImageSize-> Large] (* We only display the fifth one *)

νcc=Reverse[ν](* The conjugate of ν *)

?pictographsCoordinates

pictographsCoordinates[λ,μ,ν]
(* Components of the 16 oblades along a basis of 25 fundamental pictographs *)

Dimensions[%]

MatrixRank[%%]-1 (* Dimension of the hive polytope: the triple is therefore generic. *)

Other functions : value of edges. Example with λ={2,1,1,1,1};μ={1,1,2,1,1};ν={2,2,3,2,1}

The following three functions give the list of values of (internal) edges in the directions EW, NE-SW and NW-SE.
Warning: one has to conjugate the last argument in the function call

edgesEWvalues[λ, μ,Reverse[ν]]

edgesNESWvalues[λ, μ,Reverse[ν]]

edgesNWSEvalues[λ, μ,Reverse[ν]]

An application : determine a Littlewood Richardson polynomial

{ λ, μ, ν}

Table[multiplicity[s λ,s μ,s ν],{s,1,10}](*Warning:be patient! The determination of multiplicity for scaling factors s=9 or s=10 take some time...*)

tb=%;

pictographsCoordinates[λ,μ,ν]

deg=MatrixRank[%]-1

polruless=Flatten[Solve[Table[1+Sum[a[j] s^j ,{j,1,deg}]== tb[[s]],{s,1,deg}], Table[a[j],{j,1,deg}]]]

polruless=Flatten[Solve[Table[1+Sum[a[j] s^j ,{j,1,deg}]== tb[[s]],{s,1,deg}], Table[a[j],{j,1,deg}]]]

pol=1+Sum[a[j]s^j, {j,1,deg}]/. polruless (* the Littlewood Richardson polynomial for the chosen triple *)

pol/. s-> 1

multiplicity[λ,μ,ν](* check for :  la  mu -> nu *)

pol/. s->6

multiplicity[6 λ,6 μ,6 ν](* direct check *)

100 { λ, μ, ν}

Multiplicity of 100 * { λ, μ, ν} = {{200,100,100,100,100},{100,100,200,100,100},{200,200,300,200,100}} for the group SU(4) is :

pol/. s-> 100

An example with n = 6 : cf comments in the section “The SU(N) game”

multiplicity[{3,4,3,5},{4,3,5,4},{3,4,4,7}]

Flatten@nondegeneratedObladesMain[{3,4,3,5},{4,3,5,4},{3,4,4,7}]

We shall not display the 1427 oblades associated with this triple (!),  but we can display for instance the one which is in position 799

plotHoneycombs[{3,4,3,5},{4,3,5,4},{3,4,4,7}, 799]

A non admissible case

The value returned by the function multiplicity is 0

multiplicity[{1,0},{2,1},{3,0}]

Then plotHoneycombs returns an empty list (maybe one should modify this behaviour in such a way that plotHoneycombs returns a single point)

plotHoneycombs[{1,0},{2,1},{3,0}]

currentgroup

Packages and code for user interface (works with Mathematica and with the CDF Player on the computer)

Messages (to be initialized)

limitlenval=800;
limittimeval=1.5;

Print[Style["Web version: CHANGE The number of inequivalent irreps generated by the program should be smaller than ",12,Bold], Style[limitlenval,12,Bold]]

Print[Style["More time needed: the computation is terminated if it takes more than ",12,Bold],
Style[limittimeval,12,Bold],Style[" seconds",12,Bold]]

limittext="Web version: CHANGE the computation is terminated if it takes more than "1.5`" seconds";

limittime="More time needed: the computation is terminated if it takes more than "1.5`" seconds";

abouttabletext={"A triple of irreducible representations (ω1, ω2, ω3) specified by their higest weights is admissible if ω1 ⊗ ω2 ⊗ ω3 contains ℂ (the scalars)," , "or equivalently if the decomposition of ω1 ⊗ ω2 into a direct sum contains (OverBar[ω3]) (the conjugate of ω3).","Lines of the above table are the components of three highest weights (ω1, ω2; (OverBar[ω3])) in the basis of fundamental weights (Dynkin basis).",
"The triple (ω1, ω2, ω3) should be admissible.","","FILL THE ABOVE TABLE (USE TABS) AND HIT \"Update Components\".",
"If needed, the decomposition of ω1 ⊗ ω2 as a direct sum is obtained by clicking the button \"Tensor product decomposition of ω1 ⊗ ω2 \"; the last entry of each term returned by this command is its multiplicity; warning: the output can be quite long. "
  };

aboutobladetext={"A triplet of multiplicity m is associated with m distinct couplings represented by pictographs.",
 "There are several types of pictographs: BZ-triangles, KT-honeycombs, O-blades. Here we display O-blades (or oblades).",
"Display all pictographs, one at a time, by increasing or descreasing the count index (buttons Next pictograph, Previous pictograph, or the popup menu)."};

notadmissibletext=StringJoin[
"(ω1, ω2, ω3) is not an admissible triple: Modify the components and press \"Update\" \n
To see all possible choices for (OverBar[ω3]), using the displayed values of ω1 and ω2 (the list may be long):\n
 Press the button \"Tensor product decomposition of ω1 ⊗ ω2\" "];

O-BLADES ASSOCIATED WITH AN ADMISSIBLE TRIPLE OF IRREDUCIBLE REPRESENTATIONS OF SU(n)

Code for the user interface (the user should enable dynamic updating)

With[{fieldSize=3,n=3, limitlen=limitlenval, limittime=limittimeval},
DynamicModule[{rows=3,cols=n-1,
mat=With[{mat12=Table[RandomInteger[7],{2},{n-1}]},Append[mat12,First@RandomChoice[Apply[tensorproduct,mat12]]]],
coupling=1, mul, myRange, myPart,tp=0,tpval},
myRange[s_]:= Range[s];
myPart[expr_,s__]:= Part[expr,s];
mul=Dynamic[Apply[multiplicity,mat]];
Dynamic@Manipulate[
Which[
tp==0,(* Draw pictograph *)
Row[{Invisible[doit],
CheckAbort[If[Length[#]>limitlen, Abort[],#],Print[limittext, limitlen]]&[TimeConstrained[If[Setting@mul==0,notadmissibletext,
TableForm[{PopupMenu[Dynamic[coupling],Range[1,Setting@mul]],Show[plotHoneycombs[myPart[mat,1],myPart[mat,2],myPart[mat,3], coupling],ImageSize-> Full (* Large *)]}]],limittime,Print[limittime, limittime, " seconds"]]]}],

tp==1,(* Calculate the decomposition of ω1 ⊗ ω2 *)
tpval=tensorproduct[myPart[mat,1],myPart[mat,2]],

tp==2,(* a nice SU(6) example *)
tp=0;
mat={{3,2,3,2,2},{2,3,2,2,3},{4,5,4,2,5}};
TableForm[{PopupMenu[Dynamic[coupling],Range[1,Setting@mul]],Show[plotHoneycombs[myPart[mat,1],myPart[mat,2],myPart[mat,3], coupling],ImageSize-> Large]}]
],

Evaluate@With[{makeRow=Function[{rowIndex}, Map[Function[{colIndex},InputField[Dynamic[mat[[rowIndex,colIndex]]],Number,FieldSize->fieldSize]],myRange[cols]],HoldAll]},
Row[{TextGrid[{{"ω1",""},{},{"ω2",""},{},{OverBar["ω3"],""}}],Grid[Map[makeRow,myRange[rows]],Dividers->{{False,False,False},{False,False,Red}}],Invisible["xxxxxx"],
Button[Style["Update components",FontSize->14,Bold, Blue],mat;coupling=1;cols++;cols--;tp=0],
Column[{
Button[Style["Previous pictograph",Bold],If[coupling>1, coupling--; ]],
Button[Style["Next pictograph",Bold], If[coupling<Setting[mul], coupling++; ]]}],
Column[abouttabletext]}]],
Column[{Panel[Style[cols+1,FontSize->14,Bold],Style["SU(n), with n =",Bold, FontSize->14],Left,BaselinePosition->Bottom],Panel[Style[Column[{"Pictographs for admissible triples","of irreducible representations", "of SU(n)","The honeycomb version"},Center], "Title"]]},Invisible["xxxxxx"]],
Panel[mul,Style["Multiplicity is",FontSize->14,Bold],Left],
Panel[coupling,Style["The count index of this pictograph is",Bold],Left],
Column[aboutobladetext],
Button[Style["SU(n): decrease n",FontSize->14,Bold],If[rows>1,
mat=Map[(Drop[#,-1])&,mat];
coupling=1;
cols--;]],
Button[Style["SU(n): increase n",FontSize->14,Bold],
mat=Transpose[Append[Transpose[mat],Table[0,{3}]]];
coupling=1;
cols++;],
Button[Style["Tensor product decomposition of ω1 ⊗ ω2 ",FontSize->14,Bold, Blue],coupling=1; 
tp=1;cols++;cols--;],
Button[Style["An SU(6) example with multiplicity 592",FontSize->10,Bold, Brown,TextAlignment->Left],coupling=1;cols=6-1;tp=2; cols++;cols--; ],
Button[Style["Reset random SU(3) example",FontSize->10,Bold, Brown,TextAlignment->Left],
cols=2;mat=With[{mat12=Table[RandomInteger[7],{2},{3-1}]},Append[mat12,First@RandomChoice[Apply[tensorproduct,mat12]]]];
coupling=1;cols++;cols--;tp=0],
{{doit,0,""},{0},ControlType->None},
TrackedSymbols:> {doit},ContentSize->{610,600}],
SaveDefinitions->True, SynchronousUpdating-> False]]

CAPTION

Given an admissible triple, the program determines its multiplicity and draws the corresponding honeycombs.
This can be explained in terms of representation theory (see the subsection Details And References), or in a purely combinatorial way, see the next subsection :  “The SU(N) game”.

THE SU(N) GAME

External faces of the honeycombs (excluding corners) are given: for each direction (NW, NE, S) there are N-1 faces are labelled with N-1 arbitrary non-negative integers. 
Internal edges carry non-negative integers.

Problem: find all the pictographs obeying the following constraints: 

	Conservation of integers on each face (its label is equal to the sum of the two edges that bound the face).
	For each hexagon of the honeycomb,  pair of edges that are adjacent to directly opposite angles have the same sum.
	
A triple (three sides, i.e. three triplets of N-1 non-negative integers ) is called admissible if the above problem admits a solution. Arbitrary triples are usually not admissible. 
For SU(N), honeycombs have (N-1)(N-2)/2 internal hexagons, but they may be partially or totally degenerate (vanishing edges).
Given two sides, the set of admissible triples is finite : the third side has to be chosen in a specific list (the one returned by the  tensorproduct command).
A chosen admissible triple may have multiplicity (several pictographs with the same sides) : the various solutions differ by the values of internal edges.
The solutions are given by the pictographs. Here we study the honeycomb version (see also the O-blade version in the obladesSUn program).

Example
	
Consider SU(5)

{3,4,3,5} ⊗ {4,3,5,4} ⟶{3,4,4,7}
This is one of the 5223 possible branchings returned by the function tensorproduct.
Its multiplicity is 1427, which is then also the number of honeycombs with those given sides.
Among them, 37 are non degenerated (none of their internal sides vanishes).
Their positions in the list (count index) returned by the function nondegeneratedObladesMain (defined below in the section Examples) 
{168,169,172,252,255,256,259,286,287,290,486,487,496,497,574,577,584,587,588,591,598,601,617,625,626,629,637,717,720,729,732,755,758,766,769,790,799}
Here are two of them.

plotHoneycombs[{3,4,3,5},{4,3,5,4},{3,4,4,7},168]

plotHoneycombs[{3,4,3,5},{4,3,5,4},{3,4,4,7},169]

DETAILS AND REFERENCES

Irreducible representations (irreps) of the Lie group SU(n) are denoted by their highest weights. 
Their  n-1 components are given in a  particular basis called the Dynkin basis.

One starts from three irreps building an admissible triple.
Warning about the orientation of the last member of the triple... the triple obtained by conjugating the last member of an admissible triple is usually not admissible!
If the user only knows the first two members of the triple, he has  first to decomposes their tensor product ω1⊗ω2 as a sum of irreps, with multiplicities.

The user chooses one of them ((OverBar[ω3])), the program then draws the pictographs (O-blade version) associated with the coupling ω1⊗ω2 ⟶ (OverBar[ω3]).
Or, equivalently, with the coupling ω1⊗ω2 ⊗ω3 ⟶  1

The multiplicity of the coupling (aka Littlewood-Richardson coefficient) is equal to the number of pictographs.

Components of highest weights (non-negative integers) are read as follows:

ω1 : external vertices belonging to the left side of the triangle, bottom to top.
ω2 : external vertices belonging to the right side of the triangle, top to bottom.
ω3 : external vertices belonging to the bottom side of the triangle, right to left (equivalently (OverBar[ω3]) : left to right)

Internal edges carry non-negative integers.
They obey the following constraints : 

	Conservation of integers at each external vertex, 
	Equality of opposite angles at each internal vertex (the value of an angle being defined as the sum of its edges).

The displayed collection of pictographs, for a given triple  (ω1, ω2 ,  ω3), solves the above constraints.

Several types of pictographs can be used to display the same space of intertwiners (Subscript[Hom, SUn])(ω1⊗ω2, (OverBar[ω3])) :  BZ-triangles, KT-honeycombs, O-blades.
BZ stands for Berenstein-Zelevinski , KT for Knutsen-Tao, and O for Ocneanu.   The generic  term "pictographs" was introduced in [1] to denote these combinatorial objects.

Here we display isometric honeycombs (where edges have  a length precisely equal to the integer that they carry).

O-blades (also called “oblades”) are introduced and documented in [1][2][3]. 
Properties of Isometric honeycombs are also discussed in these references. 

[1] MouseOver
[2] MouseOver
[3] MouseOver

The decomposition of the tensor product of irreducible representations is done by using an improved hive technique developed by the author and inspired from [4], [5], [6]. 
In order to speed up the calculation we use a basis of elementary pictographs where syzygies (constraints) are eliminated before the actual reduction of the system of inequalities takes place.

[4] MouseOver
[5] MouseOver
[6] MouseOver

CAVEATS

The graphs obtained with the CDF Player on the tablet sometimes appear to be badly scaled, although they look nice on the computer screen.

Constraint on the values of weight components when using the  tensorproduct command :
In order to run the command  tensorproduct[la, mu], the components of the weights la and mu should obey the constraint Or[max(la) < 10, max(mu)] < 10 == True
This value of 10 comes from the default setting of the global system options for Reduce in Mathematica version 11.1
Strangely enough, the constraint was much less drastic -- it was 10^4 rather than 10^1 -- in Mathematica 6.0
This behavior will be “repaired” (hope so) in a later version of Mathematica.
Meanwhile,  If you need to manipulate simultaneously two weights that have components bigger than 10 (but smaller than 20, for instance),  quit the kernel, start it again, run the command 
SetSystemOptions[“ReduceOptions” -> {“DiscreteSolutionBound” -> 20}]
and evaluate the needed packages again (adjmatPackage,  obladePackage and honeycombPackage). The function tensorproduct is defined in obladePackage.

CITATION

If you use this program in a scientific publication or talk, please give proper academic credit to the author :

MouseOver
MouseOver
September 2017

Code for user interface  (for the CDF Player on IOS) : the same

Todo

Warning: because of the recent change of behavior of Reduce when the nb of solutions  > 10 we use Solve in the tensorProdIrrep program, but one should find a replacement for componentsEdgesAndnuc[{lam__},{mu__},{nuc__}] with three arguments.
 This is not used anyway in the shorttensorProdIrrepPackage, the latter being an adapted (because it uses Solve) and shortened version (because it only contains the tensorproduct code) of the /Users/robert/Library/Mathematica/Applications/oblade.m package.
 
When we use not only tensorproduct with two arguments, but also tensorproductCC, or the fct multiplicity, with three arguments, ie when we use the full tensorProdIrrepPackage we should worry when two lists  of components of weights involve integers larger than 10. To solve this problem one can use Reduce (instead of Solve) but modify its DiscreteSolutionBound option.

On the iPad the cdf programs usually work  when the tablet is in portrait (vertical) mode, but not always on landscape ( horizontal) mode !

The code uses a single Manipulate wrapped into a dynamic module, in order to avoid a code using nested manipulates, something forbidden (as of Nov 2017) by the IOS cdf Reader.

The RandomSeed option of GraphPlot is system dependent and maybe time dependent (Mathematica versions !).
The function plotOblade uses GraphPlot and assumes that the graph generated by adjmatgraph has a well defined global orientation.
This explain why we have one a-list nntoseed for the computer and another one for the tablet.
We shall maybe have to modify the values of nntoseed if Mathematica changes the way it draws graphs.

The graphs obtained with the tablet often appear to be badly scaled, although they look nice on the computer screen.