:

## Extracting the constant term of a multivariate polynomial

Consider the task of extracting the constant-term from a multivariate polynomial. This seems a common operation; I expected that there would be a predefined command for doing it. Alas, I could not find one. The usual suspects, coeff and tcoeff, do not directly do the job: coeff does not work with multivariate polynomials and tcoeff returns the coefficent of the lowest-order term, which may not be the zero-order term. Here are two simple procedures that implement different ways of solving this problem:
# Add a dummy term to polynomial to ensure that it is the zero-order term, then remove it.
constantterm1 := proc(poly, vars::list)
local dummy;
return tcoeff(poly + dummy, vars) - dummy;
end proc:

# Iteratively call coeff with each variable (and the 0 argument)
constantterm2 := proc(poly, vars::list)
return foldl(rcurry(coeff,0), poly, op(vars));
end proc:

p1 := a*x^2 + b*x*y + x:
p2 := p1 + c:

map(constantterm1, [p1,p2], [x,y]);
[0, c]
map(constantterm2, [p1,p2], [x,y]);
[0, c]

time(proc() to 10^5 do constantterm1(p2,[x,y]) od end proc());
2.8
time(proc() to 10^5 do constantterm2(p2,[x,y]) od end proc());
6.9
The first technique is considerably faster than the second. However, it has a subtle bug; if poly is not a polynomial it can return the wrong result (with an escaped local, no less):
constantterm1(1/x+c,[x]);
1 - dummy
That may or may not be an issue, depending on the usage. The second procedure is immune to that:
constantterm2(1/x+c,[x]);
c
Note that all these procedures require that poly be collected with respect to the variables. Be sure to use the 'distributed' option when collecting. By default collect uses 'recursive', which doesn't work with coeffs and multivariate polynomials. Is there a cleaner way to solve this problem? Here's a third approach. For these simple polynomials it is the fastest. It doesn't have the "problem" of the first one.
# Use remove to remove all terms that don't include the vars.
# Add a dummy term so that this works correctly with a product,
# otherwise 3*x would return 3.
constantterm3 := proc(poly, vars::list)
local dummy;
return remove(has,poly+dummy,vars)-dummy;
end proc:
Here's a fourth approach. It is the fastest yet, but can fail with an error if poly is not a polynomial in the variables.
constantterm4 := proc(poly, vars::list)
local x;
return subs(seq(x=0,x=vars),poly);
end proc:

﻿