Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Find NaN elements in array

1,836 views
Skip to first unread message

Woody

unread,
Oct 14, 2009, 3:23:48 PM10/14/09
to
I have a large array of reals, c. I want to find any element in this
array which is NaN. I have a test IF(ANY(IsNaN(c))), and this works
fine. But I don't see how to get the index of the elements in the
array which have the value NaN. I would be satisfied to find the first
NaN index, or the last.

dpb

unread,
Oct 14, 2009, 3:27:03 PM10/14/09
to

get rid of the any()

find(isnan(c))

--

glen herrmannsfeldt

unread,
Oct 14, 2009, 3:42:23 PM10/14/09
to
Woody <ols...@sbcglobal.net> wrote:

It might be best to just use a DO loop and go through the array.
There has to be a loop in any case. ANY(IsNan(C)) might generate
a temporary LOGICAL array for IsNaN(C), and then pass that to ANY,
somewhat less efficient than using a loop in the first place.

If you actually want to do things with the NaN's, might
just as well use a loop.

-- glen

dpb

unread,
Oct 14, 2009, 3:46:12 PM10/14/09
to

OOOPS!!! This looked so much like Matlab code I thought I was in
comp.soft-sys.matlab group when I responded... :(

isnan(c) in Matlab returns a logical vector, the find() function returns
the true indices of a logical.

Of course, find() is implemented as a loop as Glen suggested (and
noticing it was Glen who responded clued me in I had made a group id
misake)...

--

Paul van Delst

unread,
Oct 14, 2009, 3:59:26 PM10/14/09
to

What about,

n = COUNT(IsNan(c))
ALLOCATE(IsNanIdx(n))
IsNanIdx = PACK( (/(i,i=1,SIZE(c))/), MASK=IsNan(c) )

?

IsNanIdx should contain the indices of c that correspond to the mask, IsNan(c).

Note that the above code is untested so there may be syntax and logic errors.

cheers,

paulv

Thomas Koenig

unread,
Oct 17, 2009, 1:59:57 PM10/17/09
to
On 2009-10-14, Woody <ols...@sbcglobal.net> wrote:
> I have a large array of reals, c. I want to find any element in this
> array which is NaN.


program main
real, dimension(10) :: a
data a /3.4, 4.1, 2.3, 5.2, 4.6, 5.1, 7.1, 0.4, 9.1, 10.7/
f = 1.2
a (2) = acos(f)
a (4) = acos(f)
print *,pack((/(i,i=1,size(a))/),a(:)/=a(:))
end program main

Works if your compiler doesn't optimize the test for equality away;
you might have to set some compiler switches to do so.

Richard Maine

unread,
Oct 17, 2009, 2:19:04 PM10/17/09
to
Thomas Koenig <tko...@netcologne.de> wrote:

> On 2009-10-14, Woody <ols...@sbcglobal.net> wrote:
> > I have a large array of reals, c. I want to find any element in this
> > array which is NaN.

...
> print *,pack((/(i,i=1,size(a))/),a(:)/=a(:))
...


> Works if your compiler doesn't optimize the test for equality away;
> you might have to set some compiler switches to do so.

The OP already used isnan, which is generally a far less problematic way
to test for a NaN than the x/=x style test. I suggest that going to the
x/=x style is not an improvement. As you imply, it is very compiler
dependent. You might not be able to coax some compilers into doing what
you want with that at all, others might need special switches as you
suggest (and those switches might kill optimizations that you really
want elsewhere).

There are several tricky ways to test for NaNs; this is one of them. I
have observed it as quite wide accepted advice that, regardless of what
way you use, it is best to isolate it to a separate procedure. Of
course, that's pretty typical advice for many compiler-dependent things.

The OP already seemed to have that isolation with his use of isnan.
Although isnan is nonstandard, it at least is in a nicely isolated form
such that a you could write your own isnan if your compiler didn't
happen to support it natively. Or one could use the f2003 ieee_is_nan.

The pack trick (also mentioned by Paul) is nice. It is just the x/=x
test that I'm giving you a hard time about.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain

0 new messages