|
Getting Started with IDL: Manipulating Data |
|
Programs with array expressions run faster than programs with scalars, loops, and IF statements. The following sections provide alternatives to using IF statements.
The first example adds all positive elements of array B to array A.
FOR I=0,(N-1)DO IF B[I]GT 0 THEN A[I]=A[I] + B[I]
A=A + (B GT 0) * B
A=A + (B > 0)
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.
In the example below, 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].
FOR I=0,(N-1) DO IF A[I] LE 0 THEN C[I]=-SQRT(-A[I]) ELSE C[I]=SQRT(A[I])
C = ((A GT 0) * 2 - 1 ) * SQRT(ABS(A))
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.
NEGS=WHERE(A LT 0)
C = SQRT(ABS(A))
C[negs] = -C[negs]
Whenever possible, vector and array data should always be processed with IDL array operations instead of scalar operations in a loop. For example, consider the problem of flipping a 512 ´ 512 image. This problem arises because approximately half the available image display devices consider the origin to be the lower-left corner of the screen, while the other half recognize it as the upper-left corner.
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
TEMP=IMAGE[I, J]
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
temp = image[*, J]
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:
image2 = BYTARR(512, 512)
FOR J = 0, 511 DO image2[*, J] = image[*, 511-J]
image2 = image[*, 511 - INDGEN(512)]
that reverses the array using subscript ranges and array-valued subscripts.
IDL Online Help (March 06, 2007)