Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Halton draws issue

    Mata newbie here. I'm looking to use Halton draws (rather than pseudouniform random draws) in a estimator that uses maximum simulated likelihood methods. I want draws in 2 dimensions.

    I know I can use Mata to generate Halton draws. For example, suppose I have 10 observations, then the following code generates a matrix x containing a vector of draws (one draw per obs). I can use these for the first calculation of the simulated likelihood.

    Code:
    . mata: x = halton(10,2,1)
    
    . mata: x
                      1             2
         +-----------------------------+
       1 |           .5   .3333333333  |
       2 |          .25   .6666666667  |
       3 |          .75   .1111111111  |
       4 |         .125   .4444444444  |
       5 |         .625   .7777777778  |
       6 |         .375   .2222222222  |
       7 |         .875   .5555555556  |
       8 |        .0625   .8888888889  |
       9 |        .5625    .037037037  |
      10 |        .3125   .3703703704  |
         +-----------------------------+
    But what about the second and subsequent calculations? For these I need further sets of draws for each obs. I read the Mata manual and -help mf_halton- as telling me that I can modify x using _halton()


    _halton(x) modifies the n x d matrix x so that it contains a Halton set of dimension d of length n.


    _halton(x, start) does the same thing, but the first row of the returned matrix contains the sequences starting at index start. The default is start = 1.

    ...

    _halton() modifies x and can be used when repeated calls are made to generate long sequences in blocks. Here update the start index between calls by using start = start + rows(x).
    So, I try the following and discover the new matrix y is empty.

    Code:
    . mata: y = _halton(x)
    
    . mata: y
    
    .
    So, clearly, I'm misunderstanding something. If _halton() is not for me, do I need instead to use halton() itself to generate a ( nobs*S) x 2 matrix, where S is the number of simulations, and then extract the draws in chunks of n?

    PS using _halton(x) by itself doesn't change x
    Code:
    . mata: _halton(x)
    
    . mata: x
                      1             2
         +-----------------------------+
       1 |           .5   .3333333333  |
       2 |          .25   .6666666667  |
       3 |          .75   .1111111111  |
       4 |         .125   .4444444444  |
       5 |         .625   .7777777778  |
       6 |         .375   .2222222222  |
       7 |         .875   .5555555556  |
       8 |        .0625   .8888888889  |
       9 |        .5625    .037037037  |
      10 |        .3125   .3703703704  |
         +-----------------------------+


  • #2
    I will look into it. It seems the one argument version of _halton() is not updating the start index as documneted:

    " _halton() modifies x and can be used when repeated calls are made to generate long sequences in blocks. Here update the start index between calls by using start = start + rows(x)."

    I suppose a temporay workaround is to explicitly update the start value between calls:

    Code:
    . mata:
    ------------------------------------------------- mata (type end to exit) ----
    :
    : start = 1
    
    : x = halton(10, 2, start)
    
    : x
                      1             2
         +-----------------------------+
       1 |           .5   .3333333333  |
       2 |          .25   .6666666667  |
       3 |          .75   .1111111111  |
       4 |         .125   .4444444444  |
       5 |         .625   .7777777778  |
       6 |         .375   .2222222222  |
       7 |         .875   .5555555556  |
       8 |        .0625   .8888888889  |
       9 |        .5625    .037037037  |
      10 |        .3125   .3703703704  |
         +-----------------------------+
    
    :
    :         // update start
    : start = start + rows(x)
    
    : _halton(x, start)
    
    : x
                      1             2
         +-----------------------------+
       1 |        .8125   .7037037037  |
       2 |        .1875   .1481481481  |
       3 |        .6875   .4814814815  |
       4 |        .4375   .8148148148  |
       5 |        .9375   .2592592593  |
       6 |       .03125   .5925925926  |
       7 |       .53125   .9259259259  |
       8 |       .28125   .0740740741  |
       9 |       .78125   .4074074074  |
      10 |       .15625   .7407407407  |
         +-----------------------------+
    
    :
    :         // update start again
    : start = start + rows(x)
    
    : _halton(x, start)
    
    : x
                      1             2
         +-----------------------------+
       1 |       .65625   .1851851852  |
       2 |       .40625   .5185185185  |
       3 |       .90625   .8518518519  |
       4 |       .09375   .2962962963  |
       5 |       .59375   .6296296296  |
       6 |       .34375    .962962963  |
       7 |       .84375    .012345679  |
       8 |       .21875   .3456790123  |
       9 |       .71875   .6790123457  |
      10 |       .46875   .1234567901  |
         +-----------------------------+
    
    : end
    Last edited by Hua Peng (StataCorp); 07 Feb 2026, 07:44.

    Comment


    • #3
      thanks!

      Comment


      • #4
        After a closer look at the code of _halton() and its documentation. I believe the code is fine as is, but the documnetation is confusing. _halton(x) is the same as _halton(x, 1), hence it will always modify x to the same matrix with start index 1.


        Code:
        _halton() modifies x and can be used when repeated calls are made to generate long sequences in blocks. Here update the start index between calls by using start = start + rows(x).
        I think a better description might be:

        Code:
        _halton() modifies x and can be used when repeated calls are made to generate long sequences in blocks. To arachive that, update the start index between calls by using start = start + rows(x).
        We will look into updating the manual to make it clear.

        Comment


        • #5
          Thank you, Hua Peng (StataCorp) . That makes sense. However, with further explorations hoping to exploit this new understanding, I continue to have problems with assignments that puzzle me:

          Code:
          . clear all
          
          . 
          . set obs 10
          Number of observations (_N) was 0, now 10.
          
          . 
          . local start = 1
          
          . local S = 2
          
          . local N = _N
          
          . mata: N = st_local("N")
          
          . mata: N
            10
          
          . mata: S = st_local("S")
          
          . mata: S
            2
          
          . mata: start = st_local("start")
          
          . mata: start
            1
          
          . mata: length = N*S
                                 *:  3251  nonnumeric found where numeric required
                           <istmt>:     -  function returned error
          r(3251);
          I get the same 3251 error if I type "x = halton(N*S, 2, 1)".

          Because length is not created, the line " mata: x = halton(length, 2, 1) " also throws an error, so I try the following instead ... also leading to an error further down the track when I try to update start as suggested

          Code:
          . mata: x = halton(20, 2, 1)  // "20" instead of "length" or "N*S"
          
          . mata: x 
                            1             2
               +-----------------------------+
             1 |           .5   .3333333333  |
             2 |          .25   .6666666667  |
             3 |          .75   .1111111111  |
             4 |         .125   .4444444444  |
             5 |         .625   .7777777778  |
             6 |         .375   .2222222222  |
             7 |         .875   .5555555556  |
             8 |        .0625   .8888888889  |
             9 |        .5625    .037037037  |
            10 |        .3125   .3703703704  |
            11 |        .8125   .7037037037  |
            12 |        .1875   .1481481481  |
            13 |        .6875   .4814814815  |
            14 |        .4375   .8148148148  |
            15 |        .9375   .2592592593  |
            16 |       .03125   .5925925926  |
            17 |       .53125   .9259259259  |
            18 |       .28125   .0740740741  |
            19 |       .78125   .4074074074  |
            20 |       .15625   .7407407407  |
               +-----------------------------+
          
          . mata: rows(x)
            20
          
          . mata: start
            1
          
          . 
          . mata: start = start + rows(x)
                           <istmt>:  3250  type mismatch
          r(3250);
          
          end of do-file
          
          r(3250);
          So, the line "mata: _halton(x, start)" with (what I'd hope was) the revised start value also throws an error. I get what I hoped to get if, instead, I use the new start value directly
          Code:
          . mata: _halton(x, 21)
          
          . mata: x
                            1             2
               +-----------------------------+
             1 |       .65625   .1851851852  |
             2 |       .40625   .5185185185  |
             3 |       .90625   .8518518519  |
             4 |       .09375   .2962962963  |
             5 |       .59375   .6296296296  |
             6 |       .34375    .962962963  |
             7 |       .84375    .012345679  |
             8 |       .21875   .3456790123  |
             9 |       .71875   .6790123457  |
            10 |       .46875   .1234567901  |
            11 |       .96875   .4567901235  |
            12 |      .015625   .7901234568  |
            13 |      .515625   .2345679012  |
            14 |      .265625   .5679012346  |
            15 |      .765625   .9012345679  |
            16 |      .140625    .049382716  |
            17 |      .640625   .3827160494  |
            18 |      .390625   .7160493827  |
            19 |      .890625   .1604938272  |
            20 |      .078125   .4938271605  |
               +-----------------------------+
          
          .
          I suspect this Mata newbie is missing something very obvious but, right now, I can't see what. (Stata/MP4 19.5 Windows) BTW I was using the "mata: " line prefix because of checking one line at a time. Is there something about inline mode I should be aware of because I note that the following works as expected:

          Code:
          . clear all
          
          . mata:
          ------------------------------------------------- mata (type end to exit) -----
          :         N = 10
          
          :         S = 2
          
          :         dim = 2
          
          :         start = 1
          
          : 
          :         H = halton(N*S, dim, start)  // (N*S) x dim matrix
          
          : 
          :         N
            10
          
          :         S
            2
          
          :         
          :         H
                            1             2
               +-----------------------------+
             1 |           .5   .3333333333  |
             2 |          .25   .6666666667  |
             3 |          .75   .1111111111  |
             4 |         .125   .4444444444  |
             5 |         .625   .7777777778  |
             6 |         .375   .2222222222  |
             7 |         .875   .5555555556  |
             8 |        .0625   .8888888889  |
             9 |        .5625    .037037037  |
            10 |        .3125   .3703703704  |
            11 |        .8125   .7037037037  |
            12 |        .1875   .1481481481  |
            13 |        .6875   .4814814815  |
            14 |        .4375   .8148148148  |
            15 |        .9375   .2592592593  |
            16 |       .03125   .5925925926  |
            17 |       .53125   .9259259259  |
            18 |       .28125   .0740740741  |
            19 |       .78125   .4074074074  |
            20 |       .15625   .7407407407  |
               +-----------------------------+
          
          :         rows(H)
            20
          
          : 
          :         start = start + rows(H)
          
          :         start
            21
          
          :         _halton(H, start)
          
          :         H
                            1             2
               +-----------------------------+
             1 |       .65625   .1851851852  |
             2 |       .40625   .5185185185  |
             3 |       .90625   .8518518519  |
             4 |       .09375   .2962962963  |
             5 |       .59375   .6296296296  |
             6 |       .34375    .962962963  |
             7 |       .84375    .012345679  |
             8 |       .21875   .3456790123  |
             9 |       .71875   .6790123457  |
            10 |       .46875   .1234567901  |
            11 |       .96875   .4567901235  |
            12 |      .015625   .7901234568  |
            13 |      .515625   .2345679012  |
            14 |      .265625   .5679012346  |
            15 |      .765625   .9012345679  |
            16 |      .140625    .049382716  |
            17 |      .640625   .3827160494  |
            18 |      .390625   .7160493827  |
            19 |      .890625   .1604938272  |
            20 |      .078125   .4938271605  |
               +-----------------------------+
          
          :         
          : end

          Comment


          • #6
            Mata function string scalar st_local(string scalar name) returns a string when used to retrive the content of the local macro. To ilustrate:

            Code:
             set obs 10
            number of observations (_N) was 0, now 10
            
            . local start = 1
            
            . local S = 2
            
            . local N = _N
            
            . mata: N = st_local("N")
            
            . mata:eltype(N)
              string
            
            . mata: S = st_local("S")
            
            . mata:eltype(S)
              string
            
            . mata: N
              10
            
            . mata: S
              2
            
            . mata:length = N*S
                                   *:  3251  nonnumeric found where numeric required
                             <istmt>:     -  function returned error
            r(3251);
            Both mata scalar N and S are with string eltype(). Hence the 3251 error when multiplely them together. To fix this, we may either use mata function strtoreal() to convert them back to numerics:

            Code:
            . mata:length=strtoreal(N)*strtoreal(S)
            
            . mata:length
              20
            Or if the local macros are defined in the same context (same do-file or same interactive command session), we can refere them directly using macro expansion:

            Code:
            . mata: length1 = `N'*`S'
            
            . mata:length1
              20
            This works since macro expansion happens before Mata compilation/execution, hence when mata system gets the line, it sees:

            Code:
            mata: length1 = 10*2
            The other issue can be fixed similarly:

            Code:
            .  local start = 1
            
            .
            . mata: x = halton(20, 2, `start')
            
            .
            . mata: x
                              1             2
                 +-----------------------------+
               1 |           .5   .3333333333  |
               2 |          .25   .6666666667  |
               3 |          .75   .1111111111  |
               4 |         .125   .4444444444  |
               5 |         .625   .7777777778  |
               6 |         .375   .2222222222  |
               7 |         .875   .5555555556  |
               8 |        .0625   .8888888889  |
               9 |        .5625    .037037037  |
              10 |        .3125   .3703703704  |
              11 |        .8125   .7037037037  |
              12 |        .1875   .1481481481  |
              13 |        .6875   .4814814815  |
              14 |        .4375   .8148148148  |
              15 |        .9375   .2592592593  |
              16 |       .03125   .5925925926  |
              17 |       .53125   .9259259259  |
              18 |       .28125   .0740740741  |
              19 |       .78125   .4074074074  |
              20 |       .15625   .7407407407  |
                 +-----------------------------+
            
            . mata: start = strtoreal(st_local("start"))
            
            . mata: start
              1
            
            . mata: eltype(start)
              real
            
            . mata: start = start + rows(x)
            
            . mata: start
              21
            
            . mata: _halton(x, start)
            
            . mata: x
                              1             2
                 +-----------------------------+
               1 |       .65625   .1851851852  |
               2 |       .40625   .5185185185  |
               3 |       .90625   .8518518519  |
               4 |       .09375   .2962962963  |
               5 |       .59375   .6296296296  |
               6 |       .34375    .962962963  |
               7 |       .84375    .012345679  |
               8 |       .21875   .3456790123  |
               9 |       .71875   .6790123457  |
              10 |       .46875   .1234567901  |
              11 |       .96875   .4567901235  |
              12 |      .015625   .7901234568  |
              13 |      .515625   .2345679012  |
              14 |      .265625   .5679012346  |
              15 |      .765625   .9012345679  |
              16 |      .140625    .049382716  |
              17 |      .640625   .3827160494  |
              18 |      .390625   .7160493827  |
              19 |      .890625   .1604938272  |
              20 |      .078125   .4938271605  |
                 +-----------------------------+
            By the way, this happens fairly often to me as well when I have to interface Mata with Stata. I always forget Stata macro is a string.
            Last edited by Hua Peng (StataCorp); 08 Feb 2026, 12:14.

            Comment


            • #7
              Hua Peng (StataCorp) Thanks for taking the time to explain the issues. (And I presuming the all-within-Mata code worked because it didn't interface with Stata and then have to deal with the string/real problem.) thanks again!

              Comment


              • #8
                "..presuming the all-within-Mata code worked because it didn't interface with Stata and then have to deal with the string/real problem", yes, that's right.

                And you are very welcome. You might find Bill's "Using Mata with ado-files" useful, especially the part about "Passing arguments to Mata functions" https://www.stata.com/manuals/m-1ado.pdf#m-1Ado

                Comment

                Working...
                X