/* version 1.1, October 29, 2003, allen buxton*/
/* 29oct03 slight modification to take a matrix or matrix definition syntax */
/* 29oct03 make this rclass for potential output of exact p-values */
	/*capture program drop tarowi*/
	program define tarowi, rclass
	version 7.0

	syntax anything, [Options_tabulate(string) Row_options_tabulate(string)]

	local tabopts  `"`options_tabulate'"'
	local rtabopts `"`row_options_tabulate'"'
	local inmatrix `"`anything'"'

tempname X
tempname a
tempname b
tempname rX
tempname mX
tempname bX
tempname aX
tempname rXdim

tempvar rX1
tempvar rX2
tempvar rX3
tempvar rXdim_row

capture confirm matrix `inmatrix'		/* no matrix defined if _rc==111 */
							/* matrix is found if _rc == 0   */
if _rc == 0 {
	matrix `X' = `inmatrix'
	}
else {
	matrix input `X' = `inmatrix'
	}

local d_row = rowsof(`X')
local d_col = colsof(`X')

/*display `"number of rows: `d_row'"'*/
/*display `"number of cols: `d_col'"'*/

local rows=`d_row' * `d_col'

matrix `rXdim'=J(`rows',1,0)
qui svmat `rXdim' , names(`"`rXdim_row'"')
foreach i of numlist 1/3 {
	qui gen `rX`i''=.
	}
matrix `rX'=J(`rows',3,0)
	foreach i of numlist 1/`d_row' {
		foreach j of numlist 1/`d_col' {
			local r_i=`d_col'*(`i'-1)+`j'
			 qui replace `rX1'=`i' if _n==`r_i'
			 qui replace `rX2'=`j' if _n==`r_i'
			 qui replace `rX3'=`X'[`i',`j'] if _n==`r_i'
		}
	}
label var `rX1' row
label var `rX2' col

	if `"`tabopts'"' == `""' {
		tabulate `rX1' `rX2' [freq=`rX3']  if `rXdim_row'==0
		}
	else {
		tabulate `rX1' `rX2' [freq=`rX3'] if `rXdim_row'==0, `tabopts'
		}
drop `rX1' `rX2' `rX3' `rXdim_row'

/* create the _a_ & _b_ vector */
matrix `a' = J(`d_row',1,0)
matrix `b' = J(`d_row',1,1)

/* 2 by col tables loop */
foreach l of numlist 1/`d_row' {
	matrix `a'[`l',1]=1
	matrix `b'[`l',1]=0

	matrix `aX' = `a''*`X'
	matrix `bX' = `b''*`X'
			/*matrix list `aX'*/
			/*matrix list `bX'*/

	matrix `mX' = `aX' \ `bX'
	/*matrix list `mX'*/

	local rows = 2 * `d_col'
	matrix `rXdim'=J(`rows',1,0)
	qui svmat `rXdim' , names(`"`rXdim_row'"')
	foreach i of numlist 1/3 {
	qui gen `rX`i''=.
	}
	matrix `rX'=J(`rows',3,0)
		foreach i of numlist 1/2 {
			foreach j of numlist 1/`d_col' {
				local r_i=`d_col'*(`i'-1)+`j'
			 	qui replace `rX1'=`i' if _n==`r_i'
			 	qui replace `rX2'=`j' if _n==`r_i'
			 	qui replace `rX3'=`mX'[`i',`j'] if _n==`r_i'
			}
		}
	label var `rX1' row
	label var `rX2' col
	local lplusone=`l'+1
	qui recode `rX1' 1=`l' 2=`lplusone'
	label define `rX1' `l' `"row==`l'"' `lplusone' `"all others"'
	label val `rX1' `rX1'
	if `"`rtabopts'"' == `""' {
		tabulate `rX1' `rX2' [freq=`rX3'] if `rXdim_row'==0
		}
	else {
		tabulate `rX1' `rX2' [freq=`rX3'] if `rXdim_row'==0, `rtabopts'
		local exactp = r(p_exact)			/* save the exact p*/
		return scalar exactp`l' = `exactp'
		}
	drop `rX1' `rX2' `rX3' `rXdim_row'
	label drop `rX1'
	/* reset the _a_ & _b_ vector */
	matrix `a' = J(`d_row',1,0)
	matrix `b' = J(`d_row',1,1)
} /* 2 by col tables loop */

matrix drop `X' `a' `b' `rX' `mX' `bX' `aX' `rXdim'
end /* tarowi */