Update, December 22
I've developed a version that is more robust. I believe it should work in general, but I'm sure there are some corner cases that won't work (and probably some-not-so-corner cases too).
As before we add rules to the almost-no-built-in-meaning NonCommutativeMultiply
(**
):
Clear[ncm]
ncm[a__] := NonCommutativeMultiply[a]
Unprotect@NonCommutativeMultiply;
NonCommutativeMultiply[a___, b_ + c_, d___] := NonCommutativeMultiply[a, b, d] + NonCommutativeMultiply[a, c, d]
a_?NumericQ ** b_ := a b
a_ ** b_?NumericQ := a b
(-a_) ** b_ := -(a ** b)
a_ ** (-b_) := -(a ** b)
Protect@NonCommutativeMultiply
For convenience, we define a format for the commutator:
Format[comm[a_, b_]] := DisplayForm@RowBox[{"[", ToString@a, ",", ToString@b, "]"}]
Then, in order to generate expressions from commutator forms, we define:
Clear[expandCommutator]
expandCommutator[expr_] := expr //. comm[a_, b_] :> a ** b - b ** a // Expand
We also define the function that converts OP's form into NonCommutativeMultiply
form:
convertToNCMForm[expr_] := expr /. Thread[
Variables[expr] -> ncm @@@ (ToExpression /@ # &@*Characters@*ToString) /@ Variables[expr]]
Finally, we define the function that puts expressions in commutator form as
generateCommutatorForm[expr_, vars_List] := Module[{
rules = Join[
ncm[#2, #1] :> ncm[#1, #2] - comm[#1, #2] & @@@ Subsets[vars, {2}]
, {
comm[a : _comm, b : Except[_comm]] :> -comm[b, a]
, comm[a : _comm, b : _comm] /; Depth[a] > Depth[b] :> -comm[b, a]
, ncm[a : _comm, b : Except[_comm]] :> ncm[b, a] - comm[b, a]
, comm[ncm[a__, b_], c_] :> ncm[a, comm[b, c]] + ncm[comm[a, c], b]
, ncm[a : _comm, b : _comm] /; Signature[{a, b}] == -1 :> ncm[b, a] - comm[b, a]
, comm[x : comm[a_, b_], c : _comm] /; Depth[x] <= Depth[c] :> comm[a, comm[b, c]] + comm[b, comm[c, a]]
}
]
}, FixedPoint[Expand[# /. rules] &, expr]]
Examples:
A more complicated one, from the post:
expr = 1/6 comm[a, comm[a, b]] - 1/3 comm[b, comm[b, a]]
expr2 = expr // expandCommutator
generateCommutatorForm[expr2, {a, b}]
A more-than-two-operator example:
expr = 1/2 comm[a, comm[b, c]] - 1/3 comm[b, comm[c, a]]
expr2 = expr // expandCommutator
expr3 = generateCommutatorForm[expr2, {a, b, c}]
expr2 === expandCommutator[expr3]
A four-variable, three-times nested one (this does illustrate a limitation in that I don't simplify the resulting expression if there is a simpler expression in terms of commutators; clearly, the representation in commutators is not unique):
expr = (1/2) comm[a, comm[b, comm[c, d]]]
expr2 = expr // expandCommutator
expr3 = generateCommutatorForm[expr2, {a, b, c, d}]
expr2 === expandCommutator[expr3]
The most complicated one from the post:
expr2 = AAAAB/120 - AAABA/30 - AAABB/30 + AABAA/20 + AABAB/20 +
AABBA/20 + AABBB/20 - ABAAA/30 + ABAAB/20 - ABABA/5 - ABABB/5 +
ABBAA/20 + 3 ABBAB/10 - ABBBA/5 - ABBBB/30 + BAAAA/120 -
BAAAB/30 + BAABA/20 + BAABB/20 + BABAA/20 - BABAB/5 +
3 BABBA/10 + 2 BABBB/15 - BBAAA/30 + BBAAB/20 - BBABA/5 -
BBABB/5 + BBBAA/20 + 2 BBBAB/15 - BBBBA/30 // convertToNCMForm;
generateCommutatorForm[expr2, {A, B}]
Original Post
For this problem, we choose a normal-order: let's move all A
's to the left of all commutators, which are all moved to the left of all B
's. We will use NonCommutativeMultiply
in order to be able to use symbols that don't commute.
First of all, if your expressions are in the form of
expr = BA/2 - AB/2;
then we can use the following converter to get into a form that uses NonCommutativeMultiply
:
convertToNCMForm[expr_] := expr /. Thread[
Variables[expr] -> ncm @@@ (ToExpression /@ # &@*Characters@*ToString) /@ Variables[expr]]
(This is sort of silly, since it should be put in this form to begin with, but since the OP has it in that form, we convert it first.) So, for instance,
convertToNCMForm[expr]
(* -(A ** B/2) + B ** A/2 *)
We need some rules for NonCommutativeMultiply
that allow expressions to be automatically simplified. (For instance, we want the operation to distribute over addition.) Here's a set of rules that work:
ncm[a__] := NonCommutativeMultiply[a]
Unprotect@NonCommutativeMultiply;
NonCommutativeMultiply[a___, b_ + c_, d___] := NonCommutativeMultiply[a, b, d] + NonCommutativeMultiply[a, c, d]
a_?NumericQ ** b_ := a b
a_ ** b_?NumericQ := a b
(-a_) ** b_ := -(a ** b)
a_ ** (-b_) := -(a ** b)
Protect@NonCommutativeMultiply
Finally, we choose a nice format for the commutator:
Format[comm[a_, b_]] := DisplayForm@RowBox[{"[", ToString@a, ",", ToString@b, "]"}]
or
Format[comm[a_, b_]] := "[" <> ToString@a <> "," <> ToString@b <> "]"
Then,
comm[A, B]
(* [A, B] *)
Now, here's the meat of the problem. We use replacement Rule
s to move symbols past other symbols, introducing commutators along the way in the form of comm
. We put these rules in a function as follows:
Clear@generateCommutatorForm
generateCommutatorForm[expr_, {A_, B_}] :=
Expand@expr //. {ncm[B, A] :> ncm[A, B] - comm[A, B],
ncm[B, comm[a__]] :> ncm[comm[a], B] - comm[comm[a], B],
ncm[comm[a__], A] :> ncm[A, comm[a]] - comm[A, comm[a]]
} // Expand
Now!
expr = expr = BA/2 - AB/2;
expr2 = convertToNCMForm[expr]
(* -(A ** B/2) + B ** A/2 *)
and
generateCommutatorForm[expr2, {A, B}]
(* -(1/2) [A,B] *)
For a more complicated expression,
expr = AAB/6 - ABA/3 - ABB/3 + BAA/6 + (2 BAB)/3 - BBA/3;
expr2 = convertToNCMForm[expr]
(* A ** A ** B/6 - A ** B ** A/3 - A ** B ** B/3 + B ** A ** A/6 + (2 B ** A ** B)/3 - B ** B ** A/3 *)
and
generateCommutatorForm[expr2, {A, B}]
(* [A, [A, B]]/6 - [[A, B], B]/3 *)
Finally,
expr = -(AAAB/24) + AABA/8 + AABB/8 - ABAA/8 - ABAB/4 - ABBB/8 + BAAA/24 + BABA/4 + 3/8 BABB - BBAA/8 - 3/8 BBAB + BBBA/8;
expr2 = generateCommutatorForm[convertToNCMForm[expr], {A, B}]
If you want it in the form where the nested commutators are always in the second slot, apply the following function to the final expression:
toCanonicalForm[expr_] :=
expr //. {comm[comm[x__], y__] :> -comm[y, comm[x]],
comm[-a_, b_] :> -comm[a, b],
comm[a_, -b_] :> -comm[a, b]
} // Expand
Then,
toCanonicalForm[expr2]
B*A
toA*B
freely, so how do plan to input such polynomials? $\endgroup$