# Identify complex expression and replace

I'm having trouble finding a way (if there is) to analyse an expression, identify a complex pattern in it and then replace it with another thing. I think it will be easier to explain my problem with the code.

I have these expressions for mx and my:

mz = MZ[x, y, t];
ang = ANG[t];
mzX = D[mz, x];
mzY = D[mz, y];
mod = Sqrt[(1 - mz^2)/(mzX^2 + mzY^2)];
mx = mod (Cos[ang] mzX + Sin[ang] mzY);
my = mod (-Sin[ang] mzX + Cos[ang] mzY);


I calculate the derivative of mx with respect to t, which yields a very complicated expression:

deriv = D[mx, t] I want to identify the parts of it matching the definitions for mx and my. That may involve regrouping terms, distributing products, etc. And then, I want to replace those parts with "mx" and "my" to get an expression simpler to the eye. Note that FullSimplify does not achieve what I need.

Some thoughts. First, you may eliminate terms with sin and cos from mx and my:

scsols=Solve[({mx, my} /. {Sin[ANG[t]] -> s, Cos[ANG[t]] -> c}) == {Mx,
My}, {c, s}] // FullSimplify//First


I introduced new Mx and My, they are labels for mx and my respectively. Next you make the same substitution of sin and cos into deriv and then substitute scsols into the result:

deriv /. {Sin[ANG[t]] -> s, Cos[ANG[t]] -> c}/.scsols//FullSimplify


This gives some expression including Mx (=mx) and My (=my) and other derivatives of MZ and ANG:

Maybe this is somehow "simpler to the eye.

You could do it semi-manually:

MYoverMOD = (-Sin[ang] mzX + Cos[ang] mzY);
MXoverMOD = (Sin[ang] mzY + Cos[ang] mzX);
modSquared = (1 - mz^2)/(mzX^2 + mzY^2);
deriv = D[mx, t];
deriv /. {modSquared -> MOD^2, MXoverMOD -> MX/MOD};
Simplify[%, Assumptions -> MOD > 0];
% /. MYoverMOD -> MY/MOD Here MOD $$\equiv$$ your mod, MX $$\equiv$$ your mx, and MY $$\equiv$$ your my.

If the subexpression appears several times, it can be a time-saver to use the simple substitution syntax.

For some reason I wasn't able to replace MOD directly (the square root symbol interferes), so I had to replace the expression under the square root with MOD^2, which gave Sqrt[MOD^2]. I then converted that to MOD using Simplify. I also had to do it in two steps to get the expression in a form that allowed MY to be substituted.

You might want to look at ExperimentalOptimizeExpression. So if you run ...

 ExperimentalOptimizeExpression[D[mx, t], "OptimizationSymbol" -> z]


You get what essentially involves a program that finds subexpressions that occur frequently in your program and recursively builds a formula out of them. It will not solve all of the issues you raise, but I suspect it will help.