RE: RE: On Defining Functions Symmetric wrt Some Indices
- To: mathgroup at smc.vnet.net
- Subject: [mg34362] RE: [mg34328] RE: [mg34316] On Defining Functions Symmetric wrt Some Indices
- From: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>
- Date: Thu, 16 May 2002 05:08:56 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
Yes, Bobby, there are some variations. Mathematica is so ample, that mostly you have multiple solutions, even equivalent from an algorithmic standpoint. When I post, I sometimes like to show this breadth; therefore I used f[x, ##] & @@ Sort[{y}] (in my first suggestion) f[x, Sequence@@Sort[{y}]]] (further down in RuleCondition) Possibly you didn't see f[x_,y__]:= f[x]~Join~Sort[f[y]] /; !OrderedQ[f[y]] but this is a corollary to {x}~Join~Sort[{y}] mentioned, under _this_ condition. As has been noted by myself and others, instead of Sort you can use a helper function f0 with Orderless attribute: In[1]:= Attributes[f0] = Orderless; In[2]:= f /: f[x___, f0[y__]] := f[x, y] In[3]:= f[x_, y__ /; ! OrderedQ[{y}]] := f[x, f0[y]] In[4]:= f[a, b, c] === f[a, c, b] Out[4]= True In[5]:= f[a, b, c] === f[b, a, c] Out[5]= False So computation just loops once through f0. I should have better posted this instead of my somewhat silly last example. -- Hartmut > -----Original Message----- > From: DrBob [mailto:majort at cox-internet.com] To: mathgroup at smc.vnet.net > Sent: Wednesday, May 15, 2002 5:20 PM > Subject: [mg34362] RE: [mg34328] RE: [mg34316] On Defining Functions > Symmetric wrt > Some Indices > > > Wolf, > > Here's a slightly different definition: > > f[x_, y__] /; ! OrderedQ[{y}] := f[x, Sequence @@ Sort[{y}]] > > The pattern-matching concerns are probably beyond what Alexei cares > about, but thanks for teaching us all something here. > > I'm learning a lot! > > Bobby Treat > > -----Original Message----- > From: Wolf, Hartmut [mailto:Hartmut.Wolf at t-systems.com] To: mathgroup at smc.vnet.net > Sent: Wednesday, May 15, 2002 2:35 AM > Subject: [mg34362] [mg34328] RE: [mg34316] On Defining Functions Symmetric wrt > Some Indices > > > > -----Original Message----- > > From: Alexei Akolzin [mailto:akolzine at uiuc.edu] To: mathgroup at smc.vnet.net > > Sent: Tuesday, May 14, 2002 10:13 AM > > Subject: [mg34362] [mg34328] [mg34316] On Defining Functions > Symmetric wrt Some > Indices > > > > > > Hello, > > > > For the purposes of formula simplification I need to > specify that some > > function "f" is symmetric upon SOME of its indices. For example, > > f[a,b,c] == f[a,c,b] but NOT equal to f[b,a,c]. > > > > The proposed command SetAttribute[f,Orderless] makes the function > > symmetric wrt ALL of its indices, which I want to avoid. > > > > Is there is a way to neatly solve this problem? > > > > Thanks. > > > > Alexei. > > > > Alexei, > > from your question I suppose that you intend to use f merely as a > container > to transform the ordering of the arguments. Otherwise, if you have a > definition for f, you were free to bring the arguments to any > order you > like > at rhs, e.g. > > In[1]:= f[x_,y__]:={x}~Join~Sort[{y}] > > In[2]:= f[a,b,c]===f[a,c,b] > Out[2]= True > In[3]:= f[a,b,c]===f[b,a,c] > Out[3]= False > In[4]:= Quit[] > > But the problem with this presumably is just that head f is lost (and > cannot > be transformed further). This will keep it > > In[1]:= f[x_, y__] /; ! OrderedQ[{y}] := f[x, ##] & @@ Sort[{y}] > > In[2]:= f[a, b, c] === f[a, c, b] > Out[2]= True > In[3]:= f[a, b, c] === f[b, a, c] > Out[3]= False > In[4]:= f[1, 2, 3] /. f[a_, c_, b_] :> {a, b, c} > Out[4]= {1, 2, 3} > In[5]:= f[1, 2, 3] /. HoldPattern[f[a_, c_, b_]] :> {a, b, c} > Out[5]= {1, 3, 2} > > Deplorably Out[5] is not consistent with pattern matching of Orderless > attribute: > > In[6]:= Attributes[g] = {Orderless}; > > In[7]:= g[1, 2, 3] /. g[a_, c_, b_] :> {a, b, c} > Out[7]= {1, 2, 3} > In[8]:= g[1, 2, 3] /. HoldPattern[g[a_, c_, b_]] :> {a, b, c} > Out[8]= {1, 2, 3} > > In[9]:= Quit[] > > > Perhaps a good way to reach your ends would be to transform your > expression > explicitely using a rule: > > In[1]:= > normalizingRule = f[x_, y__] :> RuleCondition[f[x, > Sequence@@Sort[{y}]]] > > In[2]:= Unevaluated[f[a, b, c] === f[a, c, b]] /. normalizingRule > Out[2]= True > In[3]:= Unevaluated[f[a, b, c] === f[b, a, c]] /. normalizingRule > Out[3]= False > In[4]:= > Unevaluated[f[1, 2, 3] /. f[a_, c_, b_] :> {a, b, c}] /. > normalizingRule > Out[4]= {1, 2, 3} > In[5]:= > Unevaluated[ > f[1, 2, 3] /. HoldPattern[f[a_, c_, b_]] :> {a, b, c}] /. > normalizingRule > Out[5]= {1, 2, 3} > In[6]:= Quit[] > > What is ugly with this is the need to deliberately hold your > expressions > unless the rule is tried. But that can be done in a rather mechanical > fashion. > > If you know in advance which arguments are not to be ordered > (stretching > your example) perhaps you might try: > > In[1]:= Attributes[f] = Orderless; > In[3]:= f[b, c][a] === f[c, b][a] > Out[3]= True > In[4]:= f[b, c][a] === f[a, c][b] > Out[4]= False > In[5]:= f[2, 3][1] /. f[c_, b_][a_] :> {a, b, c} > Out[5]= {1, 2, 3} > In[6]:= f[2, 3][1] /. HoldPattern[f[c_, b_][a_]] :> {a, b, c} > Out[6]= {1, 2, 3} > In[7]:= Quit[] > > Another idea would be this > > In[1]:= Attributes[f0] = Orderless; > In[2]:= f[x_, y__] := f[x][f0[y]] > > In[3]:= f[a, b, c] === f[a, c, b] > Out[3]= True > In[4]:= f[a, b, c] === f[b, a, c] > Out[4]= False > In[5]:= f[1, 2, 3] /. f[a_, c_, b_] :> {a, b, c} > Out[5]= {1, 2, 3} > In[6]:= f[1, 2, 3] /. HoldPattern[f[a_, c_, b_]] :> {a, b, c} > Out[6]= f[1][f0[2, 3]] > In[3]:= Quit[] > > yet having more disadvantages. > > It is difficult to tell the "right way" unless you tell more > about what > you > finally intend. I would be surprised, if there were a simple > and direct > way > to reach that "partially orderless" property for f you quested. > > -- > Hartmut > > > >