// functions overriding virtual functions from bases classes
//////////
-basic *pseries::duplicate() const
-{
- debugmsg("pseries duplicate", LOGLEVEL_DUPLICATE);
- return new pseries(*this);
-}
-
void pseries::print(std::ostream &os, unsigned upper_precedence) const
{
debugmsg("pseries print", LOGLEVEL_PRINT);
if (precedence<=upper_precedence) os << "(";
+ // objects of type pseries must not have any zero entries, so the
+ // trivial (zero) pseries needs a special treatment here:
+ if (seq.size()==0)
+ os << '0';
for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
- // omit zero terms
- if (i->rest.is_zero())
- continue;
// print a sign, if needed
if (i!=seq.begin())
os << '+';
{
debugmsg("pseries printraw", LOGLEVEL_PRINT);
os << "pseries(" << var << ";" << point << ";";
- for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
+ for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i)
os << "(" << (*i).rest << "," << (*i).coeff << "),";
- }
os << ")";
}
point.printtree(os, indent+delta_indent);
}
+int pseries::compare_same_type(const basic & other) const
+{
+ GINAC_ASSERT(is_of_type(other, pseries));
+ const pseries &o = static_cast<const pseries &>(other);
+
+ int cmpval = var.compare(o.var);
+ if (cmpval)
+ return cmpval;
+ cmpval = point.compare(o.point);
+ if (cmpval)
+ return cmpval;
+
+ epvector::const_iterator it1 = seq.begin(), it2 = o.seq.begin(), it1end = seq.end(), it2end = o.seq.end();
+ while ((it1 != it1end) && (it2 != it2end)) {
+ cmpval = it1->compare(*it2);
+ if (cmpval)
+ return cmpval;
+ it1++; it2++;
+ }
+ if (it1 == it1end)
+ return it2 == it2end ? 0 : -1;
+
+ return 0;
+}
+
/** Return the number of operands including a possible order term. */
unsigned pseries::nops(void) const
{
}
}
+/** Return coefficient of degree n in power series if s is the expansion
+ * variable. If the expansion point is nonzero, by definition the n=1
+ * coefficient in s of a+b*(s-z)+c*(s-z)^2+Order((s-z)^3) is b (assuming
+ * the expansion took place in the s in the first place).
+ * If s is not the expansion variable, an attempt is made to convert the
+ * series to a polynomial and return the corresponding coefficient from
+ * there. */
ex pseries::coeff(const symbol &s, int n) const
{
if (var.is_equal(s)) {
return convert_to_poly().coeff(s, n);
}
-
+/** Does nothing. */
ex pseries::collect(const symbol &s) const
{
return *this;
ex pseries::expand(unsigned options) const
{
epvector newseq;
- newseq.reserve(seq.size());
- for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i)
- newseq.push_back(expair(i->rest.expand(), i->coeff));
+ for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
+ ex restexp = i->rest.expand();
+ if (!restexp.is_zero())
+ newseq.push_back(expair(restexp, i->coeff));
+ }
return (new pseries(relational(var,point), newseq))
->setflag(status_flags::dynallocated | status_flags::expanded);
}