How to build private function with built-in function's option
New analysis (in v10.1)
For your newly stated goal:
If I don't want to build a new function.I just wanna change the
GeneralUtilities`BenchmarkPlot
's default option into{"IncludeFits" -> True, "Models" -> Automatic, TimeConstraint -> .8}
. ... Can it be implemented?
The standard options model in Mathematica means that this should work:
Options[BenchmarkPlot] =
{TimeConstraint -> 8, MaxIterations -> 1024,
"IncludeFits" -> True, "Models" -> Automatic};
It does not however. That means that BenchmarkPlot
or one of its subordinate functions is not written correctly. Let's have a look. Using PrintDefinitions
from the same package we find that our code will call
GeneralUtilities`Benchmarking`PackagePrivate`plot
Which has the definition (contexts omitted):
plot[data_Association, opts___Rule] :=
ListLogLogPlot[
Sequence @@
addfits[data,
Lookup[{opts}, "Models", Automatic],
MemberQ[{opts}, "IncludeFits" -> True]],
FilterOptions[opts],
PlotLegends -> fstyle[Keys[data]], GridLines -> Automatic,
PlotMarkers -> {$pmarker}, GridLinesStyle -> Opacity[0.05`],
AxesLabel -> {"n", "time (s)"}, ImageSize -> Medium, PlotRangeClipping -> True,
Mesh -> False,
PlotRange -> {Full,
With[{v = Values[data][[All, All, 2]]}, {LogFloor[Min[v]]*1.1`^(-1),
LogCeiling[Max[v]]*1.1`}]}];
Please draw your attention to the line MemberQ[{opts}, "IncludeFits" -> True]
and note that here opts
is the pattern that will match explicit options given to this function and nothing else. BenchmarkPlot
does not pass all options to this function either. This means that only explicit appearences of "IncludeFits"
will have effect. (Likewise for "Models"
from the line above.)
To correct this we either need to expressly pass all of Options[BenchmarkPlot]
to this inner plot
function, or we need to modify plot
so that it considers Options[BenchmarkPlot]
. I'll do the latter.
<< "GeneralUtilities`"
With[{plot = GeneralUtilities`Benchmarking`PackagePrivate`plot},
PrependTo[DownValues[plot],
HoldPattern[plot[arg___]] :>
Block[{$fixGUBPopts = True},
plot[arg, Sequence @@ Options[BenchmarkPlot]]
] /; ! TrueQ[$fixGUBPopts]
]
];
Options[BenchmarkPlot] =
{TimeConstraint -> 8, MaxIterations -> 1024,
"IncludeFits" -> True, "Models" -> Automatic};
BenchmarkPlot[{SortBy[#, Identity] &, Sort}, Range]
Old answer
I wrote a fairly lengthy answer hoping to guide just this sort of thing; please take a look:
- Functions with Options
From your comment
But
Options[myBen4]
get{}
. I hope it can get all options. Can it be implement?
I think you want something like this.
Options[myBen] = {"IncludeFits" -> True, "Models" -> Automatic,
TimeConstraint -> .8};
myBen[args__, opts : OptionsPattern[]] :=
BenchmarkPlot[args, opts, Sequence @@ Options[myBen]]
myBen[{SortBy[#, Identity] &, Sort}, Range]
(source: clouddn.com)
And it meet the extra need:
Options[myBen]
{"IncludeFits"->True,Models->Automatic,TimeConstraint->0.8}
Including the options in the definition of your auxiliary function seems to work fine:
myBen3[x__, opt : OptionsPattern[]] :=
GeneralUtilities`BenchmarkPlot[x, opt, "IncludeFits" -> True]
Above I left off the TimeConstraint
option from the definition on purpose, because I wanted to showcase the fact that the helper function still correctly passes on extra options to BenchmarkPlot
. Compare for instance:
myBen3[{SortBy[#, Identity] &, Sort}, Range, TimeConstraint -> 0.3]
myBen3[{SortBy[#, Identity] &, Sort}, Range]
So a more complete definition would be:
myBen4[x__, opt : OptionsPattern[]] :=
GeneralUtilities`BenchmarkPlot[x, opt, "IncludeFits" -> True, TimeConstraint -> 8]