Hi! On Mon, Feb 12, 2007 at 03:04:29AM -0800, Alfredo Correa wrote:
after all the difference between a expansion series and a polynomial is basically that the series contains, at the end, some information about the order of the error (i.e. O(x^n) )
In general, the error term, can not be evaluated to anything meaningful (for x!=0) (but have some properties, for example can be derived respect to x, or that O(x) - O(x) = O(x) -hey, just for curiosity: can something like this be possibly ever implemented?-).
Because of the existence of the error term, in my opinion evalm must either fail
Then valid code (like Chris posted) will fail...
or evaluate to something that holds the error term in some kind of new type (e.g. error_order type).
...so probably evalm() for power series will work this way.
If to fail (i.e. throw) is the choice, the 'principle of less surprise' can be honored by raising a meaningful exception (with some explanation)
I must admit that I have almost no experience with ginac and that I don't fully understand the philosophy of the current developers, but, in my opinion, making every method available (or evaluable) for every type is not the way to solve this kind of problems because in many cases the possible returns could be ambiguous depending on the interpretation and this is more dangerous than throwing exception and tell the user to be more specific in the syntax.
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. :( So, here is a second attempt: [PATCH] Declare and implement pseries::evalm() which evalm()s each coefficient. [in ginsh] evalm(series(sin(x), x, 2)); basic::let_op(): pseries has no operands Since let_op() and map() semantics for a power series is not clear, implement pseries::evalm() which evalm()s each coefficient. This makes evalm() behaviour consistent with other eval* methods (if operation is not applicable it should be no-op) and does some real job for matrix-valued series. --- ginac/pseries.cpp | 24 ++++++++++++++++++++++++ ginac/pseries.h | 1 + 2 files changed, 25 insertions(+), 0 deletions(-) diff --git a/ginac/pseries.cpp b/ginac/pseries.cpp index db7cef3..3b3ed51 100644 --- a/ginac/pseries.cpp +++ b/ginac/pseries.cpp @@ -489,6 +489,30 @@ ex pseries::eval_integ() const return *this; } +ex pseries::evalm() const +{ + // evalm each coefficient + epvector newseq; + bool something_changed = false; + for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) { + if (something_changed) + newseq.push_back(expair(i->rest.evalm(), i->coeff)); + else { + ex newcoeff = i->rest.evalm(); + if (!are_ex_trivially_equal(newcoeff, i->rest)) { + something_changed = true; + newseq.reserve(seq.size()); + std::copy(seq.begin(), i, std::back_inserter<epvector>(newseq)); + newseq.push_back(expair(newcoeff, i->coeff)); + } + } + } + if (something_changed) + return (new pseries(var==point, newseq))->setflag(status_flags::dynallocated); + else + return *this; +} + ex pseries::subs(const exmap & m, unsigned options) const { // If expansion variable is being substituted, convert the series to a diff --git a/ginac/pseries.h b/ginac/pseries.h index ed266c4..e53baf6 100644 --- a/ginac/pseries.h +++ b/ginac/pseries.h @@ -59,6 +59,7 @@ public: ex real_part() const; ex imag_part() const; ex eval_integ() const; + ex evalm() const; protected: ex derivative(const symbol & s) const; -- 1.4.4.4 Best regards, Alexei -- All science is either physics or stamp collecting.