Welcome to Cadabra Q&A, where you can ask questions and receive answers from other members of the community.
+1 vote

This is a weird case and perhaps unlikely to be encountered in normal use, but I'm noting it here.

Consider:

{A,X}::AntiCommuting.
ex := X A X;
sort_product(ex)
collect_factors(ex);

The above produces a negative sign as one might suspect. However:

{A,X}::AntiCommuting.
ex := X A X;
collect_factors(ex);

The above does not. Nor does this:

{A,X}::AntiCommuting.
ex := X A X;
simplify(ex);
in Bug reports by (1.1k points)

1 Answer

+1 vote

That simplify butchers the expression is expected, as no info about (anti-)commutativity currently gets passed through the sympy bridge. However, collect_factors does not use sympy and should know better. I have opened an issue on github to keep track of this, https://github.com/kpeeters/cadabra2/issues/324 .

by (83.1k points)

I was looking at the code in collect_factors to see if I could send over a bugfix for this, and I realized that sort_product is not clever enough to handle situations like:

{A,X}::AntiCommuting.
ex := X**3 *  A;
sort_product(_);

And likely you don't even want it to.

Similarly,

X::SelfAntiCommuting.
ex := X * A * X;
collect_factors(_);
canonicalise(_);

yields X**2 A.

So perhaps collect_factors simply shouldn't touch anything that has an AntiCommuting or SelfAntiCommuting property, similar to how it does not touch objects with indices?

I think it would be good (as a general rule) if algorithms would make an attempt to detect input that they know they cannot work on, and refuse. That is a lot easier than it sounds (similar in spirit to detecting mutually incompatible properties) but some obvious problems (like the one you reported) can certainly be flagged.

...