I wrote helper functions:
I'm wondering if I needed to. Are there built-in functions that indicate 0/1 whether an object `x` is a colvec/rowvec/matrix? I know that these types are nested (so a rowvector is a special type of matrix, etc.), but can't see anywhere where that is formalized in a way that I can use directly.
That's my main question, but I have a couple more following the code below.
Here's my application: I wanted union and intersection functions that work on either a pair of row vectors or column vectors:**
Two more minor questions if you've come this far:
so that I can afford to forget what I named my function.
** Working on more than a pair of vectors at once would be better, but I'll attempt that some other time. By the way, I'm using get_* instead of the vanilla names for these operations because "union" and "intersection" are reserved words/function names (since they may be implemented by StataCorp in the future, which might break code I'm writing now). And the reason why I'm making these functions in the first place is that I'm sick of taking my Mata objects to Stata and doing merges (which is the best, albeit clumsy, workaround I had up until this point). It would be really nice if we eventually got a "vectorized" version of inlist in Mata, so I could write intersect as
(...or something along those lines.) A related thread: http://www.stata.com/statalist/archi.../msg00811.html
Code:
function is_colvec(z) return(anyof(("colvector","scalar"),orgtype(z))) function is_rowvec(z) return(anyof(("rowvector","scalar"),orgtype(z))) function is_matrix(z) return(anyof(("matrix","colvector","rowvector","scalar"),orgtype(z)))
That's my main question, but I have a couple more following the code below.
Here's my application: I wanted union and intersection functions that work on either a pair of row vectors or column vectors:**
Code:
function get_union(x,y){ is_col = is_colvec(x) & is_colvec(y) is_row = is_rowvec(x) & is_rowvec(y) if (!(is_col|is_row)) return("conformability problem") res = is_col ? sort(uniqrows( (x\y) ),1) : sort(uniqrows( (x,y)' ),1)' return(res) } function get_intersection(x,y){ xy = get_union(x,y) x = is_colvec(x) ? sort(uniqrows(x),1) : sort(uniqrows(x'),1)' y = is_colvec(y) ? sort(uniqrows(y),1) : sort(uniqrows(y'),1)' n_xy = length(xy) in = is_colvec(xy) ? J(n_xy,1,0) : J(1,n_xy,0) xi = 1 yi = 1 i = 1 while (i <= n_xy & xi <= length(x) & yi <= length(y)){ v = xy[i] dx = x[xi]==v dy = y[yi]==v if (dx) xi++ if (dy) yi++ in[i] = dx*dy i++ } return(select(xy,in)) } // example x = 3,3,1 y = 2,4,3 get_intersection(x,y)
- When I run my example, the objects x and y outside of the function are modified, which is unexpected. I thought Mata functions didn't have side effects like this...?
- Is there a standard way to make aliases for a Mata function? I'm inclined to do something like
Code:
function get_intersect(x,y) get_intersection(x,y) function intersect(x,y) get_intersection(x,y)
** Working on more than a pair of vectors at once would be better, but I'll attempt that some other time. By the way, I'm using get_* instead of the vanilla names for these operations because "union" and "intersection" are reserved words/function names (since they may be implemented by StataCorp in the future, which might break code I'm writing now). And the reason why I'm making these functions in the first place is that I'm sick of taking my Mata objects to Stata and doing merges (which is the best, albeit clumsy, workaround I had up until this point). It would be really nice if we eventually got a "vectorized" version of inlist in Mata, so I could write intersect as
Code:
u = union(x,y) return(select(u,inlist(x,u):&inlist(y,u)))
Comment