# How do I invoke the default complexity function?

Documentation on ComplexityFunction says:

With the default setting ComplexityFunction->Automatic, forms are ranked primarily according to their LeafCount, with corrections to treat integers with more digits as more complex.

I need to use this default function on its own, not in Simplify or FullSimplify. Can I invoke it from my code?

If no, could you give me a custom function that behaves as close to the default function as possible?

Thanks!

• You could use this as one of your test cases. And then explain to me what's going on :)
– Rojo
May 30, 2013 at 22:42
• Do you mean that you want to know the Complexity as measured by Mathematica of a function? Can you define your own using LeafCount and integer sizes or does it need to be precisely that as defined by Mathematica? May 30, 2013 at 23:16
• The code for the automatic complexity function is listed in the help file for ComplexityFunction reference.wolfram.com/mathematica/ref/ComplexityFunction.html It is the first item under Properties and Relations. May 31, 2013 at 5:26
• @bills nice find. May 31, 2013 at 12:16

The code for the default ComplexityFunction was posted on MathSource a number of years ago by Adam Strzebonski (of Wolfram Research). You will see reference to the original reply from Adam referenced in a MathGroup reply from Andrzej Kozlowski dated 12 Jan 2010 with the subject: "[mg106386] Re : Radicals simplify". I mention all that because I can't get the hyperlink to work (: The code Adam provided is there as well. The implementation from Adam used nested If statements. I can't resist the urge to use Which instead. I give my version below. I don't know for sure that the same function is used, but I have seen no reports indicating that it has changed.

SimplifyCount[p_]:=With[{hd=Head[p]},
Which[
hd===Symbol,1,
hd===Integer,If[p===0,1,Floor[N[Log[2,Abs[p]]/Log[2,10]]]+If[Positive[p],1,2]],
hd===Rational,SimplifyCount[Numerator[p]]+SimplifyCount[Denominator[p]]+1,
hd===Complex,SimplifyCount[Re[p]]+SimplifyCount[Im[p]]+1,
NumberQ[p],2,
]
]

• The automatic function is also provided in the last example of the ComplexityFunction help page. May 31, 2013 at 5:27

This function lives in the system as SimplifySimplifyCount.

• Could you provide some example that supports the case that this is in fact the function used or its equivalent? Jun 1, 2015 at 23:15
• @Mr.Wizard Well, we can see it's presence in top-level code, but unfortunately only parts of Simplify are written in Mathematica. In[12]:= Select[( Unprotect[#]; ClearAttributes[#,ReadProtected]; # -> Count[FullDefinition[#]//ToBoxes,"SimplifySimplifyCount",\[Infinity],Heads -> True] )&/@Join[Names["Simplify*"],Names["SimplifyDump*"]],Last[#]>0&] giving Out[12]= {SimplifyFunctionExpandRules -> 4,SimplifySimplifyCount -> 1,SimplifyDumpConjunctionSimplify -> 2,SimplifyDumpPiecewiseRule -> 4,SimplifyDump$FSTab -> 4} Jun 2, 2015 at 0:31 Based on Vladimirs solution I wanted to post a faster alternative to SimplifyCount which produces the same results as SimplifyCount, but is a factor 3 faster. This can be very significant in case of complicated functions, it is however still significantly slower then Automatic. myNumberComplexity[x_Integer] := If[Positive[x], IntegerLength[x] - 1, IntegerLength[x]] myNumberComplexity[x_Real] := 1; myNumberComplexity[x_Rational] := myNumberComplexity[Numerator[x]] + myNumberComplexity[Denominator[x]] myNumberComplexity[x_Complex] := myNumberComplexity[Re[x]] + myNumberComplexity[Im[x]] myNumberComplexity[x_] := 0; myComplexityFunctionNC[x_] := LeafCount[x] + Plus @@ myNumberComplexity /@ Level[x, {-1}]  It is also possible to increase the speed of SimplifyCount by a factor of two by replacing the sum of the two Ifs after hd===Integer with just this If[Positive[p], IntegerLength[p], IntegerLength[p] + 1]. I must however say that I have my doubts that SimplifyCount is still exactly what is being done in (Full-)Simplify. I have an example were SimplifyCount (or my alternateive) does not produce the same as Automatic. Here the example (which might take a full day (!) with SimplifyCount): $Assumptions = {{a, b, m, s, q, k, x, y, x0, x1, x2, x3,
X} \[Element] Reals , s > 0, b > 0, a > 0};
kuskgaus0b[a_, b_, m_, s_] :=
ProbabilityDistribution[(b*Sqrt[Gamma[3/b]/Gamma[b^(-1)]]*
Piecewise[{{Gamma[
b^(-1), ((a*(-\[FormalX] + m)*
Sqrt[Gamma[3/b]/Gamma[b^(-1)]])/s)^b]/(2*
Gamma[b^(-1)]), a*(\[FormalX] - m) <= 0}},
1 - Gamma[
b^(-1), ((a*(\[FormalX] - m)*Sqrt[Gamma[3/b]/Gamma[b^(-1)]])/
s)^b]/(2*
Gamma[b^(-1)])])/(E^(((\[FormalX] - m)^2*Gamma[3/b])/(s^2*
Gamma[b^(-1)]))^(b/2)*s*
Gamma[b^(-1)]), {\[FormalX], -Infinity, Infinity}]
D[PDF[kuskgaus0b[a, b, 0, 1], x]*x, b] /. b -> 2;
FullSimplify[%, ComplexityFunction -> Automatic] // AbsoluteTiming


And here the result with Automatic:

Piecewise[
{{(x*(Sqrt[2]*a*x*(-3 + EulerGamma + Log[2] + 2*Log[a*x]) + E^((a^2*x^2)/2)*(Sqrt[Pi]*(-2*(1 + x^2*(-3 + EulerGamma + Log[2]) + 2*x^2*Log[x]) +
Erfc[(a*x)/Sqrt[2]]*(1 + EulerGamma*(1 + x^2) + x^2*(-3 + Log[2]) + Log[2] + 2*x^2*Log[x] + 2*Log[a*x])) + MeijerG[{{}, {1, 1}}, {{0, 0, 1/2}, {}},
(a^2*x^2)/2])))/(4*Sqrt[2]*E^(((1 + a^2)*x^2)/2)*Pi), x > 0}},
(x*(a*x*(-6 + 2*EulerGamma + Log[4*a^4*x^4]) - Sqrt[2]*E^((a^2*x^2)/2)*(Sqrt[Pi]*(1 + Erf[(a*x)/Sqrt[2]])*(1 + EulerGamma + (-3 + EulerGamma)*x^2 + x^2*Log[2*x^2] +
Log[2*a^2*x^2]) + MeijerG[{{}, {1, 1}}, {{0, 0, 1/2}, {}}, (a^2*x^2)/2])))/(8*E^(((1 + a^2)*x^2)/2)*Pi)]


And now with SimplifyCount:

Piecewise[{{ComplexInfinity, x == 0},
{(x*(Sqrt[2]*a*x*(-3 + EulerGamma + Log[2] + 2*Log[a*x]) - E^((a^2*x^2)/2)*(-2*Sqrt[2]*a*x*HypergeometricPFQ[{1/2, 1/2}, {3/2, 3/2}, -(a^2*x^2)/2] +
Sqrt[Pi]*x^2*(1 + Erf[(a*x)/Sqrt[2]])*(-3 + EulerGamma + Log[2] + 2*Log[x]) + Sqrt[Pi]*(1 + Erf[(a*x)/Sqrt[2]]*(1 + EulerGamma + Log[2] + 2*Log[a*x])))))/
(4*Sqrt[2]*E^(((1 + a^2)*x^2)/2)*Pi), x > 0}},
(x*(E^((a^2*x^2)/2)*(4*a*x*HypergeometricPFQ[{1/2, 1/2}, {3/2, 3/2}, -(a^2*x^2)/2] - Sqrt[2*Pi]*(1 + (-3 + EulerGamma)*x^2 + x^2*Log[2*x^2] +
Erf[(a*x)/Sqrt[2]]*(1 + EulerGamma + (-3 + EulerGamma)*x^2 + x^2*Log[2*x^2] + Log[2*a^2*x^2]))) + a*x*(-6 + 2*EulerGamma + Log[4*a^4*x^4])))/
(8*E^(((1 + a^2)*x^2)/2)*Pi)]


The differences are the additional Infinity at 0, and the change from MeijerG to HypergeometricPFQ.

• Could you include that example? If it is extremely long perhaps you could put it on pastebin or similar? Jun 2, 2015 at 0:14
• Ok I edited my post to include the results. I do not know where to put the input though, since it is huge. I will see tomorrow where to put it. Jun 2, 2015 at 1:11
• I have managed to strip down the example to something presentable. Have fun Jun 2, 2015 at 8:07

I ended up with this code:

NumberComplexity[x_Integer] := IntegerLength[x];
NumberComplexity[x_Real] := Round[Precision[x]];
NumberComplexity[x_Rational] := NumberComplexity[Numerator[x]] +
NumberComplexity[Denominator[x]];
NumberComplexity[x_Complex] := NumberComplexity[Re[x]] + NumberComplexity[Im[x]];
MyComplexityFunction[x_] := LeafCount[x] +
Total[NumberComplexity /@ Cases[x, _Integer | _Real | _Rational | _Complex, {0, ∞}]];


• You might want to be careful of the Hold attributes of these functions. When you put in, for instance 4000/2000, Mathematica will automatically convert this to 2 before calculating the complexity of the expression in its original form. Try using Trace` to see precisely what is happening. When you ask for improvements, it also depends what you are looking for. You haven't specified precisely what you want so it's hard to recommend improvements. Finally, I would recommend using lower cases for your function names as this avoids accidentally chosing Mathematica's built in functions. May 31, 2013 at 0:45