Search code examples
stata

GMM program evaluator does not like my temporary variable


As far as I can tell, the two programs in the code below are identical. In the first program, I just assign the parameter to a scalar. In the second program, I store this scalar for each observation in a temporary variable.

Mathematically, that should be the same, yet the second program produces "numerical derivatives are approximate" and "flat or discontinuous region encountered".

Why cannot the derivatives be computed properly in the second approach?

clear
set obs 10000
set seed 42

gen x = runiform() * 10
gen eps = rnormal()

gen y = 2 + .3 * x + eps

capture program drop testScalar
program testScalar
    syntax varlist [if], at(name)

    scalar b0 = `at'[1,1]
    scalar b1 = `at'[1,2]

    replace `varlist' = y - b0 - b1* x
end

capture program drop testTempvar
program testTempvar
    syntax varlist [if], at(name)

    tempvar tmp

    scalar b0 = `at'[1,1]
    scalar b1 = `at'[1,2]

    gen `tmp' = b1

    replace `varlist' = y - b0 - `tmp'* x

end

gmm testScalar, nequations(1) nparameters(2) instr(x) winitial(identity) onestep
gmm testTempvar, nequations(1) nparameters(2) instr(x) winitial(identity) onestep

Output:

. gmm testScalar, nequations(1) nparameters(2) instr(x) winitial(identity) onestep
(10,000 real changes made)

Step 1
Iteration 0:   GMM criterion Q(b) =  417.93313  
Iteration 1:   GMM criterion Q(b) =  1.690e-23  
Iteration 2:   GMM criterion Q(b) =  3.568e-30  

note: model is exactly identified

GMM estimation 

Number of parameters =   2
Number of moments    =   2
Initial weight matrix: Identity                   Number of obs   =     10,000

------------------------------------------------------------------------------
             |               Robust
             |      Coef.   Std. Err.      z    P>|z|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         /b1 |   2.022865   .0200156   101.06   0.000     1.983635    2.062095
         /b2 |   .2981147    .003465    86.04   0.000     .2913235    .3049059
------------------------------------------------------------------------------
Instruments for equation 1: x _cons

. gmm testTempvar, nequations(1) nparameters(2) instr(x) winitial(identity) onestep
(10,000 real changes made)

Step 1
Iteration 0:   GMM criterion Q(b) =  417.93313  
numerical derivatives are approximate
flat or discontinuous region encountered
Iteration 1:   GMM criterion Q(b) =  8.073e-17  
numerical derivatives are approximate
flat or discontinuous region encountered
Iteration 2:   GMM criterion Q(b) =  8.073e-17  (backed up)

note: model is exactly identified

GMM estimation 

Number of parameters =   2
Number of moments    =   2
Initial weight matrix: Identity                   Number of obs   =     10,000

------------------------------------------------------------------------------
             |               Robust
             |      Coef.   Std. Err.      z    P>|z|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         /b1 |   2.022865   .0201346   100.47   0.000     1.983402    2.062328
         /b2 |   .2981147   .0034933    85.34   0.000      .291268    .3049613
------------------------------------------------------------------------------
Instruments for equation 1: x _cons

. 

Solution

  • In the program testTempvar you need to generate the temporary variable tmp as type double:

    generate double `tmp' = b1
    

    In other words, this is a precision problem.