Hello, Jan,
would you accept this patch to make creation of non-commutative symbols easier?
I'm afraid no, for several reasons: 1. I don't think GiNaC really can handle non-commutative symbols. As far as I can see collect() and friends assumes symbols to be commutative. Also, I don't think GiNaC can handle objects which might be both commutative and non-commutative depending on some flag. 2. The patch is a bit mathematically inconsistent: - Non-commutative realsymbol and possymbol hardly make any sense. - symbol::domain() still says domain::complex. This is very confusing. Non-commutative complex numbers? What's that? 3. Adding extra 8 bytes for every symbol is not really welcome. All in all, just because making symbols non-commutative is technically possible doesn't mean it's a good idea. If you really need something like a non-commutative symbol, it's much safer (and in fact easier) to write a proper class (which inherits from basic).
Problem: The GiNaC info documentation claims:
"Both symbols and user-defined functions can be specified as being non-commutative"
Documentation has bugs, too, and you've found one.
------------ Now my next question is (after applying the above patch) whether there is a bug in ncmul::eval(). I created this test program
#include <ginac/ginac.h>
using namespace GiNaC;
int main() { symbol M1("M1", "M1", return_types::noncommutative);
symbol x("x"), y("y"); matrix M2(2,2); M2 = x, 0, y, 0;
symbol M3("M3", "M3", return_types::noncommutative);
ex nc; nc = M1 * M2; // Produces a mul !!
First of all, this is the expected (and documented) behavior. Say, x*M1*M3 is a commutative product, too. It consists of two terms, x and M1*M3 (where M1*M3 is a non-commutative product). See the manual (specifically, the section titled `Non-commutative objects') for more examples. Secondly, (as far as I remember) we assume matrices to commute with "scalars". Non-commutative symbols can make this assumption invalid.
nc = M1 * M1; // Produces a ncmul nc = M1 * M3; // Produces a ncmul
Again, this is the expected behavior.
nc = nc.subs(M1 == M2); // Produces a mul !!
Ditto. Best regards, Alexei