3
$\begingroup$

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

enter image description here

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

$\endgroup$
7
  • 1
    $\begingroup$ You can try something like Optional[x^Optional[_?NonNegative]] Optional[y^Optional[_?NonNegative]] $\endgroup$
    – Lukas Lang
    Commented Sep 5 at 10:48
  • 1
    $\begingroup$ And if you add Optional[_?NumericQ] you can also match the 1 and monomials with numeric prefactors $\endgroup$
    – Lukas Lang
    Commented Sep 5 at 10:52
  • $\begingroup$ 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}]. $\endgroup$
    – Domen
    Commented Sep 5 at 12:01
  • $\begingroup$ @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 $\endgroup$ Commented Sep 5 at 12:28
  • 1
    $\begingroup$ @Christopher, aha, well, in that case, you could add another condition like Length@MonomialList[expr, {x, y}] == 1. $\endgroup$
    – Domen
    Commented Sep 5 at 13:14

3 Answers 3

4
$\begingroup$

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

result

$\endgroup$
1
  • 1
    $\begingroup$ Oooh, that's pretty cool! I'm accepting your answer. $\endgroup$ Commented Sep 5 at 13:25
2
$\begingroup$

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

enter image description here

$\endgroup$
1
$\begingroup$

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

enter image description here

$\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.