comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: Regrid / Interpolation Question
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Return to the default flat view Create a new topic Submit Reply
Re: Regrid / Interpolation Question [message #79742 is a reply to message #79670] Mon, 26 March 2012 11:32 Go to previous message
Sean[1] is currently offline  Sean[1]
Messages: 11
Registered: July 2005
Junior Member
As a follow up on this, I wrote a program to do the re-grid/interpolation that does not involve loops (see example in previous post, or in program header).

I would really appreciate any feedback on this, especially if anyone thinks there is a faster way to do what I've done here. I have some huge arrays I'm working with, so making this is as fast as possible is important to me!

Thanks,
Sean


function regrid2D, vin, yin, yout

;Purpose:
;
; Re-grid a 2-D array (vin) to the output grid (yout) using the array yin.
; This program assumes that yin is the same size as vin, and that the values of yin are ordered along each row
;
; The interpolating
;
;Inputs:
; vin - 2D array (nx,ny) of values to re-grid
; yin - 2D array (nx,ny) of ordered values corresponding to elements of vin. Values must be ordered along the x-dimension
; yout - 1D array (nz) of output values used to re-grid vin
;
;Return value:
; vout - A 2D array (nz, ny) of values
;
;Example:
;
; Lets say I have 3 temperature vs. height profiles. Each profile has 6 points in the vertical, so the arrays are (6,3).
;
; IDL> temp = [ [270, 224.3, 200., 190., 210, 230.], [284,231, 206.5, 208,200.,190.],[300,280,230,220.,185.,200.]]
; IDL> height=[ [0.5,1,2.3,2.7,3.2,4], [0.,1.3,3.4,3.6,3.8,5.3], [1.,1.2,2.7,3.6,4.4,6]]
;
; I want to interpolate to interpolate the temperature to 2 new heights:
;
; IDL> heightout = [1.5, 4]
;
; So I call regrid2d
;
; IDL> newtemp = regrid2d( temp, height, heightout)
;


szv = SIZE(vin)
IF szv[0] NE 2 THEN BEGIN
print, 'Vin must be a 2D array!'
return, -1
ENDIF
nx = szv[1]
ny = szv[2]

nz = n_elements(yout)

miny=min(yin, max=maxy)
yinsc = (double(yin)-miny)/(maxy-miny) ;scale yin to the range 0-1, and make double

minxvy = min(yinsc,dim=1,max=maxxvy) ;Store the min/max of each row, to be used in preventing extrapolation (see below)

yinsc = yinsc + REBIN( REFORM(DINDGEN(ny),1,ny), nx, ny) ;Add the row number so that each row is higher than the previous. E.g., the first row goes from 0-1, the next row goes from 1-2, ...

youtsc = (double(yout)-miny)/(maxy-miny) ;Scale yout to the range 0-1, the same way as yin
youtsc = REBIN( reform(youtsc,nz,1), nz,ny) ;Recast the scaled output grid to be 2D (nz, ny)

;*********** We need to prevent extrapolation of the values of yout are outside the bounds of a given row of yin ***************
;*********** for each row of the youtsc array, set any values that are outside of the values in the corresponding row of yinsc to NAN ***************
bd=where( (youtsc LT rebin(transpose(minxvy),nz,ny)) OR (youtsc GT rebin(transpose(maxxvy),nz,ny)) , bdct)

youtsc = youtsc + REBIN( REFORM(DINDGEN(ny),1,ny), nz, ny) ;Add the row number so that each row is higher than the previous. E.g., the first row goes from 0-1, the next row goes from 1-2, ...

;Do the interpolation (this is a streamlined version of what interpol does)
s = VALUE_LOCATE(yinsc, youtsc) > 0L < (n_elements(vin)-2)
vout = (youtsc-yinsc[s])*(vin[s+1] - vin[s])/(yinsc[s+1] - yinsc[s]) + vin[s]

;Alternative way (slower, I think) of doing the interpolation
; vin = REFORM( vin, nx*ny, /overwrite) ;make vin and yinsc 1D arrays for feeding in to interpol (does interpol actually need them to be 1D?)
; yinsc = REFORM( yinsc, nx*ny, /overwrite)
; vout = interpol( vin, yinsc, youtsc )
; vin = reform( vin, nx, ny, /overwrite) ;Return vin to its original state

return, vout

end
[Message index]
 
Read Message
Read Message
Read Message
Read Message
Read Message
Previous Topic: New Coyote Graphics Program: cgPolygon
Next Topic: Time axis labelling (1 major label every 7 days with 6 minor ticks)

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Fri Oct 10 17:55:24 PDT 2025

Total time taken to generate the page: 1.52105 seconds