prog def mluwild, rclass
*!	mluwild by MO, CGD: version 1.1 23Aug2021
	version 11.1
	syntax anything , [Matrix(string) Clean Omit Verbose /* add */ debug ]

	tokenize `"`anything'"', parse("[,] ")

	//  Is this option useful?
	if "`add'"=="add" {
		return add
	}
	else {
	    return clear
	}

	if "`debug'"=="debug" {
		local i = 1
		while `"``i''"'~="" {
			di as txt "Token " as res "`i'" as txt " is: " as res `"``i''"'
			local i = `i' + 1
		}
	}
	// Error trap for missing comma or too many arguments before comma
	if `"`7'"'~="" {
		di as err "Too many arguments before the options."
		exit 198
	}

	// Error trap to assure that row & column are specified as strings
	capt confirm number `3'
		if _rc == 0 local arg3 numeric
	capt confirm number `5'
		if _rc == 0 local arg5 numeric
	if "`arg3'"=="numeric" | "`arg5'"=="numeric" {
		di as err "Row and column id's must be specified as strings, not numbers"
		exit 198
	}

	// Error trap to require -mlu- for versions < 16
	if `c(version)'< 16 {
		capt which mlu
		if _rc > 0 {
		    di as err _n "For Stata versions prior to version 16, -mluwild- requires the utility {help mlu}."  ///
				_n "Click here to install it: "  ///
				in smcl `"{stata "view net describe mlu, from(http://digital.cgdev.org/doc/stata/MO/Misc)":here}"'
				exit 111
		}
	}

	//	Are there wild cards in the row name or the column name?
	local wildrow = strpos("`3'","*") | strpos("`3'","?")
	local wildcol = strpos("`5'","*") | strpos("`5'","?")

	if `wildrow'+`wildcol'==0 {
		di as err "There is no wildcard in either the row or column name."   ///
			_n "To extract a sequence of rows and/or columns, see help for {help matrix_extraction}."  ///
			_n "To extract a single element of a matrix, consider using {help mlu}."
		exit 198
	}

	local thismat `1'

	capt confirm matrix `thismat'
	if _rc>0 {
		di as err "Argument -`thismat'- is not a Stata matrix."
		exit 198
	}

	local rnms : rowfullnames `thismat'
	foreach r in `rnms' {
	    if "`omit'"=="" | (strpos("`r'","o.")==0 & strpos("`r'","b.")==0) {
			if strmatch("`r'","`3'") {
				local keptrows `keptrows' `r'
				if "`clean'"~="" {
					_ms_parse_parts `r'
					if "`r(type)'"=="factor" {
						local cleanrows `cleanrows' `r(level)'.`r(name)'
					}
					else {
						local cleanrows `cleanrows' `r'
					}
				}
			}
		}
	}
	local nkeptrows = wordcount("`keptrows'")
	if `nkeptrows'==0 {
	    di as err "Row specification -`3'- does not match any of the rows in matrix -`thismat'-"
		exit 198
	}

	local cnms : colfullnames `thismat'
	foreach c in `cnms' {
	    if "`omit'"=="" | (strpos("`c'","o.")==0 & strpos("`c'","b.")==0) {
			if strmatch("`c'","`5'") {
				local keptcols `keptcols' `c'
				if "`clean'"~="" {
					_ms_parse_parts `c'
					if "`r(type)'"=="factor" {
						local cleancols `cleancols' `r(level)'.`r(name)'
					}
					else {
						local cleancols `cleancols' `c'
					}
				}
			}
		}
	}
	local nkeptcols = wordcount("`keptcols'")
	if `nkeptcols'==0 {
	    di as err "Column specification -`5'- does not match any of the columns in matrix -`thismat'-"
		exit 198
	}

	if "`debug'"~="" {
		di as txt "The kept columns are: " as res "`keptcols'"
		di as txt "The kept rows are: " as res "`keptrows'"
		if "`clean'"~="" {
			di as txt "The clean kept rows are: " as res `"`cleanrows'"'
			di as txt "The clean kept columns are: " as res `"`cleancols'"'
		}
	}

	tempname submat newrow element

	foreach r in `keptrows' {
		foreach c in `keptcols' {
			if `c(version)'< 16 {
				mlu `thismat'["`r'","`c'"]
				mat define `newrow' = nullmat(`newrow'), `r(element)'
			}
			else {
				capt scalar `element' = `thismat'["`r'","`c'"]
				if "`debug'" di as txt "element [`3',`5'] of matrix -" as res "`thismat'" as txt "- is: " as res scalar(`element')
				if scalar(`element') >=. & scalar(`element') ~=.b & scalar(`element') ~=.o {
					di as err "Matrix -`thismat'- contains no element with row and column names matching [`3',`5']"
					exit 198
				}
				mat define `newrow' = nullmat(`newrow'), scalar(`element')
			}
		}
		mat define `submat' = nullmat(`submat') \ `newrow'
		cap mat drop `newrow'
	}
	if "`clean'"=="" {
		mat rownames `submat' = `keptrows'
		mat colnames `submat' = `keptcols'
	}
	else {
		mat rownames `submat' = `cleanrows'
		mat colnames `submat' = `cleancols'
	}
	if "`verbose'"~="" | "`debug'"~=""  matlist `submat'

	local rtrndmat = cond("`matrix'"=="","submat","`matrix'")

	return matrix `rtrndmat' `submat'
	return local rnms `rnms'
	return local cnms `cnms'

	return local keptcols `keptcols'
	return local cleancols `cleancols'
	return local nkeptcols `nkeptcols'

	return local keptrows `keptrows'
	return local cleanrows `cleanrows'
	return local nkeptrows `nkeptrows'

end
*	ver 1.1 23Aug2021 Fix typo in row -specification -`5'- does not match-