# Expansion on sums of NonCommutativeMultiply

Following the MMa's documentations, the ExpandNCM[] function expands a**(b+c) without efforts (although I don't have very good idea how it works). However it got stuck if I tried use it to expand summations of two expressions for example: a1**(b1+c1)+a2**(b2+c2), the output is itself with no expansions. The function is defined below. Please help! Thanks a lot.

ExpandNCM[(h : NonCommutativeMultiply)[a___, b_Plus, c___]] :=
Distribute[h[a, b, c], Plus, h, Plus, ExpandNCM[h[##]] &]

ExpandNCM[(h : NonCommutativeMultiply)[a___, b_Times, c___]] :=
Most[b] ExpandNCM[h[a, Last[b], c]]

ExpandNCM[a_] := ExpandAll[a]
• The standard recommendation seems to be to use the NCAlgebra package for non-commutative algebra. I haven't used it yet. Apr 12 '16 at 15:04

This should work for expansions at any level of the expression:

ClearAll[ExpandNCM];

ExpandNCM[expr_] := expr /.
{(h : NonCommutativeMultiply)[a___, b_Plus, c___] :>
Distribute[h[a, b, c], Plus, h, Plus, ExpandNCM@*h],
(h : NonCommutativeMultiply)[a___, b_Times, c___] :>
Most[b] ExpandNCM[h[a, Last[b], c]]
};

Examples:

a1 ** (b1 + c1) // ExpandNCM
(* a1 ** b1 + a1 ** c1 *)

a1 ** (b1 c1) // ExpandNCM
(* b1 a1 ** c1 *)

a1 ** (b1 + c1) + a2 ** (b2 + c2) // ExpandNCM
(* a1 ** b1 + a1 ** c1 + a2 ** b2 + a2 ** c2 *)

a1 ** (b1 c1) + a2 ** (b2 c2) // ExpandNCM
(* b1 a1 ** c1 + b2 a2 ** c2 *)

a1 ** (b1 + c1) + a2 ** (b2 + c2 ** (b3 + c3)) // ExpandNCM
(* a1 ** b1 + a1 ** c1 + a2 ** b2 + a2 ** c2 ** b3 + a2 ** c2 ** c3 *)

a1 ** (b1 c1) + a2 ** (b2 c2 ** (b3 c3)) // ExpandNCM
(* b1 a1 ** c1 + b2 b3 a2 ** c2 ** c3 *)

{1, a1 ** (b1 + c1), {a1 ** (b1 c1)}} // ExpandNCM
(* {1, a1 ** b1 + a1 ** c1, {b1 a1 ** c1}} *)
• @hggreen Great, I'm glad this was helpful.
– user31159
Mar 19 '16 at 16:19
• are there any references for symbols like "_ _ " and "a _ _ " inside the function definition? I would love to learn more for the logic behind the function – hggreen 2 mins ago edit Mar 19 '16 at 16:20
• @hggreen __ is called a BlankSequence, and a__ is a named BlankSequence (with name a). You can find some references in the documentation, here and here. There are also nice posts in this forum about the use of these symbols, for instance (6588) and (58325).
– user31159
Mar 19 '16 at 16:29