[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: subscript array question
In article <36C2B49A.204E@bigfoot.com>, David Ritscher wrote:
>> array = intarr(5)
>> subs = [0,2,4,4]
>> array[subs] = array[subs] + 1
>>
>> and have the resulting values for array be:
>>
>> 1 0 1 0 2
>>
>> Because of the way IDL manages memory for expression evaluation
>> and assignments, what happens for the last two elements of the
>> addition is that the original value of array[4] is used twice,
>> rather than what I want, which is to use the current value of
>> array[4] each time. I.e. IDL gives the resulting values for
>> array to be:
>>
>> 1 0 1 0 1
>>
>
>
>
>With my version, IDL Version 5.1.1, I get the latter, not the former!
Correct.
>I suspect it is true with your version, as well. What IDL does is,
>for the duplicate subscript, it does the operation twice, but since
>'array' on the right hand of the expression is a copy of the original,
>it goes and gets the same '0' twice, incremnts it by '1', and inserts
>it into the same location twice.
Yes, that's what I figured was happening, too. For that reason,
I'd be very surprised if the behavior were to change from one version
of IDL to another.
>
>If in your actual application you're having similar problems, the
>uniq function might help you out:
>
>array = intarr(5)
>subs = [0,2,4,4]
>
>subs = subs(uniq(subs, sort(subs)))
>
>print, subs
> 0 2 4
>
>
>array[subs] = array[subs] + 1
>
>In this case, it gives the same result, as I explained, but in your
>application, it might serve to solve your problem.
Yes, it gives the same result, which is not what I want.
In article <36C2EFD5.8D76D36@no.spam.edu>,
eddie haskell <haskell@no.spam.edu> wrote:
>> I'm using IDL 5.0 and need to be able to use a subscript
>> array containing duplicate values like this:
>>
>> array = intarr(5)
>> subs = [0,2,4,4]
>> array[subs] = array[subs] + 1
>>
>> and have the resulting values for array be:
>>
>> 1 0 1 0 2
>
>How about something like this:
>IDL> array = intarr(9)
>IDL> subs = [2,3,4,2,4,4,7,5]
>IDL> array[min(subs):max(subs)] = array[min(subs):max(subs)] +
>histogram(subs)
>IDL> print, array
> 0 0 2 1 3 1 0 1 0
>
>I checked it with arrays up to a size of findgen(100000) and it runs
>without
>any noticeable time delays. I have not, however, done any error
>checking,
>i.e., if subs contain elements outside of array, or any real checking of
>any
>sort for that matter. :-) HTH
>
That sure looks ingeniously devious to me. I had to try out all
the pieces to see how it worked. :-) However, I couldn't get my 2D
case to perform well. I'm omitting here some non-essentials, but the
routine originally had this in it:
llsubs = where(llthetaindex ne lmissing, llcnt)
if llcnt gt 0 then begin
llvol = latlonvol[j,k] ; get cell volume at this latitude
; Add cell volumes to appropriate table entries
thsubs = llthetaindex[llsubs]
ssubs = llsindex[llsubs]
ths[thsubs,ssubs] = ths[thsubs,ssubs] + llvol
endif
Written like that, it ran in ~15 seconds on my test data set, but gave
values in ths that were often too small, as I originally posted. I no
longer have the number handy, but a "print,total(ths)" showed a result
that was only about 28-30% of the correct total. So I replaced the
last assignment statement with:
for ll = 0, llcnt - 1 do $
ths[thsubs[ll],ssubs[ll]] = ths[thsubs[ll],ssubs[ll]] +$
llvol
(Sorry about the terribly wide lines!) This takes ~46 seconds to run,
but does give the correct results. A "print,total(ths)" gives the
correct total of 1.32526e+18.
After looking at your 1D example, I read the description in the
_IDL_Reference_Guide_ of hist_2d and tried replacing the for loop with:
thmaxsub = max(thsubs)
smaxsub = max(ssubs)
ths[0:thmaxsub,0:smaxsub] = ths[0:thmaxsub,0:smaxsub] + $
float(hist_2d(thsubs,ssubs)) * llvol
A "print,total(ths)" with this method also shows 1.32526e+18, which is
correct, but it took ~37 minutes 58 seconds to run! So I guess I'll
stick with the for loop for now. :-(
Many thanks to both of you for your replies. Once again IDL has
provided me a "learning experience."
Scott Bennett, Comm. ASMELG, CFIAG
Dept. of Atmospheric Sciences
Oregon State University
Corvallis, Oregon 97331
**********************************************************************
* Internet: sbennett@oce.orst.edu *
*--------------------------------------------------------------------*
* "The jury has a right to judge both the law as well as the fact in *
* controversy."--John Jay, First Chief Justice, U.S. Supreme Court *
* in Georgia vs. Brailsford, 1794 *
**********************************************************************