Language > Arrays > Understanding Array Subscripts

# Understanding Array Subscripts

You can use subscripts to 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.

Specify the elements of multidimensional arrays by using one subscript for each dimension. IDL’s convention is that for generic arrays and images, the first subscript denotes the column and the second subscript denotes the row. In standard mathematical representation (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 Manipulating Arrays.

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.

Arrays with multiple dimensions are addressed by specifying a subscript expression for each dimension. A two-dimensional array with n columns and m rows, is addressed with a subscript of the form [i, j], where 0 ≤ i < n and 0 ≤ j < m. The first subscript, i, is the column index; the second subscript, j, is the row index. For example, the following statements select and print the element in the first column of the second row of `array`:

array = [[1, 2, 3], [4, 5, 6]]

PRINT, array[0,1]

IDL prints:

4

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.

A0,0 A0,1

A0,1 A1,1

A0,2 A1,2

In the 2 by 3 element array, `A`, element `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 signed 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]`.

Note: Subscripts are converted to the signed integer type used for addressing memory for your system (for example, on a 32-bit architecture, subscripts are converted to signed 32-bit integers). Using subscripts that are outside of the range for that integer type may produce unexpected results.

## 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 extra 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.

Use the REFORM function to add degenerate trailing dimensions to an array if needed. 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)

## 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, and can produce either a syntax or runtime error.

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, 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.

Tip: To ensure that you only use square brackets, it is strongly recommended that you use `COMPILE_OPT strictarr` (or `COMPILE_OPT IDL2`) at the top of your routine. This will avoid any confusion in the IDL compiler between the use of parentheses for array indexing and the use of parentheses for function calls. See COMPILE_OPT for details.

Note: Note that using the COMPILE_OPT statement with the `idl2` option will enforce the use of square brackets within the scope of a routine. This is the recommended technique. Alternately, the FORWARD_FUNCTION statement can be used to declare a function before it is used in a routine.