[GiNaC-list] Bug with evalm()?

Ondrej Certik ondrej at certik.cz
Mon Mar 26 18:57:09 CEST 2007


> Anyway, Add(A,Mul(-1,A)) is going to be  zero (a number). Sometimes
> this is just plain wrong, e.g. think about power series:
> (x+O(x))-(x+O(x)) should be O(x), not zero.

Well, in SymPy it works like this:

In [1]: Add(x,Mul(Rational(-1),x))
Out[1]: 0

In [2]: x-x
Out[2]: 0

In [3]: (x+Order(x)) - (x+Order(x))
Out[3]: O(x)


It's Order's responsibility, not to evaluate itself to zero. (in
detail, the Mul and Add classe call some virtual method of Basic at
the evaluation, and Order just implements this method)

> I don't think the problem is some C++ limitation[s]. I think the problem
> is the sloppy, mathematically inconsistent type system of GiNaC.
> What is add, exactly? Is it a polynomial? A rational expression?
> An algebraic one? A tensor? Or what?

At least in SymPy the class Add is a correct class to call whenever
you write * on the paper by a pencil. Whether the objects on the left
and right hand side of * are commutative, or not (with respect to
multiplication), is another thing. How they simplify is of course
depending on the object, and in SymPy this is implemented in each
particular object, not in Add or Mul.

> Typically those general-purpose garbage collectors suck badly. Otherwise
> I would be using some [Free] CAS (such as Axiom or Maxima) instead of
> fiddling with C++ (to put it mildly, it is certainly not my favourite
> programming language).

I was using GiNaC because I like its philosophy. Being a library in a
normal language. And I thought I could even improve the design a
little bit. Speed is not (a top) priority for me. I just want
something, that is extensible and simple and powerful.

> IFAIK this is what eval() for: some kind of "virtual constructor".
> The constructor can not return an object of arbitrary type, but eval()
> can return anything.

In SymPy we have a normal constructor and eval(). But the Basic class
contains a metaclass that assures that whenever the user calls
Add(x,x), what actually happens is not just Add().__init__(x,x)
(__init__ is a constructor in Python), but

Add().__init__(x,x).eval()

__init__ in Python also cannot return anything else besides the
instance of the class Add, but the Add.eval() can return anything, and
the metaclass just makes this automatic. But anyway, this is just
specific to Python. In C++ we would have to use some kind of macro for
that. (as suggested in my previous email).


Ondrej


More information about the GiNaC-list mailing list