2
$\begingroup$

I have a large package of Mathematica routines for magnetic resonance simulations.They work great but there is one problem I just cannot crack. It boils down to the following problem: suppose there is a routine that evaluates to a real numeric value if it has a numerical argument, but to something else if the argument is not numeric. As a demonstration example, consider this function:

g[x_?NumericQ] := Cos[x] 
g[x : Except[_?NumericQ]] := $Failed

I would expect FindMaximum and similar routines to pass a numerical value to the function, so that this behaves just like Cos. However, it doesn't work:

FindMinimum[g[x], {x, 0.5}]

During evaluation of In[37]:= FindMinimum::nrnum: The function value $Failed is not a real number at {x} = {0.5}.

FindMinimum[g[x], {x, 0.5}]

Of course my real example is much more complicated, but this demonstrates the problem. Why does this behaviour happen, and what can be done to get round it?

$\endgroup$
  • 2
    $\begingroup$ You do not need the second definition that returns $Failed to ensure that the function will only attempt to evaluate on numerical values.. If you remove it, everything works. $\endgroup$ – MarcoB Aug 24 '18 at 16:23
  • 1
    $\begingroup$ @MarcoB The OP has defined the function in the manner shown to simulate his real life code. $\endgroup$ – Jack LaVigne Aug 24 '18 at 19:23
  • $\begingroup$ What can be done: define a new function which does not evaluate for non-numeric arguments. f[x_?NumericQ] := g[x]. If g[x] immediately evaluates to $Failed, then FindMinimum will only see $Failed. The expression passed to FindMinimum must evaluate to a number after doing an expr /. x -> number type replacement on it. Let me know if you still have questions after this explanation. $\endgroup$ – Szabolcs Sep 3 '18 at 6:54
2
$\begingroup$

The work around is to put a wrapper around your magnetic resonance function which you are emulating with g[x].

g[x_?NumericQ] := Cos[x]
g[x : Except[_?NumericQ]] := $Failed

Incidentally the reason you are experiencing this problem can be found in the documentation for FindMinimimum

FindMinimum first localizes the values of all variables, then evaluates f with the variables being symbolic, and then repeatedly evaluates the result numerically.

The new function is:

gN[x_?NumericQ] := g[x]

and this will work fine.

FindMinimum[gN[x], {x, 0.5}]
(* {-1., {x -> 3.14159}} *)
$\endgroup$
  • $\begingroup$ This is, in my opinion, entirely equivalent to removing the .. Except[ definition in the original definition, only unnecessarily convoluted. $\endgroup$ – MarcoB Aug 24 '18 at 21:13
  • $\begingroup$ OK, thanks, I get the idea. This definitely gives me something to go on. $\endgroup$ – MalcolmHLevitt Aug 25 '18 at 20:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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