Home | Categories | Alphabetical | Classes | All Contents | [ < ] | [ > ]

Array Subscripting


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[12] denotes the value of the 13th element of arr (because subscripts start at 0), while the statement arr[12] = 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.

If A is a 2-element by 3-element array (using [column, row] notation), the elements are stored in memory as follows:

 
 
Stored in Memory
A0,0
A1,0
Lowest memory address
A0,1
A1,1
.
.
.
A0,2
A1,2
Highest memory address

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.

Note
When comparing IDL's memory layout to other languages, remember that those languages usually use a mathematical [row, column] notation for array dimensions, which is the reverse of the array notation used for the example above. See Columns, Rows, and Array Majority for more on comparing IDL's array layout to that of other languages.

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 !ORDER to a nonzero value). Array data are printed to standard text output (such as the IDL output log or console window) with the first row on top.

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[2] is the same element as A[0, 1], and A[5] is the same element as A[1, 2].

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.

Note
When floating-point numbers are converted to longword integers, they are truncated, not rounded. Thus, specifying A[1.99] is the same as specifying A[1].

Extra Dimensions

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[10] 

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 arr:

X = arr[5] 
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) 

Subscripting Scalars

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[0] 

IDL prints:

5 

If we redefine the first element of A:

;Redefine the first element of A. 
A[0] = 6 
 
PRINT, A 

IDL prints:

6 

Note
You cannot subscript a variable that has not yet been defined. Thus, if the variable B has not been previously defined, the statement:

B[0] = 9

will fail with the error "variable is undefined."

Array Subscript Syntax: [ ] vs. ( )

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[5] 

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[5] 

is unambiguous,

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.


Home | Categories | Alphabetical | Classes | All Contents | [ < ] | [ > ]