invalid expression in content|unit|...()
Hi, While unit-testing pyginac, I found the following inconsistency: 1) define a = symbol("a") b = symbol("b") c = constant("c") 2) observe content(2,a) -> 0 (ok) content(2*a + 4*c,a) -> 2 (ok) content(a*c,a) -> exception 'invalid expression in unit()' ?! content(a*b,a) -> b (ok) 3) similar behaviour can be observed also for other functions like unit,.. The question is: Is it possible to unify the behaviour of the relevant functions? That is, to extend them to accept other objects in addition to symbol, numeric, add, etc. Or, to raise an exception whenever there are alien object in expressions. (Though, constants should not be alien when comparing them with symbols.) My argument to consider this inconsistency as a problem is that this behaviour is confusing and could lead to difficult-to-find bugs. Thanks, Pearu
Hi! On Thu, Nov 22, 2001 at 03:21:30PM +0200, Pearu Peterson wrote:
content(a*c,a) -> exception 'invalid expression in unit()' ?!
Well, all these functions are designed to be used with polynomials with (at least) rational coefficients and the intended use for the "constant" class in GiNaC is non-rational numbers like Pi. There's always to_rational() to work around this limitation. Maybe the polynomial handling functions in GiNaC should always treat constants like symbols but this would require changing get_first_symbol() and everything that depends on it, a non-trivial change. Seeing that a constant is just a global symbol with a special evalf() behavior, maybe these two classes should be integrated better... Bye, Christian -- / Coding on PowerPC and proud of it \/ http://www.uni-mainz.de/~bauec002/
On Thu, 22 Nov 2001, Christian Bauer wrote:
On Thu, Nov 22, 2001 at 03:21:30PM +0200, Pearu Peterson wrote:
content(a*c,a) -> exception 'invalid expression in unit()' ?! <snip>
Seeing that a constant is just a global symbol with a special evalf() behavior, maybe these two classes should be integrated better...
Indeed, while wrapping GiNaC to Python, I also noticed that this is the only relevant difference. That is, in addition diff(<constant>) returns always 0. I went ahead and derived constant from symbol. It was quite simple, I just had to remove some constant methods that were almost identical with the corresponding methods in symbol (there were some stylistic differences). Right now I am running checks, and if they pass, I will send patches if you are interested in. Currently it looks like with these changes GiNaC will be also backward compatible. Pearu
Hi Pearu, On Thu, 22 Nov 2001, Pearu Peterson wrote:
On Thu, 22 Nov 2001, Christian Bauer wrote:
On Thu, Nov 22, 2001 at 03:21:30PM +0200, Pearu Peterson wrote:
content(a*c,a) -> exception 'invalid expression in unit()' ?! <snip>
Seeing that a constant is just a global symbol with a special evalf() behavior, maybe these two classes should be integrated better...
Indeed, while wrapping GiNaC to Python, I also noticed that this is the only relevant difference. That is, in addition diff(<constant>) returns always 0.
I went ahead and derived constant from symbol. It was quite simple, I just had to remove some constant methods that were almost identical with the corresponding methods in symbol (there were some stylistic differences). Right now I am running checks, and if they pass, I will send patches if you are interested in. Currently it looks like with these changes GiNaC will be also backward compatible.
We had this layout already where constant was derived from symbol and we changed it because it turned out to produce all kinds of weird problems. That seems to have been before 0.4.0, though, since I can't find it in the archives right now. Generally it is considered problematic to have a concrete class for use by folks and derive another concrete class from it. Scott Meyers discusses this in his books to some extend.
From a design perspective, I would much rather have an intermediate class derived from basic from wich both constant and numeric are derived. This class could then provide everything these two have in common.
Regards -richy. -- Richard B. Kreckel <Richard.Kreckel@Uni-Mainz.DE> <http://wwwthep.physik.uni-mainz.de/~kreckel/>
On Thu, 22 Nov 2001, Richard B. Kreckel wrote:
We had this layout already where constant was derived from symbol and we changed it because it turned out to produce all kinds of weird problems. That seems to have been before 0.4.0, though, since I can't find it in the archives right now. Generally it is considered problematic to have a concrete class for use by folks and derive another concrete class from it. Scott Meyers discusses this in his books to some extend.
From a design perspective, I would much rather have an intermediate class derived from basic from wich both constant and numeric are derived. This class could then provide everything these two have in common.
Ok then, but how about the following solution: remove constant class altogether and put its current initnumber/efun stuff into symbol class. Is there any reasons not to take this approach other than it would be rather radical one (and broke some codes that use constants)? Btw, there was one failure in checks caused by deriving constant from symbol. Here are relevant messages: examining indexed objects........ failed simplify_indexed(p.i^2*q.j^2-p.n^2*q.j^2)-0 erroneously returned p.i^2*q.j^2-q.i^2*p.j^2 instead of 0 Other tests passed fine. Regards, Pearu
Hi! On Thu, Nov 22, 2001 at 08:10:56PM +0200, Pearu Peterson wrote:
Ok then, but how about the following solution: remove constant class altogether and put its current initnumber/efun stuff into symbol class.
This is what I had in mind.
simplify_indexed(p.i^2*q.j^2-p.n^2*q.j^2)-0 erroneously returned p.i^2*q.j^2-q.i^2*p.j^2 instead of 0
Interesting. Maybe this is one of those checks that were never guaranteed to always work... :-) Bye, Christian -- / Coding on PowerPC and proud of it \/ http://www.uni-mainz.de/~bauec002/
Hi, On Thu, 22 Nov 2001, Christian Bauer wrote:
On Thu, Nov 22, 2001 at 08:10:56PM +0200, Pearu Peterson wrote:
Ok then, but how about the following solution: remove constant class altogether and put its current initnumber/efun stuff into symbol class.
This is what I had in mind.
simplify_indexed(p.i^2*q.j^2-p.n^2*q.j^2)-0 erroneously returned p.i^2*q.j^2-q.i^2*p.j^2 instead of 0
Interesting. Maybe this is one of those checks that were never guaranteed to always work... :-)
Indeed. It is sensitive to the serial number of the symbols involved. I have attached a testsuite for this particular problem. Am wondering what "never guaranteed to always work" was supposed to mean... Cheers -richy. -- Richard B. Kreckel <Richard.Kreckel@Uni-Mainz.DE> <http://wwwthep.physik.uni-mainz.de/~kreckel/>
participants (3)
-
Christian Bauer
-
Pearu Peterson
-
Richard B. Kreckel