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

# Re: st: mata: how function can return several results

 From wgould@stata.com (William Gould, Stata) To statalist@hsphsun2.harvard.edu Subject Re: st: mata: how function can return several results Date Tue, 17 Oct 2006 09:37:18 -0500

```Abdelrahmen El Lahga writes,

> I would like to write a subroutine in mata that can return several results
> ata once. More precisely if I define a function (myreg for exemple ) defined
> as
>
>       -------------start myreg
>       function myreg()
>       {
>               st_view(y, .,  st_local("yvar"))
>               st_view(x, ., st_local("xvar"))
>               bhat=invsym(x'*x)x'*y   // estimated coefficient
>               uhat=y-x*bhat       // residual
>        }
>        ----------- finish myreg
>
>     how can i tell mata to return 2 results res1=bhat and res2=uhat?
>
>     res1 and res2 are for use in the rest of my programme.  Ideally I want
>     some thing like this:
>
>        {b,u}=myreg() as can i code in gauss for exemple

There are two solutions to Abdelrahmen's problem:  (1) structures and
(2) returning results in arguments.  I believe that (2) is the better
solution in this case.

1.  The structure solution
--------------------------

I don't want to discuss this solution, but let me at least show it to you.

structure regression_results {
real colvector    bhat
real colvector    uhat
}

structure regression_results scalar myreg
{
structure regress_results scalar   res

st_view(y, .,  st_local("yvar"))
st_view(x, ., st_local("xvar"))
res.bhat = invsym(x'*x)x'*y
res.uhat = y-x*bhat
return(res)
}

This is a great solution but it requires a bit more setup (namely, the
definition of the structure).  It is merely because of that setup I wish to
suggest on an alternative solution.

2.  Returning resutls via arguments
-----------------------------------

Here is the solution that requires no setup:

void regression_results(bhat, uhat)
{
st_view(y, .,  st_local("yvar"))
st_view(x, ., st_local("xvar"))
bhat = invsym(x'*x)x'*y
uhat = y-x*bhat
}

This program is very easy to use.   In a program, just code

regression_results(b, u)

and the predictions will be in b and the residuals in u.

Interactively, you must first define b and u before you can use them:

: b = u = .
: regression_results(b, u)

We can mix input arguments and output arguments in the same function.
When I do that, I tend to put the output arguments last, but that is
just a matter of style, and the opposite style (outputs first) is, to
me, equally appealing.  Anyway, here is a better regression_results()
in that it allows me to pass the names of yvar and xvar to the program.

void regression_results(ynvarname, xvarname, bhat, uhat)
{
st_view(y, .,  st_local(yvarname))
st_view(x, ., st_local(xvarname))
bhat = invsym(x'*x)x'*y
uhat = y-x*bhat
}

If I were to include explicit declarations (again, it's a matter of style),
here's how I would do that:

void regression_results(string scalar ynvarname,
string scalar xvarname,
bhat, uhat)
{
real colvector   y, x

st_view(y, .,  st_local(yvarname))
st_view(x, ., st_local(xvarname))
bhat = invsym(x'*x)x'*y
uhat = y-x*bhat
}

That is, when I include explicit declarations, it is my style to leave
the output variables undeclared, which is the same as explicitly declaring
them to be "polymorphic matrix".  I don't care what type the output variables
are because I am going to replace them in this program and, by the time I'm
done, bhat and uhat will be real colvectors.

-- Bill
wgould@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–2015 StataCorp LP   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index