See this answer for a more general discussion.
Rule based solution:
If a direct substitution does not work you can make the substitution more obvious for Mathematica by picking out a simpler sub-expression that is clearly present and doing a substitution with that sub-expression:
So instead of
2*A1^2 + A1*B2 + 2*B1^2 - B1*A2 + 2*C1^2 + C1*D2 + 2*D1^2 - D1*C2 /. A1^2+B1^2 + C1^2 + D1^2 -> h1^2 /. A1*B2 - B1*A2 + C1*D2 - D1*C2 -> h12
where A1^2+B1^2 + C1^2 + D1^2 is not explicitly present you can use
2*A1^2 + A1*B2 + 2*B1^2 - B1*A2 + 2*C1^2 + C1*D2 + 2*D1^2 - D1*C2 /. A1^2 -> h1^2 - (B1^2 + C1^2 + D1^2) /. A1*B2 - B1*A2 + C1*D2 - D1*C2 -> h12 // Simplify
In general if you would like to substitute a composite expression to a new variable, that is,
BigExpression /. CompositeExpression-> NewVariable
and the original expression (BigExpression in the example above) does not make the substitution obvious for Mathematica, you can instead pick out a simpler term in CompositeExpression and rewrite the substitution in terms of the simpler expression like in the above example.
Ok, but how to automatize this ?
Simplify
The answer provided by @Nasser is one possibility although I wonder whether the overhead of Simplify might take a long time with a BigBigExpression.
Reduce
The answer provided in the link above gives a lot of possibilities. Here is one of them adapted to the problem at hand:
Refine[Reduce[{p == 2*A1^2 + A1*B2 + 2*B1^2 - B1*A2 + 2*C1^2 + C1*D2 + 2*D1^2 - D1*C2, A1^2 + B1^2 + C1^2 + D1^2 == h1^2, A1*B2 - B1*A2 + C1*D2 - D1*C2 == h12}, {p}, {A1, B1, A2, B2, C1, D1, C2, D2}], {h12 != 0, h1 != 0}]
output: (* p == 2 h1^2 + h12 || p == 2 h1^2 + h12 *)
Edit: You could use Variables in the above code instead of making the list of variables by hand.
You can then extract the expression by adding //First //Last to the expression above.
Eliminate
A faster method from the above link uses Eliminate. For your example you can use:
Eliminate[{p == 2*A1^2 + A1*B2 + 2*B1^2 - B1*A2 + 2*C1^2 + C1*D2 + 2*D1^2 - D1*C2, A1^2 + B1^2 + C1^2 + D1^2 == h1^2, A1*B2 - B1*A2 + C1*D2 - D1*C2 == h12}, {A1, B1, A2, B2, C1, D1, C2, D2}]
output: (* -2 h1^2 + p == h12 *)
You can obtain the expression for p by using SolveValues
First@SolveValues[-2 h1^2 + p == h12, p]
output: 2 h1^2 + h12
BenchMarks
It is likely that the comparison of timings will change if the expression is more complicated.
I did not try the method using Solve from the first link above.
I used RepeatedTiming.
Simplify: 0.000695496 s
Rule: 0.0000197091 s
Reduce: 0.0833688 s
Eliminate: 0.00161821 s
Edit
I got interested in how these methods compare when the expression is more complicated. Hence, I used AntiSimplify from the resource functions. I was unable to use it with RessourceFunction so I installed it as a package.
original expression:
s = 2*A1^2 + A1*B2 + 2*B1^2 - B1*A2 + 2*C1^2 + C1*D2 + 2*D1^2 - D1*C2
anti-simplified expression (note I installed the package from the Author's note to use AntiSimplify):
s2 = AntiSimplify[s, A1^2 + B1^2, "Complexity" -> 3]
output:
Cos[49/3 (17576/125 - (8619 A1^2)/175 + (11271 A1^4)/1960 - ( 4913 A1^6)/21952 - (8619 B1^2)/175 + (11271 A1^2 B1^2)/980 - ( 14739 A1^4 B1^2)/21952 + (11271 B1^4)/1960 - (14739 A1^2 B1^4)/ 21952 - (4913 B1^6)/21952 - (26/5 - 17/28 (A1^2 + B1^2))^3) Sin[ Cosh[Sin[A1^2 + B1^2]]]] (-(56/9) Cos[A1^2 + B1^2]^2 Cos[ 1/2 (29791/343 - (1922 A1^2)/735 + (124 A1^4)/4725 - (8 A1^6)/ 91125 - (1922 B1^2)/735 + (248 A1^2 B1^2)/4725 - ( 8 A1^4 B1^2)/30375 + (124 B1^4)/4725 - (8 A1^2 B1^4)/30375 - ( 8 B1^6)/91125 - (31/7 - 2/45 (A1^2 + B1^2))^3 + \[Pi])]^4 + (2 A1^2 - A2 B1 + 2 B1^2 + A1 B2 + 2 C1^2 - C2 D1 + 2 D1^2 + C1 D2) Cos[ 9/32 (13824/6859 + (27648 A1^2)/15523 + (18432 A1^4)/35131 + ( 4096 A1^6)/79507 + (27648 B1^2)/15523 + (36864 A1^2 B1^2)/ 35131 + (12288 A1^4 B1^2)/79507 + (18432 B1^4)/35131 + ( 12288 A1^2 B1^4)/79507 + (4096 B1^6)/ 79507 - (24/19 + 16/43 (A1^2 + B1^2))^3) (1 + Sinh[Cosh[A1^2 + B1^2]])])
Check:
Simplify[s - s2]
output: 0
Reduce took too long no matter the option I chose for "Complexity" in AntiSimplify.
The rule based method is fast but it was unable to obtain the desired expression as the rule has to be applied differently at different parts.
Thus the last two contenders are Simplify and Eliminate (I did not try with Solve). Who will win ?
(I used AbsoluteTiming and both methods gave the same output)
Simplify: 0.087227 s
Eliminate: 0.00586 s
Note: Using Simplify a second time reduced the timing. Does Simplify save information ? Perhaps the repeated timing before was not a good choice.
Editbutton under your post and format as code using the{ }icon in the Edit window. Thanks. $\endgroup$