Statalist


[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

Re: st: Mata and Optimize Command


From   jpitblado@stata.com (Jeff Pitblado, StataCorp LP)
To   statalist@hsphsun2.harvard.edu
Subject   Re: st: Mata and Optimize Command
Date   Thu, 27 Sep 2007 15:41:29 -0500

Randy Akee <akee@iza.org> 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
jpitblado@stata.com
*
*   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/



© Copyright 1996–2014 StataCorp LP   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index