- // FIXME: Only handle one special case for now...
- if (x.is_equal(s) && point.is_zero()) {
- ex e = 1 / s - EulerGamma + s * (pow(Pi, 2) / 12 + pow(EulerGamma, 2) / 2) + Order(pow(s, 2));
- return e.series(s, point, order);
- } else
- throw(std::logic_error("don't know the series expansion of this particular gamma function"));
+ // method:
+ // Taylor series where there is no pole falls back to psi functions.
+ // On a pole at -n use the identity
+ // series(GAMMA(x),x=-n,order) ==
+ // series(GAMMA(x+n+1)/(x*(x+1)...*(x+n)),x=-n,order+1);
+ ex xpoint = x.subs(s==point);
+ if (!xpoint.info(info_flags::integer) || xpoint.info(info_flags::positive))
+ throw do_taylor();
+ // if we got here we have to care for a simple pole at -n:
+ numeric n = -ex_to_numeric(xpoint);
+ ex ser_numer = gamma(x+n+exONE());
+ ex ser_denom = exONE();
+ for (numeric p; p<=n; ++p)
+ ser_denom *= x+p;
+ return (ser_numer/ser_denom).series(s, point, order+1);