The function value is not a real number

I am trying to use the method of moments to fit parameters to a distribution. This involves minimizing a function. This certainly gives real numbers, but FindMinimum gives an error message saying that the function value is not a real number at the starting values that I have chosen. I wondered if the StackExchange community might be able to identify what I am doing wrong or how I could solve this problem.

I've looked at answers to similar questions but they do not seem directly applicaable. I undertake to attempt to answer other peoples' questions.

The code is as follows:

a = 0;
b = 2;
c = -3;
d = 10;

funMomIT[Mu_Real,Sigma_Real,Nu_Real,Tau_Real] := (locdist = 
 TransformedDistribution[Mu + Log[x]*Sigma, 
x~BetaPrimeDistribution[Nu,Tau]]; 
 m1 = Moment[locdist, 1]; m2 = Moment[locdist, 2]; 
 m3 = Moment[locdist, 3]; 
 m4 = Moment[locdist, 4]; (m1 - a)^2 + (m2 - b)^2 + (m3 - c)^2 + (m4 - d)^2)

I've used a single tilde ~ instead of the correct double tilde for typesetting reasons.

When I type

FindMinimum[funMomIT, {{Mu, 1.0}, {Sigma, 0.0}, {Nu, 0.5}, {Tau, 0.5}}]

I get the message:

FindMinimum::nrnum: The function value findMomIT is not a real number 
 at {Mu,Sigma,Nu,Tau} = {1.,0.,0.5,0.5}. >>

But when I evaluate the function,

funMomIT[1.0, 0.0, 0.5, 0.5]

I get the value 99.

Plainly, then, the function is producing a real number at the evaluated point. Can anyone suggest what is going wrong here?

Note that I've tried different formulations, such as using a Module to run the function and evaluating the theoretical moments separately and then substituting them into the Module. These suffer from the same problem.

And I've also tried NMinimize. Same error message.

By the way, I'm aware of the function FindDistributionParameters. This is also failing for the MLE and various MoMs.

Updated: page 5 of the following paper gives formulae for the first four moments of the above distribution, and this appears to enable rapid solution (though this needs to be done by least squares). I'm still puzzled though why Mathematica is producing these errors on functions which are clearly producing real solutions.

"Some Flexible Parametric Models for Partially Adaptive Estimators of Econometric Models" by Theodossiou, Panayiotis; McDonald, James B.; Hansen, Christian B.

Also, to update on the problems with FindDistributionParameters, if one uses the method of moments, and does not restrict the number of moments considered, one gets an error message that the equations for solving the method of moments are not consistent. If one restricts it to the first four parameters, Mathematica gives an error message that the parameters to be estimated are not the same as the parameters in the Method of Moments.

The function value is not a real number
Message Boards

176995 Views

|

6 Replies

|

6 Total Likes

|

Dear Community,

I am just new to Mathematica that came with my Raspberry Pi2. For a while now I have been looking for a program, which is able to minimize a discontinuous and nonlinear problem. Up to now I created the following formulas:

f1[x_] := 
 Piecewise[{{0.00000000000252413096488599 x^4 - 
     0.0000000295981935774312 x^3 + 0.0001268180409138660 x^2 - 
     0.239339875030011 x + 368.934089585833, x > 0}, {0, x <= 0}}]

f2[x_] := 
 Piecewise[{{0.00000000000327848026710691 x^4 - 
     0.0000000379764365996404 x^3 + 0.0001584280843487410 x^2 - 
     0.284905693712486 x + 386.639837124850, x > 0}, {0, x <= 0}}]

f3[x_] := 
 Piecewise[{{0.00000000000273770414832564 x^4 - 
     0.0000000245466477791088 x^3 + 0.0000876247218487314 x^2 - 
     0.151272246878742 x + 298.178569447775, x > 0}, {0, x <= 0}}]

f4[x_] := 
 Piecewise[{{0.00000000000151824463118546 x^4 - 
     0.0000000164748347339070 x^3 + 0.0000716029554621768 x^2 - 
     0.140270401260495 x + 293.998348739492, x > 0}, {0, x <= 0}}]

NMinimize[{f1[w] + f2[x] + f3[y] + f4[z], 
  Plus[w, x, y, z] == 7000}, {w \[Element] Interval[{0, 4000}], 
  x \[Element] Interval[{0, 4000}], y \[Element] Interval[{0, 3000}], 
  z \[Element] Interval[{0, 3000}]}]

Unfortunately now I get the following error messages three times before the calculation is aborted:

During evaluation of In[8]:= NMinimize::nnum: The function value {812.066} is not a number at {Subscript[w, 1],Subscript[x, 1],Subscript[y, 1],Subscript[z, 1]} = {1052.02,1848.71,2479.67,1619.59}.

Is there any quick way of resolving this issue? Did I enter something in a wrong way? At least the sum of the resulting values for w,x,y, and z being 7000 is correct, maybe 812,066 is a local minimum already. But why is there an error message? I also tried to use Minimize and different Methods, but the outcome is the same in all cases.

And it is just a LOCAL minimum: As one might be able to see from the equation, fx[0]=0. A minimum value, f.e. for the entered w+x+y+z==7000, should incorporate that some of the functions are set to zero! Is there any way to include this possibility in a fast way? Or do I have to write a minimization for all 16 possibilities and minimize these again?

Best regards, Peter

    • Reply
    • |
    • Flag

    This works without error

    In[6]:= NMinimize[{f1[w] + f2[x] + f3[y] + f4[z], {w + x + y + z == 7000,
       0 <= w <= 4000, 0 <= x <= 4000, 0 <= y <= 3000, 0 <= z <= 3000}}, {w, x, y, z}]
    
    Out[6]= {793.412, {w -> 1829.54, x -> 1709.12, y -> 1791.87, z -> 1669.47}}
    

    For this problem this happens to find a smaller minimum

    In[7]:= NMinimize[{f1[w] + f2[x] + f3[y] + f4[z], {w + x + y + z == 7000,
       0 <= w <= 4000, 0 <= x <= 4000, 0 <= y <= 3000, 0 <= z <= 3000}}, {w, x, y, z}, 
       Method -> "RandomSearch"]
    
    Out[7]= {583.291, {w -> 2153.49, x -> 0., y -> 2663.08, z -> 2183.44}}
    

    And this finds an even smaller minimum.

    In[8]:= NMinimize[{f1[w] + f2[x] + f3[y], {w + x + y == 7000, 
       0 <= w <= 4000, 0 <= x <= 4000, 0 <= y <= 3000}}, {w, x, y}, 
     Method -> "RandomSearch", MaxIterations -> 10^4]
    
    Out[8]= {384.535, {w -> 4000., x -> 0., y -> 3000.}}
    

    I suspect almost any minimization method is going to have problems where some or all your functions have smoothly growing very large values adjacent to isolated points where the functions are much smaller. So if you have functions like that then I suspect that your idea of checking all the isolated points, in addition to using a general minimization method, might be the best approach.

      • Reply
      • |
      • Flag

      This is great, Bill, thanks a lot! Is there any Explanation for this behavior? Just want to be able to avoid this in the future...

        • Reply
        • |
        • Flag

        Realize the software has no "sense", it doesn't look at your problem, perhaps graph it, think a bit and realize it should check all the boundaries, just in case.

        Without the Method -> "RandomSearch" it (mostly) looks at some how the values are changing in the immediate neighborhood of some point, calculates in which direction the function is decreasing most rapidly, steps off in that direction by some distance and does this all over again. After repeating this again and again it finds itself in a place where everywhere around it the function is either the same or even increases and it declares that it is done.

        With the Method -> "RandomSearch" it (mostly) throws a dart up in the air, goes over and measures the function at that point, if it is smaller than that last best value it keeps this as the new last best value. After a while it doesn't find any better last best values and declares that it is done.

        Now imagine in the vast space that your function covers you have one or a few places where the function grows to a very high sharp peak, except at exactly those peaks you have drilled a deep hole of infinitely small diameter.

        Without the Method -> "RandomSearch" the software will attempt to run down hills and get far away from peaks. It will not "think" I am going up this peak and making this worse and worse, but I suppose I should keep making it worse, even though you just asked me to minimize this, just in case I find something better up there.

        With the Method -> "RandomSearch" there is almost no chance your dart will happen to hit that infinitely small diameter hole in the vast space of your function.

        You, on the other hand, can think and realize that your problem includes special cases at the boundaries where your function is not "smooth" and you can check all the special points.

          • Reply
          • |
          • Flag

          Hi Bill, thanks for this very visual explanation! But the meaning of the RandomSearch Method was relatively clear for me. I should have staded my question more precisely, because I referred to writing the constraints with 0<=x<=4000 instead of using intervals or something like x,y,z >=0 and x,y<=3000, which I had before and also resulted in the same error message...?

            • Reply
            • |
            • Flag

            I edited the problem and get pretty good results with:

            f[reqpower_] := MininmalBy[{
              Check[NMinimize[{ae1[w], {w == reqpower, 0 <= w <= maxae1}}, {w}, 
                Method -> "RandomSearch"], 999999],
              Check[NMinimize[{ae2[x], {x == reqpower, 0 <= x <= maxae2}}, {x}, 
                Method -> "RandomSearch"], 999999],
              Check[NMinimize[{ae3[y], {y == reqpower, 0 <= y <= maxae3}}, {y}, 
                Method -> "RandomSearch"], 999999],
              Check[NMinimize[{ae4[z], {z == reqpower, 0 <= z <= maxae4}}, {z}, 
                Method -> "RandomSearch"], 999999],
              Check[NMinimize[{ae1[w] + ae2[x], {w + x == reqpower, 
                  0 <= w <= maxae1, 0 <= x <= maxae2}}, {w, x}, 
                Method -> "RandomSearch"], 999999],
              Check[NMinimize[{ae1[w] + ae3[y], {w + y == reqpower, 
                  0 <= w <= maxae1, 0 <= y <= maxae3}}, {w, y}, 
                Method -> "RandomSearch"], 999999],
              Check[NMinimize[{ae1[w] + ae4[z], {w + z == reqpower, 
                  0 <= w <= maxae1, 0 <= z <= maxae4}}, {w, z}, 
                Method -> "RandomSearch"], 999999],
              Check[NMinimize[{ae2[x] + ae3[y], {x + y == reqpower, 
                  0 <= x <= maxae2, 0 <= y <= maxae3}}, {x, y}, 
                Method -> "RandomSearch"], 999999],
              Check[NMinimize[{ae2[x] + ae4[z], {x + z == reqpower, 
                  0 <= x <= maxae2, 0 <= z <= maxae4}}, {x, z}, 
                Method -> "RandomSearch"], 999999],
              Check[NMinimize[{ae3[y] + ae4[z], {y + z == reqpower, 
                  0 <= y <= maxae3, 0 <= z <= maxae4}}, {y, z}, 
                Method -> "RandomSearch"], 999999],
              Check[NMinimize[{ae1[w] + ae2[x] + ae3[y], {w + x + y == reqpower, 
                  0 <= w <= maxae1, 0 <= x <= maxae2, 0 <= y <= maxae3}}, {w, x, 
                 y}, Method -> "RandomSearch"], 999999],
              Check[NMinimize[{ae1[w] + ae2[x] + ae4[z], {w + x + z == reqpower, 
                  0 <= w <= maxae1, 0 <= x <= maxae2, 0 <= z <= maxae4}}, {w, x, 
                 z}, Method -> "RandomSearch"], 999999],
              Check[NMinimize[{ae1[w] + ae3[y] + ae4[z], {w + y + z == reqpower, 
                  0 <= w <= maxae1, 0 <= y <= maxae3, 0 <= z <= maxae4}}, {w, y, 
                 z}, Method -> "RandomSearch"], 999999],
              Check[NMinimize[{ae2[x] + ae3[y] + ae4[z], {x + y + z == reqpower, 
                  0 <= x <= maxae2, 0 <= y <= maxae3, 0 <= z <= maxae4}}, {x, y, 
                 z}, Method -> "RandomSearch"], 999999],
              Check[NMinimize[{ae1[w] + ae2[x] + ae3[y] + 
                  ae4[z], {w + x + y + z == reqpower, 0 <= w <= maxae1, 
                  0 <= x <= maxae2, 0 <= y <= maxae3, 0 <= z <= maxae4}}, {w, x, 
                 y, z}, Method -> "RandomSearch"], too much power needed]},
              First]
            

            When evaluating this formula with f[reqpower], the result looks like this:

            MininmalBy[{999999, 999999, 999999, 999999, {396.497, {w -> 3160.39, 
               x -> 1839.61}}, {390.376, {w -> 2515.03, 
               y -> 2484.97}}, {389.794, {w -> 3140.25, 
               z -> 1859.75}}, {389.996, {x -> 2293.23, 
               y -> 2706.77}}, {389.955, {x -> 3241.48, 
               z -> 1758.52}}, {383.048, {y -> 2730.85, 
               z -> 2269.15}}, {602.931, {w -> 1733.48, x -> 1638.86, 
               y -> 1627.66}}, {600.422, {w -> 1755.15, x -> 1655.01, 
               z -> 1589.84}}, {596.013, {w -> 1752.93, y -> 1659.67, 
               z -> 1587.4}}, {592.798, {x -> 1674.27, y -> 1707.44, 
               z -> 1618.29}}, {602.931, {w -> 1733.48, x -> 1638.86, 
               y -> 1627.66, z -> 0.}}}, First]
            

            Is there a trick to get the final result without having to look for the minimum list of values manually? According to the help database, MinimalBy[Arg,First] should do it...? Thanks a lot to whoever supports me on this! :)

            EDIT: Corrected brackets, but no change in the outcome...

              • Reply
              • |
              • Flag

              Okay, I found the mistake... It was a typo (MininmalBy instead of MinimalBy), sorry for bothering. -.-

                • Reply
                • |
                • Flag

                Reply to this discussion

                Attachments

                Remove Add a file to this post