reform and rebin are routines that typically go hand in hand. Separately both have their uses, but together they can do some fun tricks. We'll start with reform, which simply changes the dimensions of an array. However, it can't change the number of elements of an array. For it's most basic usage, reform can change a column array into a row array, and vice-versa. You pass reform an array and the dimensions you would like it to reform that array into:
data = indgen(5)
It is slightly more complicated for arrays with more than one row. Basically, it reads in the old array row by row and fills in the new array row by row.
print,data
; 0 1 2 3 4
new = reform(data,1,5)
print,new
; 0
; 1
; 2
; 3
; 4
print,reform(new,5)
; 0 1 2 3 4
data = indgen(5,2)
Rebin can be used to increase or decrease the size of an array. However, the dimensions of the new array must be an integer factor of the dimensions of the original array. If you decrease the size of an array, rebin will average together neighboring arrays appropriately. Like reform, you pass rebin an array and the new dimensions:
print,data
; 0 1 2 3 4
; 5 6 7 8 9
print,reform(data,2,5)
; 0 1
; 2 3
; 4 5
; 6 7
; 8 9
data = findgen(4,2)
This is a convenient way to take the mean value of a row or column, rather than looping over each row or column and calculating it directly with the
print,data
; 0.00000 1.00000 2.00000 3.00000
; 4.00000 5.00000 6.00000 7.00000
print,rebin(data,2,2)
; 0.500000 2.50000
; 4.50000 6.50000
print,rebin(data,4,1)
; 2.00000 3.00000 4.00000 5.00000
print,rebin(data,1,2)
; 1.50000
; 5.50000
mean function.
You can also use rebin to expand an array. It attempts to extrapolate, although the results are rather strange sometimes. Read about it in the online help for an exact description of how it expands an array. However, there is one circumstance where its behavior is very straight forward and useful. This is when you expand on a dimension that is only one element wide. In this case rebin will simply repeat the expanded dimension:
data = indgen(5)
You can combine this with reform to repeat arrays in a variety of ways. For instance:
print,data
; 0 1 2 3 4
print,rebin(data,5,3)
; 0 1 2 3 4
; 0 1 2 3 4
; 0 1 2 3 4
data2 = indgen(1,3)
print,data2
; 0
; 1
; 2
print,rebin(data2,4,3)
; 0 0 0 0
; 1 1 1 1
; 2 2 2 2
arr = [2,3]
How could this possibly be useful? One pratical example is calculating many points given the coefficients of a polynomial. Imagine you have 3 coefficients, a, b, and c that define a parabola: y = a*x^2 + b*x + c. For one x this is an easy problem in IDL:
new = rebin(arr,2,5)
print,new
; 2 3
; 2 3
; 2 3
; 2 3
; 2 3
print,reform(new,10)
; 2 3 2 3 2 3 2 3 2 3
new2 = rebin( reform(arr,1,2), 5, 2 )
print,new2
; 2 2 2 2 2
; 3 3 3 3 3
print,reform(new2,10)
; 2 2 2 2 2 3 3 3 3 3
ncoeff = 3
If you have many x, you could use a for loop and use the above line of code. Or, you can use reform and rebin to replicate all the necessary values, and reduce this to one very large array operation. If we have 100 x values, and 3 coefficients, then we will need arrays of size 100x3, with each x value specified by a column and each y value specified by a coefficient. Below is the solution. The 'y = total()' command is only one line, but gets wrapped to more than one in some browsers:
poly = [0, 0, 1]
x = 5.0
y = total( poly*x^findgen(ncoeff) )
print,y
; 25.00
ncoeff = 3
Certainly the above looks complicated, but is really just the same as the single-x case. I've simply used reform and rebin to make arrays of size 100x3. For instance
poly = randomu(seed,ncoeff)
nx = 100
x = findgen(nx)/2 - 25
y = total( rebin(reform(poly,1,ncoeff),nx,ncoeff) * rebin(x,nx,ncoeff) ^ rebin(findgen(1,ncoeff),nx,ncoeff), 2)
plot,x,y
rebin(reform(poly,1,ncoeff),nx,ncoeff) takes the array of coefficients and turns it into a column array, and then replicates that column array 100 times. rebin(x,nx,ncoeff) takes the 100 x values (which are a row array) and replicates them all three times making a 100x3 array. Finally, rebin(findgen(1,ncoeff),nx,ncoeff) creates the exponents - it makes a column array (0,1,2) and replicates it 100 times. Then just apply the equation for a polynomial, and sum along columns (which is what the second argument to total does). For a fourth order polynomial, using the above code (compared to a for loop) is about 5 times faster. In some cases doing many reforms/rebins like this can be slightly slower than a simple for loop, so if you are really concerned about speed you should compare your results from the above method with standard ways of calculating things.