Subscript ranges are used to select a subarray from an array by giving the starting and ending subscripts of the subarray in each dimension. Subscript ranges can be combined with scalar and array subscripts and with other subscript ranges. Any rectangular portion of an array can be selected with subscript ranges.
Types of Subscript Ranges
There are six types of subscript ranges:
All elements of a dimension.
This form is used with multidimensional arrays to select all elements along the dimension. For example, if arr is a 10-column by 12-row array, arr[*, 11] is the last row of arr, composed of elements [arr[0,11], arr[1,11], ..., arr[9,11]], and is a 10-element row vector. Similarly, arr[0, *] is the first column of arr, [arr[0,0], arr[0,1],..., arr[0,11]], and its dimensions are 1 column by 12 rows.
Subscript range from s0 to s1.
This denotes all elements whose subscripts range from the expression s0 through s1(s0 must not be greater than s1). For example, if the variable vec is a 10-element vector, vec[4:8] is a five-element vector composed of vec through vec. Negative indices may be used, where -1 indicates the last element. For example, vec[-6:-2] returns the same five elements as vec[4:8].
A range from the given element to the last element of dimension.
This denotes all elements from a given element to the last element of the dimension. If the variable vec is a 50-element vector, vec[10:*] is a 40-element vector made from vec through vec.
Every n-th element in a range of subscripts from s0 to s1.
The expression n is referred to as the subscript stride. The stride value may be positive or negative (but must not be zero). If the stride is positive then s0 must be less than or equal to s1. If the stride is negative then s0 must be greater than or equal to s1. If the stride is 1, then the result is identical in meaning to [s0:s1], as described above. For example, if the variable vec is a 50-element vector, vec[5:13:2] is a five-element vector composed of vec, vec, vec, vec, and vec. In another example, vec[-1:0:-3] would return every third element of vec, in reverse order.
Every n-th element from element s0 to the end of the dimension.
The expression n is referred to as the subscript stride. If the variable vec is a 50-element vector, vec[10:*:4] is a 10-element vector made from every fourth element between vec through vec.
A simple subscript, either positive or negative.
Positive subscripts are indexed from the beginning of the array, while negative subscripts are indexed from the end (where -1 is the last element). When used with multidimensional arrays, simple subscripts specify only elements with subscripts equal to the given subscript in that dimension.
Multidimensional subarrays can be specified using any combination of the above forms. For example, if arr is a 10x10 array, arr[*,0:4] returns a 10 x 5 array that is made from all columns of rows 0 to 4 of arr.
Dimensionality of Subarrays
The dimensions of an extracted subarray are determined by the size in each dimension of the subscript range expression. In general, the number of dimensions is equal to the number of subscripts and subscript ranges. The size of the n-th dimension is equal to one if a simple subscript was used to specify that dimension in the subscript; otherwise, it is equal to the number of elements selected by the corresponding range expression.
Degenerate dimensions (trailing dimensions with a size of one) are removed. If arr is a 10-column by 12-row array, the expression arr[*,11] results in a row vector with a single dimension. (The result of the expression is a 10-column by 1-row array; the last dimension is degenerate and is removed.) On the other hand, the expression arr[0, *] became a column vector with dimensions of [1, 12], showing that the structure of columns is preserved because the dimension with a size of one does not appear at the end.
To see this, enter the following statements in IDL:
arr = INDGEN(10,12)
In the following examples, vec is a 50-element floating-point vector, and arr is a 10-column by 12-row integer array. Some typical subscript range expressions are as follows:
vec = BINDGEN(50)
arr = BINDGEN(10,12)
I = 25
print, vec[I - 1:I + 1]
print, [vec[I - 1], vec[I], vec[I + 1]]
print, arr[3, *]
print, arr[*, 0]
X = 3
Y = 4
print, arr[X - 1:X + 1, Y - 1:Y + 1]
To insert the contents of an array called A into array B, starting at point B[13, 24], use the following statement:
B[13, 24] = A
If A is a 5-column by 6-row array, elements B[13:17, 24:29] are replaced by the contents of array A.
In the next example, a subarray is moved from one position to another:
B[100, 200] = B[200:300, 300:400]
A subarray of B, specifically the columns 200 to 300 and rows 300 to 400, is moved to columns 100 to 200 and rows 200 to 300, respectively.
Assuming the variable B is a 512 x 512-byte array, some examples are as follows:
array[*, I] = 1
array[J, *] = 1
array[200:220, *] = 0
array[200:220, -5:-1] = 0
array[*] = 100
Avoid Using Range Subscripts for Assignment
It is possible to use range subscripts in an assignment statement; however, when possible, avoid using range subscripts in favor of using scalar or array subscripts. This type of assignment statement takes the following form:
Variable[Subscript_Range] = Expression
A subscript range specifies a beginning and ending subscripts, which are separated by the colon character. An ending subscript equal to the size of the dimension minus one can be written as *. For example, arr[I:J] denotes those points in the vector arr with subscripts between I and J inclusive. I must be less than or equal to J and greater than or equal to zero. See above for more details on subscript ranges.
When possible, avoid using range subscripts in favor of using scalar or array subscripts. In the following example, the array elements of X are inserted into array A. The slow way uses subscript ranges, specifying the insertion of X array elements into the 5th through 7th elements of A. The fast way uses a scalar subscript specifying the first element (the 5th) to be replaced with the elements of A.
A = INTARR(10)
X = [1,1,1]
PRINT, 'A = ', A
t = SYSTIME(1) & FOR i=0L,100000 DO A[4:6] = X &
PRINT,'Slow way: ', SYSTIME(1)-t
PRINT, 'A = ', A
t = SYSTIME(1) & FOR i=0L,100000 DO A = X &
PRINT, 'Fast way: ', SYSTIME(1)-t
PRINT, 'A = ', A
A = 0 0 0 0 0 0 0 0 0 0
Slow way: 0.47000003
A = 0 0 0 0 1 1 1 0 0 0
Fast way: 0.12100005
A = 0 0 0 0 1 1 1 0 0 0
The statement A = X, where X is a three-element array, causes IDL to start at index 4 of array A, and replace the next three elements in A with the elements in X. Because of the way it is implemented in IDL, A = X is much more efficient than A[4:6] = X.