0
$\begingroup$

I would like to minimize a function, which is supplied as an argument to another function, and report back the estimates of the values of the variables that result in its minimum. In specific, I would like:

y = x^2 - w^2;
fTest[f_] := Module[{w, x}, NMinimize[{f, 1 >= x >= 0, 1 >= w >= 0}, {x, w}]]
fTest[y]

To work the same as:

y = x^2 - w^2;
NMaximize[{y, 1 >= x >= 0, 1 >= w >= 0}, {x, w}]

I think the issue is due to the difference between local and global variables, as I seem to sometimes get the function itself returned, but unevaluated, with the following:

NMinimize[{-w^2 + x^2, 1 >= x$140868 >= 0, 1 >= w$140868 >= 0}, {x$140868, w$140868}]

Suggesting some difference between $w$ and $w\$140868$ for example.

I have seen this answer: Pass function or formula as function parameter and have tried setting the 'HoldAll' attribute of the function itself, but to no avail. Not convinced this is the right approach either!

Does anyone know how I can get around this issue properly?

Note: I could not declare the local variables in my Module declaration, (referring hence to global variables in its body), but I find this a bit messy, and would like a cleaner way.

Best,

Ben

$\endgroup$
  • $\begingroup$ Remove the Module[{w,x}, ...] scoping construct .... $\endgroup$ – Dr. belisarius Feb 25 '15 at 0:36
  • 1
    $\begingroup$ y[x_, w_] := x^2 - w^2; fTest[f_] := NMinimize[{f[x, w], 1 >= x >= 0, 1 >= w >= 0}, {x, w}];fTest[y] $\endgroup$ – Dr. belisarius Feb 25 '15 at 0:37
  • $\begingroup$ @belisarius - thanks for your comment. However, I need to keep the Module scoping construct, as the particular function I am applying this to is quite a bit more complex in reality. Is there a workaround here? Best, Ben $\endgroup$ – ben18785 Feb 25 '15 at 0:43
  • 1
    $\begingroup$ But you can always remove the {x,w} vars from the Module[{xxx} ,] part. That is the easiest solution $\endgroup$ – Dr. belisarius Feb 25 '15 at 0:45
  • 1
    $\begingroup$ Oh, there are! "Global`x" is the easiest. $\endgroup$ – Dr. belisarius Feb 25 '15 at 1:12
1
$\begingroup$

Not sure if this help or not but you can try it:

fTest[f_, variables_] := 
 Module[variables, NMinimize[{f, 1 >= x >= 0, 1 >= w >= 0}, {x, w}]]

ans=fTest[y, {x, w}]

(*1., {x$8300 -> 0., w$8300 -> 1.}}*)

The easiest way I found is as follows:

ToExpression[StringReplace[ToString[ans], "$" :> "+0*"]]

(*{-1., {x -> 0., w -> 1.}}*)
$\endgroup$
  • $\begingroup$ that's a great idea. Thanks for that! Much appreciated. Best, Ben $\endgroup$ – ben18785 Feb 25 '15 at 1:09
  • $\begingroup$ Is there a way to associate the x$8300 with the global x? No worries if it's just the case of setting x=x$8300! Just wondered if there was a neater way. Best, Ben $\endgroup$ – ben18785 Feb 25 '15 at 1:12
  • 1
    $\begingroup$ I don't know straightforward answer but it can be done long way. if you wish I can add it in the answer. $\endgroup$ – Algohi Feb 25 '15 at 1:17
  • $\begingroup$ Don't worry - it's not too important for me. Thanks again! Best, Ben $\endgroup$ – ben18785 Feb 25 '15 at 1:18
0
$\begingroup$

Module is not necessary here, and is in fact the source of the problem:

fTest1[f_] := Module[{w, x}, NMinimize[{f, 1 >= x >= 0, 1 >= w >= 0}, {x, w}]]
fTest2[f_] := NMinimize[{f, 1 >= x >= 0, 1 >= w >= 0}, {x, w}]

fTest1[x^2 - w^2]
(* NMinimize::nnum errors and NMinimize[___] *)
fTest2[x^2 - w^2]
(* {-1., {x -> 0., w -> 1.}} *)

Basically, the Module localizes instances of w and x inside it: the ones in the constraints and the list of variables. However, the instances inside f are not localized, since they are defined outside of the Module! You can see this in the output, where the localized and non-localized forms are co-mingled.

The reason Module is not necessary here is that no definitions are ever associated to x and w. NMinimize essentially does it's own localization of the variables.

$\endgroup$

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.