Symbolic cut-off of high-order terms

I know that I can cut-off high-order terms of a $1$-variable polynomial P = a0 + a1*x + a2*x^2 + a3*x^3 + a4*x^4 + a5*x^5; simply by doing for example P /. {x^y_ /; y > 2 -> 0}.

Now I have a $n$-variable polynomial expression and I want to cut off all the terms of order 3 and more, for every product of variables.

For example consider the polynomial P = a*x^2 + b*x^3 + c*x*y + d*x^2*y + e*x*y^2 + y^2, I want an operation who returns me a*x^2 + c*x*y + y^2

I am looking for a similar expression which does this cut-off for each symbol which is more than squared !

EDIT :

I didn't specify that I am considering a rational function. Mr.Wizard's answer works perfectly for the numerator, but what about the full function ?

Is it possible to do this cut-off for all the terms appearing in both the numerator and the denominator of a rational function ?

In general, the function I am considering is something like $(\sum a_i\prod x_j^i)/(\sum b_k\prod x_l^k)$ where the product is over the variables and the $a_i$ are the coefficients.

A simple example could be $(a_1x^2 + a_2xy^2z + a_3zy+a_4x )/(b_1y+b_2zy^2+b_3xz)$ which I want to cut-off to $(a_1x^2 + a_3zy+a_4x )/(b_1y+b_3xz)$

(Sorry I am not very clear in my questions...!)

• Sorry for being obtuse but could you explain the transformation of a*x^2 + b*x^3 + c*x*y + d*x^2*y + e*x*y^2 + y^2 into a*x^2 + c*x*y + y^2 more literally? I'm not seeing it. :-/ – Mr.Wizard Jun 25 '15 at 13:17
• @Mr.Wizard It appears that terms for which the sum of exponents in x and y exceeds two are being deleted. – bbgodfrey Jun 25 '15 at 13:21
• @bbgodfrey Thanks! The text just didn't read that way to me but I think I see it now. – Mr.Wizard Jun 25 '15 at 13:25
• I still have a problem with the text; nowhere are x and y singled out as in bbgodfrey's observation. However if I count the exponents of all variables in each term and add them the remaining ones are those with a total of three or less. I posted an answer following that interpretation. – Mr.Wizard Jun 25 '15 at 13:33
• Use Numerator[] and Denominator[] to pick out those parts, do the cut-off on both, and recompose your new rational function. – J. M. will be back soon Jun 25 '15 at 14:19

Thanks to bbgodfrey's comment I think I understand what you want:

p = a*x^2 + b*x^3 + c*x*y + d*x^2*y + e*x*y^2 + y^2;

Total @ Exponent[#, Variables @ #] & /@ List @@ p

Pick[P, # <= 3 & /@ %]
{3, 4, 3, 4, 2, 4}

a x^2 + c x y + y^2

Following your update here is a somewhat different formulation that may be useful:

op[var_List, max_][p__] :=
#*Boole[max >= Tr @ Exponent[#, var]] & /@ {p} // Total

Use is:

p = a*x^2 + b*x^3 + c*x*y + d*x^2*y + e*x*y^2 + y^2;

op[{x, y}, 2] @@ p       (* replace Plus using Apply *)
a x^2 + c x y + y^2

Or:

p2 = (a1*x^2 + a2*x*y^2*z + a3*z*y + a4*x)/(b1*y + b2*z*y^2 + b3*x*z);

p2 /. Plus -> op[{x, y}, 2]        (* replace all instances of Plus *)
(a4 x + a1 x^2 + a3 y z) / (b1 y + b3 x z + b2 y^2 z)
• Thanks ! This looks perfect (you had the right interpretation, sorry if the question was fuzzy), but would you like to explain me what's going on here more precisely ? – Tool Jun 25 '15 at 13:35
• (+1). I'd probably suggest one thing though. I think you'd have to specify what are the "non-coefficient" variables. So you're example would be... Total @ Exponent[#, {x,y}] & /@ List @@ p and then Pick[P, # < 3 & /@ %], but we'd need further clarification from the OP on that regard... – kale Jun 25 '15 at 13:39
• @LSnoopyD I just updated the answer to a hopefully clearer form. List @@ p splits the expression into a list of terms. Then Total @ Exponent[#, Variables @ #] & is mapped over this list, which is a function to total the exponents of all variables in a given term. Finally Pick is employed to select from p itself those totals which are <= 3, preserving the head of p which is Plus. Hopefully this is the operation you wanted? – Mr.Wizard Jun 25 '15 at 13:40
• @kale I am uncertain of the correct interpretation, but thank you for providing a method for the other one too. – Mr.Wizard Jun 25 '15 at 13:42
• Thank you for this clarification. This is indeed what I wanted ! More precisely, the expression I want to cut-off isn't a polynomial but a rational function (I can replace Variables @ P by the list of variables generated at the beginning of my code), I hope this will not cause problems for this approach. – Tool Jun 25 '15 at 13:47

Competely untested, but I believe this ought to work nicely:

p = a*x^2 + b*x^3 + c*x*y + d*x^2*y + e*x*y^2 + y^2;
coeffs = CoefficientArrays[p, {x, y}];
k = 2; (* highest degree wanted *)
Fold[#1.{x, y} + #2 &, {0, 0}, Take[coeffs, {k + 1, 1, -1}]]
• I get y^2 + x (a x + c y) which is equivalent. You're too good at programming blind! – Mr.Wizard Jun 25 '15 at 14:10
• Expand[] will take care of that, of course. :) Nevertheless, it's sometimes useful to leave polynomials in Horner form. – J. M. will be back soon Jun 25 '15 at 14:12

Standard method: create a univariate in a new variable t, by changing every variable x to t*x. Take a Series expansion in t. Then use Normal to make it explicitly polynomial, and substitute t->1.

poly = a*x^2 + b*x^3 + c*x*y + d*x^2*y + e*x*y^2 + y^2;
vars = {x, y};
Normal[Series[poly /. Thread[vars -> t*vars], {t, 0, 2}]] /. t -> 1

(* Out= a x^2 + c x y + y^2 *)
P = a*x^2 + b*x^3 + c*x*y + d*x^2*y + e*x*y^2 + y^2 + f*x^2*y^3;

rule1 = {Times[a_, Power[x, n_], y] -> n + 1,
Times[a_, x, Power[y, n_]] -> n + 1}
rule2 = Times[a_, Power[x, n_], Power[y, m_]] ->
m + n; rule3 = {Times[a_, Power[b_, n_]] -> n, Power[b_, n_] -> n,
Times[a_, x, y] -> 2};
rule3 = {Times[a_, Power[b_, n_]] -> n, Power[b_, n_] -> n,
Times[a_, x, y] -> 2};

Delete[P,
Position[(P /. Plus -> List) /. rule1 /. rule2 /. rule3, x_ /; x > 2]]

(*  a x^2 + c x y + y^2   *)