12
$\begingroup$

It appears that, counter to my expectation, all of these (and probably many others) seem to work fine:

Plot[Hold[x], {x, 0, 10}]

FindRoot[Hold[x^2 == 2], {x, 1}]

NMinimize[Hold[x^2], x]

I would expect Plot or NMinimize to complain that e.g. Hold[0] is not a number.

These were mentioned a few times on this site but didn't get any attention: (1) (2).

Doing this does appear to solve problems which would normally require _?NumericQ.

Is this usage of Hold supported? Is it meant to work this way, does it work by design, or is it accidental?

My guess is that these work accidentally because these functions use ReleaseHold internally.

$\endgroup$
4
  • 2
    $\begingroup$ NMinimize[Hold[Print["hi"]; x^2], x] causes my kernel to crash. NMinimize[Hold[x]^2, x] complains and NMinimize[Hold@Hold[x^2], x] works; however, NMinimize[Hold@Hold@Hold[x^2], x] does not. I suppose it could be ReleaseHold, but not in the ordinary way. $\endgroup$
    – Michael E2
    Mar 4, 2014 at 0:09
  • 1
    $\begingroup$ @MichaelE2 That pretty much settles that this is not supported functionality. I think it is good to have this information in a Q/A. You could consider answering. $\endgroup$
    – Szabolcs
    Mar 4, 2014 at 0:12
  • $\begingroup$ I would absolutely agree with your guess that it is the internal handling of evaluation control which make these work accidentially. The question remains whether that indicates that these internally do more ReleaseHolds than necessary and whether that is intended or a lack of attention. In any case it seem to not cause much problems, I think? $\endgroup$ Mar 4, 2014 at 10:41
  • $\begingroup$ I noticed this a while ago and suspected it to be due to the behavior of the Experimental`NumericalFunction, which is definitely used by NMinimize and probably by the others. But I don't really know anything about this undocumented function and so can't elaborate further. $\endgroup$ Mar 4, 2014 at 23:50

1 Answer 1

9
$\begingroup$

I took a rather shotgun approach to the question and got a range of behaviors. The range is rather confusing, so I agree with Szabolcs's conclusion that using Hold this way is not supported.

First, NMinimize[Hold[Print["hi"]; x^2], x] prints "hi" and then crashes the kernel, while NMinimize[Print["hi"]; x^2, x] prints "hi" and returns {0., {x -> 0.}}.

Next consider the sequence

NMinimize[x^2, x]                  (* -> {0., {x -> 0.}} *)
NMinimize[Hold[x^2], x]            (* -> {5.55112*10^-17, {x -> -7.45058*10^-9}} *)
NMinimize[Hold@Hold[x^2], x]       (* -> {5.55112*10^-17, {x -> -7.45058*10^-9}} *)
NMinimize[Hold@Hold@Hold[x^2], x]  (* -> NMinimize::nnum error *)

as well as

NMinimize[Hold[x]^2, x]            (* -> NMinimize::nnum error *)

One or two Holds prevent symbolic analysis but allow the numeric function to be evaluated. You have to really, really Hold the argument to stop evaluation. A Hold inside the function is not released, so it is not a simple application of ReleaseHold to the argument that allows minimization of Hold[x^2].

With Plot, you have to wrap the function five times with Hold to stop the function from being plotted. FindRoot behaves similar to NMinimize, except that it does not crash the kernel.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.