# Pattern-matching of monomials

I am trying to match monomials of the type x^a y^b, where a, b can be 0, 1, 2, ...

So far I have been able to come up with the following rule, using Optional patterns:

Table[x^i   y^j, {i, -2, 2}, {j, -2, 2}] //
Replace[#,
expr : (a : (x^i_. /; i >= 0) : 1)  (b : (y^j_. /; j >= 0) : 1) ->
Framed[expr], {2}] & // MatrixForm


Question:

• The pattern also feels a little clunky. Is there a more idiomatic way to express it? Do I really need to name "a" and "b" in optional "complex" patterns, when I don't care about them being named?

• Also, why isn't "1" being matched? I would have thought that when "a" and "b" are take their default values, then Times[1, 1] would simplify to 1.

I tried to use alternatives such as expr : (x^i_. /; i >= 0 | 1) (y^j_. /; j >= 0 | 1), but this didn't work, although I didn't quite understand why...

• You can try something like Optional[x^Optional[_?NonNegative]] Optional[y^Optional[_?NonNegative]] Commented Sep 5 at 10:48
• And if you add Optional[_?NumericQ] you can also match the 1 and monomials with numeric prefactors Commented Sep 5 at 10:52
• Instead of relying on structural pattern matching, you should rather use algebraic functions, for example: Replace[#, expr_ /; PolynomialQ[expr, {x, y}] && ! NumberQ[expr] :> Framed[expr], {2}]. Commented Sep 5 at 12:01
• @LukasLang thanks, I did not realise one could use the full form of Optional to avoid naming the complex patterns. This is great and answers most of my question. +1 Commented Sep 5 at 12:28
• @Christopher, aha, well, in that case, you could add another condition like Length@MonomialList[expr, {x, y}] == 1. Commented Sep 5 at 13:14

In addition to pattern matching, you can make a query function something like this:

ClearAll[x,y];
monomialQ[f_]:=(f===x^Max[0,Exponent[f,x]]*y^Max[0,Exponent[f,y]]);

Map[If[monomialQ[#],Framed[#],#]&,Table[x^i y^j,{i,-2,2},{j,-2,2}],{2}]//MatrixForm


• Oooh, that's pretty cool! I'm accepting your answer. Commented Sep 5 at 13:25

An alternative is to use Grad and PolynomialQ as follows:

Replace[Table[x^i  y^j, {i, -2, 2}, {j, -2, 2}],
mon_ /; AllTrue[Grad[mon, {x, y}], PolynomialQ[#, {x, y}] &] :>
Framed[mon, Background -> LightRed], {2}] // MatrixForm


Using a condition on the denominator of the matrix elements:

Replace[Table[x^i   y^j, {i, -2, 2}, {j, -2, 2}],
mon_ /; FreeQ[Denominator[mon], x | y] :>
Framed[mon], {2}] // MatrixForm