# Determine whether a list is a reordering of another

For some context: I have a function Prod[a___,state] which represents a list a___ of quantum mechanical operators acting on a state. After manipulating the elements in a___, I end up with a sum of products of operators. For example, I get c_1*Prod[P1,P2,state] + c_2*Prod[P2,P1,state], where P1 and P2 commute. I am looking for a way to directly obtain the coefficient c_1+c_2. To do so:

I am trying to define a bilinear function Dot[Prod[a___,state],Prod[b___,state]] that would return 1 if a___ is a reordering of b___ and 0 otherwise.

I know how to make my function bilinear, but I have no idea how to specify the condition of "a is a reordering of b".

Note that P1 can appear multiple times, which prevents me from simply using Complement[].

Any help is appreciated, thank you.

• If Prod is not itself commutative (that is, some but not all operators commute with one another) then one could use Sort[{a}]===Sort[{b}]. May 25, 2020 at 21:49

You can declare prod Orderless, and then use Simplify to obtain the result:

SetAttributes[prod, Orderless]
c1 prod[P1, P2, state] + c2 prod[P2, P1, state] // Simplify


(c1 + c2) prod[P1, P2, state]

I'm not sure I follow your idea for how to extract the coefficient, but perhaps something like this:

prod /: Times[a_prod, b_prod] := If[a === b, 1, 0]
Sqrt[sum sum]


Sqrt[(c1+c2)^2]

Also see the comment by Michael E2 on how to make sure that state is not mixed up with the orderless parameters.

• By my reading of the OP, state has to come last — at least it is distinguished by being a state and not an operator. Orderless cannot guarantee it comes last. I think the syntax would have to be changed to prod[P1, P2,...][state]. May 25, 2020 at 20:01
• @MichaelE2 thank you, I added a pointer to your comment in the answer. May 25, 2020 at 20:32
(c1 prod[P1, P2, state] + c2 prod[P2, P1, state]) /. p_prod :> Sort[p] // Simplify

  (c1 + c2) prod[P1, P2, state]


If prod is orderless only in the first two arguments, you can do:

(c1 prod[P1, P2, state] + c2 prod[P2, P1, state]) /.
prod[a_, b_, st_] :> prod[## & @@ Sort[{a, b}], st] // Simplify

(c1 + c2) prod[P1, P2, state]


or

(c1 prod[P1, P2, state] + c2 prod[P2, P1, state]) /.
prod[OrderlessPatternSequence[a_, b_], st_] :> prod[a, b, st] // Simplify

(c1 + c2) prod[P1, P2, state]