*! version 2.5.2 2009-12-11 jsl
*  - deal with negative value in ologit for outcome option
*  version 2.5.1 2009-12-10 jsl
*  - deal with negative value in ologit

capture program drop prchange
program define prchange, rclass

    * 1.9.0
     local caller = _caller()

    version 6
    tempname delthlf delt
    tempname tobase tobase2 min max mean sd min2 max2 mean2 sd2 marg
    tempname margout marg2 margou2
    tempname sdx sdxhalf minx maxx lobase hibase x_base xb xb_lo xb_hi mu
    tempname p1 p_lo p_hi temp tmp tmp_lo tmp_hi vmarg vchange dchange basepr
    tempname baseval basezi // 2006-02-18 for estout
    mat def `baseval' = J(1,1,.)
    mat def `basezi' = J(1,1,.)
    tempname /*deltais*/ predis change      // changed 05nov2007 bj
    mat def `change' = J(1,1,.)
    mat def `predis' = J(1,1,.)
    tempname nomtemp

*=> classify each valid type of model

    *zt 18Feb2005
    local iszt = 0 //
    if ("`e(cmd)'"=="ztp" | "`e(cmd)'"=="ztnb") {
            local iszt = 1
    }
    if "`e(cmd)'"=="ztp"  { local io = "typical count"   }
    if "`e(cmd)'"=="ztnb"  {    local io = "typical count"     }

    if "`e(cmd)'"=="cloglog"  { local io = "typical binary" }
    if "`e(cmd)'"=="gologit"  { local io = "typical ordered" }
    if "`e(cmd)'"=="logistic" { local io = "typical binary" }
    if "`e(cmd)'"=="logit"    { local io = "typical binary" }
    if "`e(cmd)'"=="mlogit"   { local io = "typical nomord" }
    if "`e(cmd)'"=="mprobit"  { local io = "typical nomord" } // 16Feb2008 sl
    if "`e(cmd)'"=="nbreg"    { local io = "typical count" }
    if "`e(cmd)'"=="ologit"   { local io = "typical nomord" }
    if "`e(cmd)'"=="oprobit"  { local io = "typical nomord" }
    if "`e(cmd)'"=="slogit"   { local io = "typical nomord" }
    if "`e(cmd)'"=="poisson"  { local io = "typical count" }
    if "`e(cmd)'"=="probit"   { local io = "typical binary" }
    if "`e(cmd)'"=="zinb"     { local io = "twoeq count" }
    if "`e(cmd)'"=="zip"      { local io = "twoeq count" }
    if "`io'"=="" {
        di
        di in y "prchange" in r " does not work for last model estimated."
        exit
    }
    local input : word 1 of `io'   /* input routine to _pepred */
    local output : word 2 of `io'  /* output routine */

*=> get info about variables

    _perhs
    local nrhs = `r(nrhs)'
    local rhsnms "`r(rhsnms)'"
    if "`input'"=="twoeq" {
        local nrhs2 = `r(nrhs2)'
        local rhsnms2 "`r(rhsnms2)'"
    }
    if "`output'" != "regress" & "`output'" != "tobit" {
        _pecats
        local ncats = r(numcats)
        local catnms8 `r(catnms8)'
        local catvals `r(catvals)'
        local catnms `r(catnms)'
    }

*=> decode input

    syntax [varlist(default=none)] [if] [in] /*
    */ [, x(passthru) Rest(passthru) Level(passthru) Delta(real 1) /*
    */ UNCentered Fromto all Outcome(string) noBAse noLAbel Help Brief /*
    */ CONditional ]

    *zt 19Feb2005
    if `iszt'==1 & "`conditional'"=="conditional" ///
        & "`outcome'"=="0" {
        di _n in r "conditional probabilities for outcome 0 are undefined."
        exit
    }

    *convert delta() to scalars
    sca `delt' = `delta'
    sca `delthlf' = `delt'/2

    * _pebase handles input and sets base values
    _pebase `if' `in', `x' `rest' `choices' `all'
    mat `tobase' = r(pebase)
    if "`input'"=="twoeq" { mat `tobase2' = r(pebase2) }

    * _peife combines `if' with e(sample)==1 if needed
    _peife `if', `all'
    local if "`r(if)'"

    * summary statistics on rhs variables
    quietly _pesum `if' `in'
    mat `min' = r(Smin)
    mat `min' = `min'[1, 2...]
    mat `max' = r(Smax)
    mat `max' = `max'[1, 2...]
    mat `mean' = r(Smean)
    mat `mean' = `mean'[1, 2...]
    mat `sd' = r(Ssd)
    mat `sd' = `sd'[1, 2...]

    * 2006-02-18 - base values to be returned for estout
    mat `baseval' = `mean' \ `sd' \ `min' \ `max'
    mat rownames `baseval' = Mean SD Min "Max"

    if "`input'"=="twoeq" {
        quietly _pesum `if' `in', two
        mat `min2' = r(Smin)
        mat `min2' = `min2'[1, 2...]
        mat `max2' = r(Smax)
        mat `max2' = `max2'[1, 2...]
        mat `mean2' = r(Smean)
        mat `mean2' = `mean2'[1, 2...]
        mat `sd2' = r(Ssd)
        mat `sd2' = `sd2'[1, 2...]
        * 2006-02-18 - zip & zinb base values to be returned for estout
        mat `basezi' = `mean2' \ `sd2' \ `min2' \ `max2'
        mat rownames `basezi' = Mean SD Min Max
    }

    * set values of PE_in, to be modified before sent to _pepred
    capture mat drop PE_in
    mat PE_in = `tobase'
    if "`input'"=="twoeq" {
        capture mat drop PE_in2
        mat PE_in2 = `tobase2'
    }

    if "`varlist'" == "" { local varlist "`rhsnms'" }

*=> handle outcome() option

    if "`outcome'"!="" {
        if "`output'"=="binary" {
            di in r "outcome() not allowed for prchange after `e(cmd)'"
            exit 198
        }
        if "`output'"=="nomord" {
            local found "no"
            * cycle through outcome categories
            local i = 1
            while `i' <= `ncats' {
                local valchk : word `i' of `catvals'
                local nmchk : word `i' of `catnms'
                * outcome() value to category value
                if ("`outcome'"=="`valchk'") | ("`outcome'"=="`nmchk'") {
                    local found "yes"
                    local outcmv = "`valchk'"
* 2.5.2
local outcmvnm "`outcmv'"
if `outcome'<0 {
    local outcmvnm = abs(`outcmv')
    local outcmvnm "_`outcmvnm'"
}

                    if "`valchk'"!="`nmchk'" { local outcmnm " (`nmchk')" }
                    local outcome = `i'
                    local i = `ncats'
                }
                local i = `i' + 1
            }
            if "`found'"=="no" {
                di in r "`outcome' not category of `e(depvar)'"
                exit 198
            }
        } // output is nomord

        if "`output'"=="count" {
            confirm integer number `outcome'
            if `outcome' < 0 { exit 198 }
            local outcmv "`outcome'"
        }
    }

*=> compute marginal effects (_pemarg requires mat PE_base that was set by _pebase)

    * zt 19Feb2005 TO DO
    * 1.8.0 _pemarg
    _pemarg, caller(`caller') // 1.9.0
    local hasmarg = "`r(hasmarg)'"
    if "`hasmarg'"=="yes" {
        mat `marg' = r(marginal)
        if "`output'"=="count" | "`output'"=="binary" {
            mat `marg' = `marg'[2, 1...]
        }
    }

*=> header information

    if "`brief'"=="" {

        *zt 19Feb2005
        if `iszt'==1 {
            if "`conditional'"=="" {
                local type "Unconditional "
            }
            else {
                local type "Conditional "
            }
        }
        di _n in y "`e(cmd)'" _c
        if "`output'"=="count" & "`outcome'"=="" {
            di in g ": Changes in `type'Rate for " _c
        }
        else { di in g ": Changes in `type'Probabilities for " _c}
        di in y "`e(depvar)'"
        if "`outcome'"!="" {
            di in g _new "Outcome: " in y "`outcmv'" in y "`outcmnm'" // 2007-01-07
        }

        *print value of delta if specified
        if `delt'!=1 {
            if "`uncentered'"!="" {
                di _n in g "(Note: delta = " in y `delt' in g ")"
            }
            else {
                di _n in g "(Note: d = " in y `delt' in g ")"
            }
        }
    }

*=> cycle through all variables in varlist
*   varnum = matrix position of rhs variable; -1 if not in count equation
*   varnum2 =position in binary matrix of rhs var in ZIP/ZINB; -1 if absent

    local i = 1
    local i_to : word count `varlist'
    while `i' <= `i_to' {
        local var : word `i' of `varlist'
        local found "no"
        local varnum -1
        local i2 = 1
        local i2_to : word count `rhsnms'
        while `i2' <= `i2_to' {
            local varchk : word `i2' of `rhsnms'
            unab varchk : `varchk', max(1)
            if "`var'"=="`varchk'" {
                local found "yes"
                local varnum = `i2'
                local i2 = `i2_to'
            }
            local i2 = `i2' + 1
        } /* while `i2' < `i2_to' */

        if "`input'"=="twoeq" {
            local i3 = 1
            local i3_to : word count `rhsnms2'
            local varnum2 -1
            while `i3' <= `i3_to' {
                local varchk : word `i3' of `rhsnms2'
                unab varchk : `varchk', max(1)
                if "`var'"=="`varchk'" {
                    local found "yes"
                    local varnum2 = `i3'
                    local i3 = `i3_to'
                }
                local i3 = `i3' + 1
            }
        } /* if "`input'"=="twoeq" */

        if "`found'"=="no" {
            di in r "`var' not rhs variable"
            exit 198
        }

*=> arrange `marg' matrix for output

        if `varnum' != -1 & "`hasmarg'"=="yes" {
            if "`output'"=="nomord" | "`output'"=="mlogit" {
                mat `margout' = nullmat(`margout') \ `marg'[`varnum', 1...]
            }
            else {
                mat `margout' = nullmat(`margout') , `marg'[1, `varnum']
            }
        }

        *=> PE_in has values of start and end of change variable
        *   and levels of other variables for all changes considered
        if `varnum' != -1 {

            * create scalar values for discrete change calculations
            sca `sdx' = `sd'[1, `varnum']
            sca `sdxhalf' = `sdx' / 2
            sca `minx' = `min'[1, `varnum']
            sca `maxx' = `max'[1, `varnum']
            sca `x_base' = `tobase'[1, `varnum']

            * for min --> max
            mat `lobase' = `tobase'
            mat `lobase'[1, `varnum'] = `minx'
            mat PE_in = PE_in \ `lobase'
            mat `hibase' = `tobase'
            mat `hibase'[1, `varnum'] = `maxx'
            mat PE_in = PE_in \ `hibase'

            * low and high values for 0 --> 1
            mat `lobase' = `tobase'
            mat `lobase'[1, `varnum'] = 0
            mat PE_in = PE_in \ `lobase'
            mat `hibase' = `tobase'
            mat `hibase'[1, `varnum'] = 1
            mat PE_in = PE_in \ `hibase'

            * +/- delta
            if "`uncentered'"=="" {
                mat `lobase' = `tobase'
                mat `lobase'[1, `varnum'] = `x_base'-`delthlf'
                mat PE_in = PE_in \ `lobase'
                mat `hibase' = `tobase'
                mat `hibase'[1, `varnum'] = `x_base'+`delthlf'
                mat PE_in = PE_in \ `hibase'
            }
            else {
                mat `lobase' = `tobase'
                mat `lobase'[1, `varnum'] = `x_base'
                mat PE_in = PE_in \ `lobase'
                mat `hibase' = `tobase'
                mat `hibase'[1, `varnum'] = `x_base'+`delt'
                mat PE_in = PE_in \ `hibase'
            }

            * for +/- sdx
            if "`uncentered'"=="" {
                mat `lobase' = `tobase'
                mat `lobase'[1, `varnum'] = `x_base'-`sdxhalf'
                mat PE_in = PE_in \ `lobase'
                mat `hibase' = `tobase'
                mat `hibase'[1, `varnum'] = `x_base'+`sdxhalf'
                mat PE_in = PE_in \ `hibase'
            }
            else {
                mat `lobase' = `tobase'
                mat `lobase'[1, `varnum'] = `x_base'
                mat PE_in = PE_in \ `lobase'
                mat `hibase' = `tobase'
                mat `hibase'[1, `varnum'] = `x_base'+`sdx'
                mat PE_in = PE_in \ `hibase'
            }

        } /* if `varnum' != -1 */

        * if rhs variable not in equation, then all PE_in rows == tobase
        else {
            mat PE_in = nullmat(PE_in) \ `tobase'
            mat PE_in = PE_in \ `tobase'
            mat PE_in = PE_in \ `tobase'
            mat PE_in = PE_in \ `tobase'
            mat PE_in = PE_in \ `tobase'
            mat PE_in = PE_in \ `tobase'
            mat PE_in = PE_in \ `tobase'
            mat PE_in = PE_in \ `tobase'
        }

        * handle PE_in2 for second equation if zip/zinb
        if "`input'"=="twoeq" {
            if "`varnum2'" != "-1" {

                tempname sdx sdxhalf minx maxx
                sca `sdx' = `sd2'[1, `varnum2']
                sca `sdxhalf' = `sdx' / 2
                sca `minx' = `min2'[1, `varnum2']
                sca `maxx' = `max2'[1, `varnum2']
                tempname lobase hibase x_base
                sca `x_base' = `tobase2'[1, `varnum2']

                * min --> max
                mat `lobase' = `tobase2'
                mat `lobase'[1, `varnum2'] = `minx'
                mat PE_in2 = PE_in2 \ `lobase'
                mat `hibase' = `tobase2'
                mat `hibase'[1, `varnum2'] = `maxx'
                mat PE_in2 = PE_in2 \ `hibase'

                * 0 --> 1
                mat `lobase' = `tobase2'
                mat `lobase'[1, `varnum2'] = 0
                mat PE_in2 = PE_in2 \ `lobase'
                mat `hibase' = `tobase2'
                mat `hibase'[1, `varnum2'] = 1
                mat PE_in2 = PE_in2 \ `hibase'

                * +/- delta
                if "`uncentered'"=="" {
                    mat `lobase' = `tobase2'
                    mat `lobase'[1, `varnum2'] = `x_base'-`delthlf'
                    mat PE_in2 = PE_in2 \ `lobase'
                    mat `hibase' = `tobase2'
                    mat `hibase'[1, `varnum2'] = `x_base'+`delthlf'
                    mat PE_in2 = PE_in2 \ `hibase'
                }
                else {
                    mat `lobase' = `tobase2'
                    mat `lobase'[1, `varnum2'] = `x_base'
                    mat PE_in2 = PE_in2 \ `lobase'
                    mat `hibase' = `tobase2'
                    mat `hibase'[1, `varnum2'] = `x_base'+`delt'
                    mat PE_in2 = PE_in2 \ `hibase'
                }

                * +/- sdx
                if "`uncentered'"=="" {
                    mat `lobase' = `tobase2'
                    mat `lobase'[1, `varnum2'] = `x_base'-`sdxhalf'
                    mat PE_in2 = PE_in2 \ `lobase'
                    mat `hibase' = `tobase2'
                    mat `hibase'[1, `varnum2'] = `x_base'+`sdxhalf'
                    mat PE_in2 = PE_in2 \ `hibase'
                }
                else {
                    mat `lobase' = `tobase2'
                    mat `lobase'[1, `varnum2'] = `x_base'
                    mat PE_in2 = PE_in2 \ `lobase'
                    mat `hibase' = `tobase2'
                    mat `hibase'[1, `varnum2'] = `x_base'+`sdx'
                    mat PE_in2 = PE_in2 \ `hibase'
                }

            } /* if "`varnum2'" != "-1" */

            * if not in inflate equation, PE_in2==tobase2
            else {
                mat PE_in2 = nullmat(PE_in2) \ `tobase2'
                mat PE_in2 = PE_in2 \ `tobase2'
                mat PE_in2 = PE_in2 \ `tobase2'
                mat PE_in2 = PE_in2 \ `tobase2'
                mat PE_in2 = PE_in2 \ `tobase2'
                mat PE_in2 = PE_in2 \ `tobase2'
                mat PE_in2 = PE_in2 \ `tobase2'
                mat PE_in2 = PE_in2 \ `tobase2'
            } /* else */

        } /* if "`input'"=="twoeq" */

        local i = `i' + 1
    } /*  while `i' <= `i_to' */


*=> _pepred calculates probabilities based on PE_in

    _pepred, `level'
    local max_i = r(maxcount)

*=> BINARY MODELS

    if "`output'"=="binary" {
        * predicted probability for all rows of PE_in
        mat `p1' = r(p1)
        local i = 1
        local i_to : word count `varlist'
        mat `dchange' = J(`i_to', 4, 0)
        local dchcol 1
        if "`fromto'"=="fromto" {
            mat `dchange' = J(`i_to', 12, 0)
            local dchcol 3
        }
        * cycle though variables
        while `i' <= `i_to' {
            * calculate discrete change as difference and put in dchange matrix
            local anchor = (`i' * 8) - 6
            sca `p_lo' = `p1'[`anchor', 1]
            sca `p_hi' = `p1'[`anchor'+1, 1]
            if "`fromto'"=="fromto" {
                mat `dchange'[`i', 1] = `p_lo'
                mat `dchange'[`i', 2] = `p_hi'
            }
            mat `dchange'[`i', 1*`dchcol'] = `p_hi' - `p_lo'
            sca `p_lo' = `p1'[`anchor'+2, 1]
            sca `p_hi' = `p1'[`anchor'+3, 1]
            if "`fromto'"=="fromto" {
                mat `dchange'[`i', 4] = `p_lo'
                mat `dchange'[`i', 5] = `p_hi'
            }
            mat `dchange'[`i', 2*`dchcol'] = `p_hi' - `p_lo'
            sca `p_lo' = `p1'[`anchor'+4, 1]
            sca `p_hi' = `p1'[`anchor'+5, 1]
            if "`fromto'"=="fromto" {
                mat `dchange'[`i', 7] = `p_lo'
                mat `dchange'[`i', 8] = `p_hi'
            }
            mat `dchange'[`i', 3*`dchcol'] = `p_hi' - `p_lo'
            sca `p_lo' = `p1'[`anchor'+6, 1]
            sca `p_hi' = `p1'[`anchor'+7, 1]
            if "`fromto'"=="fromto" {
                mat `dchange'[`i', 10] = `p_lo'
                mat `dchange'[`i', 11] = `p_hi'
            }
            mat `dchange'[`i', 4*`dchcol'] = `p_hi' - `p_lo'
            local i = `i' + 1
        } /* while `i' <= `i_to' */

        mat rownames `dchange' = `varlist'
            *added to make matrix headings stata7 compatible
            mat _PEtemp = `dchange''
            _peabbv _PEtemp
            mat `dchange' = _PEtemp'

        *column names for centered change
        if "`uncentered'"=="" {
            if `delt' == 1 {
                mat colnames `dchange' = min->max 0->1 -+1/2 -+sd/2
                if "`fromto'"=="fromto" {
                    mat colnames `dchange' =  x=min x=max min->max /*
                    */  x=0 x=1 0->1 x-1/2 x+1/2 -+1/2 x-1/2sd x+1/2sd -+sd/2
                }
            }
            else {
                mat colnames `dchange' = min->max 0->1 -+d/2 -+sd/2
                if "`fromto'"=="fromto" {
                    mat colnames `dchange' =  x=min x=max min->max /*
                    */  x=0 x=1 0->1 x-d/2 x+d/2 -+d/2 x-1/2sd x+1/2sd -+sd/2
                }
            }
        }
        *column names for uncentered change
        else {
            if `delt' == 1 {
                mat colnames `dchange' = min->max 0->1 +1 +sd
                if "`fromto'"=="fromto" {
                    mat colnames `dchange' =  x=min x=max min->max /*
                    */  x=0 x=1 0->1 x x+1 +1 x x+sd +sd
                }
            }
            else {
                mat colnames `dchange' = min->max 0->1 +delta +sd
                if "`fromto'"=="fromto" {
                    mat colnames `dchange' =  x=min x=max min->max /*
                    */  x=0 x=1 0->1 x x+delta +delta x-sd x+sd +sd
                }
            }
        }

        if "`fromto'"=="fromto" {
            mat coleq `dchange' = from to dif from to dif /*
            */ from to dif from to dif
        }

        * add marginals to output if available
        if "`hasmarg'"=="yes" {
            mat rownames `margout' = MargEfct
            mat roweq `margout' = _
            mat `margout' = `margout''
            mat `dchange' = `dchange', `margout'
        }

        * output list discrete change matrix
        mat list `dchange', noheader f(%8.4f)
        mat `change' = `dchange'' // 2006-02-18 for estout

        * list probabilities at tobase if desired
        mat temp = r(p0)
        mat temp2 = r(p1)
        mat `basepr' = temp[1,1] , temp2[1,1]
        mat rownames `basepr' = "Pr(y|x)"
        if "`label'"=="nolabel" { mat colnames `basepr' = `catvals' }
        else { mat colnames `basepr' = `catnms8' }
        if "`brief'"=="" { mat list `basepr', noheader f(%8.4f) }
        mat `predis' = `basepr' // 2006-02-18 for estout

    } /*  if "`output'"=="binary" */

*=> COUNT MODELS, but not zt

    if "`output'"=="count" & `iszt'==0 {
        if "`outcome'"=="" { mat `tmp' = r(mu) }
        else { mat `tmp' = r(p`outcome') }
        local i = 1
        local i_to : word count `varlist'
        mat `dchange' = J(`i_to', 4, 0)
        local dchcol 1
        if "`fromto'"=="fromto" {
            mat `dchange' = J(`i_to', 12, 0)
            local dchcol 3
        }
        * cycle through all variables specified in varlist
        while `i' <= `i_to' {
            * calculate discrete change and put in dchange matrix
            local anchor = (`i' * 8) - 6
            sca `tmp_lo' = `tmp'[`anchor', 1]
            sca `tmp_hi' = `tmp'[`anchor'+1, 1]
            if "`fromto'"=="fromto" {
                mat `dchange'[`i', 1] = `tmp_lo'
                mat `dchange'[`i', 2] = `tmp_hi'
            }
            mat `dchange'[`i', `dchcol'*1] = `tmp_hi' - `tmp_lo'
            sca `tmp_lo' = `tmp'[`anchor'+2, 1]
            sca `tmp_hi' = `tmp'[`anchor'+3, 1]
            if "`fromto'"=="fromto" {
                mat `dchange'[`i', 4] = `tmp_lo'
                mat `dchange'[`i', 5] = `tmp_hi'
            }
            mat `dchange'[`i', `dchcol'*2] = `tmp_hi' - `tmp_lo'
            sca `tmp_lo' = `tmp'[`anchor'+4, 1]
            sca `tmp_hi' = `tmp'[`anchor'+5, 1]
            if "`fromto'"=="fromto" {
                mat `dchange'[`i', 7] = `tmp_lo'
                mat `dchange'[`i', 8] = `tmp_hi'
            }
            mat `dchange'[`i', `dchcol'*3] = `tmp_hi' - `tmp_lo'
            sca `tmp_lo' = `tmp'[`anchor'+6, 1]
            sca `tmp_hi' = `tmp'[`anchor'+7, 1]
            if "`fromto'"=="fromto" {
                mat `dchange'[`i', 10] = `tmp_lo'
                mat `dchange'[`i', 11] = `tmp_hi'
            }
            mat `dchange'[`i', `dchcol'*4] = `tmp_hi' - `tmp_lo'
            local i = `i' + 1
        }
        mat rownames `dchange' = `varlist'
            *added to make matrix headings stata7 compatible
            mat _PEtemp = `dchange''
            _peabbv _PEtemp
            mat `dchange' = _PEtemp'

        *column names for centered change
        if "`uncentered'" == "" {
            *unit change
            if `delt' == 1 {
                mat colnames `dchange' = min->max 0->1 -+1/2 -+sd/2
                if "`fromto'"=="fromto" {
                    mat colnames `dchange' =  x=min x=max min->max /*
                    */ x=0 x=1 0->1 x-1/2 x+1/2 -+1/2 x-1/2sd x+1/2sd -+sd/2
                }
            }
            *change specified by delta()
            else {
                mat colnames `dchange' = min->max 0->1 -+d/2 -+sd/2
                if "`fromto'"=="fromto" {
                    mat colnames `dchange' =  x=min x=max min->max /*
                    */ x=0 x=1 0->1 x-d/2 x+d/2 -+d/2 x-1/2sd x+1/2sd -+sd/2
                }
            }
        }
        *column names for uncentered change
        else {
            *unit change
            if `delt' == 1 {
                mat colnames `dchange' = min->max 0->1 +1 +sd
                if "`fromto'"=="fromto" {
                    mat colnames `dchange' =  x=min x=max min->max /*
                    */ x=0 x=1 0->1 x x+1 -+1 x x+sd +sd
                }
            }
            *change specified by delta
            else {
                mat colnames `dchange' = min->max 0->1 +delta +sd
                if "`fromto'"=="fromto" {
                    mat colnames `dchange' =  x=min x=max min->max /*
                    */ x=0 x=1 0->1 x x+delta +delta x x+sd +sd
                }
            }
        }
        if "`fromto'"=="fromto" {
            mat coleq `dchange' = from to dif from to dif from /*
            */ to dif from to dif
        }

        if "`hasmarg'"=="yes" & "`outcome'"=="" {
            mat rownames `margout' = MargEfct
            mat roweq `margout' = _
            mat `margout' = `margout''
            mat `dchange' = `dchange', `margout'
        }
        mat list `dchange', noheader f(%8.4f)
        if "`outcome'"=="" {
            local i = 0
            mat `temp' = r(mu)
            sca `mu' = `temp'[1,1]
            mat `predis' = `mu' // 2006-02-18 for estout
            mat rownames `predis' = exp(xb) // 2006-02-18 for estout
            if "`brief'"=="" { di _n in g "exp(xb): " in y %8.4f `mu' }
        }
        else {
            local i = 0
            while `i' <= `max_i' {
                mat `temp' = r(p`i')
                mat `basepr' = nullmat(`basepr') , `temp'[1, 1]
                local cntvals "`cntvals'`i' "
                local i = `i' + 1
            }
            mat rownames `basepr' = "Pr(y|x)"
            mat colnames `basepr' = `cntvals'
            if "`brief'"=="" { mat list `basepr', noheader f(%8.4f) }
            mat `predis' = `basepr' // 2006-02-18 for estout
            mat rownames `predis' = "Pr(y|x)" // 2006-02-18 for estout
        }
        mat `change' = `dchange'' // 2006-02-18 for estout
    }

*=> ZT COUNT MODELS 19Feb2005

    if `iszt'==1 {
        if "`conditional'"=="" {
            local type ""
        }
        else {
            local type "C"
        }

        * grab conditional or not based on type
        if "`outcome'"=="" { mat `tmp' = r(`type'mu) }
        else { mat `tmp' = r(`type'p`outcome') }
        local i = 1
        local i_to : word count `varlist'
        mat `dchange' = J(`i_to', 4, 0)
        local dchcol 1
        if "`fromto'"=="fromto" {
            mat `dchange' = J(`i_to', 12, 0)
            local dchcol 3
        }

        * cycle through all variables specified in varlist
        while `i' <= `i_to' {
            * calculate discrete change and put in dchange matrix
            local anchor = (`i' * 8) - 6
            sca `tmp_lo' = `tmp'[`anchor', 1]
            sca `tmp_hi' = `tmp'[`anchor'+1, 1]
            if "`fromto'"=="fromto" {
                mat `dchange'[`i', 1] = `tmp_lo'
                mat `dchange'[`i', 2] = `tmp_hi'
            }
            mat `dchange'[`i', `dchcol'*1] = `tmp_hi' - `tmp_lo'
            sca `tmp_lo' = `tmp'[`anchor'+2, 1]
            sca `tmp_hi' = `tmp'[`anchor'+3, 1]
            if "`fromto'"=="fromto" {
                mat `dchange'[`i', 4] = `tmp_lo'
                mat `dchange'[`i', 5] = `tmp_hi'
            }
            mat `dchange'[`i', `dchcol'*2] = `tmp_hi' - `tmp_lo'
            sca `tmp_lo' = `tmp'[`anchor'+4, 1]
            sca `tmp_hi' = `tmp'[`anchor'+5, 1]
            if "`fromto'"=="fromto" {
                mat `dchange'[`i', 7] = `tmp_lo'
                mat `dchange'[`i', 8] = `tmp_hi'
            }
            mat `dchange'[`i', `dchcol'*3] = `tmp_hi' - `tmp_lo'
            sca `tmp_lo' = `tmp'[`anchor'+6, 1]
            sca `tmp_hi' = `tmp'[`anchor'+7, 1]
            if "`fromto'"=="fromto" {
                mat `dchange'[`i', 10] = `tmp_lo'
                mat `dchange'[`i', 11] = `tmp_hi'
            }
            mat `dchange'[`i', `dchcol'*4] = `tmp_hi' - `tmp_lo'
            local i = `i' + 1
        }
        mat rownames `dchange' = `varlist'
            *added to make matrix headings stata7 compatible
            mat _PEtemp = `dchange''
            _peabbv _PEtemp
            mat `dchange' = _PEtemp'

        *column names for centered change
        if "`uncentered'" == "" {
            *unit change
            if `delt' == 1 {
                mat colnames `dchange' = min->max 0->1 -+1/2 -+sd/2
                if "`fromto'"=="fromto" {
                    mat colnames `dchange' =  x=min x=max min->max /*
                    */ x=0 x=1 0->1 x-1/2 x+1/2 -+1/2 x-1/2sd x+1/2sd -+sd/2
                }
            }
            *change specified by delta()
            else {
                mat colnames `dchange' = min->max 0->1 -+d/2 -+sd/2
                if "`fromto'"=="fromto" {
                    mat colnames `dchange' =  x=min x=max min->max /*
                    */ x=0 x=1 0->1 x-d/2 x+d/2 -+d/2 x-1/2sd x+1/2sd -+sd/2
                }
            }
        }
        *column names for uncentered change
        else {
            *unit change
            if `delt' == 1 {
                mat colnames `dchange' = min->max 0->1 +1 +sd
                if "`fromto'"=="fromto" {
                    mat colnames `dchange' =  x=min x=max min->max /*
                    */ x=0 x=1 0->1 x x+1 -+1 x x+sd +sd
                }
            }
            *change specified by delta
            else {
                mat colnames `dchange' = min->max 0->1 +delta +sd
                if "`fromto'"=="fromto" {
                    mat colnames `dchange' =  x=min x=max min->max /*
                    */ x=0 x=1 0->1 x x+delta +delta x x+sd +sd
                }
            }
        }
        if "`fromto'"=="fromto" {
            mat coleq `dchange' = from to dif from to dif from /*
            */ to dif from to dif
        }

        if "`hasmarg'"=="yes" & "`outcome'"=="" {
            mat rownames `margout' = MargEfct
            mat roweq `margout' = _
            mat `margout' = `margout''
            mat `dchange' = `dchange', `margout'
        }
        mat list `dchange', noheader f(%8.4f)
        mat `change' = `dchange'' // 2006-02-18 for estout

        if "`outcome'"=="" {
            local i = 0
            mat `temp' = r(mu)
            sca `mu' = `temp'[1,1]
            mat `predis' = `mu' // 2006-02-18 for estout
            mat rownames `predis' = exp(xb) // 2006-02-18 for estout

            if "`brief'"=="" { di _n in g "exp(xb): " in y %8.4f `mu' }
        }
        else {
            local i = 0
            while `i' <= `max_i' {
                mat `temp' = r(p`i')
                mat `basepr' = nullmat(`basepr') , `temp'[1, 1]
                local cntvals "`cntvals'`i' "
                local i = `i' + 1
            }
            mat rownames `basepr' = "Pr(y|x)"
            mat colnames `basepr' = `cntvals'
            if "`brief'"=="" { mat list `basepr', noheader f(%8.4f) }
            mat `predis' = `basepr' // 2006-02-18 for estout
            mat rownames `predis' = "Pr(y|x)" // 2006-02-18 for estout
        }
    }

*=> NOMINAL and ORDINAL

    * jsl 10/23/00 - add average absolute discrete change
    if "`output'"=="nomord" {
        local dchcol 1
        if "`fromto'"=="fromto" { local dchcol 3 }
        local i = 1
        local i_to : word count `varlist'
        * loop over variables
        tempname a01 a1 asd arange amarg    // changed 23oct2007 bj
        mat `amarg' = J(1,`i_to',0)         // added 23oct2007 bj
        while `i' <= `i_to' {
            scalar `a01' = 0
            scalar `a1' = 0
            scalar `asd' = 0
            scalar `arange' = 0
            local ncats1 = `ncats' + 1
            mat `vchange' = J(4, `ncats1', 0)
            if "`fromto'"=="fromto" { mat `vchange' = J(12, `ncats1', 0) }
            local anchor = (`i' * 8) - 6
            local i2 = 2
            local i2_to = `ncats1'
            * loop over categories
            while `i2' <= `i2_to' {
                local tmp = `i2' - 1
                mat `temp' = r(p`tmp')
                sca `p_lo' = `temp'[`anchor', 1]
                sca `p_hi' = `temp'[`anchor'+1, 1]
                if "`fromto'"=="fromto" {
                    mat `vchange'[1, `i2'] = `p_lo'
                    mat `vchange'[2, `i2'] = `p_hi'
                }
                * range
                mat `vchange'[`dchcol'*1, `i2'] = `p_hi' - `p_lo'
                scalar `arange' = `arange' + abs(`p_hi' - `p_lo')/`ncats'
                mat `vchange'[`dchcol'*1, 1] = `arange'
                sca `p_lo' = `temp'[`anchor'+2, 1]
                sca `p_hi' = `temp'[`anchor'+3, 1]
                if "`fromto'"=="fromto" {
                    mat `vchange'[4, `i2'] = `p_lo'
                    mat `vchange'[5, `i2'] = `p_hi'
                }
                * 0->1
                mat `vchange'[`dchcol'*2, `i2'] = `p_hi' - `p_lo'
                scalar `a01' = `a01' + abs(`p_hi' - `p_lo')/`ncats'
                mat `vchange'[`dchcol'*2, 1] = `a01'
                * -+1
                sca `p_lo' = `temp'[`anchor'+4, 1]
                sca `p_hi' = `temp'[`anchor'+5, 1]
                if "`fromto'"=="fromto" {
                    mat `vchange'[7, `i2'] = `p_lo'
                    mat `vchange'[8, `i2'] = `p_hi'
                }
                mat `vchange'[`dchcol'*3, `i2'] = `p_hi' - `p_lo'
                scalar `a1' = `a1' + abs(`p_hi' - `p_lo')/`ncats'
                mat `vchange'[`dchcol'*3, 1] = `a1'
                * -+sd
                sca `p_lo' = `temp'[`anchor'+6, 1]
                sca `p_hi' = `temp'[`anchor'+7, 1]
                if "`fromto'"=="fromto" {
                    mat `vchange'[10, `i2'] = `p_lo'
                    mat `vchange'[11, `i2'] = `p_hi'
                }
                mat `vchange'[`dchcol'*4, `i2'] = `p_hi' - `p_lo'
                scalar `asd' = `asd' + abs(`p_hi' - `p_lo')/`ncats'
                mat `vchange'[`dchcol'*4, 1] = `asd'
                local i2 = `i2' + 1

            } /* loop over categories */
            local var : word `i' of `varlist'

            * column names for centered change
            if "`uncentered'"=="" {
                if `delt'==1 {
                    mat rownames `vchange' = "Min->Max" "    0->1"  "   -+1/2" /*
                    */ "  -+sd/2"
                    if "`fromto'"=="fromto" {
                        mat rownames `vchange' = "   x=min" "   x=max" "min->max"  /*
                        */  "     x=0" "     x=1" "    0->1" "   x-1/2" "   x+1/2" /*
                        */ "   -+1/2" " x-1/2sd" " x+1/2sd" "  -+sd/2"
                    }
                }
                else {
                    mat rownames `vchange' = "Min->Max" "    0->1"  "   -+d/2" /*
                    */ "  -+sd/2"
                    if "`fromto'"=="fromto" {
                        mat rownames `vchange' = "   x=min" "   x=max" "min->max"  /*
                        */  "     x=0" "     x=1" "    0->1" "   x-d/2" "   x+d/2" /*
                        */ "   -+d/2" " x-1/2sd" " x+1/2sd" "  -+sd/2"
                    }
                }
            }
            * uncentered change
            else {
                if `delt'==1 {
                    mat rownames `vchange' = "Min->Max" "    0->1"  "      +1" /*
                    */ "     +sd"
                    if "`fromto'"=="fromto" {
                        mat rownames `vchange' = "   x=min" "   x=max" "min->max"  /*
                        */  "     x=0" "     x=1" "    0->1" "       x" "     x+1" /*
                        */ "      +1" "       x" "    x+sd" "     +sd"
                    }
                }
                else {
                    mat rownames `vchange' = "Min->Max" "    0->1"  "  +delta" /*
                    */ "     +sd"
                    if "`fromto'"=="fromto" {
                        mat rownames `vchange' = "   x=min" "   x=max" "min->max"  /*
                        */  "     x=0" "     x=1" "    0->1" "       x" " x+delta" /*
                        */ "  +delta" "       x" "    x+sd" "     +sd"
                    }
                }
            }
            if "`fromto'"=="fromto" {
                mat roweq `vchange' = from to dif from to dif from /*
                */ to dif from to dif
            }

*=> save PE_dc with discrete change values; used by mlogplot and mlogview

            tempname zeros tempmat
            * 1 row x ncats with 0's
            mat `zeros' = J(1, `ncats', 0)
            mat rownames `zeros' = "    void"
            * is it binary?
            capture assert `var' == 0 | `var' == 1 | `var' == . `if' `in'
            * if binary, only 0/1 in 2nd row
            if _rc == 0 {
            * DROP 16Nov2005 1.6.9
            * mat `tempmat' = `zeros' \ `vchange'[1,2...] \ `zeros' \ `zeros' \ `zeros'
                * 16Nov2005 1.6.9
                mat `tempmat' = `vchange'[2,2...] \ `vchange'[1,2...] \ `zeros' /*
                */ \ `zeros' \ `zeros'
            } /* else, 1: min/max 2:null 3:1 4:sd */
            else {

            /* DROP 16Nov2005 1.6.9
                * contains 0->1, zeros, -+1, -+sd
                mat `tempmat' = `vchange'[2,2...] \ /*
                */ `zeros' \ `vchange'[3..4,2...] \ `zeros'
            */
                * 16Nov2005 1.6.9
                * contains 0->1, min->max, -+1, -+sd
                mat `tempmat' = `vchange'[2,2...] \ /*
                */ `vchange'[1,2...] \ `vchange'[3..4,2...] \ `zeros'

            }
            mat roweq `tempmat' = `var'
            if "`i'"=="1" {
                mat PE_dc = `tempmat'
                if "`label'"=="nolabel" { mat colnames PE_dc = `catvals' }
                else { mat colnames PE_dc = `catnms8' }
            }
            if "`i'"!="1" {
                mat PE_dc = PE_dc \ `tempmat'
            }

            * grab all info on change
            mat `nomtemp' = nullmat(`nomtemp') \ `vchange' // 2006-02-18 for estout

*=> set up matrices for output

            if "`label'"=="nolabel" {
                mat colnames `vchange' = "Avg|Chg|" `catvals'
            }
            else {
                mat colnames `vchange' = "Avg|Chg|" `catnms8'
            }
            if "`outcome'"=="" {
                * is 0/1 variable
                capture assert `var' == 0 | `var' == 1 | `var' == . `if' `in'
                if "`fromto'"=="fromto" {
                    if _rc == 0 { mat `vchange' = `vchange'[4..6, 1...] }
                    else {
                        tempname vchang1 vchang2
                        mat `vchang1' = `vchange'[1..3, 1...]
                        mat `vchang2' = `vchange'[7..., 1...]
                        mat `vchange' =  `vchang1' \ `vchang2'
                    }
                }
                else {
                    if _rc == 0 { mat `vchange' = `vchange'[2, 1...] }
                    else {
                        tempname vchang1 vchang2
                        mat `vchang1' = `vchange'[1, 1...]
                        mat `vchang2' = `vchange'[3..., 1...]
                        mat `vchange' =  `vchang1' \ `vchang2'
                    }
                }
                if "`hasmarg'"=="yes" {
                    capture assert `var' == 0 | `var' == 1 /*
                    */ | `var' == . `if' `in'
                    if _rc != 0 {
                        mat `vmarg' = `margout'[`i', 1...]
                        * compute avg abs discrete change
                        local k = 1
                        * amarg changes made in 1.8.0 for estout returns
                        *tempname amarg                                 // removed 23oct2007 bj
                        *scalar `amarg' = 0                             // removed 23oct2007 bj
                        while `k' <= `ncats' {
                            mat `amarg'[1,`i'] = `amarg'[1,`i'] + abs(`vmarg'[1,`k'])    // changed 23oct2007 bj
                            local k = `k' + 1
                        }

                        * jf 5/20/03
                        mat `amarg'[1,`i'] = `amarg'[1,`i'] / `ncats'   // changed 23oct2007 bj
                        mat `vmarg' = (`amarg'[1,`i'],`vmarg')          // changed 23oct2007 bj
                        mat rownames `vmarg' = MargEfct
                        mat roweq `vmarg' = _
                        mat `vchange' = `vchange' \ `vmarg'
                    }
                }
                di _n in y "`var'" _c
                mat list `vchange', noheader
                mat roweq `vchange' = `var'
                mat `dchange' = nullmat(`dchange') \ `vchange'

            } /* "`outcome'"=="" */

            else {
                * mat `vchange' = `vchange'[1..., `outcome']
                * 1.7.1 06Jan2007
                * +1 since average in in first column
                mat `vchange' = `vchange'[1..., `outcome'+1]
                mat `vchange' = `vchange''
                mat rownames `vchange' = `var'
                mat `dchange' = nullmat(`dchange') \ `vchange'
            }
            local i = `i' + 1
        } /* while `i' <= `i_to' */

        if "`outcome'"!="" {
            if "`hasmarg'"=="yes" {
                mat `margout' = `margout'[1..., `outcome']
                mat colnames `margout' = MargEfct
                mat coleq `margout' = _
                mat `dchange' = `dchange' , `margout'
            }
            *added to make matrix headings stata7 compatible
            mat _PEtemp = `dchange''
* 2.5.2
local outcmvnm "`outcmv'"
return mat change`outcmvnm' = _PEtemp, copy
*            return mat change`outcmv' = _PEtemp, copy           // added 23oct2007 bj
            _peabbv _PEtemp
            mat `dchange' = _PEtemp'
            mat list `dchange', noheader
            mat `dchange' = `dchange''
        }
        local i = 1
        while `i' <= `ncats' {
            mat temp = r(p`i')
            mat `basepr' = nullmat(`basepr') , temp[1, 1]
            local i = `i' + 1
        }
        mat rownames `basepr' = "Pr(y|x)"
        if "`label'"=="nolabel" { mat colnames `basepr' = `catvals' }
        else { mat colnames `basepr' = `catnms8' }
        if "`brief'"=="" { mat list `basepr', noheader }

        // rearrange info to be returned 2006-02-18 for estout
        if "`outcome'"=="" {            // if-condition added 23oct2007 bj
            tempname tempmat mtemp      // changed 24oct2007 bj
            local i = 1
            while `i' <= (`ncats'+1) {
                * move col i into one column for each variable
                local v = 1
                while `v' <= `i_to' {
                    local nrowper = 4 + 8*("`fromto'"=="fromto") // rows of info per variable - changed 07nov2007 bj
                    local rst = 1+ ((`v'-1)*`nrowper')
                    local ren = `rst' + `nrowper' - 1
                    mat `tempmat' = nullmat(`tempmat') , `nomtemp'[`rst'..`ren'', `i']
                    local ++v
                }
                mat colnames `tempmat' = `varlist'
                if `i'==1 {
                    if "`hasmarg'"=="yes" {             // block added 23oct2007 bj
                        mat rowname `amarg' = MargEfct
                        mat `tempmat' = `tempmat' \ `amarg'
                    }
                    return mat changemn = `tempmat'
                }
                else {
                    local c = `i' - 1
                    local catnum : word `c' of `catvals'
                    * 2.5.1 if negative, replace - with _ 2009-12-10
                    if `catnum'<0 {
                        local catnum = abs(`catnum')
                        local catnum "_`catnum'"
                    }
                    tempname change`catnum'

                    * 1.7.1 add marg to return matrix
                    if "`hasmarg'"=="yes" {             // if-condition added 23oct2007 bj
                        mat `mtemp' = `margout'[1...,`c']'  // changed 23oct2007 bj
                        mat rowname `mtemp' = MargEfct
                        *mat def mtemp = `mtemp'        // removed 23oct2007 bj
                        *mat def tempmat = `tempmat'    // removed 23oct2007 bj
                        mat `tempmat' = `tempmat' \ `mtemp'
                    }
                    return mat change`catnum' = `tempmat'

                }
                local ++i
            }
        } /* if "`outcome'"=="" */
        mat `predis' = `basepr'

    } /* if "`output'"=="nomord" */

*=> print base values

    if "`brief'"=="" & "`base'"!="nobase" {
        if "`input'"=="twoeq" {
            di _n in g "base x values for count equation: "
        }
        mat `tobase' = `tobase' \ `sd'
        * 2009-07-10 1.8.1 for Stata 11
        mat rownames `tobase' = "x=" "sd_x="
        mat _PEtemp = `tobase'
        _peabbv _PEtemp
        mat list _PEtemp, noheader f(%8.0g)
        if "`input'"=="twoeq" {
            di _n in g "base x values for binary equation: "
            mat `tobase2' = `tobase2' \ `sd2'
            * 2009-07-10 1.8.1 for Stata 11
            mat rownames `tobase2' = "x=" "sd_x="
            mat _PEtemp = `tobase2'
            _peabbv _PEtemp
            mat list _PEtemp, noheader f(%8.0g)
        }
    }

*=> Help option

    if "`help'"=="help" {
        di
        di in g " Pr(y|x): probability of observing each y for "/*
        */ "specified x values"
        di in g "Avg|Chg|: average of absolute value of the change"/*
        */ " across categories"
        di in g "Min->Max: change in predicted probability as x"/*
        */ " changes from its minimum to"
        di in g "          its maximum"
        di in g "    0->1: change in predicted probability as x"/*
        */ " changes from 0 to 1"

        if "`uncentered'"=="" {
            if `delt'==1 {
                di in g "   -+1/2: change in predicted probability as x"/*
                */ " changes from 1/2 unit below"
                di in g "          base value to 1/2 unit above"
            }
            else {
                di in g "   -+d/2: change in predicted probability as x"/*
                */ " changes from " `delthlf' " units"
                di in g "          below base value to "`delthlf' " units"/*
                */ " above"
            }
        }
        else {
            if `delt'==1 {
                di in g "      +1: change in predicted probability as x"/*
                */ " increases by 1 unit"
            }
            else {
                di in g "  +delta: change in predicted probability as x"/*
                */ " increases by " `delt' " units"
            }
        }

        if "`uncentered'"=="" {
            di in g "  -+sd/2: change in predicted probability as x"/*
            */ " changes from 1/2 standard"
            di in g "          dev below base to 1/2 standard"/*
            */ " dev above"
        }
        else {
            di in g "     +sd: change in predicted probability as x"/*
            */ " increases by a standard dev"
        }

        di in g "MargEfct: the partial derivative of the predicted"/*
        */ " probability/rate with"
        di in g "          respect to a given independent variable"
    }

//  2006-02-18 returns for estout

    mat rown `tobase' = X                                    // 23oct2007 bj
    mat `baseval' = `tobase'[1,1...] \ `baseval'[2...,1...]  // 23oct2007 bj
    * combine base values and name equations if zip or zinb
    if "`input'"=="twoeq" {
        mat rown `tobase2' = X                                      // added 23oct2007 bj
        mat `basezi' = `tobase2'[1,1...] \ `basezi'[2...,1...]      // added 23oct2007 bj
        matrix colnames `basezi' = inflate:
        local eqnm "`e(depvar)':"
        matrix colnames `baseval' = `eqnm'
        matrix `baseval' = `baseval' , `basezi'
    }

    return matrix baseval = `baseval'
    if "`output'"!="nomord" { return matrix change = `change' }     // changed 23oct2007 bj
    return matrix predval = `predis'
    return scalar delta = `delt'                        // 05nov2007 bj
    return scalar centered = ("`uncentered'"=="")       // 05nov2007 bj
    if "`outcome'"!="" {                                // 23oct2007 bj
        return scalar outcome = `outcmv'
    }
    return local modeltype `"`io'"'         // 23oct2007 bj

    * return names and values of outcome categories
    tempname catn
    if "`catvals'"!="" {
        local i = 1
        while `i' <= `ncats' {
            local valchk : word `i' of `catvals'
            local nmchk : word `i' of `catnms'
            mat `catn' = nullmat(`catn') \ `valchk'
            local ++i
        }
    }
    else {
        matrix `catn' = J(1,1,.)
        local catnms = ""
    }
    matrix `catn' = `catn''
    matrix colnames `catn' = `catnms'
    matrix rownames `catn' = "`e(depvar)'"
    return matrix catval = `catn'
end
exit

*  version 1.6.8 13Apr2005
*  version 1.6.7c 27Mar2005 slogit
*  version 1.6.7b 19Feb2005 zt
*  version 1.6.6  20May2003
*  version 1.6.9 - 19May2006
*   - Add min->max change to PE_dc for mlogplot
*   - required for mlogplot v1.6.8 to plot changes over range
*  version 1.7.1 jsl 06Jan2007 for estout
*   - outcome() fixed for ord and nom
*  version 1.7.2 - 07nov2007 Ben Jann changes for estout
*  - -fromto- results were not returned correctly with nomord models - this is fixed
*  - brief option caused error - this is fixed
*  - returns r(outcome) if -outcome()- specified
*  - returns type of model in r(modeltype)
*  - returns marginal effects now also in r(changemn)
*  - no longer crashes on nomorg models without marginals (i.e. -slogit-)
*  - returns correct basevals now if x() is specified
*  - returns results now only for the specified outcome if -outcome()- is specified
*  - no longer returns r(change) for nomord models
* version 1.8.0 2008-02-16 sl
*   - revised to work with estout
*   - added mprobit
* version 1.8.1 2009-07-10
*   - sd(x) fix for Stata 11
* version 1.9.0 jsl 2009-09-19
*   - fix mlogit for e(b) in stata 11
* version 2.5.0 2009-10-28 jsl
*  - stata 11 update for returns from -mlogit-