- More Maths
- Natural logarithm: ALOG(X)
- Base 10 log: ALOG10(X)
- Trigonometric functions: SIN(X), COS(X), TAN(X)
- Inverse Trig functions: ASIN(X), ACOS(X), ATAN(X)
- All Trig functions are based on Radians
- Scientific Notation: 6e+7 = 60,000,000. 3e-4 = 0.0003
- Absolute Value: ABS(X)
- Definition of an Array
An array is a matrix variable. It can be used to store whole rows, columns,
tables, or even cubes of data. Arrays are made up of many individual
elements, which are the same as variables. For instance, if A is an array of
length 10, it would look like:
______________________________
|0||1||2||3||4||5||6||7||8||9|
------------------------------
Where 0 - 9 are the indicies of the individual array elements.
The first element in an array always has the index of 0. Array
elements are accessed with [] square brackets. Each element can be treated
just as any variable would. For instance, A[1] = 5*3. Arrays can be very
useful for instance when you want to store the prices of 50 different items
or when you want to store the flux of an object at thousands of different
wavelengths.
- Arrays in IDL
- Unlike most languages, in IDL many operations
can be performed directly on the entire array instead of having to loop
through individual array elements. For instance, A = A * 2 will double
the value of every element in the array A without you having to use the
traditional FOR J=0, N do A[J] = A[J] * 2.
- Multidimensional arrays:
Arrays do not have to be 1-dimensional. They can hold whole tables or cubes
of data. If an array has multiple dimensions, its elements are accessed
by specifying the row and column (and depth if 3D) within the square brackets:
print,A[3,4]
threeDarray[3,1,6] = twoDarray[4,0] * 5 + X
- Creating Arrays in IDL:
Arrays can be created for every data type in IDL (integer, float, etc.). There
are two ways to make an array for each data type. One of them will create
an empty array i.e. every element will have its value set to 0 or null. The
other will create a prenumbered array in which every element will have its
value set to its index i.e. A[0]=0, A[1]=1, ..., A[20]=20.
| Data Type | Create Empty Array | Create Numbered Array |
| Integer | X=INTARR(10) | X=INDGEN(10) |
| Long | X=LONARR(10) | X=LINDGEN(10) |
| Float | X=FLTARR(10) | X=FINDGEN(10) |
| Double | X=DBLARR(10) | X=DINDGEN(10) |
| String | X=STRARR(10) | X=SINDGEN(10) |
Again, since the first element in an array has an index 0, if you create
a 10-element array, its highest element is 9, so you can access X[0], X[1],
..., and X[9].
- Multidimensional Arrays can be created by putting (cols,rows) instead
of just the number of elements. X=INTARR(10,5) would then create an array
that would hold a table of 10 columns and 5 rows, or 50 total elements. The
individual elements can be accessed by X[0,0],X[1,0],...,X[9,4] or they can
be accessed by the 1-dimensional index X[0], X[1],...,X[49]. X[col,row] is
usually the preferred way to access elements, but if you create a numbered
array X=FINDGEN(10,5) it will use the 1-dimensional index to do the numbering
(i.e. X[0,0]=0, X[1,0]=1,...,X[0,1]=10,...,X[9,4]=49.
A third way of creating arrays is to enter the data manually. For example:
A = [5, 3, 7, 9, 0, 1]
B = [[3,2],[4,7],[6,3]]
Creates an array A of length 6 and a 2-dimensional array B with 2 columns
and 3 rows.
- Arrays and Maths
IDL is unique in that it is array based. That means that any arithmatic
operation can be used on an entire array and not just individual elements.
A = FINDGEN(10) A=[0,1,2,3,4,5,6,7,8,9]
B = FINDGEN(10)*10+100 B=[100,110,120,130,140,150,160,170,180,190]
A = A+2 every element in A is incremented by 2 so A=[2,3,...,11]
B = B/20. every element in B is divided by 20. so B=[5,5.5,6,...,9.5]
A = A*B every element in A is multiplied by the corresponding element in B so A=[0,110,240,...,1710]
print,A > B takes the greater value of each element i.e.A[0] > B[0], A[1] > B[1],...
Matrix Multiplication:
a=[[1,2],[3,4]]
b=[[10,5],[3,1]]
print,a#b
25 40
6 10
print,b#a
16 7
42 19
print,a##b
16 7
42 19
- Array subscripts
- Extra dimensions:
IDL allows you to specify "extra" dimensions for an array as long as the
extra dimensions are all zero. For example, if A = fltarr(10), then
A[5] and A[5,0] would both access the sixth element of A. If B is a scalar
(or ordinary variable), B=2 and you type print,B[0], IDL will treat it just
as if you typed print,B and return the value 2.
- Subscript Ranges:
- A range of subscripts can be specified by [i:j]. For instance,
A[5:9] would return an array of the 6th through 10th elements of A.
B[3:6,2] would return colums 4 through 7 for row 3 of B and B[2:4, 0:3] would
return columns 3 through 5 for the first 4 rows of B.
- All elements are represented by *. B[2:4,*] would return columns 3 through
5 for all rows of B. A[*,2] would return all columns for row 3 of A.
- All elements from a given element to the last are represented by [i:*].
For instance if A = fltarr(20), then A[5:*] would return an array consisting
of A[5] through A[19]. B[0,3:*] would return the first column for rows 4
and up of B.
- Arrays as subscripts:
Arrays can also be used to subscript other arrays. For example:
A = [6,5,1,8,4,3]
B = [0,2,4,1]
C = A[B]
print, C
Results in 6 1 4 5. The first element of C is 6 because A[B[0]] = A[0]
= 6. The second element is 1 because A[B[1]] = A[2] = 1 and so on. The
command A[[1,3],7:9] = 3 sets the following 6 elements of A to the value 3:
A[1,7], A[3,7], A[1,8], A[3,8], A[1,9], and A[3,9].
- Array operations
- MAX: Return the maximum value in an array. If A=[2,4,7,1,3,-1,5] then
print,MAX(A) will return 7. MAX(A[3:*]) though, would return 5.
- MIN: Similar to MAX, returns the minimum value in an array. MIN(A) would
return -1. One option that can be set in either MAX or MIN is /NAN. In IDL,
if a number is invalid (for instance the log of a negative number), it is
represented by NaN or Not a Number. If I took B = alog10(A) then B[5] would
be NaN since it is the log of -1. If I then took MIN(B), it would return NaN.
If, however I specify MIN(B,/NAN) then all NaNs are treated as missing data
and it would return 0 (log of 1).
- N_ELEMENTS: Returns the number of elements in an array. n_elements(A) = 7.
If B = findgen(3,6) then n_elements(b) = 18.
- SIZE: Returns an array. If S = SIZE(A) then S = [1,7,4,7]. The first
element of size is n, the number of dimensions of the array. The next n
elements are the lengths of each dimension. The next to last element is the
type of array it is (find SIZE in ? to see the codes for different datatypes.
4 means float), and the last element is the number of elements in the array
(same as you get with N_ELEMENTS). So if B = findgen(3,6) then SIZE(B) =
[2,3,6,4,18].
- SORT: Returns an array of subscripts that allow access to the elements
of the array in ascending order. SORT(A) returns [5,3,0,4,1,6,2] because
the element with index 5 is -1, the lowest value, then index 3 has value 1, ...
A common use would be A[SORT(A)], which results in [-1,1,2,3,4,5,7].
- REVERSE: Returns the current array reversed. REVERSE(A) returns
[5,-1,3,1,7,4,2] and REVERSE(A[SORT(A)]) returns [7,5,4,3,2,1,-1].
- TOTAL: Returns the sum of all elements of the array. TOTAL(A)
returns 21.0000
- AVG: Returns the average of the elements in the array. AVG(A) returns
3.0000, and AVG(A[2:5]) returns 2.5000
- TRANSPOSE: Returns a transpose of the array. B=TRANSPOSE(A)
- ROTATE: Rotates the current array. B=ROTATE(A,n) where n is from 0 to 7
and defines how many degrees to rotate and whether the array should be
transposed as well (see ROTATE in ? for which values of n do what).
- SHIFT: Shifts the elements of an array by a specified number, and wraps
around the end. SHIFT(A,3) = [3,-1,5,2,4,7,1]. SHIFT(A,-1) =
[4,7,1,3,-1,5,2].
- Bubble Sort
Many times, you'll want to write your own sort routine, based on your own
criteria. One of the simplest sorting routines is the bubble sort. The
bubble sort has a good efficiency, with time complexity of the order n^2.
Quick sorts, heaps, and winner trees can sort with better time complexity,
of order n*log(n), but are much more complicated to design. In its simplest
version, say you have an array A of numbers (or Strings) that you want to sort
from lowest to highest (or alphabetically):
FOR j=0,n_elements(A)-2 do begin
FOR l=j+1,n_elements(A)-1 do begin
IF A[l] lt A[j] then begin
temp=A[j]
A[j]=A[l]
A[l]=temp
ENDIF
ENDFOR
ENDFOR
The first loop goes from the first element to the n-1 element. The
second loop goes from the current position of the first loop and checks the
rest of the array. If it finds any values less than that at the current
position of the first loop, it swaps the two positions. Example:
A = [3, 6, 0, 4]
j=0, l=2: A[l]=0  < A[j]=3 so they are swapped
A = [0, 6, 3, 4]
j=1, l=2: A[l]=3  < A[j]=6 so they are swapped
A = [0, 3, 6, 4]
j=2, l=3: A[l]=4  < A[j]=6 so they are swapped
A = [0, 3, 4, 6]
This would work the same way with strings for instance if you had
A = ["Moss","Walsh","Drejer","Roberson"] since Drejer  < Moss   <
Roberson   < Walsh
Say you want to sort these 4 basketball players by their scoring averages
and the basketball players are in an array names, while their averages are in
an array points:
FOR j=0,n_elements(points)-2 do begin
FOR l=j+1,n_elements(points)-1 do begin
IF points[l] gt points[j] then begin
temp=points[j]
points[j]=points[l]
points[l]=temp
temp=names[j]
names[j]=names[l]
names[l]=temp
ENDIF
ENDFOR
ENDFOR
The names are now sorted by how many points per game they score, highest
listed first (Roberson, Walsh, Moss, Drejer if anyone wants to know).
- WHERE function
The WHERE function is one of the most powerful features of IDL. It allows
you to sort, find, and manipulate data within arrays in numerous ways. The
structure is B = WHERE(condition involving A) where A and B are arrays.
- Finding where datapoints are 0 or nonzero
To find out the indices where array elements equal zero:
B = WHERE(A EQ 0)
B is now an array containing the index number of all elements i of A where
A[i] = 0. Similarly, to find where an array contains nonzero elements, type
B = WHERE(A NE 0).
- Finding maxima and minima
As mentioned earlier, maxima and minima of an array A are given by MAX(A) and
MIN(A). Therefore finding the index that corresponds to the maxima or minima
of an array is given by:
B = WHERE(A EQ MAX(A))
B = WHERE(A EQ MIN(A))
- Finding data in specific ranges
If you're looking for the indices of elements whose value is in a specific
range, you could use the following:
B = WHERE(A GT 5 AND A LE 10)
- Finding the values of the data
The above line of code give you the index numbers of elements in A that are
between 5 and 10. If you want the actual values of those elements:
B = A[WHERE(A GT 5 AND A LE 10)]
- When WHERE returns -1
If the condition is never true in the array (for instance if no element of A
above is between 5 and 10), then WHERE returns the scalar -1 instead of the
normal array. Thus it is usually useful to check whether any elements in
the array met the specified condition:
B = WHERE(A GT 5 AND A LE 10)
If B[0] NE -1 THEN BEGIN
B=A[B]
print,"These values are between 5 and 10",B
ENDIF
If B=-1, B[0] will also return -1 because IDL will ignore the [0]. If B is
an array of indices, then B[0], the first index, will not be -1. When you
are looking for a max or min, or any other time you're only looking for one
particular index number, it may be useful to set B=B[0]:
B = WHERE(A EQ MAX(A))
B = B[0]
Now B is a scalar, so you can just use B instead of B[0] throughout the
rest of the program.
- Finding values in a corresponding array:
Going back to the example of the names of Gator b-ball players in an array
called names and their scoring averages in an array called points, what if
you wanted to print out the names of all players that are averaging over 10
points per game:
X = WHERE(points ge 10)
IF X[0] NE -1 THEN print,names[X]
- Using selected index ranges:
If you only want to look at a selected range within an array, you can subscript
the array within the conditional of the WHERE command:
B = WHERE(A[15:20] gt 5)
It is important to remember B will contain the indices of A[15:20], a 6
element array, that are greater than 5. It will NOT contain the indices
of A that are greater than 5. If A[15:20]=[3,6,5,0,9,7] then
B=WHERE(A[15:20] gt 5) will result in B=[1,4,5]. If you want the indices
of A you then need to add 15 since A[15] is the 0th element of A[15:20].
So B=WHERE(A[15:20] gt 5)+15 will result in B=[16,19,20], which are the three
elements of A that are within the selected range and greater than 5.
- Additional example:
I was just asked a question that ends up using the WHERE function, so I'll
provide this as an additional example of how versatile the function is. Say
you have an array and you want to find out the index of the datapoint closest
to 1.2:
B = WHERE(ABS(X-1.2) EQ MIN(ABS(X-1.2)))