2
$\begingroup$

Niminize works fine if I copy the minimized function directly by hands, but doesn't work if I try to do something like this:

exp=minimizedExpression;
f[variables_]:=NMinimize[{exp,constraints},{...}]

then it fails.

Particular example:

exp = (-(1/f) - ((1 + a)^(1 + m)
  m x (a + x)^(-1 - m))/λ + (-a + (1 + a)^(
  1 + m) (a + x)^-m)/λ)^2 + (-((3 w)/f) - (
3 (1 + a)^(1 + m) m X (a + X)^(-1 - m))/Λ + (
3 (-a + (1 + a)^(1 + m) (a + X)^-m))/Λ)^2 + (-((
 9 (1 + a)^(1 + m) m z (a + z)^(-1 - m))/Λ) + (
9 (-a + (1 + a)^(1 + m) (a + z)^-m))/Λ - (
9 τ)/
f)^2 + (-((2 (1 + a)^(1 + m) m y (a + y)^(-1 - m))/λ) + (
2 (-a + (1 + a)^(1 + m) (a + y)^-m))/λ - (2 τ)/
f)^2 + (-((
 6 (1 + a)^(1 + m) m Y (a + Y)^(-1 - m))/Λ) + (
6 (-a + (1 + a)^(1 + m) (a + Y)^-m))/Λ - (
6 w τ)/
f)^2 + (-((3 (1 + a)^(1 + m) m Z (a + Z)^(-1 - m))/λ) + (
3 (-a + (1 + a)^(1 + m) (a + Z)^-m))/λ - (3 w τ)/
f)^2 + (-1.` + (x (-a + (1 + a)^(1 + m) (a + x)^-m))/λ + (
2 y (-a + (1 + a)^(1 + m) (a + y)^-m))/λ + (
9 z (-a + (1 + a)^(1 + m) (a + z)^-m))/Λ - (
x + 2 y τ + 9 z τ)/
f)^2 + (-((
 z (-a + (1 + a)^(1 + m) (a + z)^-m))/(Λ (1.` + (
    x + 2 y τ + 9 z τ)/f))) + (
Z (-a + (1 + a)^(1 + m) (a + Z)^-m))/(λ (1.` + (
   3 X + 6 Y τ + 3 Z τ)/f)))^2 + ((
3 Z (-a + (1 + a)^(1 + m) (a + Z)^-m))/λ + (
3 X (-a + (1 + a)^(1 + m) (a + X)^-m))/Λ + (
6 Y (-a + (1 + a)^(1 + m) (a + Y)^-m))/Λ - 
w (1.` + (3 X + 6 Y τ + 3 Z τ)/f))^2

Clear[f$minimize2]
f$minimize2[a_?NumericQ, m_?NumericQ, L_?NumericQ, 
  s_?NumericQ, τNotRationalized_?NumericQ, f_?NumericQ] :=
 TimeConstrained[
  f$minimize2[a, m, L, s, τNotRationalized, f] = Block[
    {list, b, b$1, X, Y, Z, x, y, 
     z, τ = Rationalize[τNotRationalized]},
    b$1 = 
     NMinimize[{exp, 
       X >= 10^-12 && Y >= 10^-12 && Z >= 10^-12 && x >= 10^-12 && 
        y >= 10^-12 && 
        z >= 10^-12 && λ >= 10^-12 && Λ >= 
         10^-12 && w >= 10^-12},
      {X, Y, Z, x, y, z, λ, Λ, w}];
    b = b$1
    ]
  , 1]

f$minimize2[1., 0.25, 1., 0.5, 1., 0.3]
$\endgroup$
2
  • 1
    $\begingroup$ Basically,even the first version of this question showed enough code to exactly reproduce the problem. This might be a question that has already been answered in different flavors on SE, but I think it is a valid question. Unfortunately, the moment I had written my answer, it was closed. Could someone at least mark this as exact duplicate and show the OP a solution? Or reopen it and I post a solution. $\endgroup$
    – halirutan
    May 11, 2015 at 18:23
  • 2
    $\begingroup$ @halirutan It is now open. $\endgroup$
    – rm -rf
    May 11, 2015 at 22:08

1 Answer 1

3
$\begingroup$

You basic problem can be broken down to this simple example

myExpr = m^2;
f[m_] := m*myExpr

f[3]
(* 3*m^2 *)

You can use Trace to see the steps of evaluation, but to cut it short here are the two steps that happen when you call f[3]:

  1. Every occurrence of m in the right side of the definition of f is replaced by 3. This is unfortunately only one occurrence, because when you look at ??f you see that myExpr is still unevaluated.
  2. The body of the definition is evaluated. This is the point, where myExpr is replaced with its actual value. Now, we have another m there, but too late to insert the 3.

Now let's review the error message you get with your particular NMinimize example:

Mathematica graphics

It says

The function value... [now a formula where all are parameters like a and m are still present appear] ...is not a number.

Well, like in the small example above, your parameters were not replaced by the values that you have supplied in your call

f$minimize2[1., 0.25, 1., 0.5, 1., 0.3]

The solution is to insert the body of your exp before the assignment happens and this is the point where I cannot offer a that can directly be understood. You will have to learn about how Mathematica evaluates expressions and which rules it follows.

First solution: Make a pure function where the expression you try to insert is the parameter and directly call this function with your expression:

ClearAll[f]
myExpr = m^2;
(f[m_] := m*#) &[myExpr]

This works because myExpr is evaluated before it is used as argument that is inserted in the body. Therefore, at the place of the #, you full body of myExpr is inserted and not the variable name myExpr.

Another way is to prevent your function definition from evaluation using Hold and replace your expression before you give it free for evaluation (using ReleaseHold). This one is hard to understand, so please read this answer of Leonid carefully.

ClearAll[f]
myExpr = m^2;
Hold[f[m_] := m*placeToInsert] /. 
 placeToInsert :> With[{e = myExpr}, e /; True]
ReleaseHold[%]

Using the first solution on your code gives the answer you want:

ClearAll[f$minimize2]
(f$minimize2[a_?NumericQ, m_?NumericQ, L_?NumericQ, 
     s_?NumericQ, τNotRationalized_?NumericQ, f_?NumericQ] := 
    f$minimize2[a, m, L, s, τNotRationalized, f] = 
     Block[{list, b, b$1, X, Y, Z, x, y, 
       z, τ = Rationalize[τNotRationalized]}, 
      b$1 = NMinimize[{#, 
         X >= 10^-12 && Y >= 10^-12 && Z >= 10^-12 && x >= 10^-12 && 
          y >= 10^-12 && 
          z >= 10^-12 && λ >= 10^-12 && Λ >= 
           10^-12 && w >= 10^-12}, {X, Y, Z, x, y, 
         z, λ, Λ, w}];
      b = b$1]) &[exp]


f$minimize2[1., 0.25, 1., 0.5, 1., 0.3]
(* {4.38851*10^-15, {X -> 0.251408, Y -> 0.251408, 
  Z -> 0.251408, x -> 0.251408, y -> 0.251408, 
  z -> 0.251408, λ -> 0.340737, Λ -> 0.340737, 
  w -> 1.}} *)
$\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.