RE: On Defining Functions Symmetric wrt Some Indices
- To: mathgroup at smc.vnet.net
- Subject: [mg34328] RE: [mg34316] On Defining Functions Symmetric wrt Some Indices
- From: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>
- Date: Wed, 15 May 2002 03:35:18 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
> -----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: [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