On Apr 8, 9:04 am, smas...@[EMAIL PROTECTED]
wrote:
> Hi,
>
> I want to find the first non-zero value of an array. Is there a faster
> way to do this than with the "where" command: (where(array ne 0))[0]
> "Where" will look for all non-zero values and I only need the first
> one. It would be great if I could stop "where" in its search process
> as soon as it found one element...
>
> sebastien
Hi Sebastien,
I can think of two separate ways of going about it:
Firstly, for certain arrays it may be perfectly sensible to use the
'inefficient', FORTRAN 101 route:
i = 0
WHILE Array[i] EQ 0 DO i++
RETURN, i
Secondly, I've attempted to do it using HISTOGRAM below.
-----
; Is the first element non-zero?
; If it is, we can save ourselves a lot of
; hassle...
IF Array[0] NE 0 THEN RETURN, 0L
; We now know element 0 contains data = 0.
; Generate a histogram of the array such
; that this element will always be put in the
; first bin:
H = HISTOGRAM(CEIL(ABS(Array)), REVERSE_INDICES = RI)
; Are there non-zero elements in the array?
IF N_ELEMENTS(H) EQ 1 THEN MESSAGE, $
'Array contains only zeroes!'
; Array[0] is always going to be in the first bin.
; Get the contents of that bin:
BinContents = RI[RI[0]:RI[1]-1]
; How many drops in that bin?
NBC = N_ELEMENTS(BinContents)
; Where do the drop indices stop increasing linearly?
; That's where the first non-zero element must be.
Index = WHERE((LINDGEN(NBC) - BinContents) NE 0, Count)
; If all the zeroes in the array come before the first
; non-zero value, then we won't get any indices returned,
; but the next index will be the next element after the
; end of our BinContents vector. This must be non-zero.
IF Count EQ 0 THEN RETURN, NBC
; Otherwise, use the WHERE results to return
; the index of first non-zero element of the array.
RETURN, Index[0]
-----
As far as I can tell, both methods work; and which is going to be
faster (between these two and just using WHERE) is going to depend on
your array.
Let us know how you get on,
Regards,
Chris


|