[GiNaC-list] Re: Disabling flattening of sums and products?
Martin Sandve Alnæs
martinal at simula.no
Thu Nov 15 10:03:47 CET 2007
2007/11/14, Alexei Sheplyakov <varg at theor.jinr.ru>:
> Hello!
>
> On Wed, Nov 14, 2007 at 02:38:44PM +0100, Martin Sandve Alnæs wrote:
> > Is it possible to disable the automatic flattening of expressions like
> > f = (x+y) + (x+y)
> > into
> > g = 2*y+2*x
> > ?
>
> No.
>
> > In other words, I want to be able to retain the additions in
> > expression f as binary operators.
>
> And GiNaC wants to 1) canonicalize the tree (expression), 2) make
> the tree as flat as possible, so large expressions can be stored
> reasonably well.
Ok. (I think SymPy has a flag to switch behaviour on this one.)
> > The reason for this is that I want
> > to examine some expression to detect subtrees that occur multiple
> > times,
>
> ex::to_polynomial() does somethings similar, so you might want to look
> how different classes implement this method (see the ginac/normal.cpp file).
Good idea, will do.
> N.B.: the concept is a bit ill-defined: it depends not on the mathematical
> properties of the expression in question, but on its internal representation.
> E.g. is x*y a subtree of x^2*y?
I'm aware of that, I've already experimented with things like this a bit.
> > and this automatic flattening destroys some opportunities for
> > this.
>
> Not flattening the tree destroys some opportunities for this. Example:
Sure, it depends very much on the structure of the expressions, like
you said above. But with some experience with the particular
application in question, I know that some large expressions often
occur multiple times, but the flattening hides their equality.
> a = c*x^2*y
> b = (c*x)*(x*y)
>
> > Example:
> >
> > a = x*y
> > b = (x*y) * (x*y)
>
> #include <ginac/ginac.h>
> #include <iostream>
> using namespace std;
> using namespace GiNaC;
>
> int main(int argc, char** argv) {
> symbol x("x"), y("y"), t("t");
> ex a = x*y;
> ex b = (x*y)*(x*y);
> cout << "b = " << b << endl;
> // b = y^2*x^2
> symbol foo;
> b = b.subs(a == foo, subs_options::algebraic);
> cout << "b = " << b << " with: " << foo << " = " << a << endl;
> // b = symbol4^2 with: symbol4 = y*x
> return 0;
> }
That's useful. Thanks, I didn't know that.
--
Martin
More information about the GiNaC-list
mailing list