Matching (y/x)^u terms wherever the appear in an expression
At least one of the problems you are encountering is that -2
and -x
do not share the same structure:
{-2, -x} // FullForm
List[-2, Times[-1, x]]
You can not destructure -2
using patterns. You can check numerically however:
(y/x)^2 /. x^a_. y^b_. /; b == -a :> t^b
t^2
Remember also that a matched expression is not further replaced, so you may need ReplaceRepeated
. Applied to your examples:
(1 + 2 (y^2/x^2))/(2 (y/x)) //. x^a_. y^b_. /; b == -a :> t^b
y/x + Sqrt[1 + (y/x)^2] //. x^a_. y^b_. /; b == -a :> t^b
(1 + 2 t^2)/(2 t) t + Sqrt[1 + t^2]
A second potential problem is operating on a manually entered held form such as HoldForm[(1 + 2 (y^2/x^2))/(2 (y/x))]
without realizing that this can have a very different internal form compared to an evaluated expression. Compare:
foo = HoldForm[(1 + 2 (y^2/x^2))/(2 (y/x))];
bar = HoldForm @@ {(1 + 2 (y^2/x^2))/(2 (y/x))};
foo // TreeForm
bar // TreeForm
I would be remiss not to mention that general algebraic manipulation should not be done with pattern matching if at all avoidable. See for example Replacing composite variables by a single variable and be aware of:
- Can I simplify an expression into form which uses my own definitions?
Other things to be aware of:
- More general pattern fails to match everything the more specific pattern does.
- Pattern matching on Orderless functions inside Hold
A simple solution: replace y
with t x
, and if there are any cases of t x
hanging around with the x
not cancelling, replace them with y
.
(expression /. {y -> t x}) /. t x -> y
Testing it on some examples:
((1 + 2 (y^2/x^2))/(2 (y/x)) /. {y -> t x}) /. t x -> y
(y/5 /. {y -> t x}) /. t x -> y
(x/y /. {y -> t x}) /. t x -> y
(y/x + Sqrt[1 + (y/x)^2] /. {y -> t x}) /. t x -> y
(1 + 2 t^2)/(2 t)
y/5
1/t
t + Sqrt[1 + t^2]
I would imagine that this is unlikely to be very robust. But I haven't tested on any convoluted examples.
Edit: To deal with the x
s left at the end, just replace them all with y/t
r[expr_] := expr /. {y -> t x} /. {t x -> y} /. {x -> y/t}
Then, in addition to the above examples, we get
r[(y/x)*y]
r[y^4/x^3]
t y
t^3 y
I know, this is not really the answer to your question. But at least in this specific problem, this helps:
expr /. {y -> t x}
Next try:
r = {
Times[z___, Power[x, k_], Power[y, l_], w___] :> If[k == -l,
Times[z, Power[t, l], w],
Times[z, Power[x, k], Power[y, l], w]
],
Times[z___, x, Power[y, -1], w___] :> Times[z, 1/t, w],
Times[z___, Power[x, -1], y, w___] :> Times[z, t, w]
};
x/y //. r
y^2/x^2 //. r
y^3/x^2 //. r
(1 + 2 (y^2/x^2))/(2 (y/x)) //. r
y/x + Sqrt[1 + (y/x)^2] //. r
(* 1/t *)
(* t^2 *)
(* y^3/x^2 *)
(* (1 + 2 t^2)/(2 t) *)
(* t + Sqrt[1 + t^2] *)
The second branch of the If
statement can be used to further elaborate on the third example. But admittedly, this is starting to get complicated...