Tally[ ] and Union[ ]

*To*: mathgroup at smc.vnet.net*Subject*: [mg83367] Tally[ ] and Union[ ]*From*: "Michael Weyrauch" <michael.weyrauch at gmx.de>*Date*: Sun, 18 Nov 2007 04:53:16 -0500 (EST)

Hello, in the Mathematica 6.0 documentation it says in the entry for Tally: Properties and Relations: "A sorted Tally is equivalent to a list of counts for the Union:" This is what I indeed expect of Tally and Union, in particular then it holds for any list: Length[Tally[list]] is equal to Length[Union[list]]. Now, I have an example, where Mathematica 6.0 produces a result where Tally[list] and Union[list] are different in length, which surprises me. And in fact, the result of Tally[ ] seems wrong to me. You can reproduce this result using the small Mathematica package enclosed, which uses Combinatorica. (Sorry for the somewhat complicated example, but I did not find a simpler case showing the effect.) If you load this package into a notebook and then execute diagrams[2] Tally and Union produce the expected result: both lists have equal length. (The list elements are diagrams.) However, if you execute diagrams[3] Tally and Union produce lists of different length. To my opinion, it really should never happen that Tally and Union produce lists of different length. I just expect of Tally to tell me the multpilicities in the equivalence classes, in addition to the information produced by Union. (The two list to be compared are called "ta" and "un" in the package enclosed.) Strangely enough, the program compares list elements 5 and 10 explicitly, and comes to the conclusion that element 5 and 10 belong to the same equivalence class, nevertheless they are both listed seperately in the Tally, but - correctly - lumped up in the Union. Do I misinterpret something here or is there a bug in Tally? (Tally is new in Mathematica 6, and I would find it extremely useful, if it would do what I expect it to do.) Michael Here comes my little package in order to reproduce the effect.... BeginPackage["wick`"] Needs["Combinatorica`"]; diagrams::usage="Calculate diagrams"; basicedges::usage; Begin["`Private`"] wick[a_, b_] := pair[a, b]; wick[a_, b__]:= Sum[Expand[pair[a, {b}[[i]]] Delete[Unevaluated[wick[b]], i]], {i, Length[{b}]}]; ham[n_Integer]:=(ns=4*n-3;{c[ns],c[ns+1],d[ns+2],d[ns+3]}); basicedges[n_]:=Flatten[Table[{{{i,i+1}, EdgeColor->Red}}, {i,1,2*n,2}],1]; hamserie[n_Integer]:=Flatten[Table[ham[i],{i,n}]]; cvertices[n_Integer]:={{n,1},{n,0}}; cvertexserie[n_Integer]:=Flatten[Table[cvertices[i],{i,n}],1]; pair[c[_],c[_]]:=0; pair[d[_],d[_]]:=0; pair[a_Integer,b_Integer]/;(a>b):=pair[b,a]; diagrams[n_]:=Module[{wickli, rep, i, cgraph, cvertices, congraph, le, un, ta}, wickli=wick[Sequence@@hamserie[n]]/.Plus->List; le=Length[wickli[[1]]]; wickli=wickli/.{pair[c[i_],d[j_]]->pair[i,j], pair[d[i_],c[j_]]->pair[i,j]}; graph={}; While[wickli=!={}, wickli=rempar[First[wickli],wickli,n, le]]; (*edge reduction and edgelist construction for use by Combinatorica*) rep=Dispatch[Flatten[Table[{Rule[2*i-1,i],Rule[2*i,i]},{i,2*n}]]]; graph=(Take[#,-le]/.rep/.pair[a__]^_->pair[a])&/@graph; be=basicedges[n]; cgraph=Map[List,(graph/.{pair->List, Times->List}),{2}]; cvertices=List/@cvertexserie[n]; cgraph=Join[be,#]&/@cgraph; cgraph=Graph[#,cvertices]&/@cgraph; (* Now I compare Union and Tally *) un=Union[cgraph,SameTest->IsomorphicQ]; Print["Union: number of elements: ", Length[un]]; Print[GraphicsGrid[Partition[ShowGraph[#]&/@un, 3,3,{1,1},{}]]]; ta=Tally[cgraph,IsomorphicQ]; ta=Sort[ta]; Print["Tally: Number of Elements: ", Length[ta]]; Print[GraphicsGrid[Partition[ShowGraph[#]&/@(First/@ta), 3,3,{1,1},{}]]]; Print["Are 5 and 10 isomorphic? ", IsomorphicQ[cgraph[[5]], cgraph[[10]]]]; ]; rempar[li_,wickli_List,n_Integer,le_]:=Module[{lis, mult, gem, pre, i}, lis={Take[li,-le]}; pre=Drop[li,-le]; Do[lis=Join[lis,lis /. {i->i+1, i+1->i}], {i,1,4*n-1,2}]; lis =Union[lis]; mult=Length[lis]; graph=Join[graph,{li*mult}]; Complement[wickli,pre*lis] ]; End[]; EndPackage[];