Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking for NaN in clojure

I have some algorithm which for one reason or another spits out NaNs, I would both like to just filter out these bad results for the time being, and some point later go and find out the problem. Hence, I need to check that a value is NaN, how do I do this?

I thought I could use the trick that a NaN is the only value not equal to itself so I wrote the following function

(defn NaN?
  "Test if this number is nan"
  [x]
  ; Nan is the only value for which equality is false
  (false? (= x x)))

This works if I ask (NaN? Double/NaN Double/NaN). However if the values NaN are in some data structure (as is the case), and have all ready been evaluated in some sense, then this does not work. For instance

(def test Double/Nan)
(NaN? test)

returns false.

like image 933
zenna Avatar asked Apr 21 '13 00:04

zenna


1 Answers

There's nothing wrong with using the java static functions for these tests, try.

(Double/isNaN x) 

As you've discovered NaN is not equal to anything including itself, if you want to ignore NaN values for equality you can either remove, replace (see clojure.walk/prewalk-replace) or test for them explicitly, eg.

(let [nan? #(and (number? %) (Double/isNaN %))
      vec-data [1 Double/NaN]
      map-data {:a 1 :b Double/NaN}]

    [;; compare vectors without NaN values
    (= (remove nan? vec-data) (remove nan? vec-data))

    ;; check that all differences in 2 maps are nan? 
    (every? nan? (mapcat vals (take 2 (clojure.data/diff map-data map-data))))])

     ;; => [true true]
like image 170
user499049 Avatar answered Sep 22 '22 23:09

user499049