0

I have a small code snippet where I have defined a local macro i to be used in a forvalues loop:

matrix I=I(4)
scalar x1=b[1,1]
scalar sum1=0

local  i = 2
forvalues i = 2/4 {
    scalar chk=i-1

    forvalues j = 1/`=chk' {
        scalar sum1=I[`i',`j']*x`j'+sum1
    }
    scalar x`i'=(b[`i',1]-sum1)/I[`i',`i']
}

However, Stata complains:

error 111 
i not found 

Note that this error is appearing only if I use the macro in a loop, not otherwise.

PGupta
  • 183
  • 1
  • 7

1 Answers1

1

The Stata problem you raise is with the line

scalar chk = i - 1

Stata sees a reference there to i, which evidently cannot be interpreted as a variable or scalar name, hence the error message you got. That's Stata's point of view.

From your point of view, the error is not using single quotation marks to extract the value or contents of the local macro i, or at least that appears to be your intention, as you nowhere else explain your aim. So, nothing is disappearing; you just referred to a non-existent entity. That's only a detail, however, and there is a larger story here.

Here is a first rewriting of your code.

matrix I = I(4)
scalar x1 = b[1,1]
scalar sum1 = 0

forvalues i = 2/4 {
    local chk = `i' - 1
    forvalues j = 1/`chk' {
        scalar sum1 = I[`i',`j'] * x`j' + sum1
    }
    scalar x`i' = (b[`i',1] - sum1) / I[`i',`i']
}

Notes.

  1. The line local i = 2 appears redundant. The forvalues loop initialises the macro.

  2. As a matter of style, experienced Stata programmers would typically use a local macro, not a permanent scalar, for a transient loop limit.

But wait: I(4) is just an identity matrix with 4 rows and columns, 1s on the principal diagonal and 0s elsewhere. So

I[`i',`i'] 

is necessarily 1 and

I[`i',`j'] 

for earlier entries on the same row of the matrix is 0. So sum1 is never anything but 0. So you don't need the identity matrix for any obvious purpose and your code seems reducible to extracting four scalars from a vector:

forvalues i = 1/4 {
    scalar x`i' = b[`i',1] 
}

EDIT. Double loops like

forvalues i = 2/4 {
    local chk = `i' - 1
    forvalues j = 1/`chk' {
        ...  
    }
    ...
}

can also be written more concisely

forvalues i = 2/4 {
    forvalues j = 1/`= `i' - 1' {
        ...  
    }
    ...
}
Nick Cox
  • 35,529
  • 6
  • 31
  • 47
  • Thank you for the explanation! I used the single quotation marks and it worked. The matrix I use in the actual code is an upper triangular matrix, not the identity matrix. This was just a MWE. Could you please explain your point 2 above? I actually want the j loop to run from 1 to i-1, but it seems like forvalues doesn't allow expressions in the range, hence I had to create the new scalar chk. – PGupta Feb 08 '15 at 16:44
  • Not so. There is no compulsion to create a scalar. My answer already showed that you can use a local macro. The assertion is that is much better style. Otherwise a permanent scalar is defined and visible beyond the termination of the loop and indeed the program. Please see also EDIT above. – Nick Cox Feb 09 '15 at 00:14