Dear All, Following my previous message on the subject (http://www.ginac.de/pipermail/ginac-devel/2006-October/001071.html) I am including the full patch. Its functionality is now described in ginac.info. Best wishes, Vladimir -- Vladimir V. Kisil email: kisilv@maths.leeds.ac.uk -- www: http://maths.leeds.ac.uk/~kisilv/
Hello, On Fri, Oct 27, 2006 at 12:37:03PM +0100, Vladimir Kisil wrote:
Following my previous message on the subject (http://www.ginac.de/pipermail/ginac-devel/2006-October/001071.html) I am including the full patch. Its functionality is now described in ginac.info.
[snipped] While I certainly like the idea, I dislike the proposed implementation very much. Keep on reading to find out why.
+It is not unusual to use some objects which have special properties with +respect to exponentiation. For example, if a symbol @code{s} may take +only values @math{-1} or @math{1} then @math{s^2=1}. Other examples are
[snipped] GiNaC offers ex::map() method for implementation of such custom evaluation rules. Frankly, I don't understand why it is not enough...
+@example + virtual ex basic::eval_power_basis(const ex & exp) const; + virtual ex basic::eval_power_exponent(const ex & basis) const; +@end example
Adding more methods to the `basic' class does not sound like good idea to me. What if someone implements custom evaluation rules, say, for the `mul' class? E.g. foosymbol times barfunction is always zero. Add even more methods to basic? [snip]
+@example + your_class::info(info_flags::is_power_basis); + your_class::info(info_flags::is_power_exponent); +@end example
Likewise, I think adding even more stuff to info_flags is bad idea. [huge snip]
+ex basic::eval_power_basis(const ex & exp) const +{ + std::cerr << "WARNING: virtual method basic::eval_power_basis is called," << std::endl + << " did you forget to redefine it in the derived class?" << std::endl; + return power(*this, exp).hold(); +}
Spamming to std{out,err} is a MORTAL SIN. NEVER, EVER do this. Either return the expression unevaluated or throw an exception.
+ // user defined classes may provide their own virtual methods for power evaluation + if (ebasis.info(info_flags::is_power_basis)) + return ebasis.eval_power_basis(eexponent); + + if (eexponent.info(info_flags::is_power_exponent)) + return eexponent.eval_power_exponent(ebasis);
This slows down a bit evaluation of *every* power expression, including those which do not provide such a method. GiNaC's performance is not exactly brilliant, why reduce it even more? Best regards, Alexei -- All science is either physics or stamp collecting.
Dear Alexei,
"SA" == Sheplyakov Alexei <varg@theor.jinr.ru> writes:
SA> GiNaC offers ex::map() method for implementation of such custom SA> evaluation rules. Unfortunately I cannot see how to use map() for simplification of automatic evaluations for derived classes, could you give me a hint? SA> Adding more methods to the `basic' class does not sound like SA> good idea to me. What if someone implements custom evaluation SA> rules, say, for the `mul' class? E.g. foosymbol times SA> barfunction is always zero. Add even more methods to basic? There is a limited number of evaluations (add(), mul(), ncmul()) so only three additional virtual methods will cover any desire in automatic evaluation. SA> Likewise, I think adding even more stuff to info_flags is bad SA> idea. However this makes a check for existence of an additional evaluation method much quicker. Are there a better way to check this? SA> Spamming to std{out,err} is a MORTAL SIN. NEVER, EVER do this. SA> Either return the expression unevaluated or throw an exception. Alright, I am not insisting on the warning message. Throwing an exception is not appropriate since nothing dangerous happens. SA> This slows down a bit evaluation of *every* power expression, SA> including those which do not provide such a method. GiNaC's SA> performance is not exactly brilliant, why reduce it even more? However it make much-much more faster evaluation of expressions which do contain such object. For example, calculations in two dimensions can be done now without usage Clifford algebras and *very* time-expensive non-commutativity. In my opinion it is a fair exchange for slowing down *a bit* for other calls. Everything in this world come at a price. Best wishes, Vladimir -- Vladimir V. Kisil email: kisilv@maths.leeds.ac.uk -- www: http://maths.leeds.ac.uk/~kisilv/
Hello, On Fri, Oct 27, 2006 at 05:17:23PM +0100, Vladimir Kisil wrote:
SA> GiNaC offers ex::map() method for implementation of such custom SA> evaluation rules.
Unfortunately I cannot see how to use map() for simplification of automatic evaluations for derived classes, could you give me a hint?
I'm sorry, I didn't realize that the the whole thing is about *automatic* evaluation. Now I have even more objections against your patch, in particular, I'm concerned about the idea itself (not only about the implementation). In general, automatic evaluation rules are quite minimalistic by design. There are evalm(), evalf(), eval_integ(), simplify_indexed(), etc. for more time-consuming simplifications. These must be called explicitly for a good reason. What about adding something like eval_pow() which has to be *explicitly called* and does whatever evaluations you want?
SA> Adding more methods to the `basic' class does not sound like SA> good idea to me. What if someone implements custom evaluation SA> rules, say, for the `mul' class? E.g. foosymbol times SA> barfunction is always zero. Add even more methods to basic?
There is a limited number of evaluations (add(), mul(), ncmul()) so only three additional virtual methods will cover any desire in automatic evaluation.
To slow down things even more? I certainly dislike this. Once again, adding some virtual method which does arbitrary time-consuming simplification *AND* never gets called automatically is not that bad (in the sense "The things I don't use should not harm me").
SA> Likewise, I think adding even more stuff to info_flags is bad SA> idea.
However this makes a check for existence of an additional evaluation method much quicker. Are there a better way to check this?
First of all, I don't understand why do you need such a check in first place. Maybe, a better approach would be to provide sensible default implementation (which does not change anything if there are no custom rules) and call the method unconditionally?
SA> This slows down a bit evaluation of *every* power expression, SA> including those which do not provide such a method. GiNaC's SA> performance is not exactly brilliant, why reduce it even more?
However it make much-much more faster evaluation of expressions which do contain such object.
If you do some optimizations for *very* special case, could you please be so kind to not harm the generic one? The change to power::eval() you've introduced costs at least two extra virtual method calls (I assume the general case when there are no any custom power evaluation rules). Now evaluation of moderately sized multivariate polynomial (say, 10 variables, several million terms) consumes several million useless instructions, even if eval() is going to just hold() the polynomial in question.
For example, calculations in two dimensions can be done now without usage Clifford algebras and *very* time-expensive non-commutativity.
In my opinion it is a fair exchange for slowing down *a bit* for other calls. Everything in this world come at a price.
Since efficient handling of large polynomials is essential for GiNaC (and probably for any other software for analytical computations) I don't think the price is acceptable. Don't get me wrong -- I completely realize that GiNaC may have suboptimal performance for problems which are important for you. But I don't think it is good idea to include your optimizations if they harm everyone else. I've got a lot of small hacks which tune GiNaC for my problems too. I post more or less generic of these (mostly bug fixes) here. For example, some gcd() misfeatures (expanding partially factored expressions for no good reason) were really show stoppers for me. Another example is divide() and collect_common_factors() (see patches I've posted about two weeks ago) misfeatures. These are very annoying too and make my calculations virtually impossible. I'd like these patches to be included in GiNaC, but if they won't get applied -- nothing prevents me from patching GiNaC myself in whatever way I need to. Best regards, Alexei -- All science is either physics or stamp collecting.
participants (2)
-
varg@theor.jinr.ru
-
Vladimir Kisil