Re: Turning off math error checking for a code block [message #28965 is a reply to message #28898] |
Fri, 18 January 2002 14:47  |
k-bowman
Messages: 12 Registered: December 2001
|
Junior Member |
|
|
In article <Ln_18.43167$WQ1.6917653@news6-win.server.ntlworld.com>, "Martin Downing" <martin.downing@ntlworld.com> wrote:
> craig wrote:
>> I have found that an operation on an array which contains NANs is
>> slowed down considerably. I think it is because each operation causes
>> a floating point exception which is handled in the OS. I use WHERE
>> most of the time when this comes up. Occassionally I get "floating
>> exception" messages, but big whoop.
Actually, I don't think it is faster. The program below creates an array with 10^6 elements with about 10% of the values set to NaN. The goal is to set all the finite values of the array less than x_min to NaN.
I tried two methods
1) turning off error messages and doing a single WHERE, and
2) doing one WHERE to find the finite values and a second WHERE to find the values less than x_min.
The problem is that the two WHERE's require creating an intermediate array and repeated indirect indexing. It may be possible to do the second method more efficiently, but I don't see how.
The code below produces
IIDL> TEST_FINITE
Turn off error checking, t = 0.082054019
Do WHERE twice, t = 1.7191260
so, turning off error messages seems to be much faster.
Also, I prefer that my codes produce floating point errors only when there really are floating point errors. I don't want to get in the habit of ignoring FP error messages.
Ken
PRO TEST_FINITE
n = 1024L*1024L
nmiss = 100L*1024L
x = RANDOMN(seed, n) ;Create 10^ random numbers
miss = LONG(n*RANDOMU(seed, nmiss)) ;Generate 10^5 random indices
x[miss] = !VALUES.F_NAN ;Set random indices to missing
x_min = 0.0
t = SYSTIME(/SECONDS)
error = CHECK_MATH(/PRINT)
save_except = !EXCEPT
!EXCEPT = 0
i = WHERE(x LT x_min, ni)
error = CHECK_MATH()
!EXCEPT = save_except
PRINT, 'Turn off error checking, t = ', SYSTIME(/SECONDS) - t
t = SYSTIME(/SECONDS)
i = WHERE(FINITE(x), ni)
IF (ni GT 0) THEN BEGIN
y = x[i]
j = WHERE(y LT x_min, nj)
IF (nj GT 0) THEN BEGIN
y[j] = !VALUES.F_NAN
x[i] = y
ENDIF
ENDIF
PRINT, 'Do WHERE twice, t = ', SYSTIME(/SECONDS) - t
END
|
|
|