*! version 1.0.2  27jun2005  by Marc-Andreas Muendler: muendler@ucsd.edu
program define matorder
  version 7
  syntax newvarname , Matrix(string) [ IFRow(string) IFCol(string) OVERwrite ]
  local matname = subinstr("`1'",`","',"",.)
  local cols = colsof(`matname')
  local rows = rowsof(`matname')
  tempname newmat
  * local newmat "newmat"
  if "`ifrow'"=="" & "`ifcol'"=="" {
    disp as err "row or column list required"
    exit 100
    }
  if "`ifrow'"~="" & "`ifcol'"~="" {
    disp as err "simultaneous row and column lists not allowed"
    exit 101
    }

  /* Row Keep and Order */
  if "`ifrow'"~="" {
    * check existence of rows
    local rownames : rowfullnames `matname'
    local totrow : word count `rownames'
    tokenize `rownames'
    foreach row in `ifrow' {
      local find = 0
      forvalues i = 1/`totrow' {
        if "`row'"=="``i''" {
          local find = `find' + 1
          }
        }
      if `find' == 0 {
        disp as err "row " in yellow "`row'" in red " not found in matrix " in yellow "`matname'"
        exit 111
        }
      }
    * work on order
    foreach row in `ifrow' {
      capture local chk = rowsof(`newmat')
      if _rc~=0 {
        mat `newmat' = `matname'[rownumb(`matname',"`row'"),1..colsof(`matname')]
        }
      else {
        mat `newmat' = `newmat' \ `matname'[rownumb(`matname',"`row'"),1..colsof(`matname')]
        }
      }
    }

  /* Col Keep and Order */
  if "`ifcol'"~="" {
    * check existence of columns
    local colnames : colfullnames `matname'
    local totcol : word count `colnames'
    tokenize `colnames'
    foreach col in `ifcol' {
      local find = 0
      forvalues i = 1/`totcol' {
        if "`col'"=="``i''" {
          local find = `find' + 1
          }
        }
      if `find' == 0 {
        disp as err "column " in yellow "`col'" in red " not found in matrix " in yellow "`matname'"
        exit 111
        }
      }
    * work on order
    foreach col in `ifcol' {
      capture local chk = colsof(`newmat')
      if _rc~=0 {
        mat `newmat' = `matname'[1..rowsof(`matname'),colnumb(`matname',"`col'")]
        }
      else {
        mat `newmat' = `newmat' , `matname'[1..rowsof(`matname'),colnumb(`matname',"`col'")]
        }
      }
    }

  /* Finalize */
  if "`matrix'"=="`matname'" {
    mat drop `matname'
    mat `matname' = `newmat'
    }
  else {
    capture local check = colsof(`matrix')
    if _rc==0 & "`overwrite'"=="" {
       disp as err "no; matrix " in yellow "`matrix'" in red " would be lost"
       exit 4
       }
    mat `matrix' = `newmat'
    }

end