9

I am looking for help in writing transformation rules in which I wish to distinguish between eight variables $x,x^2,\bar{x},\bar{x}^2, x_p,x_p^2, \bar{x}_p,\bar{x}^2_p $.

For each of these eight variables, I would like eight separate transformation rules such that :

$x,x^2,\bar{x},\bar{x}^2, x_p,x_p^2, \bar{x}_p, \bar{x}^2_p \rightarrow (\bar{x}+\tilde{x}),(\bar{x}+\tilde{x})^2,(\bar{x}+\tilde{x}),(\bar{x}+\tilde{x})^2, (\bar{x}_p+\tilde{x}_p),(\bar{x}_p + \tilde{x}_p)^2, (\bar{x}_p+\tilde{x}_p), (\bar{x} + \tilde{x}_p)^2 $

I am having considerable trouble defining the correct constraints so that each of the transformation rules only activates for its corresponding variable. I have had some partial success, for example rule six for $x^2_p$:

rule6 := { Power[Subscript[x, p], power_] -> Power[Subscript[OverBar[x], p] + Subscript[OverTilde[x], p], power]}

when applied to the expression:

$x^2 x_p^2 y_p^2 \bar{x}_p^2\text{/.}\, \text{rule6}$

which in code is:

Times[Power[x,2],Power[Subscript[x,p],2],Power[Subscript[y,p],2],Power[Subscript[OverBar[x],p],2]] /. rule6

yields the desired output $x^2 y_p^2 \bar{x}_p^2 \left(\bar{x}_p+\tilde{x}_p\right){}^2$.

Similarly, rule two for $x^2$

rule2 := { Power[x, power_] -> Power[OverBar[x] + OverTilde[x], power]}

when applied to expression

$x^2 x_p^2 y_p^2 \bar{x}_p^2\text{/.}\, \text{rule2}$

which in code is

Times[Power[x,2],Power[Subscript[x,p],2],Power[Subscript[y,p],2],Power[Subscript[OverBar[x],p],2]] /. rule2

yields the desired output $x_p^2 y_p^2 \left(\bar{x}+\tilde{x}\right)^2 \bar{x}_p^2$.

However, I am having particular trouble defining a proper rule for $x$.

My attempt

rule1 := {var_ /; var === x -> (OverBar[var] + OverTilde[x])}

is too permissive, in that it matches the $x$ even when it appears with a Subscript, with a Power, or with an OverBar.

For example, when applied to the expression

$x^2 x_p^2 y_p^2 \bar{x}_p^2\text{/.}\, \text{rule1}$

which in code is

Times[Power[x,2],Power[Subscript[x,p],2],Power[Subscript[y,p],2],Power[Subscript[OverBar[x],p],2]] /. rule1

it yields the incorrect output $y_p^2 \left(\bar{x}+\tilde{x}\right)^2 \overline{\bar{x}+\tilde{x}}_p^2 \left(\bar{x}+\tilde{x}_p\right){}^2$; the correct output in this case would have been to leave the input untouched: $x^2 x_p^2 y_p^2 \bar{x}_p^2$.

Similarly, when applied to the expression

$x x_p y_p \bar{x}_p \text{/.}\, \text{rule1}$

which in code is

Times[x,Subscript[x,p],Subscript[y,p],Subscript[OverBar[x],p]] /. rule1

it yields the incorrect output $y_p \left(\bar{x}+\tilde{x}\right) \overline{\bar{x}+\tilde{x}}_p \left(\bar{x}+\tilde{x}_p\right)$; the correct output would have been $(\bar{x} + \tilde{x}) x_p y_p \bar{x}_p$.

How do I force the pattern matching to ignore the OverBar, Power and Subscript cases?

I have tried things such as rule1ALT := var_ /; var === x && FreeQ[{Subscript, OverBar, Power}, Head[var]] -> OverBar[x] + OverTilde[x]

but the problem seems to be that Head[var] returns Symbol and not the OverBar, Subscript or Power encompassing it.

Carl Woll
  • 130,679
  • 6
  • 243
  • 355
  • 1
    I'd like to point out that, if you are going to do any calculations on these variables, you are definitely asking for trouble when using formatting expressions such as Subscript etc in variable names. See e.g. this FAQ on "Basic syntax issues". If, on the other hand, you are only interested in typographical layout, then Mathematica might honestly not be the most straightforward method. – MarcoB Sep 06 '15 at 18:48

2 Answers2

7

The real reason why this is not working is that Mathematica actually matches each x inside Subscript and OverBar individually. In other words, OverBar[x] doesn't match your rule, but the internal x individually matches the rule when ReplaceAll goes to a deeper level in the expression.

To solve this problem, you can use the LevelSpec option of the Replace function to avoid matching on deeper levels. Using the same definition for your rule1ALT, you can do:

Replace[Times[x, Subscript[x, p], Subscript[y, p], 
  Subscript[OverBar[x], p]], rule1ALT, 1]

Which yields the correct desired output: $(\bar{x} + \tilde{x}) x_p y_p \bar{x}_p$.

However, this is not a universal solution! It will not work if you have the OverBar and Subscript symbols appearing in many different levels of the expression, which most probably you will. After all, there is no way to distinguish x inside x^2 from x inside OverBar[x] if you traverse an expression hierarchically on all levels.

The best workaround in my opinion is to actually change the name of the variables, so that ReplaceAll can work on them seamlessly on all levels, and only substitute the names at the end of calculation. For example, set y to be OverBar[x] and z to be x_p, go through your manipulations, then at the end of each calculation before displaying the results, do /. {y -> OverBar[x], z->x_p}

Bichoy
  • 1,203
  • 6
  • 15
2

As in a previous answer to a similar question, I like to use multiple replacement rules to avoid replacing "avoided" patterns. In your example, I would do:

xRule = {
    s:(Subscript|Power|OverBar)[__] -> s, (* pattern to avoid *)
    x -> OverBar[x] + OverTilde[x]
};

Your first example:

ReplaceAll[
    x^2 Subscript[x,p]^2 Subscript[y,p]^2 Subscript[OverBar[x],p]^2,
    xRule
] //TeXForm

$x^2 x_p^2 y_p^2 \bar{x}_p^2$

And your second example:

ReplaceAll[
    x Subscript[x,p] Subscript[y,p] Subscript[OverBar[x],p],
    xRule
] //TeXForm

$x_p y_p \left(\bar{x}+\tilde{x}\right) \bar{x}_p$

Carl Woll
  • 130,679
  • 6
  • 243
  • 355