Use Vector and Array Operations
Programs with vector and array expressions run faster than programs with scalars, loops, and IF statements. Whenever possible, vector and array data should be processed with IDL array operations rather than scalar operations in a loop.
Example—Inverting an Image
Consider the problem of inverting a 512 × 512 image. This problem arises because some image display devices consider the origin to be the lower-left corner of the screen, while others recognize it as the upper-left corner.
Note
The following example is for demonstration only. The IDL system variable !ORDER should be used to control the origin of image devices. The ORDER keyword to the TV procedure serves the same purpose.
A programmer without experience in using IDL might be tempted to write the following nested loop structure to solve this problem:
FOR I = 0, 511 DO FOR J = 0, 255 DO BEGIN ;Temporarily save pixel image. temp = image[I, J] ;Exchange pixel in same column from corresponding row at bottom image[I, J] = image[I, 511 - J] image[I, 511-J] = temp ENDFOR
A more efficient approach to this problem capitalizes on IDL's ability to process arrays as a single entity:
FOR J = 0, 255 DO BEGIN ;Temporarily save current row. temp = image[*, J] ;Exchange row with corresponding row at bottom. image[*, J] = image[*, 511-J] image[*, 511-J] = temp ENDFOR
At the cost of using twice as much memory, processing can be simplified even further by using the following statements:
;Get a second array to hold inverted copy. image2 = BYTARR(512, 512, /NOZERO) ;Copy the rows from the bottom up. FOR J = 0, 511 DO image2[*, J] = image[*, 511-J]
Even more efficient is the single line:
that reverses the array using subscript ranges and array-valued subscripts.
Finally, using the built-in ROTATE function is quickest of all:
Inverting the image is equivalent to transposing it and rotating it 270 degrees clockwise.
See Arrays for complete details on working with arrays in IDL.
Example—Summing Elements
Consider the problem of adding all positive elements of array B to array A.
Using a loop will be slow:
Masking out negative elements using array operations will be faster:
Adding only the positive elements of B is faster still:
When an IF statement appears in the middle of a loop with each element of an array in the conditional, the loop can often be eliminated by using logical array expressions.
Example—Using Array Operators and WHERE
In this example, each element of C is set to the square-root of A if A[I] is positive; otherwise, C[I] is set to minus the square-root of the absolute value of A[I].
Using a loop statement is slow:
Using an array expression is much faster:
The expression (A GT 0) has the value 1 if A[I] is positive and has the value 0 if A[I]is not. (A GT 0)* 2 - 1 is equal to +1 if A[I] is positive or -1 if A[I] is negative, accomplishing the desired result without resorting to loops or IF statements.
Another method is to use the WHERE function to determine the subscripts of the negative elements of A and negate the corresponding elements of the result.
;Get subscripts of negative elements. negs = WHERE(A LT 0) ;Take root of absolute value. C = SQRT(ABS(A)) ;Negate elements in C corresponding to negative elements in A. C[negs] = -C[negs]