Viewing contents of file '../idllib/contrib/meron/arrloc.pro'
Function Arrloc, inds, siz, expand = exd, contract = cnt
;+
; NAME:
; ARRLOC
; VERSION:
; 3.0
; PURPOSE:
; Converts array indices from expanded (multi dimensional) form to
; contracted (one dimensional) form and vice versa.
; CATEGORY:
; Array Function.
; CALLING SEQUENCE:
; Result = ARRLOC( INDS, SIZ [, keywords])
; INPUTS:
; INDS
; Numeric, converted to long integer on input. Structure depends on
; usage mode (EXPAND versus CONTRACT) and on the input parameter SIZ, as
; follows:
; EXPAND mode : INDS can be a scalar or a vector (1-dim array).
; CONTRACT mode: If SIZ(0) = 0 then INDS arbitrary. Else INDS can
; be a scalar, vector or a 2-dim array, subject to the following
; restrictions:
; INDS is scalar: SIZ(0) must be 1.
; INDS is vector: SIZ(0) must equal the length of INDS.
; INDS is M*N array: SIZ(0) must equal M (first array dimension).
; SIZ
; Vector in the form of the standard output of the system function SIZE.
; OPTIONAL INPUT PARAMETERS:
; None.
; KEYWORD PARAMETERS:
; /EXPAND
; Switch, specifies expansion mode. This is the default.
; /CONTRACT
; Switch, specifies contraction mode.
; OUTPUTS:
; Depending on mode, as follows:
; EXPAND mode: Returns an M*N array, where M is the number of dimensions
; of the object charactarized by SIZ (i.e. SIZ(0)) and N is the
; number of elements in INDS. For example, if S = [2,3,8,4,24]
; (corresponding to a 3*8 real array) then ARRLOC(5,S) will return
; the vector [2,1] (the indices of the 5th element) while
; ARRLOC([2,5,22]) will return: 2 0
; 2 1
; 1 7
; CONTRACT mode: Reverses the action of expand. When fed an array in
; the form of the output of ARRLOC with EXPAND, returns a vector of
; 1-dimensional indices. For example a call to ARRLOC using S and
; the output array from the example above will return: 2
; 5
; 22
; In either mode, if any of the resulting indices is out of bounds for the
; array specified by SIZ, it is replaced by -1.
; OPTIONAL OUTPUT PARAMETERS:
; None.
; COMMON BLOCKS:
; None.
; SIDE EFFECTS:
; None.
; RESTRICTIONS:
; None other than those specified in the description of INDS, above.
; PROCEDURE:
; Straightforward. Calls ONE_OF from MIDL.
; MODIFICATION HISTORY:
; Created 30-MARCH-1994 by Mati Meron.
;-
on_error, 1
act = One_of(exd,cnt) > 0
item = long(inds)
ndim = siz(0)
if ndim gt 0 then begin
if act then begin
csiz = size(item)
case csiz(0) of
0: begin
if ndim eq 1 then begin
item = reform(replicate(item,1),1,1)
csiz = size(item)
endif else message, 'Size incompatibility!'
end
1: begin
if ndim eq csiz(1) then begin
item = reform(item,csiz(1),1)
csiz = size(item)
endif else message, 'Size incompatibility!'
end
2: if ndim ne csiz(1) then $
message, 'Size incompatibility!'
else: message, 'Size incompatibility!'
endcase
res = item(ndim-1,*)
for i = ndim - 2, 0, -1 do res = res*siz(i+1) + item(i,*)
for j = 0l, csiz(2) - 1 do begin
tem = item(*,j) lt 0 or item(*,j) ge siz(1:ndim)
dum = where(tem ne 0, nov)
if nov ne 0 then res(j) = -1l
endfor
endif else begin
nel = n_elements(item)
ovfl = where(item lt 0 or item ge siz(ndim+2), nov)
res = reform(lonarr(ndim*nel),ndim,nel)
i = 0
while i lt (ndim - 1) do begin
res(i,*) = item mod siz(i+1)
item = (item - res(i,*))/siz(i+1)
i = i + 1
endwhile
res(i,*) = item
if nov ne 0 then res(*,ovfl) = -1l
endelse
endif else begin
res = lonarr(n_elements(item))
jtem = where(item ne 0, ntem)
if ntem gt 0 then res(jtem) = -1l
endelse
return, res
end