program define flexmake, rclass
*!	program flexmake		version 2.41		21Nov2017

*	Program to construct the transformed variables and factor variable lists
*	for use in estimating a translog or generalized leontief flexible cost function

	version 11.1
	syntax [varname (default=none)] [if] [in] [,OUTputs(varlist max=5) Prices(varlist max=10)  ///
		INPuts(varlist max=10) INCosts(varlist max=10) SHares(varlist max=10)  ///
		OTHervars(varlist max=10 fv ts) log10 sqrt ln BOXcox(real 0) half replace GLobals one  ///
		double TCName(string) INNames(passthru) IMPvars(passthru) noMake]

	//  Identify the sample based on the -varname- and the -if- and -in- qualifiers
	marksample touse
		local andtouse & `touse'

	if "`varlist'"~="" {  //  If user specifies a total cost variable in -varname-
		local tcname `varlist'
		local totcost `varlist'
	}
	else {  //  If user does not specify a total cost variable in -varname- ...
		if "`make'"~="nomake" {  //  ... and does not specify -nomake-,
			if "`tcname'"=="" {  //  ... then flexmake selects the name of a total cost variable
				capture confirm new variable tc
				if _rc~=0 & "`replace'"=="" {
					di as err "The variable -tc-, already exists. Either specify the option -replace-"  ///
						_n "to overwrite it or use the option -tcname()- to specify a different name"  ///
						_n "for the new total cost variable created by -flexmake-"
					exit 198
				}
				local tcname tc
			}
			else {
				if "`replace'"=="" capture drop `tcname'
				capture confirm new variable `tcname'
				if _rc~=0 {
					di as err "The variable - " as txt "`tcname'" as err "- already exists. Either specify the option -replace-"  ///
						_n "to overwrite it or use the option -tcname()- to specify a different name"  ///
						_n "for the new total cost variable created by -flexmake-"
					exit 198
				}
			}
		}
	}

*	Five possible user-provided argument combinations:
*	1.	Only prices and input quantities
	if "`prices'"~="" & "`inputs'"~="" {
		if "`totcost'`incosts'`shares'"~="" {
			di as txt "Too many input options specified.  When both"  ///
				_n " input quantities, " as res "`inputs'"  as txt  ///
				_n " and input prices, " as res "`prices'" as txt  ///
				_n " are specified, -flexmake- constructs input costs, total cost and cost shares."
			exitmake, `make'
		}
		getnames  `prices' , `innames'
			local innamelist `r(names)'
		local argtype prices_inputs
		local argmissing totcost_incosts_shares
	}
*	2.	Input costs and input quantities
	if "`incosts'"~="" & "`inputs'"~=""  {
		if "`totcost'`prices'`shares'"~="" {
			di as txt "Too many input options specified.  When both"  ///
				_n " input quantities, " as res "`inputs'"  as txt  ///
				_n " and input costs, " as res "`incosts'" as txt  ///
				_n " are specified, -flexmake- constructs input prices, total cost and cost shares."
			exitmake, `make'
		}
		getnames  `incosts' , `innames'
			local innamelist `r(names)'
		local argtype incosts_inputs
		local argmissing totcost_prices_shares
	}
*	3.	Input costs and input prices
	if "`incosts'"~="" & "`prices'"~=""  {
		if "`totcost'`inputs'`shares'"~="" {
			di as txt "Too many input options specified.  When both"  ///
				_n " input prices, " as res "`prices'"  as txt  ///
				_n " and input costs, " as res "`incosts'" as txt  ///
				_n " are specified, -flexmake- constructs input quantities, total cost and cost shares."
			exitmake, `make'
		}
		getnames  `incosts' , `innames'
			local innamelist `r(names)'
		local argtype incosts_prices
		local argmissing totcost_inputs_shares
	}
*	4.	Total costs and input shares and input prices
	if "`totcost'"~="" & "`shares'"~="" & "`prices'"~=""  {
		if "`incosts'`inputs'"~="" {
			di as txt "Too many input options specified.  When all three of"  ///
				_n " input prices, " as res "`prices'"  as txt  ///
				_n " and input shares, " as res "`shares'" as txt  ///
				_n " and total cost, " as res "`totcost'" as txt  ///
				_n " are specified, -flexmake- constructs input quantities and input costs."
			exitmake, `make'
		}
		getnames  `shares' , `innames'
			local innamelist `r(names)'
		local argtype totcost_shares_prices
		local argmissing incosts_inputs
	}
*	5.	Total costs and input shares and input quantities
	if "`totcost'"~="" & "`shares'"~="" & "`inputs'"~=""  {
		if "`incosts'`prices'"~="" {
			di as txt "Too many input options specified.  When all three of"  ///
				_n " input quantities, " as res "`inputs'"  as txt  ///
				_n " and input shares, " as res "`shares'" as txt  ///
				_n " and total cost, " as res "`totcost'" as txt  ///
				_n " are specified, -flexmake- constructs input prices and input costs."
			exitmake, `make'
		}
		getnames  `shares' , `innames'
			local innamelist `r(names)'
		local argtype totcost_shares_inputs
		local argmissing incosts_prices
	}
	if "`argtype'"=="" {
		di as txt "Insufficient input options specified.  Flexmake requires "  ///
			_n "one of the following five combinations of options:"  ///
			_n "  1.  Only prices and input quantities"  ///
			_n "  2.  Input costs and input quantities (preferred arguments)"  ///
			_n "  3.  Input costs and input prices"  ///
			_n "  4.  Total costs and input shares and input prices"  ///
			_n "  5.  Total costs and input shares and input quantities"
			exitmake, `make'
	}

*	Generate the variables not provided as arguments
	if "`make'"~="nomake" {
		if "`argtype'"  == "prices_inputs" {
			//	Then generate incosts -> totcost -> shares
			local argmissing totcost_incosts_shares
			if "`impvars'"~="" {
				di as err "The option -" as res "impvars(varlist)"  ///
					as err "- is valid only if flexmake generates the input price variables."
				exit 198
			}

			makeincosts_wo_tc, prices(`prices') inputs(`inputs') `double' `innames' `replace'
				local incosts `r(incosts)'

			di as txt "Generate `tcname' = rowtotal(`incosts')"
			if "`replace'"=="replace" {
				qui capture drop `tcname'
			}
			egen `double' `tcname' = rowtotal(`incosts')
				lab var `tcname' "=rowtotal(`incosts'): Generated by flexmake"

			makeshares , incosts(`incosts') `double' `innames' `replace'
				local shares `r(shares)'
		}

		if "`argtype'" == "incosts_inputs"  {
			//	Then generate totcost -> shares -> prices
			local argmissing totcost_prices_shares

			if "`replace'"=="replace" {
				qui capture drop `tcname'
			}
			di as txt "Generate `tcname' = rowtotal(`incosts')"
			egen `double' `tcname' = rowtotal(`incosts')
				lab var `tcname' "=rowtotal(`incosts'): Generated by flexmake"

			makeprices, incosts(`incosts') inputs(`inputs') `double' `innames' `impvars'  `replace'
				local prices `r(prices)'
				local p_vars `r(p_vars)'

			makeshares , incosts(`incosts') `double' `innames' `replace'
				local shares `r(shares)'
		}

		if "`argtype'"  == "incosts_prices"  {
			//	Then generate totcost -> inputs -> shares
			local argmissing totcost_inputs_shares
			if "`impvars'"~="" {
				di as err "The option -" as res "impvars(varlist)"  ///
					as err "- is valid only if flexmake generates the input price variables."
				exit 198
			}

			makeinputs, incosts(`incosts') prices(`prices') `double' `innames'  `replace'
				local inputs `r(inputs)'

			makeshares , incosts(`incosts') `double' `innames'  `replace'
				local shares `r(shares)'

			if "`replace'"=="replace" {
				qui capture drop `tcname'
			}
			di as txt "Generate `tcname' = rowtotal(`incosts')"
			egen `double' `tcname' = rowtotal(`incosts')
				lab var `tcname' "=rowtotal(`incosts'): Generated by flexmake"

		}

		if "`argtype'"  == "totcost_shares_prices"  {
			//	Then generate incosts -> inputs
			local argmissing incosts_inputs
			if "`impvars'"~="" {
				di as err "The option -" as res "impvars(varlist)"  ///
					as err "- is valid only if flexmake generates the input price variables."
				exit 198
			}

			makeincosts_w_tc `tcname', shares(`shares') `double' `innames' `replace'
				local incosts `r(incosts)'

			makeinputs, incosts(`incosts') prices(`prices') `double' `innames' `replace'
				local inputs `r(inputs)'

		}

		if "`argtype'"  == "totcost_shares_inputs"	{
			//	Then generate incosts -> prices
			local argmissing incosts_prices

			makeincosts_w_tc `tcname', shares(`shares')  `double' `innames' `replace'
				local incosts `r(incosts)'

			makeprices, incosts(`incosts') inputs(`inputs') `double' `innames' `impvars' `replace'
				local prices `r(prices)'
				local p_vars `r(p_vars)'
		}
	}

**************************************************************
*	Construct the transformed variables
	local transvars
	local transoutputs
	local transprices
	//	The selected transformation is stored in local -trans-
	//	Transformation must be one of ln, log10 or sqrt or left blank.
	//	With the transformation -ln- or -log10-, user has the option of specifying
	//		a boxcox transformation of the outputs and the dependent variable
	//		by choosing a value of -boxcox(lambda)- different from zero.
	//  If none of the options ln, log10 or sqrt has been specified, the data will not be transformed.
	foreach transopt in ln log10 sqrt {  // User must specify no more than one of these
		if "``transopt''"~="" {
			if "`trans'"==""  {
				local trans `transopt'
			}
			else {
				di as err "Only one of the options -log10- -ln- or -sqrt- can be specified."  ///
					_n as err "The user has specified the options: " as res "`none' `log10' `sqrt' `ln'"
				exit 198
			}
		}
	}
	if "`trans'"=="" {
		local _
	}
	else {
		local _ "_"
	}

	if abs(`boxcox') > 0.000001 {
		if "`outputs'"=="" {
			di as err "The boxcox transformation is specified without providing a list of the output variables,"  ///
				_n as err "to which the transformation would be applied."
			exit 198
		}
		if "`trans'"=="ln" | "`trans'"=="log10"{
			di as txt "The boxcox transformation with lambda set to " as res "`boxcox'" as txt " is applied to the output variables"  ///
				_n "and to the dependent variable."
			local bcnotzero bcnotzero
		}
		else {
			di as err "Use the option -boxcox({it:`boxcox'})- to apply the boxcox transformation"  ///
				_n as err "to the output variables and the dependent variable is disallowed unless the"  ///
				_n as err " transformation -ln- or -log10- is specified for the other variables."
			if "`trans'" == "" {
				di as err "Here no transformation has been specified."
			}
			else {
				di as err "Here the specified transformation is: " as res "`trans'"
			}
			exit 198
		}
	}


*********************************************************************
	if "`one'"~="" {
		di as txt _n "If a variable to be transformed has values <= 0, the real number 1.0 is added before the transformation."
		local plusone + 1.0
	}

	//	Apply the Box-Cox transformation only to the outputs and the dependent variable
	if "`bcnotzero'"~="" {
		di as txt _n "Price variables transformed using the natural logarithm: " as res "ln"  ///
			as txt _n "Quantity variables transformed with the boxcox transformation with parameter: " as res "`boxcox'"  _n

		di as txt _n "Transformation of the original variables"  ///
			_n(2) _col(5) "User-"      _col(22) "Number of"   _col(35) "Generated"    _col(55) "Number of Transformed"  ///
			_n    _col(5) "Provided"   _col(22) "obs. <=0"    _col(35) "Transformed"  _col(55) "Observations which are:" ///
			_n    _col(5) "Variable"   _col(22) "or missing"  _col(35) "Variable"     _col(55) " < 0" _col(63) " = 0" _col(71) "  >=. "  ///
			_n    _col(5) "========"   _col(22) "=========="  _col(35) "========"     _col(55) "====" _col(63) "====" _col(71) "======"
		local i = 1
		foreach var of varlist `prices' {
			if "`replace'" == "replace" {
				capture drop `trans'`_'`var'
			}
			qui count if `var' <= 0
			if `r(N)' == 0 {
				local plusonehere
			}
			else {
				local plusonehere `plusone'
			}
			qui count if `var' <= 0 | `var' >= .
				local Norigmor0`var' = r(N)
			qui gen `trans'`_'`var' = `trans'(`var' `plusonehere') if `touse'
				lab var `trans'`_'`var' "`trans'(`var' `plusonehere'): Generated by flexmake"
			qui count if `trans'`_'`var'>=. `andtouse'
				local nmsng`var' = r(N)
			qui count if `trans'`_'`var'<=0 `andtouse'
				local nle0`var' = r(N)
			qui count if `trans'`_'`var'<0 `andtouse'
				local nlt0`var' = r(N)
			qui count if `trans'`_'`var'==0 `andtouse'
				local neq0`var' = r(N)
			qui count if `trans'`_'`var' > 0 & `trans'`_'`var' < .
				local Npos`var' = r(N)

			di as txt `i' as res _col(5) "`var'" _col(24) `Norigmor0`var'' _col(35) "`trans'`_'`var'" _col(57) `nlt0`var'' _col(65) `neq0`var'' _col(75) `nmsng`var''

			local transvars `transvars' `trans'`_'`var'
			local transprices `transprices' `trans'`_'`var'
			local i = `i' + 1
		}
		foreach var of varlist `tcname' `outputs' {
			if "`replace'" == "replace" {
				capture drop bc_`var'
			}
			qui count if `var' <= 0
			if `r(N)' == 0 {
				local plusonehere
			}
			else {
				local plusonehere `plusone'
			}
			qui count if `var' <= 0 | `var' >= .
				local Norigmor0`var' = r(N)
			qui gen bc_`var' = ((`var' `plusonehere')^`boxcox'-1)/`boxcox' if `touse'
				lab var bc_`var' "Boxcox trans of `var' with lambda = `boxcox': Generated by flexmake"
			qui count if bc_`var'>=. `andtouse'
				local nmsng`var' = r(N)
			qui count if bc_`var'<=0 `andtouse'
				local nle0`var' = r(N)
			qui count if bc_`var'<0 `andtouse'
				local nlt0`var' = r(N)
			qui count if bc_`var'==0 `andtouse'
				local neq0`var' = r(N)
			qui count if bc_`var' > 0 & bc_`var' < .
				local Npos`var' = r(N)

			di as txt `i' as res _col(5) "`var'" _col(24) `Norigmor0`var'' _col(35) "bc_`var'" _col(57) `nlt0`var'' _col(65) `neq0`var'' _col(75) `nmsng`var''

			local transvars `transvars' bc_`var'
			local transoutputs `transoutputs' bc_`var'
			local i = `i' + 1
		}
		capture confirm variable bc_`tcname'
		if _rc==0 {
			local depvar bc_`tcname'
			local transoutputs : list transoutputs - depvar
		}
	}
	else {  //  Apply transformations that are not -boxcox-
		if "`trans'"~="" {
			di as txt _n "Variables transformed by the function: " as res "`trans'"

			di as txt _n "Characteristics of transformed cost function variables"  ///
				_n(2) _col(5) "Cost-"      _col(22) "Number of"   _col(35) "Generated"    _col(55) "Number of Transformed"  ///
				_n    _col(5) "Function"   _col(22) "obs. <=0"    _col(35) "Transformed"  _col(55) "Observations which are:" ///
				_n    _col(5) "Variable"   _col(22) "or missing"  _col(35) "Variable"     _col(55) " < 0" _col(63) " = 0" _col(71) "  >=. "  ///
				_n    _col(5) "========"   _col(22) "=========="  _col(35) "========"     _col(55) "====" _col(63) "====" _col(71) "======"
			local i = 1
			foreach var of varlist `tcname' `prices' `outputs' {
				if "`replace'" == "replace" {
					capture drop `trans'`_'`var'
				}
				qui count if `var' <= 0
				if `r(N)' == 0 {
					local plusonehere
				}
				else {
					local plusonehere `plusone'
				}
				qui count if `var' <= 0 | `var' >= .
					local Norigmor0`var' = r(N)
				qui gen `trans'`_'`var' = `trans'(`var' `plusonehere') if `touse'
					lab var `trans'`_'`var' "`trans'(`var' `plusonehere'): Generated by flexmake"
				qui count if `trans'`_'`var'>=. `andtouse'
					local nmsng`var' = r(N)
				qui count if `trans'`_'`var'<=0 `andtouse'
					local nle0`var' = r(N)
				qui count if `trans'`_'`var'<0 `andtouse'
					local nlt0`var' = r(N)
				qui count if `trans'`_'`var'==0 `andtouse'
					local neq0`var' = r(N)
				qui count if `trans'`_'`var' > 0 & `trans'`_'`var' < .
					local Npos`var' = r(N)

				di as txt `i' as res _col(5) "`var'" _col(24) `Norigmor0`var'' _col(35) "`trans'`_'`var'" _col(57) `nlt0`var'' _col(65) `neq0`var'' _col(75) `nmsng`var''

				local transvars `transvars' `trans'`_'`var'
				local i = `i' + 1
			}
		}
		else {
			di as txt _n "Variables are not transformed"

			di as txt _n "Characteristics of cost function variables"  ///
				_n(2) _col(5) "Cost-"      _col(22) ""            _col(35) ""           _col(55) ""           ///
				_n    _col(5) "Function"   _col(22) "Number of"   _col(35) "Number of"  _col(55) "Number of"  ///
				_n    _col(5) "Variable"   _col(22) "obs. < 0"    _col(35) "missing"    _col(55) "obs. > 0"   ///
				_n    _col(5) "========"   _col(22) "=========="  _col(35) "========"   _col(55) "========="
			local i = 1
			foreach var of varlist `tcname' `prices' `outputs' {
				qui count if `var' > 0 & `var' < .
					local Npos`var' = r(N)
				qui count if `var'>=. `andtouse'
					local nmsng`var' = r(N)
				qui count if `var'<0 `andtouse'
					local nlt0`var' = r(N)

				di as txt `i' as res _col(5) "`var'" _col(24) `nlt0`var'' _col(40) `nmsng`var'' _col(58) `Npos`var''

				local i = `i' + 1
			}
		}
	}
	if "`half'"~="" {
		if "`trans'"~="ln" {
			di as err _n "The option -half- is only allowed with the transformation -ln-"
			exit 198
		}
		if "`replace'" == "replace" {
			capture drop __half
		}
		qui gen float __half = 1/2 if `touse'
			lab var __half "Utility variable identically equal to 0.5: Generated by flexmake"
		local posthalf #c.__half
	}

**********************************************************************************************
	*	Create macros to contain the factor variable expressions to be used to specify
	*	the estimating equations and thereby to name the estimated regression coefficients.
	*	These macros can also be used to test curvature hypotheses and to impose cross-equation constraints.

	*	Output coefficients, own and cross

	if "`trans'"=="" {
		local _ ""
		}
	else {
		local _ "_"
		}

	if "`outputs'"~="" {
		local thisterm
*		local transoutputs
		local ownoutputs
		local ownoutputs2		//  Squared outputs
		local crossoutputs
		local restofoutputs `outputs'
		if `boxcox'==0{
			foreach output1 of varlist `outputs' {
				local transoutputs `transoutputs' `trans'`_'`output1'
				local ownoutputs `ownoutputs' c.`trans'`_'`output1'
				local ownoutputs2 `ownoutputs2' c.`trans'`_'`output1'#c.`trans'`_'`output1'`posthalf'
				local restofoutputs : list restofoutputs - output1
				if "`restofoutputs'"~="" {
					foreach output2 of varlist `restofoutputs' {
						local thisterm c.`trans'`_'`output1'#c.`trans'`_'`output2'
						local crossoutputs `crossoutputs' `thisterm'
					}
				}
			}
		}
		else {
			foreach output1 of varlist `outputs' {
*				local transoutputs `transoutputs' bc_`output1'
				local ownoutputs `ownoutputs' c.bc_`output1'
				local ownoutputs2 `ownoutputs2' c.bc_`output1'#c.bc_`output1'`posthalf'
				local restofoutputs : list restofoutputs - output1
				if "`restofoutputs'"~="" {
					foreach output2 of varlist `restofoutputs' {
						local thisterm c.bc_`output1'#c.bc_`output2'
						local crossoutputs `crossoutputs' `thisterm'
					}
				}
			}
		}
		return local outputs `outputs'
		return local transoutputs `transoutputs'
		return local ownoutputs `ownoutputs'
		return local ownoutputs2 `ownoutputs2'
		return local crossoutputs `crossoutputs'
	}

	*	Price coefficients, own and cross
	if "`prices'"~="" {
		local thisterm
		local transprices
		local ownprices
		local ownprices2
		local crossprices
		local restofprices `prices'
		foreach price1 of varlist `prices' {
			local transprices `transprices' `trans'`_'`price1'
			local ownprices `ownprices' c.`trans'`_'`price1'
			local ownprices2 `ownprices2' c.`trans'`_'`price1'#c.`trans'`_'`price1'`posthalf'
			local restofprices : list restofprices - price1
			if "`restofprices'"~="" {
				foreach price2 of varlist `restofprices' {
					local thisterm c.`trans'`_'`price1'#c.`trans'`_'`price2'
					local crossprices `crossprices' `thisterm'
				}
			}
		}
		return local prices `prices'
		return local transprices `transprices'
		return local ownprices `ownprices'
		return local ownprices2 `ownprices2'
		return local crossprices `crossprices'
	}

	*	Output/price interactions
	if "`outputs'"~="" & "`prices'"~="" {
		if `boxcox'==0{
			local thisterm
			local outputsxprices
			foreach output of varlist `outputs' {
				foreach price of varlist `prices' {
					local thisterm c.`trans'`_'`output'#c.`trans'`_'`price'
					local outputsxprices `outputsxprices' `thisterm'
				}
			}
			return local outputsxprices `outputsxprices'
		}
		else {
			local thisterm
			local outputsxprices
			foreach output of varlist `outputs' {
				foreach price of varlist `prices' {
					local thisterm c.bc_`output'#c.`trans'`_'`price'
					local outputsxprices `outputsxprices' `thisterm'
				}
			}
			return local outputsxprices `outputsxprices'
			return local lambda `boxcox'
		}
	}

	if "`depvar'"=="" local depvar `trans'`_'`tcname'
	local innames `innamelist'

	return local tcname `tcname'
	return local depvar `depvar'
	local transrhsvars : list transvars - depvar
	return local transrhsvars `transrhsvars'
	if "`globals'"~="" {
		foreach rtrnlist in  ///
			outputsxprices crossprices ownprices2 ownprices prices p_vars crossoutputs  ///
			ownoutputs2 ownoutputs outputs sharevars shares incosts inputs othervars  ///
			depvar transrhsvars transvars transoutputs transprices tcname innames {
				global `rtrnlist' ``rtrnlist''
				local  rtrndglobals `rtrndglobals' `rtrnlist'
				global rtrndglobals `rtrndglobals' `rtrnlist'
		}
	}

	return local rtrndglobals `rtrndglobals'  // For -globals- option, list the returned globals
	return local transvars `transvars'
	return local argmissing `argmissing'
	return local argtype `argtype'
	return local shares `shares'  // Factor input cost shares (e.g. wage share in total cost)
	return local p_vars `p_vars'  // Variance of each imputed input price (if -impvars-)
	return local prices `prices'  // Factor input prices (or wages and rents)
	return local incosts `incosts'  // Factor input costs (e.g. total wage bill)
	return local inputs `inputs'  // Factor input quantities
	return local othervars `othervars'  // Other variables, if any
	return local innames `innames'

end  //  End of main program

**************************************************************************
*	Utility programs used above
program exitmake
	syntax [, nomake]
	if "`make'"=="nomake" {
		di as txt "User has specified the option " as res "nomake"   ///
			as txt ".  So execution continues."
	}
	else {
		exit 198
	}
end  // End of program exitmake

program getnames, rclass
	syntax varlist [, innames(string) ]

	if "`innames'"=="" {
		//	Assumes a naming convention: prefix_underscore_factor_name
		//	where prefix depends on whether the variable is a
		//	factor quantity, price, cost or share.
		foreach var of varlist `varlist' {
			local suffix = substr("`var'",max(1,strpos("`var'","_")+1),.)
			local names `names' `suffix'
		}
	}
	else {
		foreach name in `innames' {
			local names `names' `name'
		}
	}
	if wordcount("`varlist'")~=wordcount("`names'") {
		di as err "Number of factor or input price variables must match the number of names in the -innames()- option."  ///
			_n "Here the factor/price variables are " as txt "`varlist'"  as err  ///
			_n " and the innames are " as txt "`names'" as err " ."
		exit 198
	}
	return local names `names'
end  //  end of program getnames

program define matchnames
	syntax, names1(string) names2(string) [force]
	local i = 1
	local check yes
	foreach name1 in `names1' {
		local name2 = word("`names2'",`i')
		if "`name1'"~="`name2'" & "`check'"=="yes" {
			di as err "Since the -innames()- option is not specified, -flexmake- checks whether"  ///
				_n " the suffixes of variables that refer to the factor inputs be identical and in the same order."  ///
				_n " (A variable -suffix- is defined as the part of the variable name after the first underscore."  ///
				_n " If there is no underscore character in the name, the -suffix- is the entire variable name.)"  ///
				_n " Here are the suffixes from one set of variables: " as txt "`names1'"  as err  ///
				_n " and here are those from the other set: " as txt "`names2'" as err " ."

			if "`force'" == "" {
				exit 198
			}
			else {
				di as err _n "Since the option -force- is specified, execution continues."
				local check no
			}
		}
		local i = `i' + 1
	}
end //	end of program matchnames

program define makeincosts_wo_tc, rclass
	syntax , prices(varlist) inputs(varlist) [double innames(passthru) replace]

	getnames `prices', `innames'
		local pnames `r(names)'
	getnames `inputs' `innames'
		local qnames `r(names)'
	matchnames, names1(`pnames') names2(`qnames')

	local i = 1
	foreach price of varlist `prices' {
		local quantity = word("`inputs'",`i')
		local name = word("`qnames'",`i')
		if "`replace'"=="replace" {
			qui capture drop exp_`name'
		}
		di as txt "Generate exp_`name' = `price' * `quantity'"
		gen `double' exp_`name' = `price' * `quantity'
			lab var exp_`name' "= `price' * `quantity': Generated by flexmake"
		local incosts `incosts' exp_`name'
		local i = `i' + 1
	}
	return local incosts `incosts'
end //  End of program makeincosts_wo_tc

program define makeshares, rclass
	syntax , incosts(varlist) [double innames(passthru) replace]

	getnames `incosts', `innames'
		local shnames `r(names)'

	tempvar totcost
	egen double `totcost' = rowtotal(`incosts')
		lab var `totcost' "=rowtotal(`incosts'): Generated by flexmake"

	local i = 1
	foreach exp of varlist `incosts' {
		local shname = word("`shnames'",`i')
		if "`replace'"=="replace" {
			qui capture drop sh_`shname'
		}
		di as txt "Generate sh_`shname' = `exp'/tc"
		gen `double' sh_`shname' = `exp'/`totcost'
			lab var sh_`shname' "= `exp' /tc: Generated by flexmake"
		local shares `shares' sh_`shname'
		local i = `i' + 1
	}

	return local shares `shares'
end //  End of program makeshares

program define makeincosts_w_tc, rclass
	syntax varname, shares(varlist) [double innames(passthru) replace]

	local totcost `varlist'

	getnames `shares', `innames'
		local qnames `r(names)'

	local i = 1
	foreach share of varlist `shares' {
		local expname = word("`qnames'",`i')
		if "`replace'"=="replace" {
			qui capture drop exp_`expname'
		}
		di as txt "Generate exp_`expname' = `share' * tc"
		gen `double' exp_`expname' = `share' * `totcost'
			lab var exp_`expname' "= `share' * tc: Generated by flexmake"
		local incosts `incosts' exp_`expname'
		local i = `i' + 1
	}
	return local incosts `incosts'
end //  End of program makeincosts

program define makeprices, rclass
	syntax, incosts(varlist) inputs(varlist) [double innames(passthru) impvars(varlist fv ts) replace]

	getnames `incosts', `innames'
		local expnames `r(names)'
	getnames `inputs', `innames'
		local qnames `r(names)'
	matchnames, names1(`expnames') names2(`qnames')

	if "`impvars'"~="" {
		di _n as txt "Using Stata's {help impute} command to impute missing values of the price variables from observed values of:"  ///
			_n as res "`impvars'"
	}
	local i = 1
	foreach exp of varlist `incosts' {
		local quantity = word("`inputs'",`i')
		local name = word("`qnames'",`i')
		if "`replace'"=="replace" {
			qui capture drop p_`name'
		}
		di as txt "Generate p_`name' = `exp' / `quantity'"
		gen `double' p_`name' = `exp' / `quantity'
			lab var p_`name' "= `exp' / `quantity': Generated by flexmake"
		if "`impvars'"~="" {
			fvrevar `impvars'
			local impvars `r(varlist)'
			tempvar phat ln_phat ln_p
			di as txt "Impute the missing values of p_`name':"

			capture confirm new variable _var_p_`name'
			if _rc~=0 {
				if "`replace'"=="replace" {
					drop _var_p_`name'
				}
				else {
					di as err "User has specified the -impvars()- option to impute missing values of factor prices."  ///
						_n as err "This option creates ancillary variables with names beginning with the prefix -_var-"  ///
						_n as err "which contain the estimated variance of the log of the imputed observation."  ///
						_n as err "The variable " as txt "_var_p_`name'" as err " already exists."  ///
						_n as err "Specify the -replace- option to overwrite it"
					exit 198
				}
			}
			qui gen `ln_p' = ln(p_`name')  //  New in version 2.36
			impute `ln_p' `impvars', gen(`ln_phat') varp(_var_p_`name')
			qui replace p_`name' = exp(`ln_phat') if p_`name'>=. | p_`name' <=0
			local p_vars `p_vars' _var_p_`name'
		}
		local prices `prices' p_`name'
		local i = `i' + 1
	}
	if "`impvars'"~="" {
		di _n as txt "The estimated variance of each imputed observation is recorded in new variables:"  ///
			_n as res "`p_vars'"
	}
	return local p_vars `p_vars'
	return local prices `prices'
end //  End of program makeprices


program define makeinputs, rclass
	syntax, incosts(varlist) prices(varlist) [double innames(passthru) replace]

	getnames `incosts', `innames'
		local expnames `r(names)'
	getnames `prices', `innames'
		local pnames `r(names)'
	matchnames, names1(`expnames') names2(`pnames')

	local i = 1
	foreach exp of varlist `incosts' {
		local price = word("`prices'",`i')
		local name = word("`pnames'",`i')
		if "`replace'"=="replace" {
			qui capture drop q_`name'
		}
		di as txt "Generate q_`name' = `exp' / `price'"
		gen `double' q_`name' = `exp' / `price'
			lab var q_`name' "= `exp' / `price': Generated by flexmake"
		local inputs `inputs' q_`name'
		local i = `i' + 1
	}
	return local inputs `inputs'
end //  End of program makeinputs


*  Versions:
*	1.2	Add an option for the translog version to create a variable __half and
*		include it in the factor variable expressions for squared rhs variables
*		 in regressions
*	1.3 7/15/2012	Fix a bug in generation of share variables
*	1.4 9/3/2015	Replace "genl" with "gen"
*	1.5 11/6/2015	Fix a bug in creation of the share variables from input prices & quantities.
*		Add "qui" to suppress messages about missing observations generated.
*		Add diagnostic output to summarize the missingness of the data.
*		Add the -globals- option to generate a global macro for each return macro
*		Add ability to generate input indices from shares and prices
*	1.6 12/15/2015  Cosmetic changes to add "===" underscoring.
*	1.7	5/16/2016   Changes to comments to reflect help file
*	1.8 6/21/2016	Add Boxcox transformation
*	1.9 7/7/2016	Add 1.0 to the values of all transformed variables
*	1.10 7/10/2016	For any variable to be transformed, add 1.0 only if it contains values
*					less than or equal to zero.
*					Most relevant for ln or log10 transofrmations.
*					But for comparability, can also be used with other transformations.
*					Add the -if- and -in- to the syntax command and to the transformations
*	1.11 8/15/2016	Add -qui- to suppress unwanted zeros in the tables describing the created variables.
*					Add lambda to output; Expand maximum number of outputs to 5
*	2.00 31Oct2016	Restructure program to accommodate all argument combinations
*	2.01 14Nov2016	Edit error message.
*	2.1  14Dec2016	The transformation options, ln, log10 and sqrt, are no longer required.
*					When they are omitted, no variables are not transformed, enabling
*					the factor-variable syntax to specify a quadratic cost function.
*					The output variables transformed by the -boxcox(lambda)- option
*					use the prefix "bc_" instead of "boxcox_".
*	2.3  18Jan2017	Add characteristics description when no transformation is specified
*					Return -transoutputs- and -transprices- macros
*					Add global macros for these and for -incosts-, -pvars- and -shares-
*	2.31 25Jan2017	Delete repeated line "local ownprices `ownprices' c.`trans'`_'`price1'"
*	2.32 8Feb2017	Enable the -othervars- option to return the list of other variables.
*	2.33 10Feb2017	-replace- option applies also to the total cost variable and to the
*					ancillary variables _var* produced by -impute-.
*	2.34 10Feb2017	Fix bug which prohibited lambda < 0.000001, thereby prohibiting its default value.
*	2.35 12Feb2017	When boxcox(lambda) is specified with lambda > 0, apply the boxcox transformation
*					to the dependent variable as well as to the output variables.
*					When incorrect data is given to construct total cost, display warnings as txt, not err.
*	2.36 20Apr2017	Impute the natural log of prices instead of the raw prices.
*					This approach avoids the estimation of negative prices.
*	2.37 6Jun2017	Allow the -nomake- option to suppress default specification of tcname
*					Also condition generation of price transformations on their existence
*	2.38 8Jul2017	Add -innames(.)- to the -return-ed macros
*	2.39 26Jul2017	Tweak the nomake option, assure proper r(depvar), r(transoutputs) for boxcox option
*					Allow factor and time-series variables only in the othervars(option).
*	2.40 12Sep2017	Display number of transformed < 0 seprately from number == 0
*	2.41 21Nov2017	For -globals- option, list the returned globals