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

Home » Public Forums » archive » Re: How to speed up code which checks lots of values of an array
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Re: How to speed up code which checks lots of values of an array [message #74332] Thu, 13 January 2011 16:59 Go to next message
ben.bighair is currently offline  ben.bighair
Messages: 221
Registered: April 2007
Senior Member
On 1/13/11 11:06 AM, Robin Wilson wrote:
> Hi all,
>
> I've been writing some code which checks that all of the values in one
> half of an array are less than a threshold, and all of the values on the
> right half of an array are greater than a threshold. I've written the
> code below, which seems to be a fairly clean way of writing it, and
> works for any length of array (which is important for my use of it).
>
> However, it's not very fast. I wondered if it might be able to be sped
> up using some sort of magic like the Histogram command... Any ideas?
>
> ---CODE---
> ; Assume we're given a 1D array called line with our values in it
>
> len = N_ELEMENTS(line)
>
> section_len = (len - 1) / 2
>
> ; Get the left-hand half of the array
> LHS = line[0:section_len - 1]
> RHS = line[section_len + 1: len - 1]
>
> res = WHERE(LHS GT 180, LHS_count)
> res = WHERE(RHS LT 180, RHS_count)
>
> IF LHS_count EQ 0 AND RHS_count EQ 0 THEN BEGIN
> ; Do stuff
> ENDIF
>
> ---END CODE---
>

Hi,

I vaguely recall a discussion much like this from years ago - one of the
wizards (Craig? JD?) suggested that using TOTAL would reduce the number
of comparison scans required. For example, you have the comparison scan
of the line inside the WHERE (or MAX) (LHS GE threshold) and then the
scan by WHERE (or MAX) itself. Using TOTAL still requires two
traversals of the line: one by (LHS GE threshold) and one by TOTAL, but
TOTAL doesn't have the overhead of doing a comparison as it scans.

It seems to pan out pretty well in the test code below.

Cheers,
Ben

IDL> .comp line_test
% Compiled module: MAX_TEST.
% Compiled module: TOTAL_TEST.
% Compiled module: WHERE_TEST.
% Compiled module: LINE_TEST.
IDL> line_test
MAX_TEST
result = 1 1
elapsed = 1.0753469

TOTAL_TEST
result = 2489 2472
elapsed = 0.82091904

WHERE_TEST
result = 2489 2472
elapsed = 1.3972421


;----- START HERE

FUNCTION max_test, line, threshold

len = N_ELEMENTS(line)

section_len = (len - 1) / 2

LHS = line[0:section_len - 1]
RHS = line[section_len + 1: len - 1]

x = [MAX(LHS GE threshold), MAX(RHS LT threshold)]

return, x

END;


FUNCTION total_test, line, threshold


len = N_ELEMENTS(line)

section_len = (len - 1) / 2

LHS = line[0:section_len - 1]
RHS = line[section_len + 1: len - 1]

x = [TOTAL(LHS GE threshold, /INT), TOTAL(RHS LT threshold, /INT) ]

Return, x

END


FUNCTION where_test, line, threshold

len = N_ELEMENTS(line)

section_len = (len - 1) / 2

; Get the left-hand half of the array
LHS = line[0:section_len - 1]
RHS = line[section_len + 1: len - 1]

res = WHERE(LHS GE threshold, LHS_count)
res = WHERE(RHS LT threshold, RHS_count)

x = [LHS_count, RHS_count]

return, x

END


PRO line_test

N = 10000
thresh = 180
x = RANDOMU(s, N) * (thresh * 2)

t0 = Systime(/SEC)
for i = 0L, N do mx = max_test(x, thresh)
dt_mx = Systime(/SEC) - t0

t0 = Systime(/SEC)
for i = 0L, N do tot = total_test(x, thresh)
dt_tot = Systime(/SEC) - t0

t0 = Systime(/SEC)
for i = 0L, N do wh = where_test(x, thresh)
dt_wh = Systime(/SEC) - t0

PRINT, "MAX_TEST"
PRINT, " result = ", mx
PRINT, " elapsed = ", dt_mx
PRINT, " "
PRINT, "TOTAL_TEST"
PRINT, " result = ", tot
PRINT, " elapsed = ", dt_tot
PRINT, " "
PRINT, "WHERE_TEST"
PRINT, " result = ", wh
PRINT, " elapsed = ", dt_wh


END;

;---- END HERE
Re: How to speed up code which checks lots of values of an array [message #74363 is a reply to message #74332] Thu, 13 January 2011 08:43 Go to previous messageGo to next message
Robin Wilson is currently offline  Robin Wilson
Messages: 40
Registered: August 2010
Member
>
> IF(MAX(line[0:section_len - 1]) LE 180) AND (MIN(line[section_len + 1:
> len - 1]) GE 180) THEN
> ; Do stuff
> ENDIF

Thanks for the idea. That increases the speed a bit - the overall time
decreases by about a second.

I guess I've made that bit as fast a possible, and I need to deal with
the other speed issues with the code...like the fact that the code above
is being run inside a FOR loop, which is not the 'IDL way'.

So, does anyone have any idea how the following could be implemented
without my FOR loop. I'll describe it in words first, and post code
later if people need it:

For each pixel in the image (so, nested FOR loops going over the rows
and the columns):
Get a single 1D line centered on the pixel in question (the length is
configurable, so it could be a 5 pixel long line, or a 100 pixel long line)
Run the code in the last post on the line
Loop

At the moment I am using a function to extract the X pixel long line
from the image. I have a suspicion that this could be done using CONVOL,
but I can't see how...Any ideas?

Cheers,

Robin
Re: How to speed up code which checks lots of values of an array [message #74365 is a reply to message #74363] Thu, 13 January 2011 08:26 Go to previous messageGo to next message
Axel Martínez is currently offline  Axel Martínez
Messages: 22
Registered: June 2010
Junior Member
On Jan 13, 5:06 pm, Robin Wilson <ro...@rtwilson.com> wrote:
> Hi all,
>
> I've been writing some code which checks that all of the values in one
> half of an array are less than a threshold, and all of the values on the
> right half of an array are greater than a threshold. I've written the
> code below, which seems to be a fairly clean way of writing it, and
> works for any length of array (which is important for my use of it).
>
> However, it's not very fast. I wondered if it might be able to be sped
> up using some sort of magic like the Histogram command... Any ideas?
>
> ---CODE---
> ; Assume we're given a 1D array called line with our values in it
>
> len = N_ELEMENTS(line)
>
> section_len = (len - 1) / 2
>
> ; Get the left-hand half of the array
> LHS = line[0:section_len - 1]
> RHS = line[section_len + 1: len - 1]
>
> res = WHERE(LHS GT 180, LHS_count)
> res = WHERE(RHS LT 180, RHS_count)
>
> IF LHS_count EQ 0 AND RHS_count EQ 0 THEN BEGIN
>    ; Do stuff
> ENDIF
>
> ---END CODE---
>
> Cheers,
>
> Robin

Hi Robin,

Try that:

IF(MAX(line[0:section_len - 1]) LE 180) AND (MIN(line[section_len + 1:
len - 1]) GE 180) THEN
; Do stuff
ENDIF
Re: How to speed up code which checks lots of values of an array [message #74451 is a reply to message #74363] Fri, 14 January 2011 02:23 Go to previous message
jkeller is currently offline  jkeller
Messages: 35
Registered: October 2009
Member
When working with images/arrays needing a lot of comparisons I usually
calculate a field like
mask=(a GT 120)
and use this to manipulate the array with this mask:
b=a*mask-100+a*(1-mask)+100

Sincerely,
Jan
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: IDL 8.0 plot lat/lon data into map
Next Topic: Columnist Talking About Newsgroup

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

Current Time: Wed Oct 08 15:27:14 PDT 2025

Total time taken to generate the page: 0.00795 seconds