Original: Is there any way to control Mathematica's inner simplification algorithm? I have seen several instances where FullSimplify does not yield the most optimal solution but instead gets stuck in a local minimum. I can provide with some examples if needed.
Edit: Here are some details of the most recent place I stumbled into this:
So I am defining a derivative operator, myD, such that:
myD[x_?NumericQ*y_] := x myD[y];
myD[x_?NumericQ] := 0;
i.e. If myD acts on a scalar*something he will take the scalar outside, and if myD acts on a scalar, the output will be 0. Then, to impose linearity I impose the two following transformation functions:
myDSumTransform[x_?(MatchQ[#, myD[a_]] &)] :=
(x /. (myD[HoldPattern[Plus[y__]]] :> Plus @@ (myD /@ List[y])));
myDSumTransformInverse[x_?(MatchQ[#,Optional[a_?NumericQ] myD[b_] + Optional[c_?NumericQ] myD[d_]] &)] :=
(x /. Optional[e_?NumericQ, 1] myD[f_] + Optional[g_?NumericQ, 1] myD[h_] :> myD[e f + g h]);
The first transformation equation takes myD[a+b+c+...] and maps it into myD[a] + myD[b] +...
The second transformation takes a myD[b] + c myD[d] and maps it into myD[a b + c d].
Now I define myFullSimplify based on FullSimplify, using TransformationFunctions, such that:
$transfFunctions ={};
addToTransfFunctions[rules__]:=AppendTo[$transfFunctions, #]&/@List[rules];
myFullSimplify[expr_]:=FullSimplify[expr,TransformationFunctions->Flatten[{Automatic, $transfFunctions}]];
addToTransfFunctions[myDSumTransform, myDSumTransformInverse];
Alright, now comes the example. Take:
myD[a + b + c + 5]//myFullSimplify
The expected output would be
myD[a + b + c]
However what I get is
myD[a + b + c + 5]
My understanding is that the FullSimplify algorithm takes myD[a+b+5] applies myDSumTransform, arrives at myD[a] + myD[b] + myD[c], finds that the LeafCount is bigger, fiddles a bit with it to no avail and rejects the output. To get to the desired output, he would need to apply myDSumTransformInverse, two times and arriving at
myD[a + b + c]
If I try something a little less complex, e.g.
myD[a + b + 5 ] // myFullSimplify
I get myD[a+b] as expected.
So I guess what really need is to increase Mathematica's persistence setting, or to find a smarter way to write myDSumTransformInverse.
Sorry for the convoluted question, I understand it a complex example, but I am not sure if there is a systematic way to deal with these issues. Hence, it would be nice to have some guidance on how to proceed here.
Thanks in advance for all the help!
TransformationFunctionsandComplexityFunction? – Michael E2 Feb 04 '21 at 23:56ComplexityFunctionworks can be found here FullSimplify does not work on this expression with no unknowns. – Artes Feb 05 '21 at 00:26myDSumTransformInverse[myDSumTransform[myD[a + b + c + 5]]]-- I don't think it's doing what you want. – Michael E2 Feb 05 '21 at 15:22myDSumTransformInverse[myD[a] + myD[b] + myD[c]]. That is because I only know how to input 2 terms to myDSumTransformInverse. But Mathematica's FullSimplify should try to evaluate each Leaf ofmyD[a] + myD[b] + myD[c]against all the TransformFunctions, and hence he would eventually evaluate two at a time. Any clue how to write myDSumTransformInverse such that it may take more 3 or more terms as input? Thanks! – Filipe Miguel Feb 05 '21 at 15:33myDSumTransformInverse = Thread[#, myD] &is what you want. I'm not sureFullSimplifytries to transform each subset of terms of a sum. I think unfortunately, you will have to add a transformation function likemyDSumTransformInverse@*myDSumTransformto the mix to get it over the hump into a new minimum. – Michael E2 Feb 05 '21 at 15:39myDSumTransformInverse:ClearAll[linearCombine]; Module[{f}, SetAttributes[f, NumericFunction]; constantQ = NumericQ[# /. s_Symbol /; MemberQ[Attributes[s], Constant] :> f[0]] & ]; linearCombine[ e_Plus, head_, constants_List : {} ] := Block[{head}, Block[constants, SetAttributes[#, Constant] & /@ constants; head@Replace[e, {c_?constantQ*head[a_] :> c*a, head[a_] :> a}, 1 ] /; MatchQ[e, _[((_?constantQ)*_myD | _myD) ..]] ]];– Michael E2 Feb 05 '21 at 18:23linearCombine[myD[a] + 2 Sqrt[2] myD[b] + 3 E myD[c], myD]– Michael E2 Feb 05 '21 at 18:24