# Set Attributes -> Orderless for only some variables in a function? [duplicate]

I have the following function:

r12ExpUnit[n1_, n2_, n3_, n4_] :=

r12ExpUnit[n3, n4, n1, n2] =

r12ExpUnit[n1, n4, n3, n2] =

r12ExpUnit[n3, n2, n1, n4] = ((some function))


Here n1, n2, n3, n4 are indices in which n1 and n3 are interchangeable, and n2 and n4 are interchangeable. Is there a way to use SetAttributes to declare these two pairs of indices are orderless without declaring all four orderless?

## marked as duplicate by J. M. will be back soon♦Aug 2 '16 at 6:23

• I believe this question is a duplicate of (55702) – Mr.Wizard Aug 2 '16 at 6:17

Orderless sorts your argument in canonical order and you might want to explore the possibility to use a helper function to sort only some.

With[{f = Function[, ##, {Orderless}]},
r12ExpUnit[n1_, n2_, n3_, n4_] :=
somefunc[#1, #3, #2, #4] &[f[n1, n3], f[n2, n4]]
]


Here, you use f to specifically sort the argument pairs {n1,n3} and {n2,n4}. I don't find this particularly beautiful and I'm not sure that you can come up with a better overall design, but the information you have given only permit vague guesses.

Anyway, as you can easily see, somefunc will always be called with your specific pairs in canonical order without ordering all arguments:

r12ExpUnit[n2, n1, n4, n2]
r12ExpUnit[n4, n2, n2, n1]
r12ExpUnit[n2, n2, n4, n1]
r12ExpUnit[n4, n1, n2, n2]

(* somefunc[n2, n1, n4, n2] *)
(* somefunc[n2, n1, n4, n2] *)
(* somefunc[n2, n1, n4, n2] *)
(* somefunc[n2, n1, n4, n2] *)


Another possibility is to use OrderedQ[] to check if the corresponding arguments are in canonical order, and then use Sort[] for canonicalization:

r12ExpUnit[n1_, n2_, n3_, n4_] /; ! (OrderedQ[{n1, n3}] && OrderedQ[{n2, n4}]) :=
r12ExpUnit @@ (Join[Sort[{n1, n3}], Sort[{n2, n4}]][[{1, 3, 2, 4}]])


Test:

r12ExpUnit[n1, n2, n3, n4] === r12ExpUnit[n3, n4, n1, n2] ===
r12ExpUnit[n1, n4, n3, n2] === r12ExpUnit[n3, n2, n1, n4]
True

(* halirutan's example *)
r12ExpUnit[n2, n1, n4, n2] === r12ExpUnit[n4, n2, n2, n1] ===
r12ExpUnit[n2, n2, n4, n1] === r12ExpUnit[n4, n1, n2, n2]
True

• I think this question is a duplicate of (55702); would you look and tell me if you agree? – Mr.Wizard Aug 2 '16 at 6:18
• Yup, lemme do a few clicks... – J. M. will be back soon Aug 2 '16 at 6:23
• You might consider reposting your method the original thread. – Mr.Wizard Aug 2 '16 at 6:29
• I dunno, evanb's solution there is halfway through that of mine, but less bulletproof. (And jose's solution is vastly more elegant.) – J. M. will be back soon Aug 2 '16 at 6:31
• I left a comment already. :) – J. M. will be back soon Aug 2 '16 at 6:41