2
$\begingroup$

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?

$\endgroup$
4
$\begingroup$

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}}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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