Re: Forcing 'Plus' to format nicely
- To: mathgroup at smc.vnet.net
- Subject: [mg8250] Re: Forcing 'Plus' to format nicely
- From: Robert Villegas <villegas>
- Date: Sat, 23 Aug 1997 01:58:48 -0400
- Organization: Wolfram Research
- Sender: owner-wri-mathgroup at wolfram.com
> I have a fn that gives output like this: > > In[] ww = f[blah] > Out[]= > > { t[{6}], 2 t[{5,1}], 3 t[{4,2}], t[{4,1,1}], 2 t[{3,3}], 4 t[{3,2,1}], > t[{2,2,2}], t[{2,2,1,1}]} > > Note how the t terms are nicely sorted: {6}, then {5, 1}, then {4, 2} etc > My desired output is actually Plus@@ww, but doing so ruins my nice ordering: > > eg In[] Plus@@ww > Out[] > > t[{6}]+2 t[{3,3}]+3 t[{4,2}]+2 t[{5,1}]+t[{2,2,2}]+4 t[{3,2,1}]+t[{4,1,1}]+ > t[{2,2,1,1}] If you want a permanent display rule for lists whose elements are multiples of t[...] expressions, then you could set $PrePrint to a function that specially displays this type of list and leaves everything else alone: In[111]:= $PrePrint = Replace[#, tList:{(_. _t)..} :> Composition[HoldForm, Plus] @@ tList]&; In[112]:= expr Out[112]= t[{6}] + 2 t[{5, 1}] + 3 t[{4, 2}] + t[{4, 1, 1}] + 2 t[{3, 3}] + 4 t[{3, 2, 1}] + t[{2, 2, 2}] + t[{2, 2, 1, 1}] Add an element that doesn't conform, and the list will be displayed normally: In[118]:= Append[expr, {}] Out[118]= {t[{6}], 2 t[{5, 1}], 3 t[{4, 2}], t[{4, 1, 1}], 2 t[{3, 3}], 4 t[{3, 2, 1}], t[{2, 2, 2}], t[{2, 2, 1, 1}], {}} If you can't clobber $PrePrint (say it's already set to something), then consider putting your t terms in a custom wrapper instead of List, and define a formatting rule for the wrapper: In[123]:= Format[MyList[elems___]] := HoldForm @ Plus[elems] In[124]:= expr = MyList[ t[{6}], 2*t[{5, 1}], 3*t[{4, 2}], t[{4, 1, 1}], 2*t[{3, 3}], 4*t[{3, 2, 1}], t[{2, 2, 2}], t[{2, 2, 1, 1}] ] Out[124]= t[{6}] + 2 t[{5, 1}] + 3 t[{4, 2}] + t[{4, 1, 1}] + 2 t[{3, 3}] + 4 t[{3, 2, 1}] + t[{2, 2, 2}] + t[{2, 2, 1, 1}] Or you can create a typesetting rule if you're using the typesetting front end: In[125]:= MakeBoxes[{tElems:((_. _t)..)}, fmt_] := MakeBoxes[Plus[tElems], fmt] In[126]:= expr //StandardForm Out[126]//StandardForm= t[{6}]+2 t[{5,1}]+3 t[{4,2}]+t[{4,1,1}]+2 t[{3,3}]+4 t[{3,2,1}]+t[{2,2,2}]+ t[{2,2,1,1}] > Any ideas how one can circumvent this problem inside a Module ? > > One approach I thought of is as follows: > > In[] Unprotect[Plus]; ClearAttributes[Plus, Orderless]; Plus@@ww > > Out[431]= > t[{6}] + 2 t[{5,1}] + 3 t[{4,2}] + t[{4,1,1}] + 2 t[{3,3}] + > 4 t[{3,2,1}] + t[{2,2,2}] + t[{2,2,1,1}] > > Unfortunately, in order to be a good citizen, I still have to > turn SetAttributes[Plus, Orderless]; Protect[Plus] back on in the same > Module[]. I don't see how one can do this AFTER generating the output > to screen (v3). Any ideas? It's driving me nuts. Even a function that creates the desired expression in an artificial environment where Plus doesn't sort won't work for $PrePrint, because like all functions, it has to exit and return its final result to the main evaluator. The result gets evaluated in the global environment where the Plus changes are no longer in effect. To preserve the function's return value exactly, you therefore have to return something that you are sure will not change. I used HoldForm to prevent change. Another trick that works when the only purpose of the result is appearance is to return a string instead of an expression: MyPrint[{tElems:((_. _t)..)}] := Module[{displayStr}, ClearAttributes[Plus, Orderless]; displayStr = ToString[ Plus[tElems], Options[$Output] ]; SetAttributes[Plus, Orderless]; displayStr ] MyPrint[other_] := other $PrePrint = MyPrint; Note that MyPrint disabled only the sorting of Plus, not other behavior. If identical terms happen to be adjacent, they will get combined, which may not be what you want. Robby Villegas