Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have some transformation rules acting on subscripted variables. When I match the a product the order matters.

Subscript[Z, 2, 1] Subscript[Z, 3, 1] /. 
 Subscript[Z, l_, m_] Subscript[Z, k_, n_] -> {{l, m}, {k, n}}
Subscript[Z, 3, 1] Subscript[Z, 2, 1] /. 
 Subscript[Z, l_, m_] Subscript[Z, k_, n_] -> {{l, m}, {k, n}}

both cases yield

{{3, 1}, {2, 1}}.

It seems k,n always get assigned the subscripts with the smaller first value. Why is this and how can I influence this?

share|improve this question
add comment

1 Answer 1

up vote 3 down vote accepted

What's happening only indirectly involves the pattern matching. Mathematica, when dealing with operations that are Orderless, will put the arguments into a canonical ordering (described here). In this case, an expression like

Subscript[Z, 2, 1] Subscript[Z, 3, 1]

can be seen to be equivalent to

Times[Subscript[Z,2,1], Subscript[Z,3,1]]

using FullForm. Now, because multiplication is commutative, Times has the Orderless attribute, so mathematica will always put the terms into that canonical order, and the canonical order puts Subscript[Z,2,1] first (it's pretty much a lexicographic ordering). Thus, the order is switched before any patterns are matched by ReplaceAll (which is the name of the /. operation).

EDIT to add: There aren't necessarily a lot of easy ways to avoid this, but I can think of two. One is if you really are interested in conventional multiplication, but want to retain the ordering of terms anyway. The most expedient way to keep Times from wreaking havoc with its Orderlessness is to get rid of the attribute. Now, you could do this by using Unprotect on Times and changing its attributes, but this will probably make a mess. A better approach, and one that it is less likely to turn your Mathematica session into a smoking ruin, is to use Block to temporarily change Times:

Block[{Times},
 Subscript[Z, 3, 1] Subscript[Z, 2, 1] /.
  Subscript[Z, l_, m_] Subscript[Z, k_, n_] :> {{l, m}, {k, n}}]
{{3, 1}, {2, 1}}

This is one of the rare use cases where you actually want to use Block instead of Module. The other possibility is that you are referring to some operation that looks like multiplication but isn't commutative. In that case, NonCommutativeMultiply (written with the ** infix operator) has you covered:

 Subscript[Z, 3, 1] ** Subscript[Z, 2, 1] /.
  Subscript[Z, l_, m_] ** Subscript[Z, k_, n_] :> {{l, m}, {k, n}}
{{3, 1}, {2, 1}}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.