felimz
felimz

Reputation: 160

How to replace implicit subexpressions in Mathematica?

I have this expression in Mathematica:

(a^2 (alpha + beta)^2)/(b^2 + c^2) + (a (alpha + beta))/(b^2 + c^2) + 1  

As you can see, the expression has a couple of subexpressions that repeat throughout it.

I want to be able to replace a/(b^2+c^2) with d and alpha+beta with gamma.

The final expression should then be:

1+d*gamma+a*d*gamma^2

I have much more complicated expressions where being able to do this would greatly simplify my work.

I have tried Googling this question, and I only find answers that use FactorTerms and ReplaceRepeated, but do not work consistently and for a more complicated expression like this one. I am hoping that someone here has the answer.

Upvotes: 7

Views: 5796

Answers (3)

cyrille.piatecki
cyrille.piatecki

Reputation: 1

I modestly --- I am not a computer scientist --- think this is simpler than all other proposed solutions

1+a(alpha+beta)/(b^2 + c^2) +a^2(alpha+beta)^2/(b^2 + c^2) \\.
{a^2-> a  z, a/(b^2 + c^2)-> d,alpha+\beta -> gamma,z-> a}

Upvotes: 0

Leonid Shifrin
Leonid Shifrin

Reputation: 22579

The hard part for the case at hand is the rule for d. Perhaps, there are simpler ways to do it, but one way is to expand the powers to products, to make it work. Let's say this is your expression:

expr  = (a^2 (alpha + beta)^2)/(b^2 + c^2) + (a (alpha + beta))/(b^2 + c^2) + 1

and these are the rules one would naively write:

rules = {a/(b^2 + c^2) -> d, alpha + beta -> gamma}

What we would like to do now is to expand powers to products, in both expr and rules. The problem is that even if we do, they will auto-evaluate back to powers. To prevent that, we'll need to wrap them into, for example, Hold. Here is a function which will help us:

Clear[withExpandedPowers];
withExpandedPowers[expr_, f_: Hold] :=
  Module[{times},
    Apply[f,
       Hold[expr] /. x_^(n_Integer?Positive) :>
          With[{eval = times @@ Table[x, {n}]}, eval /; True] /.
       times -> Times //.
       HoldPattern[Times[left___, Times[middle__], right___]] :>
          Times[left, middle, right]]];

For example:

In[39]:= withExpandedPowers[expr]
Out[39]= Hold[1+(a (alpha+beta))/(b b+c c)+((alpha+beta) (alpha+beta) a a)/(b b+c c)]

The following will then do the job:

In[40]:= 
ReleaseHold[
   withExpandedPowers[expr] //. 
      withExpandedPowers[Map[MapAt[HoldPattern, #, 1] &, rules], Identity]]

Out[40]= 1 + d gamma + a d gamma^2

We had to additionally wrap the l.h.s. of rules in HoldPattern, to prevent products from collapsing back to powers there.

This is just one case where we had to fight the auto-simplification mechanism of Mathematica, but for this sort of problems this will be the main obstacle. I can't assess how robust this will be for larger and more complex expressions.

Upvotes: 7

Searke
Searke

Reputation: 789

Using ReplaceRepeated:

(a^2 (alpha + beta)^2)/(b^2 + c^2) + (a (alpha + beta))/(b^2 + c^2) + 
  1 //. {a/(b^2 + c^2) -> d, alpha + beta -> gamma}

Or using TransformationFunctions:

FullSimplify[(a^2 (alpha + beta)^2)/(b^2 + 
     c^2) + (a (alpha + beta))/(b^2 + c^2) + 1, 
 TransformationFunctions -> {Automatic, # /. 
     a/(b^2 + c^2) -> d &, # /. alpha + beta -> gamma &}]

Both give:

1 + gamma (d + (a^2 gamma)/(b^2 + c^2))

Upvotes: 2

Related Questions