3
$\begingroup$

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...!)

$\endgroup$
7
  • $\begingroup$ 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. :-/ $\endgroup$
    – Mr.Wizard
    Jun 25, 2015 at 13:17
  • 1
    $\begingroup$ @Mr.Wizard It appears that terms for which the sum of exponents in x and y exceeds two are being deleted. $\endgroup$
    – bbgodfrey
    Jun 25, 2015 at 13:21
  • $\begingroup$ @bbgodfrey Thanks! The text just didn't read that way to me but I think I see it now. $\endgroup$
    – Mr.Wizard
    Jun 25, 2015 at 13:25
  • $\begingroup$ 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. $\endgroup$
    – Mr.Wizard
    Jun 25, 2015 at 13:33
  • 1
    $\begingroup$ Use Numerator[] and Denominator[] to pick out those parts, do the cut-off on both, and recompose your new rational function. $\endgroup$ Jun 25, 2015 at 14:19

4 Answers 4

4
$\begingroup$

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)
$\endgroup$
8
  • $\begingroup$ 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 ? $\endgroup$
    – Toool
    Jun 25, 2015 at 13:35
  • 1
    $\begingroup$ (+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... $\endgroup$
    – kale
    Jun 25, 2015 at 13:39
  • $\begingroup$ @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? $\endgroup$
    – Mr.Wizard
    Jun 25, 2015 at 13:40
  • 1
    $\begingroup$ @kale I am uncertain of the correct interpretation, but thank you for providing a method for the other one too. $\endgroup$
    – Mr.Wizard
    Jun 25, 2015 at 13:42
  • $\begingroup$ 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. $\endgroup$
    – Toool
    Jun 25, 2015 at 13:47
4
$\begingroup$

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}]]
$\endgroup$
2
  • $\begingroup$ I get y^2 + x (a x + c y) which is equivalent. You're too good at programming blind! $\endgroup$
    – Mr.Wizard
    Jun 25, 2015 at 14:10
  • $\begingroup$ Expand[] will take care of that, of course. :) Nevertheless, it's sometimes useful to leave polynomials in Horner form. $\endgroup$ Jun 25, 2015 at 14:12
4
$\begingroup$

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[6]= a x^2 + c x y + y^2 *)
$\endgroup$
0
$\begingroup$
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   *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.