Randy Akee <[email protected]> asked for some advice on how to add parameter
interactions to an -optimize()- evaluator function:
> I am interested in including parameter interactions in my mata
> optimization routine. As it stands, the parameters (contained in the
> vector p) are only added linearly in my function to be optimized.
>
> For example, given the mata optimization below,
> > : c
> > 1
> > +-----+
> > 1 | 1 |
> > 2 | 2 |
> > 3 | 3 |
> > 4 | 4 |
> > 5 | 5 |
> > 6 | 6 |
> > +-----+
> > : f
> > 1 2 3 4 5 6
> > +-------------------------+
> > 1 | 1 1 0 0 0 0 |
> > 2 | 0 1 1 0 0 0 |
> > 3 | 0 0 1 1 0 0 |
> > 4 | 0 0 0 1 1 0 |
> > 5 | 0 0 0 0 1 1 |
> > 6 | 1 0 0 0 0 1 |
> > +-------------------------+
> >
> >void mv0(todo, p, c, f, lnf, S, H)
> >{
> > lnf = (c - f*p') :* (c - f*p')
> >}
> >
> >Sv = optimize_init()
> >optimize_init_evaluator(Sv, &md0())
> >optimize_init_evaluatortype(Sv, "v0")
> >optimize_init_params(Sv, J(1,6,0))
> >optimize_init_which(Sv, "min")
> >optimize_init_argument(Sv, 1, c)
> >optimize_init_argument(Sv, 2, f)
> >optimize(Sv)
> >
> >end
>
>
> The first row equation from the function: lnf = (c - f*p') :* (c - f*p')
> Would be: lnf[1] = (1 - p1 - p2)*(1 - p1 - p2)
>
> *** where p1 and p2 are the first two elements (of six elements) of the
> parameter vector p (to be solved via mata's optimization)
>
> And the second row equation would be:
>
> Lnf[2] = (2 - p2 - p3)*(2 - p2 - p3)
>
> I'm interested in having an additional term in these equations, such as
> p1*p2 or p2*p3, etc., so that the new first row equation might look
> like:
>
> lnf = (1 - p1 - p2 - p1*p3)*(1 - p1 - p2 - p1*p3)
>
> My question really comes down to finding out how one can create these
> parameter interactions. Does this problem require including several
> functions into the optimization command (i.e. one for each row
> equation)? Or is there some other solution available?
>
> Mata does have a command - optimize_init_constraints() which allows for
> constraining the parameters, however this is not going to be of use for
> me as it only allows for linear constraints.
Randy's example above is based on Mata code I posted in a reply I made to
Randy's previous question on Statalist, so I must point out that I suggested
the wrong function pointer in the code that Randy is using in the above
example. The line
> optimize_init_evaluator(Sv, &md0())
should read
> optimize_init_evaluator(Sv, &mv0())
Now let's address Randy's question.
In Randy's evaluator -mv0()-, the -f- matrix linearly controls which values in
the parameter vector -p- enter into the values produced by the evaluator
function.
Randy would like specific products of the parameters to be a part of the
function evaluation. Here are two ways of doing this:
1. Randy could simply hard code the products in the function evaluator.
2. Randy could add more argument matrices that will allow the users to
specify how the products are constructed.
I would suggest idea 1 only if Randy is working with a small toy problem that
will not require tuning of the specific parameter interactions.
Idea 2 will allow for a richer set of possibilities without requiring us to
develop more than one evaluator. Here I've modified a copy of the -mv0()-
evaluator to accept 2 new arguments, -m1- and -m2-:
void mv0p(todo, p, c, f, m1, m2, v, S, H)
{
v = (c - f*p' - (m1*p'):*(m2*p'))
v = v :* v
}
(Note that I also changed -lnf- to -v-; otherwise I might refer to the function
value as a log likelihood a la -ml-.)
Here we specify the equivalent call that identifies we will be using the new
evaluator function.
optimize_init_evaluator(Sv, &mv0p())
Now we can specify different matrices -m1- and -m2- to get whichever fits we
want for a given -c- vector. Using the original -f- matrix, we might want to
include the interaction of the same parameters identified in each row of -f-.
This is accomplished by using
m1 = I(6)
m2 = m1[|2,1\.,.|] \ m1[|1,1\1,.|]
(Note that f = m1 + m2.)
Then we add these matrices to the argument list
optimize_init_argument(Sv, 3, m1)
optimize_init_argument(Sv, 4, m2)
Here is the do-file I composed while working on Randy's query.
***** BEGIN:
mata:
mata clear
c = (1,2,3,4,5,6)'
f = ( 1,1,0,0,0,0 \
0,1,1,0,0,0 \
0,0,1,1,0,0 \
0,0,0,1,1,0 \
0,0,0,0,1,1 \
1,0,0,0,0,1)
m1 = I(6)
m2 = m1[|2,1\.,.|] \
m1[|1,1\1,.|]
// we could have produced m2 using the following:
// m2 = I(6)
// _collate(m2, (2::6 \ 1))
// note that f = m1 + m2
void mv0p(todo, p, c, f, m1, m2, v, S, H)
{
v = (c - f*p' - (m1*p'):*(m2*p'))
v = v :* v
}
Sv = optimize_init()
optimize_init_evaluator(Sv, &mv0p())
optimize_init_evaluatortype(Sv, "v0")
optimize_init_params(Sv, J(1,6,0))
optimize_init_which(Sv, "min")
optimize_init_argument(Sv, 1, c)
optimize_init_argument(Sv, 2, f)
optimize_init_argument(Sv, 3, m1)
optimize_init_argument(Sv, 4, m2)
optimize(Sv)
end
***** END:
--Jeff
[email protected]
*
* For searches and help try:
* http://www.stata.com/support/faqs/res/findit.html
* http://www.stata.com/support/statalist/faq
* http://www.ats.ucla.edu/stat/stata/