*! 1.0.0 NJC 9 November 1998
program define ineq
        version 5.0
        local varlist "max(1)"
        local if "opt"
        local in "opt"
        local options "BY(string) Format(string) Numeq"
        local options "`options' GENEnt(string) GENSim(string) GENDiss(string) *"
        local weight "fweight aweight noprefix"
        parse "`*'"

        tempvar touse sum prop propsq plnp group first freq diss
        mark `touse' `if' `in'
        markout `touse' `varlist'

        capture assert `varlist' >= 0 if `touse'
        if _rc {
                di in r "`varlist' has negative values"
                exit 411
        }

        if "`by'" != "" {
                unabbrev `by'
                local by "$S_1"
        }

        sort `touse' `by'
        if "`exp'" != "" { local exp "* `exp'" }
        qui {
                by `touse' `by' : /*
                 */ gen double `sum' = sum(`varlist' `exp') if `touse'
                by `touse' `by' : replace `sum' = `sum'[_N] if `touse'
                gen `prop' = (`varlist' `exp') / `sum'
                gen `propsq' = `prop'^2
                by `touse' `by' : replace `propsq' = sum(`propsq')
                by `touse' `by' : replace `propsq' = `propsq'[_N]
                if "`numeq'" != "" { replace `propsq' = 1 / `propsq' }

                gen `plnp' = cond(`prop'==0, 0, `prop' * ln(`prop'))
                by `touse' `by' : replace `plnp' = sum(`plnp')
                by `touse' `by' : replace `plnp' = -`plnp'[_N]
                if "`numeq'" != "" { replace `plnp' = exp(`plnp') }

                by `touse' `by' : gen byte `first' = _n == 1 & `touse'
                gen int `group' = sum(`first')

                /* use string variable to avoid decimal places in table */
                gen str1 `freq' = ""
                by `touse' `by' : replace `freq' = string(_N)

                by `touse' `by' : gen `diss' = sum(abs(`prop' - 1 / _N))
                by `touse' `by' : replace `diss' = `diss'[_N] / 2

        }

        label var `group' "group"
        if "`by'" == "" {
                label def `group' 1 all
                label val `group' `group'
        }
        label var `propsq' "Simpson"
        label var `plnp'   "entropy"
        label var `freq'   "freq"
        label var `diss'   "dissim."

        if "`format'" == "" { local format "%4.3f" }
        tabdisp `group' if `first', /*
         */ c(`by' `freq' `propsq' `plnp' `diss') `options' format(`format')
        if "`by'" == "" { label drop `group' }

        if "`genent'" != "" {
                confirm new variable `genent'
                gen `genent' = `plnp'
        }
        if "`gensim'" != "" {
                confirm new variable `gensim'
                gen `gensim' = `propsq'
        }
        if "`gendiss'" != "" {
                confirm new variable `gendiss'
                gen `gendiss' = `diss'
        }
end