*! 0.5 Peter Lachenbruch 12 March 2004
*! 0.8 NJC 12 March 2004
*! 0.9 NJC 14 March 2004
*! 0.97 NJC 15 March 2004
*! 0.98 PAL 22 March 2004
program nirand
	version 8.2
	syntax newvarname [if] [in] ///
	[, I Normal Mmix Uniform Vmix Chisquare(numlist max=1 >0) ///
	m1(real 0) s1(real 1) alpha(numlist max=1 <1 >0) m2(str) s2(str) ]

	marksample touse, novarlist
	qui count if `touse'
	if r(N) == 0 {
		di "Number of observations was not set or no observations in subset"
		error 2000
	}
	if "`i'" != "" local I "I"

	// distribution options
	local dc : word count `I' `normal' `uniform' `vmix' `chisquare' `mmix'
	if `dc' > 1 {
		di as err "too many denominators specified"
		exit 198
	}
	else if `dc' == 0 local I "I"
	if "`alpha'" != "" {
		if "`m2'" == "" | "`s2'" == "" {
			di as err "alpha() option needs m2() s2()"
			exit 198
		}
		else {
			capture confirm number `m2'
			if _rc {
				di as err "m2() must specify a number"
				exit 198
			}
			capture assert `s2' > 0
			if _rc {
				di as err "s2() must specify a positive number"
				exit 198
			}
		}
	}

	tempvar t1 v1 vx
	gen double `t1' = invnorm(uniform()) * `s1' + `m1'

	if  "`alpha'" != "" {
		gen double `v1' = uniform()
		qui replace `t1' = `t1' * (`v1' <= `alpha') + ///
		(invnorm(uniform()) * `s2' + `m2') * (`v1' > `alpha')
		local numer "Normal mixture(`alpha',`m1',`s1',`m2',`s2')"
	}
	else local numer "Normal(`m1',`s1')"

	local outvar `varlist'
	if "`I'" != "" {
		gen double `outvar' = `t1' if `touse'
		label var `outvar' "`numer'/I random numbers"
	}
	else if "`uniform'" != "" {
		gen double `outvar' = `t1' / uniform() if `touse'
		label var `outvar' "slash = `numer'/uniform(0,1) random numbers"
	}
	else if "`vmix'" != "" {
		gen double `vx'=uniform()
		gen double `outvar'=(invnorm(uniform())*`s1'+`m1')*(`vx'<=`alpha')+ ///
		 (`vx'>`alpha')*(invnorm(uniform())*`s2'+`m2')/uniform()
		label var `outvar' "normal(`m1', `s1') + slash(`m2', `s2') mixture"
/* mixture of normal and slash */
	}
	else if "`normal'" != ""  {
		gen double `outvar' = `t1' / invnorm(uniform())
		label var `outvar' "Cauchy = `numer'/normal(0,1) random numbers"
	}
	else if "`mmix'"!="" {
		gen double `vx'=uniform()
		gen double `outvar' =(invnorm(uniform())*`s1'+`m1')*(`vx'<=`alpha')+ ///
		(`vx'>`alpha')*(invnorm(uniform())*`s2'+`m2')/invnorm(uniform())
		label var `outvar' "normal (`m1', `s1') + Cauchy (`m2', `s2') mixture"
	}
/* mixture of normal and Cauchy */
	else {
		local nu = `chisquare'
		gen double `outvar' = ///
		`t1' / sqrt(invchi2(`nu', uniform()) / `nu')
		label var `outvar' "t = `numer'/sqrt(chi(`nu')) random numbers"
	}
end