# Making IDL Operators Play Nice with NaNs

QUESTION: The minimum and maximum operators do not work nicely with NaN values. Consider this code.

IDL> a = Findgen(5) IDL> a[2] = !Values.F_NaN IDL> Print, a 0.00000 1.00000 NaN 3.00000 4.00000 IDL> b = a > 2 % Program caused arithmetic error: Floating illegal operand IDL> Print, b 2.00000 2.00000 2.00000 3.00000 4.00000

I think most people would say that the proper behavior would be for the NaN value to be preserved. The IDL documentation indicates the behavior is actually hardware dependent, and on some machines the NaN is preserved. It suggests using *Where *and *Finite *instead of ">", whenever NaN values are present.

IDL> b = a IDL> goodIndices = Where(Finite(a), count) IDL> IF count GT 0 THEN b[goodIndices] = a[goodIndices] > 2 IDL> Print, b 2.00000 2.00000 NaN 3.00000 4.00000

The syntax above also eliminates the annoying "illegal operand" error message. The documentation also indicates that the ">" operator does not check for NaN values for speed reasons, and that the syntax of the operator does not allow having a *NaN *keyword be used
with it.

A related problem occurs with the *Hist_Equal* function.

IDL> Print, Hist_Equal(a) 0 85 0 170 255 % Program caused arithmetic error: Floating illegal operand

In this case, it is correct that the NaN is not preserved, since the output of *Hist_Equal* is a byte array. But I think it is a bug that the illegal operand error occurs. *Hist_Equal* does check for NaN values internally (for example, the internal *Histogram *command is called with the *NaN *keyword). It is only at the last step in *Hist_Equal*, where the > operator is used, that the NaN values are ignored. In this case, I think ExelisVis should follow their own advice and use *Where *and *Finite *rather than the > operator, even though doing so would make this a much slower operation.

Any ideas about this?

ANSWER: Well, I completely agree it is always best to follow your own advice, but you can see how far this gets you in your own life, probably.

I do note there is a faster way of obtaining the same result, without resorting to the
*Where *and *Finite *functions, although you still get the dreaded illegal operand
error, unfortunately. This syntax is about twice as fast as using *Where *and *Finite *
for a normal size image.

IDL> b = (a > 2) + a*0 % Program caused arithmetic error: Floating illegal operand IDL> Print, b 2.00000 2.00000 NaN 3.00000 4.00000

I suppose you can fix the error message by just turnning off exception handling while you are performing this operation.

IDL> !Except = 0 IDL> b = (a > 2) + a*0 IDL> Print, b 2.00000 2.00000 NaN 3.00000 4.00000 IDL> void = Check_Math() & !Except = 1

*Version of IDL used to prepare this article: IDL 8.2.3.*