[GiNaC-list] Bug with evalm()?
Sheplyakov Alexei
varg at theor.jinr.ru
Mon Feb 12 15:01:38 CET 2007
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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: Digital signature
Url : http://www.cebix.net/pipermail/ginac-list/attachments/20070212/c20b4131/attachment.pgp
More information about the GiNaC-list
mailing list