4
$\begingroup$
MatchQ[x y, (x | y) (x | y)]

It returns false. Why?

I want to eliminate terms like x^2, y^2, z^2, x y, x z, y z.

$\endgroup$
13
  • 11
    $\begingroup$ I think because (x | y) (x | y) evaluates to (x | y)^2, which doesn't match your expression. $\endgroup$ Commented Jun 13, 2016 at 4:04
  • $\begingroup$ What do you mean by "I want to eliminate terms like x^2, y^2, z^2, x y, x z, y z"? $\endgroup$ Commented Jun 13, 2016 at 4:04
  • 1
    $\begingroup$ Does MatchQ[#, _^2 | a_ b_] & /@ {x^2, y^2, z^2, x y, x z, y z} do what you want? Your post needs more information, because there is an inconsistency between the terms you want to eliminate and the patterns you are making. Do you want to eliminate any second-degree monomial? Or do you want to eliminate any second-order monomial that involves x or y? (or x or y and nothing else)? $\endgroup$ Commented Jun 13, 2016 at 4:06
  • 6
    $\begingroup$ Btw: MatchQ[x y, HoldPattern[(x | y) (x | y)]] $\endgroup$ Commented Jun 13, 2016 at 8:22
  • 1
    $\begingroup$ For more info, the reason @Kuba 's method works is to avoid the problem march mentioned. $\endgroup$ Commented Jun 13, 2016 at 9:19

3 Answers 3

4
$\begingroup$

If you Trace the evaluation sequence of this expression, you get the following:

Trace@MatchQ[x y, (x | y) (x | y)]
(* {{(x|y) (x|y), (x|y)^2}, MatchQ[x y, (x|y)^2], False} *)

This shows that (x|y) (x|y) gets evaluated to (x|y)^2 before the pattern matching occurs, and x y doesn't match (x|y)^2, although x^2 and y^2 will:

MatchQ[#, (x | y) (x | y)] & /@ {x^2, y^2, z^2, x y, x z, y z}
(* {True, True, False, False, False, False} *)

If you really want all of the expressions in that list above to match, I would do something like

MatchQ[#, a_ b_ | a_^2] & /@ {x^2, y^2, z^2, x y, x z, y z}
(* {True, True, True, True, True, True} *)
$\endgroup$
2
  • 1
    $\begingroup$ If the user wants to capture only x and y, a little work is required: MatchQ[#, a_ (b_ /; MatchQ[b, x | y]) | a_^2 /; MatchQ[a, x | y]] &. $\endgroup$ Commented Jun 13, 2016 at 21:06
  • $\begingroup$ @rcollyer. Or MatchQ[#, a_ b_ | a_^2 /; And[Or[a == x, a == y], Or[b == x, b == y]]] &. $\endgroup$ Commented Jun 13, 2016 at 21:07
1
$\begingroup$

I guess what you want is to create a function that can match something like $x x$ or $x y$ in a simple way.

So, here's my answer and hope this can help you:

f = Function[{t, l}, With[{pat = Alternatives @@ l},MatchQ[Unevaluated@t, HoldPattern[pat pat]]],HoldFirst];
f[x x, {x, y, z}]
f[x z, {x, y, z}]

Also, I think you would love to use something like Map:

f[#, {x, y, z}] & /@ (Unevaluated /@Unevaluated[{x x, x y, y y, z y}])

Can this help?

$\endgroup$
1
$\begingroup$

Thank you everyone!

Eventually I found the solution at Dropping Higher Order Terms in symbolic evaluation.

The one using

Normal[Series[expr /. Thread[vars -> t*vars], {t, 0, 10}]] /. t -> 1

My final code (for getting the components of the Riemann tensor of a certain weak gravitational field) became.

Needs["GREATER2`"];
X = {t, x, y, w};
ds2 = -(1 + 2 \[Phi][t, x, y, w]) dt^2 + (1 - 2 \[Phi][t, x, y, w]) (dx^2 + dy^2 + dw^2);
Gdd = Metric[ds2, X];
termPattern = Join[{\[Phi][t, x, y, w]}, Flatten[D[\[Phi][t, x, y, w], {{t, x, y, w}, 1}]], Flatten[D[\[Phi][t, x, y, w], {{t, x, y, w}, 2}]]];
Result = Raise[Riemann[Gdd, X], 1, Gdd];
ResultFirstOrder = Normal[Series[Result /. Thread[termPattern -> i*termPattern], {i, 0, 1}]] /. {i -> 1, \[Phi]_[t, x, y, w] -> \[Phi]}
$\endgroup$
1
  • 8
    $\begingroup$ ...this turned out to be an XY problem. Why didn't you ask about this to begin with? $\endgroup$ Commented Jun 14, 2016 at 5:39

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.