2007/11/14, Alexei Sheplyakov <varg@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