It is assumed that the JHU/APL/S1R library is on your IDL path.
First make some 1-d data to interpolate:
x = maken(10,20,10) ; 10 x values from 10 to 20.
y = randomu(k,10) ; 10 random y values.
plot,x,y,psym=-2 ; Take a look at the data.
Next make an array of desired interpolation locations:
xx = maken(10,20,40) ; Make 40 points.
yy = interpol(y,x,xx) ; Interpolate using interpol.
oplot,xx,yy,psym=4 ; Look at result.
Note that, as shown in this case, interpolated values can miss extreme values. If interpolation is done to make a non-uniformly spaced data set uniform then enough new points will be needed to minimize this effect.
interpol is a user's library routine. The calling syntax is:
new_y_array = interpol(old_y_array, old_x_array, new_x_array)
interpolate needs as input the array indices at which to interpolate. These indices will in general be fractional. Often the indices are not directly known, what is known is the x coordinates of the desired interpolated points. These may be converted to actual indices and used in interpolateas follows.
yi = interpol(indgen(n_elements(y)),x,xx) ; Use interpol to find indices. yy = interpolate(y,yi) ; Do interpolation.
Note that the advantage occurs for repeated interpolation at the same indices.
Let old_x, old_y be a function to be interpolated. Perhaps old_x is non-uniform and you need to make it uniform. new_x is the desired x coordinates (perhaps uniform). x_index = interpol( indgen(n_elements(old_x)), old_x, new_x) new_y = interpolate( old_y, x_index) For interpolate on 2-D arrays use the keyword /GRID when possible. This applies if all the lines have the same interpolation and all the columns have the same interpolation. Need both x_index and y_index for 2-D arrays. new_img = interpolate(old_img, x_index, y_index, /grid) |
Benchmark comparing the routines interpol and interpolate: On our HP 7/35 to interpolate 100,000 points: interpol took 8.8 seconds. interpolate took 0.064 seconds, over 130 times faster.
x = makenlog(10,500,600)
y = sin(x/10)
Plotting just y gives:
Plotting x and y gives the correct view:
The data can be interpolated to a uniform spacing as follows:
xx = maken(10,500,1000) ; Desired new X positions.
yi = interpol(indgen(n_elements(y)),x,xx) ; Find their indices.
yy = interpolate(y,yi) ; Interpolate corresponding Ys.
Plotting just the new y, yy, now gives:
This has importance in correcting images for non-uniformly spaced rows or columns.
The rows are evenly sampled, the columns are not. The non-uniformly spaced image columns may be remapped as follows. Assume the actual data coordinates of each are given by:
x = maken(10,20,200)
y = makenlog(10,500,200)
Let nx and ny be the X and Y size of the interpolated image.
In this example nx=200 and ny=200, this keeps the image size the same.
Uniformly spaced coordinates may be found as:
ny = 200
yu = maken(10,500,ny)
The array indices in the Y dimension which correspond to these uniformly spaced y coordinates are given by:
yi = interpol(indgen(n_elements(y)),y,yu)
The X dimension is already uniformly sampled so it's indices are
given by:
nx = 200
xi = indgen(nx)
Here again the number could be changed (like xi = maken(0,199,400)).
Now 2 index arrays are set up, one for X and one for Y:
xx = rebin(xi,nx,ny)
yy = rebin(transpose(yi),nx,ny)
Interpolation is very simple:
out = interpolate(img,xx,yy)
The result is:
The same indices, xx and yy, could be used to interpolate many images.
Generate some random data:
x = randomu(k,100)-.5 y = randomu(k,100)-.5 z = sin(x*5)+cos(y*5)Pack it up for SFITS:
d = [transpose(x),transpose(y),transpose(z)]Do fit. The /irregular keywords means the data is given as random points.
deg = 5 r = sfit(d,deg,/irregular,kx=kx)Don't care about the returned result which is just the fit at the given points. Really want to polynomial coeffecients returned in kx.
Now generate and plot a surface based on the returned coeffecients:
makenxy,-.5,.5,100,-.5,.5,100,xx,yy ; 2-d X and Y arrays. t = fltarr(100,100) ; Surface array. for i=0,deg do for j=0,deg do t=t+kx(j,i)*xx^i*yy^j ; Compute surface. surface,t,maken(-.5,.5,100),maken(-.5,.5,100),/save ; Plot surface. plots,/t3d,x,y,z,psym=2,col=255 ; Original points. tvscl,t ; Display fitted array.
The fit breaks down when the degree gets very high even if there are enough input points. Look at the results before assuming the fit is good. For 300 points the above fit was pretty good up to maybe degree 12.