[GiNaC-list] Bug with evalm()?

Sheplyakov Alexei varg at theor.jinr.ru
Mon Mar 26 07:33:12 CEST 2007


Hello,

On Sun, Mar 25, 2007 at 10:30:52PM +0200, Ondrej Certik wrote:
> >I agree with you completely: it's much better to not provide evalm() for
> >anything but matrix (frankly, I think all those eval* things are plain
> >evil).  But with current [sloppy] type system such kind of interface
> >is hardly ever possible. :(
> 
> Hi, this is the reason why GiNaC is using ex - so that it
> automatically calls eval(). We had this discussion already - it's
> because of C++, memory handling, speed and automatic evaluation.

> But in Python I recently found a very elegant solution to this (in SymPy):
> I also have eval() but it's called automatically right after the
> construtor and if it returns a different instance, then that instance
> is returned.
> Example:
> 
> e = Add(x,x)
> 
> however "e" contains Mul(2,x), because in python you can make the
> Add.eval() get called right after the Add constructor. Thus Add.eval()
> evaluates x+x to 2*x and returns Mul(2,x). So in the end Add(x,x) is
> in fact the same as Mul(2,x).

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.

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? 

> And in the end, you don't have to think about eval() at all. And you
> don't need ex (python is handling the garbage collection
> automatically).

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).
 
> But soon I would like to implement the core of SymPy in C++ for speed
> and I am curious, if my system is going to be faster or slower than
> GiNaC.
> 
> my question is this: do you know, if it is possible to implement the
> above procedure in C++? and how? maybe using some macros?

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.

> Because it is certainly non standard, that you construct an instance
> of some class Add(x,x) and it returns an instance of a completely
> different class Mul(2,x).

This is certainly impossible in C++. But the question is: may be
"virtual constructors" are not necessary at all? Suppose there is 
the Polynomial<Ring> type, and 

Polynomial<Ring3> operator+(const Polynomial<Ring2>&, const
Polynomial<Ring1>&);
Polynomial<Ring3> operator*(const Polynomial<Ring2>&, const
Polynomial<Ring1>&);
Polynomial<Ring3> operator*(const Polynomial<Ring2>&, const Ring1&);
etc.

Thus the return types are known at the compile time: if x is polynomial,
then x + x is polynomial too. Thus there is no need for "virtual 
constructors". And compiler can catch more mistakes:

Polynomial<Z> A = x; // OK
Polynomial<Z> B = x + 0.5; //  ERROR

Best regards,
 Alexei

-- 
All science is either physics or stamp collecting.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: Digital signature
Url : http://www.cebix.net/pipermail/ginac-list/attachments/20070326/cc217314/attachment.pgp


More information about the GiNaC-list mailing list