3
$\begingroup$

The following function finds the degree of a multi-variate polynomial.

PolyDeg[expr_]:=expr//ToList//Exponent[#,Variables[#]]&/@#&//Plus@@@#&//Max;

Here the function ToList is the same as MonomialList.

I found this code in somebody else's Wolfram Notebook and cannot understand how it works. There are too many pure functions and uses of the \\ operator.

Can someone explain this code? Are there any clearer ways to write an equivalent function?

$\endgroup$
4
  • 1
    $\begingroup$ That code is indeed not easy on the eyes. The word "ghastly" comes to mind. $\endgroup$ Commented Aug 1 at 16:51
  • 2
    $\begingroup$ My favored method: totalDegree[poly_, vars_] := Module[{t}, Exponent[poly /. Thread[vars -> RandomReal[{1, 2}, Length[vars]]*t], t]] $\endgroup$ Commented Aug 1 at 16:52
  • $\begingroup$ @DanielLichtblau Why did you use random number function? $\endgroup$ Commented Aug 1 at 23:28
  • $\begingroup$ To avoid cancellations of terms. $\endgroup$ Commented Aug 2 at 16:10

4 Answers 4

1
$\begingroup$

More easy to read equivalent of OP code would be:

pdeg[pol_] := Total /@ (Exponent[#, Variables[#]] & /@ MonomialList[pol]) // Max

Total/@ replaces Plus@@@.

MonomialList replaces ToList (which was probably custom defined function that was doing same as MonomialList).

The rest is same as in OP.

$\endgroup$
3
  • 1
    $\begingroup$ I found a similar wayPolyDeg[expr_]:=Max[Total[Exponent[#, Variables[#]]]&/@MonomialList[expr]] $\endgroup$ Commented Aug 1 at 23:39
  • $\begingroup$ Are you sure the Total was put in the correct place? $\endgroup$ Commented Aug 1 at 23:40
  • 1
    $\begingroup$ OK. I understand that they are equivalent. $\endgroup$ Commented Aug 2 at 7:27
3
$\begingroup$

The code you are trying to understand is very hard to read, specially if you have no idea of the precedences.

There is a second problem here : ToList is an undocumented function in the context Developer`.

First let insert the right context for ToList :

PolyDeg[expr_] := 
  expr // Developer`ToList // Exponent[#, Variables[#]] & /@ # & // 
    Plus @@@ # & // Max;  

PolyDeg[a^2 + b^3]    

5

Then, this is what should be understood :

exp00 = a^2 + b^3

enter image description here

exp01 = Developer`ToList[exp00 ](* equivalent to
 exp00//Developer`ToList
 except if ToList has Hold Attribute *)  

enter image description here

exp02 = Exponent[#, Variables[#]] & /@ exp01  (* = exp01 //Exponent[#,
  Variables[#]]&/@#& *)  

{{2, 3}}

exp03 = Apply[Plus, exp02, {1}] (* = exp02//Plus@@@#&*)  

{5}

exp03 = Max[exp03]

5

$\endgroup$
0
3
$\begingroup$

First off, there is an easier way:

testPoly = x^3 + 3*x^2*y + 3*x^5*y^2 + y^3;

CoefficientRules[testPoly, All, "DegreeLexicographic"]
(* {{5, 2} -> 3, {3, 0} -> 1, {2, 1} -> 3, {0, 3} -> 1} *)

Given how we ordered the list, we can just extract the highest order and find the sum:

CoefficientRules[testPoly, All, "DegreeLexicographic"][[1, 1]] // Total
(* 7 *)

Others beat me to explaining the original code, but here's another approach that you can generalize. One thing I do to sort of deconstruct an incomprehensible chunk of code is to make some of the symbols into undefined symbols so that I can see what's happening at particular points. Let's just do that for everything even though we probably know what symbols like Max and Plus are going to do.

PolyDeg[expr_] := expr // ToListz // Exponentz[#, Variablesz[#]] & /@ # & // Plusz @@@ # & // Maxz;

Let's test with something simple

PolyDeg[x^2 + 1]
(* Maxz[ToListz[Plusz[1 + x^2, Variablesz[1 + x^2]]]] *)

Okay, honestly that didn't work out great, and it's because we MapApplyd the Plus (so it went "inside" the ToListz expression). But hey, ya gotta learn to fiddle with stuff. And we do see where the argument got "pasted" around in the result. So, let's revert ToListz back to ToList. One problem is that this isn't a built in function and you didn't provide the definition. I'm assuming that it should turn a polynomial into a list of monomials. So, we can do that with either MonomialList or with Apply[List]. Let's choose the former:

ToList = MonomialList;
PolyDeg[expr_] := expr // ToList // Exponentz[#, Variablesz[#]] & /@ # & // Plusz @@@ # & // Maxz;
PolyDeg[x^2 + 1]
(* Maxz[{Plusz[x^2, Variablesz[x^2]], Plusz[1, Variablesz[1]]}] *)

Okay, now we're cooking with gas. The input polynomial was de-structured into monomials and we did some fancy stuff with each monomial. Hmmm, where did Exponentz go to? Well, we mapped over a list, so at some point we have a list of expressions with head Exponentz. Then we MapApplyd Plusz, so the Plusz just replaced the Exponentz. So, at some point we had expressions like

Exponentz[x^2, Variablesz[x^2]]

Next thing to do is figure out what Exponent and Variables do. Read the documentation.... okay, they do pretty much what it sounds like they should do. Let's try them out:

Variables[x^2]
(* {x} *)

Exponent[x^2, Variables[x^2]]
(* {2} *)

Makes sense, and if we had more variables, we'd have longer lists of variables and exponents. Now it makes sense why we're MapApplying Plus--that's how we're getting the degree of each monomial. Since we understand that now, let's revert these two functions:

PolyDeg[expr_] := expr // ToList // Exponent[#, Variables[#]] & /@ # & // Plusz @@@ # & // Maxz;
PolyDeg[x^2 + 1]
(* Maxz[{Plusz[2], Plusz[]}] *)

Okay, we have a Plusz for the x^2 and one for the 1. Maybe we should do something a bit more complicated:

PolyDeg[x^2 + x^2 y^3 + 1]
(* Maxz[{Plusz[2, 3], Plusz[2], Plusz[]}] *)

Yep, looks like it's working as expected. At this point we can see what Plus and Max will do, so let's revert those:

PolyDeg[expr_] := expr // ToList // Exponent[#, Variables[#]] & /@ # & // Plus @@@ # & // Max;
PolyDeg[x^2 + x^2 y^3 + 1]
(* 5 *)
$\endgroup$
1
$\begingroup$

First, note that "expr // fun" applies fun to expr like fun[expr].

Second, "ToList" is no inbuild function. I assume it is supposed to wrap a list around expr. You may replace it e.g. by: {#}&.

Third, consider: Exponent[#, Variables[#]] & /@ # &. Note that fun /@ list applies fun to each element of list. The function here is: Exponent[#, Variables[#]] &. Variables extracts the variables. Exponent gives a list of the max. powers of each variables in a polynomial.

Forth, We now have {{maximal exponents}}. Note that fun@@@{{expr}} is equal to: {fun[expr]}. Therefore, // Plus @@@ # & will add all the maximal exponents.

Fifth, //Max seems superfluous, as we added up all max. exponents, leaving a simple integer. Maybe this is needed in a more complicated case that I may miss.

$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.