0
$\begingroup$

I am attempting an optimization with 50 variables. In the documentation for FindMinimum, it says:

If the starting point for a variable is given as a list, the values of the variable are taken to be lists with the same dimensions.

The question is how to refer to elements of the variable in my code for the expression to be optimized. To set the stage:

tst6 has dimensions {3,1460}.

The function prob just maps a scalar to a scalar.

prob[d_] := 1/2 (1 + Erf[d/2])

Here is the optimization:

FindMinimum[-Total@
   Log[prob[tst6[[3]] (jnd[[tst6[[1]]]] - jnd[[tst6[[2]]]])]], {jnd, 
  Range[0, 49]/10.}]

This failed with the message:

Part::partd: Part specification

jnd[[{21,18,50,35,32,1,29,21,44,4,30,20,37,2,24,29,32,29,18,49,9,4,1,31,13,23,37,19,15,34,47,27,1,21,31,19,7,42,43,50,2,34,22,40,23,31,44,39,30,20,<<1410>>}]] is longer than depth of object.

Evidently the variable jnd cannot be treated as a list. So I tried the following.

FindMinimum[-Total@
   Log[prob[
     tst6[[3]] (Table[jnd[[k]], {k, tst6[[1]]}] - 
        Table[jnd[[k]], {k, tst6[[2]]}])]], {jnd, Range[0, 49]/10.}]

This also failed, with the message

Part::partd: Part specification jnd[[21]] is longer than depth of object.

So I am at a loss as to how to refer to parts of the variable jnd. Any ideas?

$\endgroup$
1
$\begingroup$

The problem is that FindMinimum first does some symbolic stuff -- and it doesn't know that jnd is a list. The simplest route is to make a black-box routine. Say:

res[myjnd_List] := -Total@Log[prob[tst6[[3]] (myjnd[[tst6[[1]]]] - myjnd[[tst6[[2]]]])]]  

That way it can only be evaluated on lists.

One can then run FindMinimum[res, {jnd, Range[0, 49]/10.}]

$\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.