Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Saving a class through mosave

    Dear Stata users,

    I would like to ask a question on the mosave command. Below you can find the code that creates a matrix containing the ranks of the numbers in a real matrix that is given as argument (the functions are rowrank() and colrank() respectively). To account for possible ties, and also to exercise object-oriented programming, I programmed a class. The code is not very efficient I'm afraid, but it works out perfectly, at least for my purposes. Having said this, it works with one exception: everytime I try to store the ties() class by typing

    mata mosave ties(), dir(PERSONAL) replace complete

    Stata freezes. Mysteriously (only for me I guess) that happens only in Stata 13, while the same code works fine in Stata 11. Still I suspect there's a problem with the code, since when I restart Stata 11 and type

    mata describe ties()

    the class seems to be empty. In the mata help file it states that the entire class definition, including all compiled member functions, should be stored by the mosave class() command, so I am confused of what I did wrong.


    This is the code which can just be copied and run in Stata as it is. The sercond-to-last line (which is now commented out) is the problematic one

    Code:
    capture mata mata drop ties()
    capture mata mata drop rowrank()
    capture mata mata drop colrank()
    
    mata:
        class ties {
            /* Take care of ties while creating colrank or rowrank matrix */
            real vector rank_me        /* vector of interest (to be ranked) */
            real vector k, m, v        /* determined by function ::range_ties() */
            real vector range_ties()
            real scalar t, s, u
        }
    
        real vector ties::range_ties()
        {
            minindex(rank_me,.,k,m)
            if (!allof(m[,2], 1)) { /* perform only if there are any ties in vector rank_me */
                t=s=1
                v=J(length(rank_me),1,.)
                while (t<=length(v)) {
                    u=m[s,2]     /* u = how many rows to fill in v ( equalling the # of tied numbers). u >= 1 */
                    v[t::(t+u-1)] = J(u,1,m[s,1])
                    t=t+u; s=s+1
                }
            }
            else v = 1::length(rank_me)
            return(v)
        }
    
        real matrix colrank (real matrix a)
        {
            real matrix b
            real scalar j
            class ties scalar c
            
            b=J(rows(a),cols(a),.)
            
            for (j=1; j<=cols(a); j++) {
                c.rank_me = a[.,j]
                b[,j] = sort( (order(a,j),c.range_ties() ), 1)[.,2]
            }
            return(b)
        }
    
    
        real matrix rowrank (real matrix a)
        {
            real matrix b
            real scalar j
            pointer scalar atrans
            class ties scalar d
            
            /* Transpose vector since sort() fn can only sort columns */
            atrans = &(a')
            b=J(rows(*atrans),cols(*atrans),.)
            
            for (j=1; j<=cols(*atrans); j++) {
                d.rank_me = (*atrans)[.,j]
                b[,j] = sort( (order(*atrans,j),d.range_ties() ), 1)[.,2]
            }
            
            b=b'
            return(b)
        }
    
        mata mosave rowrank(), dir(PERSONAL) replace
        mata mosave colrank(), dir(PERSONAL) replace
        //mata mosave ties(), dir(PERSONAL) replace complete    /* Causes Stata to freeze */
    end
    As an example, try

    Code:
    a=(1,5,3,120,5)
    rowrank(a)

    Any suggestion is highly appreciated! Not only for this particular problem, but also for general education Thanks a lot!

    Regards
    Jann
    Last edited by Jann Goedecke; 26 Mar 2015, 11:55. Reason: Sorry for double-posting, not sure how to remove the first post...
Working...
X