Subscripts can be used either to retrieve the value of one or more array elements or to designate array elements to receive new values. The expression
arr denotes the value of the 13th element of
arr (because subscripts start at 0), while the statement
arr = 5 stores the number 5 in the 13th element of
arr without changing the other elements.
Elements of multidimensional arrays are specified by using one subscript for each dimension. IDL's notational convention is that for generic arrays and images, the first subscript denotes the column and the second subscript denotes the row. When arrays are used for mathematical operations (linear algebra, for example), the convention is reversed: the first subscript denotes the row and the second subscript denotes the column.
A is a 2-element by 3-element array (using [column, row] notation), the elements are stored in memory as follows:
The elements are ordered in memory as: A0,0, A1,0, A0,1, A1,1, A0,2, A1,2. This ordering is like Fortran. It is the opposite of the order used by C/C++. For more information on how IDL arranges multidimensional data in memory, see Columns, Rows, and Array Majority. For a discussion of how the ordering of such data relates to IDL mathematics routines, see Arrays and Matrices.
Arrays that contain image data are usually displayed in graphics displays with row zero at the bottom of the screen, matching the display's coordinate system (although this order can be reversed by setting the system variable
Elements of multidimensional arrays also can be specified using only one subscript, in which case the array is treated as a vector with the same number of points. In the above example,
A is the same element as
A[0, 1], and
A is the same element as
If an attempt is made to reference a nonexistent element of an array using a scalar subscript (a subscript that is negative or larger than the size of the dimension minus 1), an error occurs and program execution stops.
Subscripts can be any type of vector or scalar expression. If a subscript expression is not integer, a longword integer copy is made and used to evaluate the subscript.
A[1.99]is the same as specifying
When creating arrays, IDL eliminates all size 1, or "degenerate", trailing dimensions. Thus, the statements
A = INTARR(10, 1) HELP, A
print the following:
A INT = Array
This removal of superfluous dimensions is usually convenient, but it can cause problems when attempting to write fully general procedures and functions. Therefore, IDL allows you to specify "extra" dimensions for an array as long as the extra dimensions are all zero.
For example, consider a vector defined as follows:
arr = INDGEN(10)
The following are all valid references to the sixth element of
X = arr X = arr[5, 0] X = arr[5, 0, 0, *, 0]
Thus, the automatic removal of degenerate trailing dimensions does not cause problems for routines that attempt to access the resulting array.
The REFORM function can be used to add degenerate trailing dimensions to an array if desired. For example, the following statements create a 10 element integer vector, and then alter the dimensions to be [10, 1]:
A = INTARR(10) A = REFORM(A, 10, 1, /OVERWRITE)
Scalar quantities in IDL can be thought of as the first element of an array with one dimension. They can be subscripted with a zero reflecting the first and only position. Therefore,
;Assign the value of 5 to A. A = 5 ;Print the value of the first element of A. PRINT, A
If we redefine the first element of A:
;Redefine the first element of A. A = 6 PRINT, A
Bhas not been previously defined, the statement:
B = 9
Versions of IDL prior to version 5.0 used parentheses to indicate array subscripts. Function calls use parentheses in a visually identical way to specify argument lists. As a result, the IDL compiler was not able to distinguish between arrays and functions by looking at the statement syntax. For example, the IDL statement
value = fish(5)
could either set the variable value equal to the sixth element of an array named fish, or set value equal to the result of passing the argument 5 to a function called fish.
To determine if it is compiling an array subscript or a function call, IDL checks its internal table of known functions. If it finds a function name that matches the unknown element in the command (fish, in the above example), it calls that function with the argument specified. If IDL does not find a function with the correct name in its table of known functions, it assumes that the unknown element is an array, and attempts to return the value of the designated element of that array. This rule generally gives the desired result, but it can be fooled into the wrong choice under certain circumstances, much to the surprise of the unwary programmer.
For this reason, versions of IDL beginning with version 5.0 use square brackets rather than parentheses for array subscripting. An array subscripted in this way is unambiguously interpreted as an array under all circumstances. In IDL 5.0 and later:
value = fish
sets value to the sixth element of an array named fish.
Due to the large amount of existing IDL code written in the older syntax, as well as the ingrained habits of thousands of IDL users, IDL continues to allow the old syntax to be used, subject to the ambiguity mentioned above. That is, while
value = fish
value = fish(5)
is still subject to the same ambiguity-and rules-that applied in IDL versions prior to version 5.0
Since the older syntax has been used widely, you should not be surprised to see it from time to time. However, square brackets are the preferred form, and should be used for new code.