Re: Where and lists of regions [message #41316] |
Tue, 12 October 2004 04:35 |
Ben Panter
Messages: 102 Registered: July 2003
|
Senior Member |
|
|
JD Smith wrote:
> On Mon, 11 Oct 2004 14:47:23 +0200, Ben Panter wrote:
>> I've written a code with EXECUTE, but I may want to use VM in the future
>> so I'd like to avoid it if possible.
>
> How about:
> ...
Thanks guys. I need to look at both these methods to try and understand
them, but they look far better than what I had before!
Ben
|
|
|
Re: Where and lists of regions [message #41317 is a reply to message #41316] |
Mon, 11 October 2004 21:39  |
JD Smith
Messages: 850 Registered: December 1999
|
Senior Member |
|
|
On Mon, 11 Oct 2004 14:47:23 +0200, Ben Panter wrote:
> Hi,
>
> I'm in the middle of trying to simplify a large body of code which I
> inherited a few years ago and have been mangling ever since. Among other
> things, I'd be interested in anyone's thoughts on simplfying the case
> statement I use (full code below). Basically I have a list of regions
> which I want to remove from a vector. At the moment I use CASE to call
> WHERE to remove the regions elements (case to choose how many where
> statements are required). This is fine for a few regions, but I'm sure
> there must be a neater way, as when I need 10 regions, or even 20, this
> code is going to look terrible...
>
> I've written a code with EXECUTE, but I may want to use VM in the future
> so I'd like to avoid it if possible.
How about:
flag=bytarr(n_elements(wave))
for i=0,n_regions-1 do $
flag+=wave gt reg[i,0] AND wave lt reg[i,1]
return, where(~flag)
There are other methods for removing more complicated lists of unwanted
items. From the HISTOGRAM tutorial:
Problem: Remove some elements, listed in random order, from a vector.
IDL> vec=randomu(sd,10)
IDL> remove=[3,7,2,8]
IDL> keep=where(histogram(remove,MIN=0,MAX=n_elements(vec)-1) eq 0,cnt)
IDL> if cnt ne 0 then vec=vec[keep]
IDL> print,keep
0 1 4 5 6 9
We've used HISTOGRAM and WHERE to simply generate a list of kept
indices.
JD
|
|
|
Re: Where and lists of regions [message #41319 is a reply to message #41317] |
Mon, 11 October 2004 07:47  |
Chris Lee
Messages: 101 Registered: August 2003
|
Senior Member |
|
|
In article <2svdmrF1pveu8U1@uni-berlin.de>, "Ben Panter" <me@privacy.net>
wrote:
> Hi,
>
> I'm in the middle of trying to simplify a large body of code which I
> inherited a few years ago and have been mangling ever since. Among other
> things, I'd be interested in anyone's thoughts on simplfying the case
> statement I use (full code below). Basically I have a list of regions
> which I want to remove from a vector. At the moment I use CASE to call
> WHERE to remove the regions elements (case to choose how many where
> statements are required). This is fine for a few regions, but I'm sure
> there must be a neater way, as when I need 10 regions, or even 20, this
> code is going to look terrible...
> I've written a code with EXECUTE, but I may want to use VM in the future
> so I'd like to avoid it if possible.
> Many Thanks,
>
> Ben
Hi,
I'm not sure this counts as 'neater' (and there are probably better
ways), but the following code does what you want, without EXECUTE. It
should be a drop in replacement for the CASE block of code. It works at
least for the trivial case of wave=findgen(1000)*10.
Chris.
for i=0,n_region-1 do em[i,*]=strsplit(em_list[i], '-', /extract)
;setup
em=reform(transpose(em), n_elements(em))
offset=1
endoffset=1
if(em[0] gt wave[0]) then begin
em=[wave[0],em]
offset=0
endif
if(em[n_elements(em)-1] le wave[n_elements(wave)-1]) then begin
em=[em,wave[n_elements(wave)-1]]
endoffset=0
endif
w=value_locate(wave,em)
;bounds forcing
w=w>0 < n_elements(wave)-1
;special case of 'delete all'
if(offset and endoffset and n_elements(em) eq 4) then return ,-1
n=n_elements(w)-2+offset-endoffset ;take care of the special end cases
for i=offset, n,2 do begin
if(n_elements(output) eq 0) then $ ;does output exist?no
if(w[i] ge w[i+1]) then $ ;are the indices coincident? yes
output=w[i+1] $
else $ ;no
output=lindgen(w[i+1]-w[i]+1)+w[i]+1 $
else $ ;does output exit? yes
if(w[i]+1 ge w[i+1]) then $ ;are the indices coincident? yes
output=[output,w[i+1]] $
else $ ;no
output=[output,lindgen(w[i+1]-w[i]+1)+w[i]+1]
endfor
if(offset eq 1) then output=[0,output];this, I think, is wrong, but it matches the original
|
|
|