views:

87

answers:

1

Using Mathematica, I need to optimize a function that is defined in terms of BinCounts; the arguments that I want to maximize over define the bin cutpoints.

I think the problem is that Mathematica expands the objective function in terms of the arguments before they have been given numerical values, so BinCounts complains that the bin specification is not "a list containing real values, Infinity, and -Infinity".

I think the following is a minimal example of the kind of thing I'm trying to do and what's happening. I'd be very grateful for advice on how to address this problem.

In[1]:= data = RandomReal[1, 30]; (* Make some test data. *)

In[2]:= f[a_, b_, c_] := BinCounts[data, {{0, a, b, c, 1}}] (* Shorthand to use below… *)

In[12]:= g[a_, b_, c_] := Max[f[a, b, c]] - Min[f[a, b, c]] (* Objective function. *)

In[13]:= NMaximize[{g[a, b, c], 0 < a < b < c < 1}, {a, b, c}] (* Try to oprimize. *)

During evaluation of In[13]:= BinCounts::cvals: The bin specification {{0,a,b,c,1}} is not a list containing real values, Infinity, and -Infinity. >>

During evaluation of In[13]:= BinCounts::cvals: The bin specification {{0,a,b,c,1}} is not a list containing real values, Infinity, and -Infinity. >>

During evaluation of In[13]:= BinCounts::cvals: The bin specification {{0,a,b,c,1}} is not a list containing real values, Infinity, and -Infinity. >>

During evaluation of In[13]:= General::stop: Further output of BinCounts::cvals will be suppressed during this calculation. >>

Out[13]= {0., {a -> 0., b -> 0., c -> 1.}}
+2  A: 

The solution is simply to specify that the objective function is defined only in terms of numerical arguments, like so:

g[a_?NumericQ, b_?NumericQ, c_?NumericQ] := Max[f[a, b, c]] - Min[f[a, b, c]]
Microserf