# Simplification of sum of terms r a^m + s a^m to (r+s)a^m

+1 vote

I'm trying to solve simple operator algebra problems invovling the harmonic oscillator creation and annihilation operators. So I want to do things like a b^n -> n b^(n-1) + b^n a where [a,b] = 1

I've defined a set of rules that almost get me there, but the final result does not fully simplify and I don't know why. For example if I try to reduce a b^5 it produces 2 b^4 + 3 b^4 + b^5 a

I'm not sure what I'm doing wrong here. If there is a better way to go about doing this kind of simplification please let me know.

My code is as follows:

a::Symbol;
b::Symbol;

{a,b}::NonCommuting;
{m,n,r,s}::Integer.

r1 := {
a^0 -> 1,
b^0 -> 1,
b^1 -> b,
a b^m  -> (1+b a) b^{m-1},
a b -> 1 + b a,
b^m  b -> b^{m+1},
b  b^m -> b^{1+m}
};

def act(ex):
converge(ex):
distribute(ex)
expand(ex)
substitute(ex,r1)
sort_sum(ex)
collect_factors(ex)
collect_terms(ex)
simplify(ex)
return ex

act($a b^5$);    

edited

+1 vote

The problem in your code arises because b^{4} is not the same as b**4. If you do print(tree(ex)) on the output, you can see that one of the terms has b^{4} and the other b**4 (represented as \pow{b}{4}.

You can solve this in various ways. One way is to convert the b**4 to b^{4} with another rule. But since you really mean a power, perhaps a quicker way to achieve the wanted result is to use powers everywhere, not superscripts:

a::Symbol;
b::Symbol;

{a**m?, b**n?, a, b}::NonCommuting;
{m,n,r,s}::Integer.

r1 := {
a b**m?  -> (1+b a) b**{m?-1},
a b -> 1 + b a,
};

def act(ex):
converge(ex):
substitute(ex,r1)
distribute(ex)
collect_factors(ex)
return ex

act($a b**5$);

I have cut out a few other unnecessary steps in your act function (you don't need to call collect_terms to collect terms in an exponent, and you also never need to call the brute force hammer simplify unless you need a simplification for which SymPy is needed).

by (80.4k points)

Thank you for the simplifications and clarifications!