Announcement

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

  • if and else in Stata versus Mata

    Dear all
    I am analysing the Mata code behind a command (fairlie) in order to understand what actually this is doing, and I have arrived to a part of the script which works unexpectedly in my terminal. A simplified version of the problematic part is:

    Code:
    mata
    mata clear
            for (j=1; j<=3; j++) {
                printf("{result}%1.0fc\n",j)
    
                if (j==1) {            
                    xl = (10\8\7)
                    xl
                }
                else {
                    xl=xr
                    xl
                }
                if (j==3) {
                    xr=(8\7\6)
                    xr
                }
                else {
                    xr = xl
                    xr
                }
                
            }
                    
    end
    After running this, the program issues the following run-time error

    <istmt>: 3499 xr not found

    I think it fails to recognize that the last else statement should be executed in the first iteration, when j==1, which defines xr and pass it on for the second iteration, when j==2. What puzzles me is that in Stata the equivalent code actually works

    Code:
            foreach j of numlist 1/3 {
                display as result "`j'"
    
                if (`j'==1) {
                    matrix xl = (10\8\7)
                    matrix list xl
                }
                else {
                    matrix xl=xr
                    matrix list xl
                }
                if (`j'==3) {
                    matrix xr=(8\7\6)
                    matrix list xr
                }
                else {
                    matrix xr = xl
                    matrix list xr
                }
                
                display _n(2)
                local ++j    
            }
    Can somebody tell me what is wrong in the code above? Do Mata and Stata understand differently the if and else branching? Note that the program was written in version 9.2 but I am controlling this with version control in my PC (I don't think this may make a difference, though)
    Thank you

    JM
    Stata 14.0
    Last edited by Juan del Pozo; 06 Jun 2019, 07:02. Reason: typo: changed "same" for "equivalent"

  • #2
    Perhaps the discussion in the output of help m1_how will clarify how Mata handles code differently than the Stata command language.

    Comment


    • #3
      Thanks for your answer, William. In fact, I checked that reference before venturing to read Mata code and it does not mention the possibility that the branching works separately in both languages. In fact I read most of Gould, W. (2018) The Mata Book and, even though the if, else and else if commands, as well as how Mata works are throughly discussed there, it does not help me to get through this specific question.
      Last edited by Juan del Pozo; 06 Jun 2019, 07:35.

      Comment


      • #4
        I think I have an answer for my question. Correct me if I am wrong, but it has to do with the initialization of variables in Mata: unlike Stata, variables in Mata should be defined at the moment they are called in the loop, regardless of the fact that these are executed when they are called. Hence, I was calling to xr in the first else condition but it had not been defined yet. Stata handles this problem since it enters this condition when j!=1 (from the second iteration onwards) after xr has been defined in the first iteration, but Mata complains because xr has not been defined at the time the loop is passed. So a solution for my problem is

        Code:
        mata
        mata clear
                xl = xr =.                 //<-- variables initialization
                for (j=1; j<=3; j++) {
                    printf("{result}%1.0fc\n",j)
        
                    if (j==1) {            
                        xl = (10\8\7)
                        xl
                    }
                    else {
                        xl=xr
                        xl
                    }
                    if (j==3) {
                        xr=(8\7\6)
                        xr
                    }
                    else {
                        xr = xl
                        xr
                    }
                    
                }
                        
        end
        Is there something I am missing in this self-explanation?
        Thanks!
        Last edited by Juan del Pozo; 06 Jun 2019, 09:04.

        Comment

        Working...
        X