[GiNaC-list] Bug with evalm()?

Sheplyakov Alexei varg at theor.jinr.ru
Mon Feb 12 15:01:38 CET 2007


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

 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;
 	ex derivative(const symbol & s) const;

Best regards,

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