Simplification with User defined rules and assumptions

The results of DSolve are usually expressions that can be further simplified. For instance, consider the following expression for a co-ordinate of a particle in constant magnetic field,

z[t] -> -((1/(2*(Bx^2 + By^2 + Bz^2)^2))*(E^(t*(-Sqrt[-Bx^2 - By^2 - Bz^2]))*
(-(2*Bx^2*Bz^2*t*E^(t*Sqrt[-Bx^2 - By^2 - Bz^2])) -
2*By^2*Bz^2*t*E^(t*Sqrt[-Bx^2 - By^2 - Bz^2]) + Bx^2*Sqrt[-Bx^2 - By^2 - Bz^2]*
E^(2*t*Sqrt[-Bx^2 - By^2 - Bz^2]) + By^2*Sqrt[-Bx^2 - By^2 - Bz^2]*
E^(2*t*Sqrt[-Bx^2 - By^2 - Bz^2]) - By^2*Sqrt[-Bx^2 - By^2 - Bz^2] -
Bx^2*Sqrt[-Bx^2 - By^2 - Bz^2] - 2*Bz^4*t*E^(t*Sqrt[-Bx^2 - By^2 - Bz^2]))))


I want to define absB^2 = Bx^2 + By^2 + Bz^2, so that the exponential and denominators are simple and the output is more readable. However if I simply define it as a rule Bx^2 + By^2 + Bz^2 -> absB^2, mathematica fails to make the substitution in the exponentials (it works for the denominators), likely because of the negative signs. In this case I can make do by putting in another rule Bx^2 + By^2 +Bz^2 -> I abs B, but that doesn't seem a principled approach to me. Another idea I had was something like Bx -> Sqrt[absB^2 - By^2 -Bz^2], but that will mess up all the Bx elsewhere.

How should I do it? All quantities are real, but as long as the complex numbers occur as exponentials only it's fine.

• Thank you. As I said the first one is working. When I tried the second, only Bx was replaced by absB, any guesses why? May 15, 2021 at 9:13
• Yes I thought it must've been a typo. The problem remains after using a single comma. May 15, 2021 at 10:20

I scrape-n-paste exactly your input from above

In[3]:= z[t]->-((1/(2*(Bx^2+By^2+Bz^2)^2))*(E^(t*(-Sqrt[-Bx^2-By^2-Bz^2]))*
(-(2*Bx^2*Bz^2*t*E^(t*Sqrt[-Bx^2-By^2-Bz^2]))-
2*By^2*Bz^2*t*E^(t*Sqrt[-Bx^2-By^2-Bz^2])+Bx^2*Sqrt[-Bx^2-By^2-Bz^2]*
E^(2*t*Sqrt[-Bx^2-By^2-Bz^2])+By^2*Sqrt[-Bx^2-By^2-Bz^2]*
E^(2*t*Sqrt[-Bx^2-By^2-Bz^2])-By^2*Sqrt[-Bx^2-By^2-Bz^2]-
Bx^2*Sqrt[-Bx^2-By^2-Bz^2]-2*Bz^4*t*E^(t*Sqrt[-Bx^2-By^2-Bz^2]))))/.
{Bx^2+By^2+Bz^2->absB^2,-Bx^2-By^2-Bz^2->-absB^2}//InputForm


and I get

Out[3]//InputForm= z[t] -> -(-(Sqrt[-absB^2]*Bx^2) - Sqrt[-absB^2]*By^2 +
Sqrt[-absB^2]*Bx^2*E^(2*Sqrt[-absB^2]*t) + Sqrt[-absB^2]*By^2*
E^(2*Sqrt[-absB^2]*t) - 2*Bx^2*Bz^2*E^(Sqrt[-absB^2]*t)*t -
2*By^2*Bz^2*E^(Sqrt[-absB^2]*t)*t - 2*Bz^4*E^(Sqrt[-absB^2]*t)*t)/
(2*absB^4*E^(Sqrt[-absB^2]*t))


I scrape-n-paste exactly your input from above

In[4]:= Simplify[z[t]->-((1/(2*(Bx^2+By^2+Bz^2)^2))*(E^(t*(-Sqrt[-Bx^2-By^2-
Bz^2]))*(-(2*Bx^2*Bz^2*t*E^(t*Sqrt[-Bx^2-By^2-Bz^2]))-
2*By^2*Bz^2*t*E^(t*Sqrt[-Bx^2-By^2-Bz^2])+Bx^2*Sqrt[-Bx^2-By^2-Bz^2]*
E^(2*t*Sqrt[-Bx^2-By^2-Bz^2])+By^2*Sqrt[-Bx^2-By^2-Bz^2]*
E^(2*t*Sqrt[-Bx^2-By^2-Bz^2])-By^2*Sqrt[-Bx^2-By^2-Bz^2]-
Bx^2*Sqrt[-Bx^2-By^2-Bz^2]-2*Bz^4*t*E^(t*Sqrt[-Bx^2-By^2-Bz^2])))),
Bx^2+By^2+Bz^2==b]/.b->absB^2 //InputForm


and I get

Out[4]//InputForm= z[t] -> (Sqrt[-absB^2]*Bz^2*(-1 + E^(2*Sqrt[-absB^2]*t)) +
absB^2*(Sqrt[-absB^2] - Sqrt[-absB^2]*E^(2*Sqrt[-absB^2]*t) +
2*Bz^2*E^(Sqrt[-absB^2]*t)*t))/(2*absB^4*E^(Sqrt[-absB^2]*t))


I appended //InputForm onto those only to translate the radical symbols, etc into text to show here and for you to use that in further calculations you will need to remove those.

Please try to reproduce exactly what I did with a fresh restart of Mathematica and using only what you posted above.

You almost certainly correctly guessed that your attempts at pattern matching failed because of the minus signs. Pattern matching in Mathematica is almost completely literal and only matches if the "form" matches exactly. Thus the form of -Bx^2 - By^2 - Bz^2 is not exactly the same form as Bx^2 + By^2 + Bz^2 and the matching will fail, even though the bright student will immediately know that the first is just -1* the second. Thus I used two different patterns, one without and one with the minus signs so that each would match the appropriate forms in your input. Getting patterns to match can sometimes be difficult.

The "Simplify trick" that I used in the second example can sometimes overcome this and more likely recognize and deal with simple algebraic manipulations needed when you want to replace a more complicated expression with a simpler expression, but your problem showed me this fails when I tried to use Bx^2+By^2+Bz^2==bsq^2 as the second argument to Simplify. Thus I modified that to make it a two step process, first replace the expression you want to simplify with b and then afterwards replace all instances b with bsq^2, and get it to do what I believe you want. But, as always, using Simplify can sometimes rearrange the result in ways that it thinks is simpler, but that you may not want.

If either of those results are still not what you are looking for then please describe what needs to be done and I will try it again.

We will track this down and correct my mistakes and get this working for you.

I apologize for this not working the first time.

• Thank you a lot, it works perfectiy now. I think the problem i mentioned earlier, where only Bx was was getting replaced by b. Also using Simplify with two equations (both using ==) doesn't work, and I am also not sure if putting anything more complicated than a single variable in lhs of this equation is a good idea. Simplify with one rule and then a substitution (using /. b ->absB^2) does the trick. I also simplified once again at the end with Assumptions -> {absB>0} option which gave me a exactly what I was looking for. Once again, I really appreciate the help. May 17, 2021 at 2:48

I would like to add a few words to the nice answer of @Bill. My point is that one can regard the present question in a broader context.

Namely, often one faces with the necessity to make a replacement in some parts of the expression while avoiding it in other places.

Indeed, the approach Bx -> Sqrt[absB^2 - By^2 -Bz^2] used by OP is what it is usually recommended to do instead of substituting the whole expression. However, as OP mentions it causes some undesired replacements. This is the particular case of the general task I formulated above.

Generally, there may be several approaches to cope with such a task. In the answer of Bill, this task is successfully solved by a careful choice of a corresponding pattern. I would like to write about an alternative approach.

Let us denote the original expression as expr1. I do not repeat it here. One can take it from the text of the question.

One can see that there are two types of expressions to make a replacement. One of them stays in the denominator and has the form Bx^2 + By^2 + Bz^2 while all the others stay in the exponentials or in front of them with the form Sqrt[-Bx^2 - By^2 - Bz^2].

Let us first determine the positions of the former and the latter terms in the original expression:

pos1 = Position[expr1, Bx^2 + By^2 + Bz^2]

(* {{2, 1}}  *)

pos2 = Position[expr1, Sqrt[-Bx^2 - By^2 - Bz^2]]

(* {{3, 2, 2}, {4, 1, 3}, {4, 2, 3}, {4, 3, 2}, {4, 3, 3, 2, 2}, {4, 4,
2}, {4, 4, 3, 2, 2}, {4, 5, 4, 2, 1}, {4, 6, 4, 2, 1}, {4, 7, 3, 2,
1}} *)


and let us join these two lists together:

pos = Join[pos1, pos2];


Now it is possible to map the replacement proposed by OP directly onto the desired terms while leaving all the other terms intact:

expr2 = MapAt[ReplaceAll[#, Bx^2 -> B^2 - By^2 - Bz^2] &, expr1, pos]


To make it better visible on the screen I publish here the output in the form of an image:

In principle, this is what OP wanted to obtain. However, one can advance a step further:

Simplify[expr2, B > 0] /. Bx^2 + By^2 + Bz^2 -> B^2

(*  -((I (Bx^2 + By^2) E^(-I B t) (-1 + E^(2 I B t)))/(2 B^3)) + (
Bz^2 t)/B^2  *)


Done.

I show here a general trick that I have successfully applied in many calculations on rather complex expressions.

Have fun!

• Thank you, great idea. I will try it out and compare it plain substitution, and see which suits the kind of expressions I get better. May 17, 2021 at 2:56

Mathematica's replacement rules rely on matching the exact literal forms. This can make replacing composite variables tricky, since the forms into which Mathematica's interpreter puts them can be different from the forms in which you entered them. To address this, one can "protect" the form of the input expression using Unevaluated, and protect the forms used during the replacment with HoldPattern:

Unevaluated[-((1/(2*(Bx^2 + By^2 +
Bz^2)^2))*(E^(t*(-Sqrt[-Bx^2 - By^2 - Bz^2]))*(-(2*Bx^2*
Bz^2*t*E^(t*Sqrt[-Bx^2 - By^2 - Bz^2])) -
2*By^2*Bz^2*t*E^(t*Sqrt[-Bx^2 - By^2 - Bz^2]) +
Bx^2*Sqrt[-Bx^2 - By^2 - Bz^2]*
E^(2*t*Sqrt[-Bx^2 - By^2 - Bz^2]) +
By^2*Sqrt[-Bx^2 - By^2 - Bz^2]*
E^(2*t*Sqrt[-Bx^2 - By^2 - Bz^2]) -
By^2*Sqrt[-Bx^2 - By^2 - Bz^2] -
Bx^2*Sqrt[-Bx^2 - By^2 - Bz^2] -
2*Bz^4*t*E^(t*Sqrt[-Bx^2 - By^2 - Bz^2]))))]
/. {HoldPattern[Bx^2 + By^2 + Bz^2] -> B^2,
HoldPattern[Sqrt[-Bx^2 - By^2 - Bz^2]] -> Sqrt[-B^2]}