Statalist The Stata Listserver


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

Re: st: Mata: Recursive structures and pointers


From   Phil Schumm <[email protected]>
To   [email protected]
Subject   Re: st: Mata: Recursive structures and pointers
Date   Thu, 18 May 2006 09:06:40 -0500

On May 18, 2006, at 5:36 AM, Ulrich Kohler wrote:
we have a rather weird problem with recursive Mata structures and pointers, which is even somwhat beyond the limits of what we can express in English.
<snip>

Our main problem, however, concerns the using of pointers. The pointer "last" should move along the list and always point to the last element of the list (it means, it should allow to set a new point at the end of the list). It does not work. How can we add a new element at the end of the list?

I see a few issues with the code you posted, but I'm afraid I don't have time right now to deconstruct and go through it. However, if I understand correctly, the following will accomplish what you are trying to do:


struct list_element {
real scalar a, b
pointer(struct list_element scalar) scalar next
}

struct linked_list {
pointer(struct list_element scalar) scalar first, last
}

void add_list_element(struct linked_list scalar l, real scalar s) {
struct list_element scalar e
e.a = e.b = s
l.last->next = &e
l.last = &e
}

struct linked_list scalar make_list(real rowvector seq) {
struct list_element scalar first_element
struct linked_list scalar result
real scalar i

first_element.a = first_element.b = seq[1]
result.first = result.last = &first_element

for (i=2; i<=length(seq); i++) {
add_list_element(result, i)
}

return(result)
}


There are, admittedly, several rough edges here, so don't take exactly what I've written too seriously. Since we can't access a structure's contents explicitly at the interpreter, we must write a little function to check that the code works:


void show_list(struct linked_list scalar l) {
struct list_element scalar e

e = *l.first
while (1) {
printf("(%f,%f)\n", e.a, e.b)
if (e.next) {
e = *e.next
}
else {
break
}
}
}


Again, pretty rough code, I'm afraid. This function just prints the items in the list. For example:


: mylist = make_list((1..3))

: show_list(mylist)
(1,1)
(2,2)
(3,3)


I hope this helps. I'm sure Bill will provide the definitive response at some point.


-- Phil

*
* 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–2024 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index