12
$\begingroup$

This question already has an answer here:

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?

$\endgroup$

marked as duplicate by J. M. is away Aug 2 '16 at 6:23

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

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

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] *)
$\endgroup$
1
$\begingroup$

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

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