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

From |
wgould@stata.com (William Gould, StataCorp LP) |

To |
statalist@hsphsun2.harvard.edu |

Subject |
Re: st: basic quesion about using structures in mata |

Date |
Tue, 18 Sep 2007 10:34:22 -0500 |

Matthew Weinberg <mweinber@gmail.com> writes, > I'm trying to use structures for the first time and am having a little > trouble. I want the function markups to take three arguments (s,p,b) > and return three arguments (margins, marks, and costs). I'm getting > back one > > My code is: > > struct mups { /*define the structure*/ > real matrix margins > real matrix marks > real matrix costs > } > > struct mups function markups(s,p,b) /*define the function*/ > { > struct mups scalar ms /*declare structure variable*/ > n=rows(s) > S=J(n,n,0) > for(i=1;i<=n;i++){ > for(j=1;j<=n;j++){ > S[i,j]=-b*s[i]*s[j] > } > } > for(i=1;i<=n;i++){ > S[i,i]=-b*s[i]*s[i]+b*s[i] > } > Omega=I(n)*S > ms.margins=invsym(Omega)*s > ms.costs=p-ms.margins > ms.marks=(p-ms.costs):/p > return(ms) > } > > When I evaluate my function, I get back what something like 0x27c65c > instead of the three vectors margins, costs, and marks. Everything is working as it should. The result 0x27c65c is the address of the structure. That's what you see when you use a structure interactively, such as : markups(..., ..., ...) 0x27c65c /* you might see a different address */ However, in a programming context, they work as you might expect. Try the following program with the above, void listresult(struct mups scalar ms) { "margins is" ms.margins "marks is" ms.marks "costs is" ms.cost } With that extra program, you could interactively type : listresult(markups(..., ..., ...)) margins is <matrix listed here> marks is <matrix listed here> costs is <matrix listed here> More usefully, you might have another program that reads void mainroutine(...) { struct mups scalar m ... m = markups(..., ..., ...) ... a = <calculation made with m.margins, m.marks, and m.costs> ... printf("The final result is %9.2f\n", a) } or void anotherroutine(...) { struct mups scalar m1, m2 ... m1 = markups(..., ..., ...) m2 = markups(..., ..., ...) ... a = <calculation made with m1.margins, m1.marks, and m2.costs and m2.margins, m2.marks, and m2.costs> ... printf("The final result is %9.2f\n", a) } or void lastexample(...) { struct mups scalar m1, m2 ... m1 = markups(..., ..., ...) m2 = markups(..., ..., ...) ... a = perform_basic_calc(m1) b = perform_basic_calc(m2) ... printf("The final result is %9.2f\n", a+b) } real scalar perform_basic_calc(struct mps scalar m) { result = <calculation made with m.margins, m.marks, and m.costs> return(result) } So what is 0x27c65c? In the above examples, markups() returned a structure, not some hexadecimal number, and we just used what markups() returned as the structure it is. This is difficult to explain, so bear with me. 1. A structure is, internally, a "pointer" to a memory address. That memory address contains the values of the elements of the structure. 2. You are not required to know (1) or even understand what (1) means; it is a detail of the implementation of Mata. 3. In the programs above, I used variables such as ms, m, m1, and m2 to hold the structures returned by markup(). Note that, in each case, I explicitly declared ms, m, m1, and m2 to be struct mups. 4. Because I did that, Mata knew ms, m, m1, and m2 were struct mups, and because it knew that, given the structure definition, Mata knew (for instance) m.margins referred to the first element of the structure, m.marks referred to the second, and m.costs referred to the third. Mata also knew that, had I coded m.bill, that would be a mistake because there is no element of the structure mups called bill. 5. Now consider a line such as : x = markups(..., ..., ...) Note, I typed the line interactively. Well, you say to yourself, then I suspect is can similarliy refer to x.margins, x.marks, and m.costs. But you cannot because you did not previously declare x to be a struct mups. x is just a transmorphic and, as such, it can hold a structure such as a struct mups, but Mata doesn't understand that it really is a structure. Said differently, Mata understands that x is a structure of some sort, but it doesn't know that it is in particular a struct mups, and so Mata does not know how to translate things like x.margins, x.marks, and x.costs into 1st element, 2nd element, and 3rd element. For all Mata knows, the translation might be 2nd element, 1st element, and 3rd element, or x.marks might simply be an error and correspond to no element. 6. So what happens if you look at x interacctively? Mata just gives up and shows you the memory address of the structure. 7. If the above makes no sense, I apologize. The short answer is (1) structures work as you would expect INSIDE Mata programs and (2) structures were never intended to work interactively, so don't use them that way. One more aside. Concerning notes 5 and 6, while structures cannot be interpreted interactively, transmorphics can be used to hold the contents of a structure. For instance, I might interactively type : x = markup(.., ..., ...) : listresult(x) and that will work! x contains the structure, it is just that Mata can't work out the details of the INTERPRETATION based on what is stored in x. I've mentioned this before: Mata is a compiler, and being a compiler is what makes Mata fast. -- 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/

- Prev by Date:
**Re: st: can't reproduce bootstrap confidence intervals** - Next by Date:
**Re: st: RE: re: a drawing in Stata Journal** - Previous by thread:
**st: basic quesion about using structures in mata** - Next by thread:
**st: re: a drawing in Stata Journal** - Index(es):

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