program define _gvreldif, sortpreserve

    version 10

    gettoken type 0 : 0
    gettoken g    0 : 0
    gettoken eqs  0 : 0

    syntax varlist [if] [in] , BY(string)

    marksample touse, novarlist

    capture confirm variable `by'
    if _rc {
       di as err "`by' found where varlist expected"
       exit 7
    }
    sort `by' `_sortorder'
    capture bysort `by' : assert _N <= 2
    if _rc {
       di as err "the data should have at most two observations per unique combination(s) of `by'"
       exit 9
    }

    tempvar vrd panelid
    qui bysort `by' : gen long `panelid' = (_n==1)
    qui replace `panelid' = sum(`panelid')
    qui gen double `vrd' = .

    mata : VRelDif( "`varlist'", "`panelid'", "`vrd'", "`touse'" )

    qui generate `type' `g' = `vrd'

end

version 10
mata

void VRelDif( string scalar varlist, string scalar byname, string scalar genname, string scalar tousename ) {

   real matrix x, thex, gen, thegen, by, info;
   real scalar i;

   st_view(x=.,   ., tokens(varlist), tousename)
   st_view(by=.,  ., tokens(byname),  tousename)
   st_view(gen=., ., tokens(genname), tousename)

   info = panelsetup( by, 1, 2, 2)
   for(i=1;i<=rows(info);i++) {
      thex  = panelsubmatrix( x, i, info )
      panelsubview( thegen, gen, i, info )
      thegen[,] = J(rows(thegen),1, mreldif( thex[1,.], thex[2,.] ) )
   }

}

end

exit