*! version 2.61 April 2020 Fernando Rios-Avila
* Minor ineficiencies fixed. Sort when not needed.
* consider adjusting pvar so is fixed by income level? It may be more important when wages are involved.
* version 2.6 September 2019 Fernando Rios-Avila
* Adds options q2 iqr2 iqratio2. This allow for IF=0 when y=q(p)
* version 2.5 July 2019 Fernando Rios-Avila
* Add option for userwritten RIF
* version 2.4 March 2019 Fernando Rios-Avila
* minor changes on how UQR RIfs are saved
* Needs improvement in code for faster calculations in large datasets
* Add Sortseed to have replicable results. Important for rank dependent indices with ties, and for share variables that depend on percentile not quantile.
* Using percentile, depending on "weights" the SHARE may change because of the marginal individual.
* version 2.3 March 2019 Fernando Rios-Avila
* All indices have been tested for by option, and simulations for covariances
* version 2.2 March 2019 Fernando Rios-Avila
* This version cleans up some of the references and adds on last RIFS
* version 2.1 Feb 2019 Fernando Rios-Avila
* This version does most RIF's in the literature except for the propoor growth elasticities.
* version 2.0 Jan 2019
* This version adds the RIFS from RIF-I-O to the program
* Still by able
* version 1.0 Dec 2018
* This file is used to create RIF variables for various distributional statistics
* Their output (constrained on the correct sample) can be used to obtain results similar to
* RIFREG from Firpo Fortin Lemieux.
* Here, the variables are created across groups.
* the RIF gini was taken from RIF reg code.
* Quantiles, var and mean are taken from FFL(2018) (decomposition using RIFS)
* Poverty is based on Essama-Nssah, B. and Lambert, P. J. (2012),
* Entropy and Atkinson indices are constructed based on Cowell, F. A. and Flachaire, E. (2007),
* other statistics from Gawain Heckley RIFIREG  HEckley Gerdthan and Kjellson
* Others from
* Needs some Flags to avoid "noncompatible" options.
* Potential to add other methods

** Future Versions Cowel 2015
** Mean Deviation
** Pietra index
** Perhaps Half variance
** Sen Sorrocks inequality

** ucs mcs
*capture program drop _grifvar
program define _grifvar_old, sortpreserve
	version 8
	* Syntax sextion. Indicates what can be used and what cannot
	syntax newvarname =/exp [if] [in] ,  					///
	[, weight(varname) BY(varlist) 							/// This are options for allowing for sample weights and BY groups
	gini mean var cvar std q(str) iqr(str) kernel(str) bw(str)	/// Thes are options for basic RIFS See FFL(2018) Kernel and bw are optional.
	iqratio(str) ginismall q2(str) iqr2(str) iqratio2(str)	/// This comes from Choe Van Kerm 2018, im also adding q2, as a better alternative than q when there are ties.
	glor(str) lor(str) ucs(str) iqsr(str) mcs(str)			/// This will contain the options from Essama-NssahLambert Lorenz Glorenz and IQRS (me?)
	pov(str) pline(str) watts(str) sen(str) tip(str) 		/// This will contain the options from Essama-NssahLambert
	entropy(str) atkin(str) logvar   						/// This are RIFS from Cowell Flachaire (2007) There are other couple from Cowell 2015
	agini giniold											/// This are RIFS from HEckley Gerdthan and Kjellson Only one that is rank independent
	acindex(str) cindex(str) 								/// This are RIFS from HEckley Gerdthan and Kjellson which are Rank Dependent
	eindex(str) arcindex(str) srindex(str) windex(str) ub(str) lb(str) hvarp hvarn seed(str) /// This are RIFS from Heckley Gerdthan and Kjellson  which are Rank Dependent and with additional information
	rifown(str) rifopt(str)]
															/// hvarp and hvarn are semivariances or half variances implement by LOO
															/// ginismall better GINI for small samples undocumented
	** Data cleaning before syntax
	* This cleans the "exp" from paranthesis or spaces. Just handy
	local exp = regexr("`exp'", "\(", "")
	local exp = regexr("`exp'", "\)", "")
	local exp = regexr("`exp'", " ", "")

	tempvar touse
	quietly {
		gen byte `touse'=0
		replace  `touse'=1 `if' `in'
		if "`weight'"!="" {
			replace `touse'=0 if `weight'==.
		}
		if "`by'"!="" {
			replace `touse'=0 if `by'==.
		}
	   replace `touse'=0 if `exp'==.
	** This checks how many options have been selected	Only 1 option is allowed
	local d=("`gini'"!="")+("`ginismall'"!="")+("`mean'"!="")+("`var'"!="")+("`std'"!="")+("`cvar'"!="")+("`q'"!="")+("`q2'"!="")+("`iqr'"!="")+("`iqr2'"!="")+("`iqratio'"!="")+ ///
	        ("`glor'"!="")+("`lor'"!="")+("`ucs'"!="")+("`iqsr'"!="")+("`mcs'"!="")+("`pov'"!="")+("`entropy'"!="")+("`atkin'"!="")+ ///
			("`agini'"!="")+("`acindex'"!="")+("`cindex'"!="")+("`eindex'"!="")+("`logvar'"!="")+("`giniold'"!="")+ ///
			("`watts'"!="")+("`sen'"!="")+("`tip'"!="")+("`arcindex'"!="")+("`srindex'"!="")+("`windex'"!="")+("`rifown'"!="")

	if `d'>1  {
	display in red "Only one option allowed"
	exit
	}
	if `d'==0 {
	display in red "Need to specify at least one option"
	}
	local fweight=1
	if "`weight'"=="" {
	   local weight=1
	   local fweight=0
	}

	if "`by'"=="" {
	  tempvar by
	  gen byte `by'=1
	}

	local sysseed=c(seed)

	if "`seed'"!="" {
		tempvar sortseed
		set seed `seed'
		qui:gen double `sortseed'=rnormal()
	}
	*noisily sum `sortseed'

	** This section will Test if the options are correctly specified. Right now only checks for poverty
	if "`pov'"!="" {
	   if "`pline'"=="" {
	   display "Requires to specify a poverty line (value or variable)"
	   exit
	   }
	}
	** RIF of Mean its the variable itself. Default option.
	if ("`mean'"!="") {
	* uses default mean
	 qui:gen `typlist' `varlist'=`exp' if `touse'
	 label var `varlist' "RIF for Mean of `exp'"
	}
	** RIF of variance
	if "`var'"!="" {
		** First need to sort data and get weighted mean by group.
		sort `touse' `by'   `sortseed'
		tempvar mx
		qui: by `touse' `by': gen double `mx' = sum(`exp'*`weight')/sum(`weight') if `touse'
		qui: by `touse' `by': gen `typlist' `varlist' = (`exp'-`mx'[_N])^2       if `touse'
		label var `varlist' "RIF for Var of `exp'"
	}
	** RIF of quantile
	if "`q'"!="" {
	  numlist "`q'", min(1) max(1)  range(>0 <100)
	  sort `touse' `by'  `sortseed'
	  levelsof `by' if `touse', local(nby)
	  tempvar qvar fqvar
	   qui:gen `typlist' `varlist'=.
	  if "`kernel'"=="" {
		local kernel="gaussian"
	  }
 	  if "`bw'"!="" {
		numlist "`bw'", min(1) max(1) range(>0)
	  }

	  foreach k of local nby {
	    ** For now we use Gaussian as default, but open to change.
		*display "`nby'"
		qui:capture drop `qvar'  `fqvar'
		*obtain the Quantiles of interest (sample quantile)
		*May change to be predicted quantile
		_pctile `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1, p(`q')
		gen `qvar'=r(r1) in 1
		* If bw is declared, then estimate density at qvar using BW and Kernel
		if "`bw'"!="" {
			kdensity `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1 , nograph kernel(`kernel') at(`qvar') gen(`fqvar') bw(`bw')
		}

		else {
			* Using sivermans plug in. If no BW is selected
			qui:sum `exp' [aw=`weight'] if float(`by')==float(`k') &  `touse',d
			local sd=r(sd)
			local intqr=(r(p75)-r(p25))/1.349
			local Nobs=r(N)
			local ss=min(`sd',`intqr')
			** Other Kernels can be accomodated but for now only this
			if "`kernel'"=="gaussian" 	local d=(1/(4*_pi))^.1
			if "`kernel'"=="epan"   	local d=(3/(5*sqrt(5)))^(1/5)
			if "`kernel'"=="epan2" 		local d=15^.2
			if "`kernel'"=="biweight"  	local d=35^.2
			if "`kernel'"=="cosine" 	local d=(6/(1/6-1/_pi^2)^2)^.2
			if "`kernel'"=="parzen"		local d=2*(151/35)^.2
			if "`kernel'"=="rectan" 	local d=(9/2)^.2
			if "`kernel'"=="triangle"	local d=24^.2
			if "`kernel'"=="triweight" 	local d=(9450/143)^.2
			*silverman bw
			local bw=1.3643*`d'*`Nobs'^-.2*`ss'
			*with BW we can again estimate f(x) using kdensity
			kdensity `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1 , nograph kernel(`kernel') at(`qvar') gen(`fqvar') bw(`bw')
		}
		* This is how FFL define the RIF.
		replace `varlist'=`qvar'[1]+(`q'/100-(`exp'<`qvar'[1]))/`fqvar'[1] if float(`by')==float(`k') & `touse'==1
		* I can define it slighly different. If qvar==qvar_th, then there should be nochanges
		* in the Quantile. Exactly at the quantile should have no effect on the RIF of that quantile
		* replace `varlist'=`qvar'[1]  if float(`by')==float(`k') & float(`exp')==float(`qvar'[1]) & `touse'==1
		* However, if they have no effect on the sample quantile, they may affect the Population quantile
		* I will consider adding a predictive option "qden" so that the quantile can obtained from the smooth values
	 }
	 local bbw=round(`bw',0.00001)
  	 label var `varlist' "RIF for q(`q') with kernel(`kernel') of `exp' with bw `bbw'"
	}

		** RIF of quantile2 for ties
	if "`q2'"!="" {
	  numlist "`q2'", min(1) max(1)  range(>0 <100)
	  sort `touse' `by'   `sortseed'
	  levelsof `by' if `touse', local(nby)
	  tempvar qvar fqvar
	   qui:gen `typlist' `varlist'=.
	  if "`kernel'"=="" {
		local kernel="gaussian"
	  }
 	  if "`bw'"!="" {
		numlist "`bw'", min(1) max(1) range(>0)
	  }

	  foreach k of local nby {
	    ** For now we use Gaussian as default, but open to change.
		*display "`nby'"
		qui:capture drop `qvar'  `fqvar'
		*obtain the Quantiles of interest (sample quantile)
		*May change to be predicted quantile
		_pctile `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1, p(`q2')
		gen `qvar'=r(r1) in 1
		* If bw is declared, then estimate density at qvar using BW and Kernel
		if "`bw'"!="" {
			kdensity `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1 , nograph kernel(`kernel') at(`qvar') gen(`fqvar') bw(`bw')
		}

		else {
			* Using sivermans plug in. If no BW is selected
			qui:sum `exp' [aw=`weight'] if float(`by')==float(`k') &  `touse',d
			local sd=r(sd)
			local intqr=(r(p75)-r(p25))/1.349
			local Nobs=r(N)
			local ss=min(`sd',`intqr')
			** Other Kernels can be accomodated but for now only this
			if "`kernel'"=="gaussian" 	local d=(1/(4*_pi))^.1
			if "`kernel'"=="epan"   	local d=(3/(5*sqrt(5)))^(1/5)
			if "`kernel'"=="epan2" 		local d=15^.2
			if "`kernel'"=="biweight"  	local d=35^.2
			if "`kernel'"=="cosine" 	local d=(6/(1/6-1/_pi^2)^2)^.2
			if "`kernel'"=="parzen"		local d=2*(151/35)^.2
			if "`kernel'"=="rectan" 	local d=(9/2)^.2
			if "`kernel'"=="triangle"	local d=24^.2
			if "`kernel'"=="triweight" 	local d=(9450/143)^.2
			*silverman bw
			local bw=1.3643*`d'*`Nobs'^-.2*`ss'
			*with BW we can again estimate f(x) using kdensity
			kdensity `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1 , nograph kernel(`kernel') at(`qvar') gen(`fqvar') bw(`bw')
		}
		* This is how FFL define the RIF.
		replace `varlist'=`qvar'[1]+(`q2'/100-(`exp'<`qvar'[1]))/`fqvar'[1] if float(`by')==float(`k') & `touse'==1
		replace `varlist'=`qvar'[1] if float(`by')==float(`k') & `touse'==1  &  (float(`exp')==float(`qvar'[1]))

		* I can define it slighly different. If qvar==qvar_th, then there should be nochanges
		* in the Quantile. Exactly at the quantile should have no effect on the RIF of that quantile
		* replace `varlist'=`qvar'[1]  if float(`by')==float(`k') & float(`exp')==float(`qvar'[1]) & `touse'==1
		* However, if they have no effect on the sample quantile, they may affect the Population quantile
		* I will consider adding a predictive option "qden" so that the quantile can obtained from the smooth values
	 }
	 local bbw=round(`bw',0.00001)
  	 label var `varlist' "RIF for q2(`q2') with kernel(`kernel') of `exp' with bw `bbw'"
	}



	** RIF for interquantile difference
	if "`iqr'"!="" {
	  sort `touse' `by'  `sortseed'
	  tempvar qvar fqvar
	  tempvar qlow qhigh
	  qui: capture drop `varlist'
	  qui:gen `typlist' `varlist'=.
	  qui:gen `typlist' `qlow'=.
	  qui:gen `typlist' `qhigh'=.

	  if "`kernel'"=="" {
		local kernel="gaussian"
	  }
 	  if "`bw'"!="" {
		numlist "`bw'", min(1) max(1) range(>0)
	  }

	  levelsof `by' if `touse', local(nby)
	  numlist "`iqr'", min(2) max(2) sort range(>0 <100)
	  local i0:word 1 of `r(numlist)'
	  local i1:word 2 of `r(numlist)'
	  *foreach i in  `r(numlist)' {
	  ** Same process as with q, but for 2 points
	  local bwo="`bw'"
	    foreach k of local nby {
	    ** For now we will just use Gaussian, but open to change.
			qui:capture drop `qvar'  `fqvar'
			_pctile `exp' [aw=`weight'] if float(`by')==float(`k') & `touse', p(`i0'  `i1')
			qui:gen `qvar'=r(r1) in 1
			qui:replace `qvar'=r(r2) in 2
			if "`bwo'"!="" {
				kdensity `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1 , nograph kernel(`kernel') at(`qvar') gen(`fqvar') bw(`bw')
			}

			else {
				* Using sivermans plug in. Same BW for both points
				qui:sum `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1,d
				local sd=r(sd)
				local intqr=(r(p75)-r(p25))/1.349
				local Nobs=r(N)
				local ss=min(`sd',`intqr')
				*noisily display "sd:`sd' intqr:`intqr' nobs: `Nobs' ss:`ss'"
				if "`kernel'"=="gaussian" 	local d=(1/(4*_pi))^.1
				if "`kernel'"=="epan"   	local d=(3/(5*sqrt(5)))^(1/5)
				if "`kernel'"=="epan2" 		local d=15^.2
				if "`kernel'"=="biweight"  	local d=35^.2
				if "`kernel'"=="cosine" 	local d=(6/(1/6-1/_pi^2)^2)^.2
				if "`kernel'"=="parze" 		local d=2*(151/35)^.2
				if "`kernel'"=="rectan" 	local d=(9/2)^.2
				if "`kernel'"=="triangle" 		local d=24^.2
				if "`kernel'"=="triweight" 	local d=(9450/143)^.2
				*silverman bw
				local bw=1.3643*`d'*`Nobs'^-.2*`ss'
 				kdensity `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1 , nograph kernel(`kernel') at(`qvar') gen(`fqvar') bw(`bw')
			}

			* see above for discussion on the commented step.
			qui:replace `qlow' =`qvar'[1]+(`i0'/100-(`exp'<`qvar'[1]))/`fqvar'[1]  if float(`by')==float(`k') & `touse'==1
			*qui:replace `qlow'=`qvar'[1] 										    if float(`by')==float(`k') & float(`exp')==float(`qvar'[1]) & `touse'==1
			qui:replace `qhigh' =`qvar'[2]+(`i1'/100-(`exp'<`qvar'[2]))/`fqvar'[2] if float(`by')==float(`k') & `touse'==1
			*qui:replace `qhigh'=`qvar'[2] 									 	    if float(`by')==float(`k') & float(`exp')==float(`qvar'[2]) & `touse'==1
		}
	 * For Replacing IF for IQR
	   qui:replace  `varlist'=`qhigh'-`qlow' if `touse'
       local bbw=round(`bw',0.00001)
	   label var `varlist' "RIF for Interquantile difference(`i1' `i0') of `exp' with bw `bbw'"
	 }
	*** like IQR but allows for ties
	if "`iqr2'"!="" {
	  sort `touse' `by'   `sortseed'
	  tempvar qvar fqvar
	  tempvar qlow qhigh
	  qui: capture drop `varlist'
	  qui:gen `typlist' `varlist'=.
	  qui:gen `typlist' `qlow'=.
	  qui:gen `typlist' `qhigh'=.

	  if "`kernel'"=="" {
		local kernel="gaussian"
	  }
 	  if "`bw'"!="" {
		numlist "`bw'", min(1) max(1) range(>0)
	  }

	  levelsof `by' if `touse', local(nby)
	  numlist "`iqr2'", min(2) max(2) sort range(>0 <100)
	  local i0:word 1 of `r(numlist)'
	  local i1:word 2 of `r(numlist)'
	  *foreach i in  `r(numlist)' {
	  ** Same process as with q, but for 2 points
	  local bwo="`bw'"
	    foreach k of local nby {
	    ** For now we will just use Gaussian, but open to change.
			qui:capture drop `qvar'  `fqvar'
			_pctile `exp' [aw=`weight'] if float(`by')==float(`k') & `touse', p(`i0'  `i1')
			qui:gen `qvar'=r(r1) in 1
			qui:replace `qvar'=r(r2) in 2
			if "`bwo'"!="" {
				kdensity `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1 , nograph kernel(`kernel') at(`qvar') gen(`fqvar') bw(`bw')
			}

			else {
				* Using sivermans plug in. Same BW for both points
				qui:sum `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1,d
				local sd=r(sd)
				local intqr=(r(p75)-r(p25))/1.349
				local Nobs=r(N)
				local ss=min(`sd',`intqr')
				*noisily display "sd:`sd' intqr:`intqr' nobs: `Nobs' ss:`ss'"
				if "`kernel'"=="gaussian" 	local d=(1/(4*_pi))^.1
				if "`kernel'"=="epan"   	local d=(3/(5*sqrt(5)))^(1/5)
				if "`kernel'"=="epan2" 		local d=15^.2
				if "`kernel'"=="biweight"  	local d=35^.2
				if "`kernel'"=="cosine" 	local d=(6/(1/6-1/_pi^2)^2)^.2
				if "`kernel'"=="parze" 		local d=2*(151/35)^.2
				if "`kernel'"=="rectan" 	local d=(9/2)^.2
				if "`kernel'"=="triangle" 		local d=24^.2
				if "`kernel'"=="triweight" 	local d=(9450/143)^.2
				*silverman bw
				local bw=1.3643*`d'*`Nobs'^-.2*`ss'
 				kdensity `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1 , nograph kernel(`kernel') at(`qvar') gen(`fqvar') bw(`bw')
			}

			* see above for discussion on the commented step.
			qui:replace `qlow' =`qvar'[1]+(`i0'/100-(`exp'<`qvar'[1]))/`fqvar'[1]  if float(`by')==float(`k') & `touse'==1
			qui:replace `qlow'=`qvar'[1] 										   if float(`by')==float(`k') & float(`exp')==float(`qvar'[1]) & `touse'==1
			qui:replace `qhigh' =`qvar'[2]+(`i1'/100-(`exp'<`qvar'[2]))/`fqvar'[2] if float(`by')==float(`k') & `touse'==1
			qui:replace `qhigh'=`qvar'[2] 									 	   if float(`by')==float(`k') & float(`exp')==float(`qvar'[2]) & `touse'==1
		}
	 * For Replacing IF for IQR
	   qui:replace  `varlist'=`qhigh'-`qlow' if `touse'
       local bbw=round(`bw',0.00001)
	   label var `varlist' "RIF for Interquantile difference(`i1' `i0') of `exp' with bw `bbw'"
	 }


	** RIF of Gini. Last done in FFL 2018. Follows RIFREG code
	/*if "`gini'"=="gini"  {
		 sort `touse' `by' `exp'
		  qui{
			  *Get totals first
				tempvar glp rnk vcv ggini rf
			  *_prank au1 au2 au3, svar(price) mvar(mpg) tvar(touse)
				_prank `glp' `rnk' `vcv' , svar(`exp') mvar(`exp') tvar(`touse') byvar(`by')
				by `touse' `by':gen double `ggini'=2/`glp'[_N]*`vcv'[_N]           if `touse'
				*by `touse' `by':gen `typlist' `varlist' =`ggini'
				by `touse' `by':gen double `rf' = sum(`glp'*(`rnk'-`rnk'[_n-1]))
				by `touse' `by':gen `typlist' `varlist' =(2/`glp'[_N]*`rf'[_N])*`exp'/`glp'[_N]+2/`glp'[_N]*(`exp'*(`rnk'-1)-`glp') +1 if `touse'

			  *gen pd0 = `rnk'
			  *1-2*`glp'/`glp'[_N]+`exp'*(1-`ggini'-2*(1-`rnk'))/`glp'[_N] if `touse'
			  *by `touse' `by':gen `typlist' `varlist' =(2/`mns'*`rf')*`exp'/`mns'+2/`mns'*(`exp'*(`pvar'-1)-`glp') +1 if `touse'
			  * At some point add :SMALL correction
			  label var `varlist' "RIF for gini of `exp'"
		  }
	 }  */

	if "`gini'"!=""  {
     levelsof `by' if `touse', local(nby)
	 sort `touse' `by' `exp' `sortseed'
	  qui{
      *Get totals first
	  tempvar cum_wt mns cumwy tot_wt pvar padj mns glp rfvar rf ggini
	  tempvar rfx
	  by `touse' `by':gen double `cum_wt'=sum(`weight')
	  by `touse' `by':gen double `tot_wt'=`cum_wt'[_N]
	  by `touse' `by':gen double `pvar' = `cum_wt'/`tot_wt'
	  by `touse' `by':gen double `glp'=sum(`exp'*`weight'/`tot_wt')
	  by `touse' `by':gen double `mns'=`glp'[_N]
	  gen double `rfvar'=.
	  by `touse' `by':integ `glp' `pvar', gen(`rfvar') replace
	  by `touse' `by':gen double `rf' =  `rfvar'[_N]
	  by `touse' `by':gen double `ggini'=1-2/`mns'*`rf'            if `touse'
      by `touse' `by':gen `typlist' `varlist' =(2/`mns'*`rf')*`exp'/`mns'+2/`mns'*(`exp'*(`pvar'-1)-`glp') +1 if `touse'
	  * At some point add :SMALL correction
	  label var `varlist' "RIF for gini of `exp'"
      }
	 }
	 *** This is another variance of GINI. Should give similar results. It creates an adjustment on F(y)
	 *** currently not used
	 if "`ginismall'"=="ginismall"  {
      levelsof `by' if `touse', local(nby)
	  sort `touse' `by' `exp' `sortseed'
	  qui{
      *Get totals first
	  tempvar cum_wt mns cumwy tot_wt pvar mns glp covpx ggini padj
	  tempvar rfx
	  by `touse' `by':gen double `cum_wt'=sum(`weight')
	  by `touse' `by':gen double `tot_wt'=`cum_wt'[_N]
	  by `touse' `by':gen double `pvar' = `cum_wt'/`tot_wt'
	  by `touse' `by':gen double `padj' = max(0,`pvar'[_n-1])+((`pvar'-max(0,`pvar'[_n-1]))/2)
	  *egen t1=sum((ix1-4.525895)*(padj-0.5)*(w)/73)
	  gen pd1 = `padj'
	  by `touse' `by':gen double `glp'=sum(`exp'*`weight'/`tot_wt')
	  by `touse' `by':gen double `mns'=`glp'[_N]
	  by `touse' `by':gen double `covpx'=sum((`exp'-`mns')*(`padj'-0.5)*`weight'/`tot_wt')
	  by `touse' `by':gen double `ggini'=2/`mns'*`covpx'[_N]
 	  if `fweight'==1 {
	      by `touse' `by':gen `typlist' `varlist' =1-2*`glp'/`mns'+`exp'*(1-`ggini'-2*(1-`padj'))/`mns' if `touse'
	  }
	  else {
	      by `touse' `by':gen `typlist' `varlist' =1-2*`glp'/`mns'+`exp'*(1-`ggini'-2*(1-`pvar'))/`mns' if `touse'
	  }

	  *by `touse' `by':gen `typlist' `varlist' =1-2*`glp'/`mns'+`exp'*(1-`ggini'-2*(1-`pvar'))/`mns'
      label var `varlist' "RIF for gini of `exp'"
      }
	 }

    ** Coefficient of variation. From Firpo and Pinto(2016)	. I ll set it here because its kind of the baby from FFL
	if "`cvar'"!="" {
	  qui {
  	  sort `touse' `by' `exp' `sortseed'
	  tempvar cum_wt mns mnssq cumwy tot_wt icvar
	  by `touse' `by':gen double `cum_wt'=sum(`weight')
	  by `touse' `by':gen double `tot_wt'=`cum_wt'[_N]
	  by `touse' `by':gen double `mns'=sum(`exp'*`weight'/`tot_wt')
	  by `touse' `by':replace    `mns'=`mns'[_N]
	  by `touse' `by':gen double `mnssq'=sum(`exp'^2*`weight'/`tot_wt')
	  by `touse' `by':replace    `mnssq'=`mnssq'[_N]
	  *** CV
	  *** RIF
  	  by `touse' `by':gen `typlist' `varlist' =(`mnssq'-`mns'^2)^0.5/`mns'+1/2*((`exp'-`mns')^2-(`mnssq'-`mns'^2))/(`mns'*(`mnssq'-`mns'^2)^.5)-(`exp'-`mns')*(`mnssq'-`mns'^2)^.5/(`mns'^2) if `touse'
      label var `varlist' "RIF for coefficient of variation of `exp'"
	 }
	}

	*** standard deviation RIF. Based on CVAR
	if "`std'"!="" {
	  qui {
  	  sort `touse' `by' `exp' `sortseed'
	  tempvar cum_wt mns mnssq cumwy tot_wt icvar
	  by `touse' `by':gen double `cum_wt'=sum(`weight')
	  by `touse' `by':gen double `tot_wt'=`cum_wt'[_N]
	  by `touse' `by':gen double `mns'=sum(`exp'*`weight'/`tot_wt')
	  by `touse' `by':replace    `mns'=`mns'[_N]
	  by `touse' `by':gen double `mnssq'=sum(`exp'^2*`weight'/`tot_wt')
	  by `touse' `by':replace    `mnssq'=`mnssq'[_N]
	  *** CV
	  *** RIF
  	  by `touse' `by':gen `typlist' `varlist' =(`mnssq'-`mns'^2)^0.5+1/2*((`exp'-`mns')^2-(`mnssq'-`mns'^2))/((`mnssq'-`mns'^2)^.5)  if `touse'
      label var `varlist' "RIF for Standard deviation of `exp'"
	 }
	}

	*********************************************************************************************************
	** This one is from Choe Van Kerm
	** Interquartile Ratio
	if "`iqratio'"!="" {
	  sort `touse' `by'   `sortseed'
	  tempvar qvar fqvar
	  tempvar qlow qhigh
	  qui: capture drop `varlist'
	  qui:gen `typlist' `varlist'=.
	  qui:gen `typlist' `qlow'=.
	  qui:gen `typlist' `qhigh'=.
	  if "`kernel'"=="" {
		local kernel="gaussian"
	  }
 	  if "`bw'"!="" {
		numlist "`bw'", min(1) max(1) range(>0)
	  }
	  levelsof `by' if `touse', local(nby)
	  numlist "`iqratio'", min(2) max(2) sort range(>0 <100)
	  local i0:word 1 of `r(numlist)'
	  local i1:word 2 of `r(numlist)'
	  ** original bwo
  	  local bwo="`bw'"

	  *foreach i in  `r(numlist)' {
	  ** Same process as with q, but for 2 points
	    foreach k of local nby {
	    ** For now we will just use Gaussian, but open to change.
			qui:capture drop `qvar'  `fqvar'
			_pctile `exp' [aw=`weight'] if float(`by')==float(`k') & `touse', p(`i0'  `i1')
			qui:gen `qvar'=r(r1) in 1
			qui:replace `qvar'=r(r2) in 2
			if "`bwo'"!="" {
				kdensity `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1 , nograph kernel(`kernel') at(`qvar') gen(`fqvar') bw(`bw')
			}
			else {
				* Using sivermans plug in. Same BW for both points
				qui:sum `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1,d
				local sd=r(sd)
				local intqr=(r(p75)-r(p25))/1.349
				local Nobs=r(N)
				local ss=min(`sd',`intqr')
				if "`kernel'"=="gaussian" 	local d=(1/(4*_pi))^.1
				if "`kernel'"=="epan"   	local d=(3/(5*sqrt(5)))^(1/5)
				if "`kernel'"=="epan2" 		local d=15^.2
				if "`kernel'"=="biweight"  	local d=35^.2
				if "`kernel'"=="cosine" 	local d=(6/(1/6-1/_pi^2)^2)^.2
				if "`kernel'"=="parze" 		local d=2*(151/35)^.2
				if "`kernel'"=="rectan" 	local d=(9/2)^.2
				if "`kernel'"=="triangle"   local d=24^.2
				if "`kernel'"=="triweight" 	local d=(9450/143)^.2
				*silverman bw
				local bw=1.3643*`d'*`Nobs'^-.2*`ss'
 				kdensity `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1 , nograph kernel(`kernel') at(`qvar') gen(`fqvar') bw(`bw')
			}
			* see above for discussion on the commented step.
			qui:replace `qlow' =(`i0'/100-(`exp'<`qvar'[1]))/`fqvar'[1]  if float(`by')==float(`k') & `touse'==1
			*qui:replace `qlow'=`qvar'[1] 										    if float(`by')==float(`k') & float(`exp')==float(`qvar'[1]) & `touse'==1
			qui:replace `qhigh' =(`i1'/100-(`exp'<`qvar'[2]))/`fqvar'[2] if float(`by')==float(`k') & `touse'==1
			*qui:replace `qhigh'=`qvar'[2] 									 	    if float(`by')==float(`k') & float(`exp')==float(`qvar'[2]) & `touse'==1
			qui:replace  `varlist'=`qvar'[2]/`qvar'[1]+1/`qvar'[1]*(`qhigh'-`qvar'[2]/`qvar'[1]*`qlow') if float(`by')==float(`k') & `touse'==1
		}
	 * For Replacing IF for iqratio
	    *** Formula is IQR
	    label var `varlist' "RIF for Inter quantile ratio(`i1' `i0') of `exp'"
	 }

	*iqratio2 for ties at q(p)
	if "`iqratio2'"!="" {
	  sort `touse' `by'   `sortseed'
	  tempvar qvar fqvar
	  tempvar qlow qhigh
	  qui: capture drop `varlist'
	  qui:gen `typlist' `varlist'=.
	  qui:gen `typlist' `qlow'=.
	  qui:gen `typlist' `qhigh'=.
	  if "`kernel'"=="" {
		local kernel="gaussian"
	  }
 	  if "`bw'"!="" {
		numlist "`bw'", min(1) max(1) range(>0)
	  }
	  levelsof `by' if `touse', local(nby)
	  numlist "`iqratio2'", min(2) max(2) sort range(>0 <100)
	  local i0:word 1 of `r(numlist)'
	  local i1:word 2 of `r(numlist)'
	  ** original bwo
  	  local bwo="`bw'"

	  *foreach i in  `r(numlist)' {
	  ** Same process as with q, but for 2 points
	    foreach k of local nby {
	    ** For now we will just use Gaussian, but open to change.
			qui:capture drop `qvar'  `fqvar'
			_pctile `exp' [aw=`weight'] if float(`by')==float(`k') & `touse', p(`i0'  `i1')
			qui:gen `qvar'=r(r1) in 1
			qui:replace `qvar'=r(r2) in 2
			if "`bwo'"!="" {
				kdensity `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1 , nograph kernel(`kernel') at(`qvar') gen(`fqvar') bw(`bw')
			}
			else {
				* Using sivermans plug in. Same BW for both points
				qui:sum `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1,d
				local sd=r(sd)
				local intqr=(r(p75)-r(p25))/1.349
				local Nobs=r(N)
				local ss=min(`sd',`intqr')
				if "`kernel'"=="gaussian" 	local d=(1/(4*_pi))^.1
				if "`kernel'"=="epan"   	local d=(3/(5*sqrt(5)))^(1/5)
				if "`kernel'"=="epan2" 		local d=15^.2
				if "`kernel'"=="biweight"  	local d=35^.2
				if "`kernel'"=="cosine" 	local d=(6/(1/6-1/_pi^2)^2)^.2
				if "`kernel'"=="parze" 		local d=2*(151/35)^.2
				if "`kernel'"=="rectan" 	local d=(9/2)^.2
				if "`kernel'"=="triangle" 		local d=24^.2
				if "`kernel'"=="triweight" 	local d=(9450/143)^.2
				*silverman bw
				local bw=1.3643*`d'*`Nobs'^-.2*`ss'
 				kdensity `exp' [aw=`weight'] if float(`by')==float(`k') & `touse'==1 , nograph kernel(`kernel') at(`qvar') gen(`fqvar') bw(`bw')
			}
			* see above for discussion on the commented step.
			qui:replace `qlow' =(`i0'/100-(`exp'<`qvar'[1]))/`fqvar'[1]  if float(`by')==float(`k') & `touse'==1
			qui:replace `qlow'=`qvar'[1] 										    if float(`by')==float(`k') & float(`exp')==float(`qvar'[1]) & `touse'==1
			qui:replace `qhigh' =(`i1'/100-(`exp'<`qvar'[2]))/`fqvar'[2] if float(`by')==float(`k') & `touse'==1
			qui:replace `qhigh'=`qvar'[2] 									 	    if float(`by')==float(`k') & float(`exp')==float(`qvar'[2]) & `touse'==1
			qui:replace  `varlist'=`qvar'[2]/`qvar'[1]+1/`qvar'[1]*(`qhigh'-`qvar'[2]/`qvar'[1]*`qlow') if float(`by')==float(`k') & `touse'==1
		}
	 * For Replacing IF for iqratio
	    *** Formula is IQR
	    label var `varlist' "RIF for Inter quantile ratio(`i1' `i0') of `exp'"
	 }
	*********************************************************************************************************
	** From here on it follows ESSANNA Lambert
	** RIF for Glorenz
	 if "`glor'"!="" {
	 *technically for glor=100 we get th mean, which reverts to the default case i think.
		numlist "`glor'", min(1) max(1)  range(>0 <100)
		levelsof `by' if `touse', local(nby)
		sort `touse' `by' `exp' `sortseed'
		tempvar qvar
		qui:gen `typlist' `varlist'=.
		foreach k of local nby {
	    	qui:capture drop `qvar'
			_pctile `exp' [aw=`weight'] if float(`by')==float(`k') & `touse', p(`glor')
		    qui:gen `qvar'=r(r1) in 1
		 ** need qntl done above and glp? Lets assume not for now.
		   	replace `varlist'=`exp'-(1-`glor'/100)*`qvar'[1] if float(`by')==float(`k') & `exp'<`qvar'[1]  & `touse'
		    replace `varlist'= `glor'/100*`qvar'[1]          if float(`by')==float(`k') & `exp'>=`qvar'[1] & `touse'
		}

		label var `varlist' "RIF for Glorenz ordinate at p(`glor') of `exp'"
	}
	** RIF lorenz
	** Im erasing the _n-1 for the lorenz Cant remember why i put it there to begin with
    if "`lor'"!="" {
       numlist "`lor'", min(1) max(1)  range(>0 <100)
	   local lorp=`lor'/100
       levelsof `by' if `touse', local(nby)
	   sort `touse' `by' `exp' `sortseed'
	   tempvar qvar cum_wt glp lpc mu lpcp
	   qui:gen `typlist' `varlist'=.
       by `touse' `by':gen double `cum_wt'=sum(`weight')
	   by `touse' `by':gen double `glp'=sum(`exp'*`weight'/`cum_wt'[_N])
  	   by `touse' `by':gen double `mu'=`glp'[_N]

	   ** lorenz Truncated
	   by `touse' `by':gen double `lpc'=sum(`exp'/`glp'[_N]*`weight'/`cum_wt'[_N]*((`cum_wt'[_n]/`cum_wt'[_N])<=`lorp'))
	   by `touse' `by':gen double `lpcp'=`lpc'[_N]
	   foreach k of local nby {
	    	qui:capture drop `qvar'
			_pctile `exp' [aw=`weight'] if float(`by')==float(`k') & `touse', p(`lor')
		    qui:gen `qvar'=r(r1) in 1
			*sum `exp' [aw=`weight'] if float(`by')==float(`k') & `touse',meanonly
		 ** need qntl done above and glp? Lets assume not for now.
		   	replace `varlist'=(`exp'-(1-`lorp')*`qvar'[1])/`mu'+`lpcp'*(1-`exp'/`mu') if float(`by')==float(`k') & `exp'<`qvar'[1]  & `touse'
		    replace `varlist'=          (`lorp'*`qvar'[1])/`mu'+`lpcp'*(1-`exp'/`mu') if float(`by')==float(`k') & `exp'>=`qvar'[1] & `touse'
		}
		label var `varlist' "RIF for Lorenz ordinate at p(`lor') of `exp'"
	}

	** RIF 1-lorenz. Upper lorenz?
    if "`ucs'"!="" {
       numlist "`ucs'", min(1) max(1)  range(>0 <100)
	   local lorp=`ucs'/100
       levelsof `by' if `touse', local(nby)
	   sort `touse' `by' `exp' `sortseed'
	   tempvar qvar cum_wt glp lpc mu lpcp
	   qui:gen `typlist' `varlist'=.
       by `touse' `by':gen double `cum_wt'=sum(`weight')
	   by `touse' `by':gen double `glp'=sum(`exp'*`weight'/`cum_wt'[_N])
  	   by `touse' `by':gen double `mu'=`glp'[_N]

	   ** lorenz Truncated
	   by `touse' `by':gen double `lpc'=sum(`exp'/`glp'[_N]*`weight'/`cum_wt'[_N]*((`cum_wt'[_n]/`cum_wt'[_N])<=`lorp'))
	   by `touse' `by':gen double `lpcp'=`lpc'[_N]
	   foreach k of local nby {
	    	qui:capture drop `qvar'
			_pctile `exp' [aw=`weight'] if float(`by')==float(`k') & `touse', p(`ucs')
		    qui:gen `qvar'=r(r1) in 1
			*sum `exp' [aw=`weight'] if float(`by')==float(`k') & `touse',meanonly
		 ** need qntl done above and glp? Lets assume not for now.
		   	replace `varlist'=(`exp'-(1-`lorp')*`qvar'[1])/`mu'+`lpcp'*(1-`exp'/`mu') if float(`by')==float(`k') & `exp'<`qvar'[1]  & `touse'
		    replace `varlist'=          (`lorp'*`qvar'[1])/`mu'+`lpcp'*(1-`exp'/`mu') if float(`by')==float(`k') & `exp'>=`qvar'[1] & `touse'
			replace `varlist'=1-`varlist' if float(`by')==float(`k')  & `touse'
		}
		label var `varlist' "RIF for Upper class share: 1-Lorenz ordinate at p(`ucs') of `exp'"
	}


	** RIF iqrs

	if "`iqsr'"!="" {
	  sort `touse' `by' `exp' `sortseed'
	  tempvar qvar fqvar
	  tempvar qlow qhigh
	  **gens new var
	  qui:gen `typlist' `varlist'=.
	  qui:gen `typlist' `qlow'=.
	  qui:gen `typlist' `qhigh'=.
	  levelsof `by' if `touse', local(nby)
	  numlist "`iqsr'", min(2) max(2) sort range(>0 <100)
	  local i0:word 1 of `r(numlist)'
	  local i1:word 2 of `r(numlist)'
	  * Rescaling
	  local i0p=`i0'/100
	  local i1p=`i1'/100
	  tempvar cum_wt glp lpc0 lpc1 mu
      by `touse' `by':gen double `cum_wt'=sum(`weight')
	  by `touse' `by':gen double `glp'=sum(`exp'*`weight'/`cum_wt'[_N])
	  by `touse' `by':gen double `mu'=`glp'[_N]
	  ** lorenz Truncated
	  tempvar lpc0 lpc1	lpc0p lpc1p
  	  by `touse' `by':gen double `lpc0'=sum(`exp'/`glp'[_N]*`weight'/`cum_wt'[_N]*((`cum_wt'[_n]/`cum_wt'[_N])<=`i0p'))
	  by `touse' `by':gen double `lpc0p'=`lpc0'[_N]
	  by `touse' `by':gen double `lpc1'=sum(`exp'/`glp'[_N]*`weight'/`cum_wt'[_N]*((`cum_wt'[_n]/`cum_wt'[_N])<=`i1p'))
	  by `touse' `by':gen double `lpc1p'=`lpc1'[_N]
	  ** Same process as for lorenz, but for 2
 	  foreach k of local nby {
	    	qui:capture drop `qvar'
			_pctile `exp' [aw=`weight'] if float(`by')==float(`k') & `touse', p(`i0' `i1')
		    qui:gen double `qvar'=r(r1) in 1
			qui:replace    `qvar'=r(r2) in 2
			*sum `exp' [aw=`weight'] if float(`by')==float(`k') & `touse',meanonly
			** This are the IF's
			** Try to clean the code a bit
		   	replace `qlow' =(`exp'-(1-`i0p')*`qvar'[1])/`mu'+`lpc0p'*(-`exp'/`mu') if float(`by')==float(`k') & `exp'<`qvar'[1]  & `touse'
		    replace `qlow' =         (`i0p' *`qvar'[1])/`mu'+`lpc0p'*(-`exp'/`mu') if float(`by')==float(`k') & `exp'>=`qvar'[1] & `touse'
			replace `qhigh'=(`exp'-(1-`i1p')*`qvar'[2])/`mu'+`lpc1p'*(-`exp'/`mu') if float(`by')==float(`k') & `exp'<`qvar'[2]  & `touse'
		    replace `qhigh'=         (`i1p' *`qvar'[2])/`mu'+`lpc1p'*(-`exp'/`mu') if float(`by')==float(`k') & `exp'>=`qvar'[2] & `touse'
	  }
	  *noisily display (1-`lpc1'[_N])/`lpc0'[_N]  "   " `lpc0'[_N] "   " `lpc1'[_N]
	  qui:replace `varlist'=(1-`lpc1p')/`lpc0p'+1/`lpc0p'*(-`qhigh'-(1-`lpc1p')/`lpc0p'*`qlow')
	  label var `varlist' "RIF for IQSR p(`i0' `i1') of `exp'"
	}

	********************************
	** MIddle class share
	if "`mcs'"!="" {
	  sort `touse' `by' `exp' `sortseed'
	  tempvar qvar fqvar
	  tempvar qlow qhigh
	  **gens new var
	  qui:gen `typlist' `varlist'=.
	  qui:gen `typlist' `qlow'=.
	  qui:gen `typlist' `qhigh'=.
	  levelsof `by' if `touse', local(nby)
	  numlist "`mcs'", min(2) max(2) sort range(>0 <100)
	  local i0:word 1 of `r(numlist)'
	  local i1:word 2 of `r(numlist)'
	  * Rescaling
	  local i0p=`i0'/100
	  local i1p=`i1'/100
	  tempvar cum_wt glp lpc0 lpc1 mu
      by `touse' `by':gen double `cum_wt'=sum(`weight')
	  by `touse' `by':gen double `glp'=sum(`exp'*`weight'/`cum_wt'[_N])
	  by `touse' `by':gen double `mu'=`glp'[_N]
	  ** lorenz Truncated
	  tempvar lpc0 lpc1	lpc0p lpc1p
  	  by `touse' `by':gen double `lpc0'=sum(`exp'/`glp'[_N]*`weight'/`cum_wt'[_N]*((`cum_wt'[_n]/`cum_wt'[_N])<=`i0p'))
	  by `touse' `by':gen double `lpc0p'=`lpc0'[_N]
	  by `touse' `by':gen double `lpc1'=sum(`exp'/`glp'[_N]*`weight'/`cum_wt'[_N]*((`cum_wt'[_n]/`cum_wt'[_N])<=`i1p'))
	  by `touse' `by':gen double `lpc1p'=`lpc1'[_N]
	  ** Same process as for lorenz, but for 2
 	  foreach k of local nby {
	    	qui:capture drop `qvar'
			_pctile `exp' [aw=`weight'] if float(`by')==float(`k') & `touse', p(`i0' `i1')
		    qui:gen double `qvar'=r(r1) in 1
			qui:replace    `qvar'=r(r2) in 2
			*sum `exp' [aw=`weight'] if float(`by')==float(`k') & `touse',meanonly
			** This are the IF's
			** Try to clean the code a bit
		   	replace `qlow' =(`exp'-(1-`i0p')*`qvar'[1])/`mu'+`lpc0p'*(-`exp'/`mu') if float(`by')==float(`k') & `exp'<`qvar'[1]  & `touse'
		    replace `qlow' =         (`i0p' *`qvar'[1])/`mu'+`lpc0p'*(-`exp'/`mu') if float(`by')==float(`k') & `exp'>=`qvar'[1] & `touse'
			replace `qhigh'=(`exp'-(1-`i1p')*`qvar'[2])/`mu'+`lpc1p'*(-`exp'/`mu') if float(`by')==float(`k') & `exp'<`qvar'[2]  & `touse'
		    replace `qhigh'=         (`i1p' *`qvar'[2])/`mu'+`lpc1p'*(-`exp'/`mu') if float(`by')==float(`k') & `exp'>=`qvar'[2] & `touse'
	  }
	  *noisily display (1-`lpc1'[_N])/`lpc0'[_N]  "   " `lpc0'[_N] "   " `lpc1'[_N]
	  qui:replace `varlist'=(`lpc1p'-`lpc0p')+(`qhigh'-`qlow')
	    label var `varlist' "RIF for Middle class share at p(`i0' `i1') of `exp'"
	}
	******************************


	**RIF poverty. Flexible to admit any value for pov (0 headcount 1 poverty gap 2 poverty severity)
	** can also use either a fixed poverty line or a variable poverty line
    if "`pov'"!="" & "`pline'"!="" {
       numlist "`pov'", min(1) max(1)  range(>=0 )
		replace `touse'=. if `pline'==.
	   ** pov provides degree of sensitivity. pline the poverty line
 	   gen `typlist' `varlist'=.
	   * This estimates the standardized/censored income distribution
	   tempvar incz
	   gen double `incz'=(`pline'>`exp')*(`pline'-`exp')/`pline' if `touse'
	   if `pov'==0 {
	    qui:replace `varlist'=(`pline'>`exp') if   `touse'
	   }
	   else {
	    qui:replace `varlist'=`incz'^`pov'
	   }
	   label var `varlist' "RIF for FGT poverty with alpha=`pov' and pline:`pline' of `exp'"
	}
	*****
	* Other ESSAMMA indices
	* watts poverty index can be used with different poverty measures. So assume for now its either a variable or number
	if "`watts'"!="" {
	     sort `touse' `by'   `sortseed'
	     by `touse' `by':gen `typlist' `varlist'=ln(`watts'/`exp')*(`watts'>=`exp')
	}
	* Sen index
	if "`sen'"!="" {
		sort `touse' `by' `exp' `sortseed'
	    tempvar cum_wt tot_wt pvar cums isen glp
 	    by `touse' `by':gen double `cum_wt'=sum(`weight')
		by `touse' `by':gen double `tot_wt'=`cum_wt'[_N]
		by `touse' `by':gen double `pvar' = sum(`weight'/`tot_wt'*(`exp'<=`sen'))

		*we will use sample data for this
		* check if we can interpolate Pvar[N] when poverty line is far from the upper poor limit
 		by `touse' `by':gen double `cums' =sum((`sen'-`exp')*(`pvar'[_N]-`pvar')*(`sen'>=`exp')*`weight'/`tot_wt')
		by `touse' `by':gen double `glp' =sum(`exp'*(`sen'>=`exp')*`weight'/`tot_wt')

		by `touse' `by':gen double `isen'=2/(`sen'*`pvar'[_N])*`cums'[_N]
		tempvar fzfy intfzfy
		*by `touse' `by':gen double `fzfy'=`pvar'[_N]-`pvar'
		*gen double `intfzfy'=.
        *by `touse' `by':integ `fzfy' `exp', gen(`intfzfy') replace
		** THE RIF
		by `touse' `by':gen `typlist' `varlist'=2/(`sen'*`pvar'[_N])*(`sen'*`pvar'[_N]-1/2*`sen'*`isen'-`exp'*`pvar'[_N]+`exp'*`pvar'-`glp')

		*2-		1/`pvar'[_N]*`isen'-2/(`sen'*`pvar'[_N])*`intfzfy'  if `exp'<=`sen'
		by `touse' `by':replace  `varlist'=0 if `exp'>`sen'
	   label var `varlist' "RIF for Sen poverty index of `exp'"

	}
	*TIP curves for poverty line z at ordinate p
	*tip(p) pov()
	if "`tip'"!="" {
		*assuming excludes 0 - 100
       numlist "`tip'", min(1) max(1)  range(>0 <100)
	    sort `touse' `by' `exp' `sortseed'
	   if "`pline'"=="" {
	     noisily display "Requires to specify a poverty line using pline() option"
	     exit
	   }

	   numlist "`pline'", min(1) max(1)  range(>0)
	    tempvar cum_wt tot_wt pvar cums ptile aptile itip
 	    by `touse' `by':gen double `cum_wt'=sum(`weight')
		by `touse' `by':gen double `tot_wt'=`cum_wt'[_N]
		by `touse' `by':gen double `pvar' = sum(`weight'/`tot_wt'*(`exp'<=`pline'))

		* TIP pth quantile by group:
		by `touse' `by':gen double `aptile' =`exp' if (`cum_wt'/`tot_wt')>=`tip'/100
		by `touse' `by':egen double `ptile' =min(`aptile')
		* TIP ordinate
		by `touse' `by':gen double `itip' =sum(((`pvar'[_N])<=(`tip'/100))*(`pline'>=`exp')*(`pline'-`exp')*`weight'/`tot_wt')
		* THE RIF
		by `touse' `by':gen `typlist' `varlist'=(`pline'-`exp')									if `exp'<=`pline' & `pline'<=`ptile'
		by `touse' `by':replace 	  `varlist'=0							 		        	if `exp'> `pline' & `pline'<=`ptile'
		by `touse' `by':replace 	  `varlist'=`tip'/100*`pline'+(1-`tip'/100)*`ptile'-`exp'	if `exp'<=`ptile' & `pline'>`ptile'
		by `touse' `by':replace 	  `varlist'=`tip'/100*(`pline'-`ptile') 					if `exp'>`ptile'  & `pline'>`ptile'
	}
	** Pro poorness statistics seem not to be adequate here. It requires to estimate growth by quantiles, and not clear how is that done.
	*************************************************************************************************************
	*************************************************************************************************************
	** From here on we follow Cawley Flechaire 2007
	**Entropy Index
	if "`entropy'"!="" {
       numlist "`entropy'", min(1) max(1)
	   sort `touse' `by' `exp' `sortseed'
	   ** there could be 3 cases ENT=0 =1 =something else
	   if `entropy'==0 {
	   * first entropy: Mean Log deviation
	      tempvar v mu cum_wt e0
          by `touse' `by':gen double `cum_wt'=sum(`weight')
          by `touse' `by':gen double `v'=sum(log(`exp')*`weight'/`cum_wt'[_N])
		  by `touse' `by':gen double `mu'=sum(`exp'*`weight'/`cum_wt'[_N])
          by `touse' `by':gen double `e0'=log(`mu'[_N])-`v'[_N]
		  by `touse' `by':gen `typlist' `varlist'=`e0'-(log(`exp')-`v'[_N])+1/`mu'[_N]*(`exp'-`mu'[_N]) if `touse'
		  label var `varlist' "RIF for Entropy alpha=0 of `exp'"
	   }
	   else if `entropy'==1 {
	   **Theil Index
         tempvar v mu cum_wt e1
		  by `touse' `by':gen double `cum_wt'=sum(`weight')
          by `touse' `by':gen double `v'=sum(log(`exp')*`exp'*`weight'/`cum_wt'[_N])
		  by `touse' `by':gen double `mu'=sum(`exp'*`weight'/`cum_wt'[_N])
          by `touse' `by':gen double `e1'=`v'[_N]/`mu'[_N]-log(`mu'[_N])
		  by `touse' `by':gen `typlist' `varlist'=`e1'+1/`mu'[_N]*(`exp'*log(`exp')-`v'[_N])-(`v'[_N]+`mu'[_N])/(`mu'[_N]^2)*(`exp'-`mu'[_N])  if `touse'
		  label var `varlist' "RIF for Entropy alpha=1 of `exp'"

	   }
	   else if `entropy'!=1  & `entropy'!=0 {
	   ** All other Entropy cases
	   tempvar v mu cum_wt ea
		  by `touse' `by':gen double `cum_wt'=sum(`weight')
          by `touse' `by':gen double `v'=sum((`exp'^`entropy')*`weight'/`cum_wt'[_N])
		  by `touse' `by':gen double `mu'=sum(`exp'*`weight'/`cum_wt'[_N])
          by `touse' `by':gen double `ea'=1/(`entropy'*(`entropy'-1))*(`v'[_N]/`mu'[_N]^`entropy'-1)
		  by `touse' `by':gen `typlist' `varlist'=`ea'+(`exp'^`entropy'-`v'[_N])/(`entropy'*(`entropy'-1)*`mu'[_N]^`entropy')-`v'[_N]/((`entropy'-1)*`mu'[_N]^(`entropy'+1))*(`exp'-`mu'[_N])
		  label var `varlist' "RIF for Entropy alpha=`entropy' of `exp'"
	  }
	}
	*** Atkinson
	if "`atkin'"!="" {
       numlist "`atkin'", min(1) max(1) range(>0)
	   sort `touse' `by' `exp' `sortseed'

	if `atkin'==1  {
	   ** Special ATKINSON case
	   tempvar v mu cum_wt a1
		  by `touse' `by':gen double `cum_wt'=sum(`weight')
          by `touse' `by':gen double `v'=sum(log(`exp')*`weight'/`cum_wt'[_N])
		  by `touse' `by':gen double `mu'=sum(`exp'*`weight'/`cum_wt'[_N])
          by `touse' `by':gen double `a1'=1-exp(`v'[_N])/`mu'[_N]
		  by `touse' `by':gen `typlist' `varlist'=`a1'-exp(`v'[_N])/`mu'[_N]*(log(`exp')-`v'[_N])+(`exp'-`mu'[_N])*exp(`v'[_N])/`mu'[_N]^2 if `touse'
		  label var `varlist' "RIF for Atkinson e=`atkin' of `exp'"
		  }
	if `atkin'!=1 {
	   ** All other cases cases
	     tempvar v mu cum_wt ax
		  by `touse' `by':gen double `cum_wt'=sum(`weight')
          by `touse' `by':gen double `v'=sum(`exp'^(1-`atkin')*`weight'/`cum_wt'[_N])
		  by `touse' `by':gen double `mu'=sum(`exp'*`weight'/`cum_wt'[_N])
          by `touse' `by':gen double `ax'=1-`v'[_N]^(1/(1-`atkin'))/`mu'[_N]
          by `touse' `by':gen `typlist' `varlist'=`ax'+(`atkin'/(1-`atkin')+`exp'/`mu'[_N])*(1-`ax')-((1-`ax')^`atkin'*`exp'^(1-`atkin'))/((1-`atkin')*`mu'[_N]^(1-`atkin'))		  if `touse'
		  *by `touse' `by':gen `typlist' `varlist'=`ax'+(`v'[_N]^(`atkin'/(1-`atkin')))/((`atkin'-1)*`mu'[_N])*(`exp'^(1-`atkin')-`v'[_N])+ ///
		  *                (`v'[_N]^(1/(1-`atkin')))/(`mu'[_N]^2)*(`exp'-`mu'[_N]) if `touse'
	   label var `varlist' "RIF for Atkinson e=`atkin' of `exp'"
	   }
	}
	*** Logaritmic variance
	if "`logvar'"!="" {
       sort `touse' `by' `sortseed'
	   ** First important stuff
	     tempvar v1 v2 mu cum_wt lgvr
          by `touse' `by':gen double `cum_wt'=sum(`weight')
          by `touse' `by':gen double `v1'=sum(log(`exp')^2*`weight'/`cum_wt'[_N])
		  by `touse' `by':gen double `v2'=sum(log(`exp')*`weight'/`cum_wt'[_N])
		  by `touse' `by':gen double `mu'=sum(`exp'*`weight'/`cum_wt'[_N])
          by `touse' `by':gen double `lgvr'=`v1'[_N]-2*`v2'[_N]*log(`mu'[_N])+log(`mu'[_N])^2
		  by `touse' `by':gen `typlist' `varlist'=`lgvr' +(log(`exp')^2-`v1'[_N])-2*log(`mu'[_N])*(log(`exp')-`v2'[_N])-2/`mu'[_N]*(`v2'[_N]-log(`mu'[_N]))*(`exp'-`mu'[_N]) if `touse'
		  *noisily sum `lgvr' `varlist'

		  label var `varlist' "RIF for logvariance of `exp'"
		  *log variance is different from variance of logs
	   }
	************************************************************************************
	************************************************************************************
	* From here we get the indices added by Heckley Gerdthan and Kjellson
	*** Absolute Gini
	if "`agini'"!="" {
     levelsof `by' if `touse', local(nby)
 	  sort `touse' `by' `exp' `sortseed'
	  qui{
		  *Get totals first
		  tempvar cum_wt mns cumwy tot_wt pvar mns glp rfvar rf aggini
		  tempvar covfx
		  by `touse' `by':gen double `cum_wt'=sum(`weight')
		  by `touse' `by':gen double `tot_wt'=`cum_wt'[_N]
		  by `touse' `by':gen double `pvar' = `cum_wt'/`tot_wt'
		  by `touse' `by':gen double `glp'=sum(`exp'*`weight'/`tot_wt')
		  by `touse' `by':gen double `mns'=`glp'[_N]
		  gen double `covfx'=.
		  foreach k of local nby {
            corr `pvar' `exp' if `touse' & float(`by')==float(`k'), cov
			replace `covfx'=r(cov_12)  if `touse' & float(`by')==float(`k')
		  }

		  by `touse' `by':gen double `aggini'=2*`covfx' if `touse'
		  by `touse' `by':gen `typlist' `varlist' =-`aggini'+(-`exp'+`mns')+2*(`exp'*(`pvar')-`glp') if `touse'
		  label var `varlist' "RIF for Abs gini of `exp'"
      }
	}
	*** Absolute Concentration index
	if "`acindex'"!="" {
     levelsof `by' if `touse', local(nby)
	  ** Need to be careful. Abs concentration index is "random" if there are Ties respect to rank variable
	  ** In this version im sorting by rank and exp. This may improve some results but gives higher index than sorting by rank only
 	  sort `touse' `by' `acindex'  `sortseed'
	  qui{
		  *Get totals first
		  tempvar cum_wt mns   tot_wt pvar mns glp rfvar rf accindex ifaccindex
		  tempvar covfx
		  by `touse' `by':gen double `cum_wt'=sum(`weight')
		  by `touse' `by':gen double `tot_wt'=`cum_wt'[_N]
		  by `touse' `by':gen double `pvar' = `cum_wt'/`tot_wt'
		  by `touse' `by':gen double `glp'=sum(`exp'*`weight'/`tot_wt')
		  by `touse' `by':gen double `mns'=`glp'[_N]
		  gen double `covfx'=.
		  foreach k of local nby {
            corr `pvar' `exp' if `touse' & float(`by')==float(`k'), cov
			replace `covfx'=r(cov_12)  if `touse' & float(`by')==float(`k')
		  }
		  by `touse' `by':gen double `accindex'=2*`covfx' if `touse'
		  by `touse' `by':gen double `ifaccindex'=-2*`accindex'+(-`exp'+`mns')+2*(`exp'*(`pvar')-`glp') if `touse'
		  by `touse' `by':gen `typlist' `varlist' =`accindex'+`ifaccindex' if `touse'
		  label var `varlist' "RIF for Abs concentration of `exp'"
      }
	}
	***   Concentration index (Standard)
	if "`cindex'"!="" {
     levelsof `by' if `touse', local(nby)
	  ** Need to be careful. concentration index is "random" if there are Ties respect to rank variable
	  ** In this version im sorting first by exp then rank
	  ** This means there will ALLWAYS be some level of random component on the index.
	  **
	  sort `touse' `by' `cindex' `sortseed'

	  qui{
		  *Get totals first
		  tempvar cum_wt mns  sumw sumwp tot_wt pvar padj mns glp rfvar rfx rf ccindex
		  tempvar covfx
		  by `touse' `by':gen double `cum_wt'=sum(`weight')
		  by `touse' `by':gen double `tot_wt'=`cum_wt'[_N]
		  by `touse' `by':gen double `pvar' = `cum_wt'/`tot_wt'
		  by `touse' `by':gen double `glp'=sum(`exp'*`weight'/`tot_wt')
		  by `touse' `by':gen double `mns'=`glp'[_N]

		  gen double `rfvar'=.
	  	  by `touse' `by':integ `glp' `pvar', gen(`rfvar') replace

		  by `touse' `by':gen double `rf' =  `rfvar'[_N]
		  by `touse' `by':gen double `ccindex'=1-2/`mns'*`rf'            if `touse'
		  by `touse' `by':gen `typlist' `varlist' =(2/`mns'*`rf')*`exp'/`mns'+2/`mns'*(`exp'*(`pvar'-1)-`glp') +1 if `touse'
		  label var `varlist' "RIF for Concentration index of `exp'"
      }
	}

*********************************
	** eindex specifies the Erreygers index
	** Its a rescaling of the Concentration index. Rescale by min max. BUt here min max are indicated beforehand. Theoretical vs actual
	** min max. IE wages have a theoretical min of 0 but say an observed min if 2.1

	if "`eindex'"!="" {
	  levelsof `by' if `touse', local(nby)
	  if "`ub'"=="" | "`lb'"=="" {
	  noisily display "This index requires to specify upper -ub()- and lower bounds -lb()-"
	  exit
	  }
	  ** Need to be careful. Abs concentration index is "random" if there are Ties respect to rank variable
	  ** In this version im sorting by rank and exp. This may improve some results but gives higher index than sorting by rank only
 	  sort `touse' `by' `eindex'  `sortseed'
	  qui{
		  *Get totals first
		  tempvar cum_wt mns   tot_wt pvar mns glp rfvar rf eccindex accindex ifaccindex
		  tempvar covfx
		  by `touse' `by':gen double `cum_wt'=sum(`weight')
		  by `touse' `by':gen double `tot_wt'=`cum_wt'[_N]
		  by `touse' `by':gen double `pvar' = `cum_wt'/`tot_wt'
		  by `touse' `by':gen double `glp'=sum(`exp'*`weight'/`tot_wt')
		  by `touse' `by':gen double `mns'=`glp'[_N]
		  gen double `covfx'=.
		  foreach k of local nby {
            corr `pvar' `exp' if `touse' & float(`by')==float(`k'), cov
			replace `covfx'=r(cov_12)  if `touse' & float(`by')==float(`k')
		  }
		  by `touse' `by':gen double `accindex'=2*`covfx' if `touse'
		  by `touse' `by':gen double `ifaccindex'=-2*`accindex'+(-`exp'+`mns')+2*(`exp'*(`pvar')-`glp') if `touse'

	    by `touse' `by':gen double `eccindex'=4/(`ub'-`lb')*`accindex' if `touse'
	    by `touse' `by':gen `typlist' `varlist' =(4/(`ub'-`lb'))*(`accindex'+`ifaccindex') if `touse'
	    label var `varlist' "RIF for Erreygers index of `exp'"
	  }
	}
*********************************************************************
*********************************************************************
*********************************************************************
*********************************************************************
	** Attainment Relative Concentration Index
	*NEEDS TO BE REVISED
		if "`arcindex'"!="" {
	  levelsof `by' if `touse', local(nby)
 	  if  "`lb'"=="" {
		  noisily display "This index requires to specify lower bounds -lb()-"
		  exit
	  }
	  ** Need to be careful. Abs concentration index is "random" if there are Ties respect to rank variable
	  ** In this version im sorting by rank and exp. This may improve some results but gives higher index than sorting by rank only
 	  sort `touse' `by' `arcindex'  `sortseed'
	  qui{
		  *Get totals first
		  tempvar cum_wt mns   tot_wt pvar mns glp rfvar rf arccindex accindex ifaccindex
		  tempvar covfx
		  by `touse' `by':gen double `cum_wt'=sum(`weight')
		  by `touse' `by':gen double `tot_wt'=`cum_wt'[_N]
		  by `touse' `by':gen double `pvar' = `cum_wt'/`tot_wt'
		  by `touse' `by':gen double `glp'=sum(`exp'*`weight'/`tot_wt')
		  by `touse' `by':gen double `mns'=`glp'[_N]
		  gen double `covfx'=.
		  foreach k of local nby {
            corr `pvar' `exp' if `touse' & float(`by')==float(`k'), cov
			replace `covfx'=r(cov_12)  if `touse' & float(`by')==float(`k')
		  }
		  by `touse' `by':gen double `accindex'=2*`covfx' if `touse'
		  by `touse' `by':gen double `ifaccindex'=-2*`accindex'+(-`exp'+`mns')+2*(`exp'*(`pvar')-`glp') if `touse'
		  by `touse' `by':gen double `arccindex'=1/(`mns'-`lb')*`accindex' if `touse'
 		  by `touse' `by':gen `typlist' `varlist' =1/(`mns'-`lb')*(`accindex'+`ifaccindex')-`accindex'*(`exp'-`mns')/(`mns'-`lb')^2  if `touse'
		  label var `varlist' "RIF for Attainment Relative Concentration of `exp'"
       }
	  }

	** Shortfall relative concentration index
 	if "`srindex'"!="" {
	  levelsof `by' if `touse', local(nby)
	   	  if  "`ub'"==""  {
		  noisily display "This index requires to specify upper bound -ub()- "
		  exit
	  }
	  ** Need to be careful. Abs concentration index is "random" if there are Ties respect to rank variable
	  ** In this version im sorting by rank and exp. This may improve some results but gives higher index than sorting by rank only
 	  sort `touse' `by' `srindex'  `sortseed'
	  qui{
		  *Get totals first
		  tempvar cum_wt mns   tot_wt pvar mns glp rfvar rf srcindex accindex ifaccindex
			tempvar covfx
		  by `touse' `by':gen double `cum_wt'=sum(`weight')
		  by `touse' `by':gen double `tot_wt'=`cum_wt'[_N]
		  by `touse' `by':gen double `pvar' = `cum_wt'/`tot_wt'
		  by `touse' `by':gen double `glp'=sum(`exp'*`weight'/`tot_wt')
		  by `touse' `by':gen double `mns'=`glp'[_N]
		  gen double `covfx'=.
		  foreach k of local nby {
            corr `pvar' `exp' if `touse' & float(`by')==float(`k'), cov
			replace `covfx'=r(cov_12)  if `touse' & float(`by')==float(`k')
		  }
		  by `touse' `by':gen double `accindex'=2*`covfx' if `touse'
		  by `touse' `by':gen double `ifaccindex'=-2*`accindex'+(-`exp'+`mns')+2*(`exp'*(`pvar')-`glp') if `touse'
		  by `touse' `by':gen `typlist' `varlist' =1/(`ub'-`mns')*(`accindex'+`ifaccindex')-(`mns'-`exp')/((`ub'-`mns')^2)*`accindex' if `touse'
		  label var `varlist' "RIF for Shortfall relative concentration index of `exp'"
       }
	}
	** Wagstaff index
		*NEEDS TO BE REVISED

   if "`windex'"!="" {
	  levelsof `by' if `touse', local(nby)
	  if  "`ub'"=="" | "`lb'"==""  {
		  noisily display "This index requires to specify upper bound -ub()- and lower bound -lb()-"
		  exit
	  }
	  ** Need to be careful. Abs concentration index is "random" if there are Ties respect to rank variable
	  ** In this version im sorting by rank and exp. This may improve some results but gives higher index than sorting by rank only
 	  sort `touse' `by' `windex'  `sortseed'
	qui{
		  *Get totals first
		  tempvar cum_wt mns   tot_wt pvar mns glp rfvar rf wcindex accindex ifaccindex
		  tempvar covfx
		  by `touse' `by':gen double `cum_wt'=sum(`weight')
		  by `touse' `by':gen double `tot_wt'=`cum_wt'[_N]
		  by `touse' `by':gen double `pvar' = `cum_wt'/`tot_wt'
		  by `touse' `by':gen double `glp'=sum(`exp'*`weight'/`tot_wt')
		  by `touse' `by':gen double `mns'=`glp'[_N]
		  gen double `covfx'=.
		  foreach k of local nby {
            corr `pvar' `exp' if `touse' & float(`by')==float(`k'), cov
			replace `covfx'=r(cov_12)  if `touse' & float(`by')==float(`k')
		  }
		  by `touse' `by':gen double `accindex'=2*`covfx' if `touse'
		  by `touse' `by':gen double `ifaccindex'=-2*`accindex'+(-`exp'+`mns')+2*(`exp'*(`pvar')-`glp') if `touse'
		  by `touse' `by':gen double `wcindex'=(`ub'-`lb')/((`ub'-`mns')*(`mns'-`lb'))*`accindex' if `touse'
		  tempvar z2 z3
		  by `touse' `by':gen double `z2' 	= ((`ub'+`lb'-2*`mns')*(`exp' - `mns')) if `touse'
		  by `touse' `by':gen double `z3'	= ((`ub'-`mns')*(`mns'-`lb')) if `touse'
		  by `touse' `by':gen `typlist' `varlist' =(`ub'-`lb')/((`ub'-`mns')*(`mns'-`lb'))*(`accindex'+`ifaccindex')-((`ub'-`lb')*`z2'/(`z3'*`z3'))*`accindex' if `touse'
		  *by `touse' `by':gen `typlist' `varlist'=`accindex'+`ifaccindex'
		  label var `varlist' "RIF for Wagstaff index of `exp'"
       }
	  }


*********************** Not ready yet.
** Alternative rifown rifown
if "`rifown'"!="" {
		** Alternative User written RIFS"
		sort `touse' `by' `exp' `sortseed'
		by `touse' `by':egen `typlist' `varlist'=`rifown'(`exp'), weight(`weight') `rifopt'
	}

  }

  set seed `sysseed'
 end


 *capture program drop _prank
capture program drop _prank
program define _prank
	syntax newvarlist , svar(varname) mvar(varname) [ byvar(varname) wvar(varname) tvar(varname) ]
	local v1 :word 1 of `varlist'
	local v2 :word 2 of `varlist'
	local v3 :word 3 of `varlist'
	// Sort by, touse, main var and sort variable
	sort `tvar' `byvar' `svar' `wvar'
	if "`wvar'"=="" {
	    local wvar2=1
	}
	else {
	    local wvar2 `wvar'
	}
	tempvar sumw awgt nn g
	by `tvar' `byvar':gen double `sumw'=sum(`wvar2'/_N)
	by `tvar' `byvar':gen double `awgt'=`wvar2'/`sumw'[_N]
	by `tvar' `byvar':replace    `sumw'=sum(`awgt')
	by `tvar' `byvar':gen double `nn'=`sumw'[_N]
	by `tvar' `byvar':gen double `v1'=sum(`mvar'*`awgt'/`nn')
	by `tvar' `byvar' `svar' :gen double `v2'=0.5*(`sumw'[_N]+`sumw'[1]-`awgt'[1])/`nn'
    by `tvar' `byvar':gen double `v3'=sum((`mvar'-`v1'[_N])*(`v2'-0.5)*`awgt'/`nn')
end