Tell me more ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a Mathematica expression that is mapped onto an external C function via MathLink. The external function passes a double array (using MLPutReal64List[]), which Mathematica interprets as a list of Real's. Sometimes the external function sends values for which the C math library function isnan(value) returns 1 (say from division by zero, or log(0)). Mathematica reads these values as NaN`. For example,

In[1]:= result = externalFunction[<some input>]
Out[1]= {NaN`, 0.18225}

Evaluating {NaN`, 0.182255} gives a syntax error:

In[2]:= {NaN`, 0.182255}
Syntax::tsntxi: "{NaN`,0.182255}" is incomplete; more input is needed.
Syntax::sntxi: Incomplete expression; more input is needed.

which makes sense, since a variable name is expected to follow the `, giving some variable in the NaN context.

But mathematica accepts result[[1]] as a number:

In[3]:= NumericQ[result[[1]]] 
Out[3]= True
In[4]:= NumberQ[result[[1]]]
Out[4]:= True

!!

Yet I haven't been able to find a pattern that matches NaN` and not all other numbers (for use in Position, Cases, etc.).

So what are ways of a) passing NaN's from c into Mathematica so that Mathematica interprets them as Indeterminate, or b) handling these NaNs inside mathematica (with a pattern match to replace them with Indeterminate, for example).

Is it possible to construct the first element of result using keyboard input? Note that InputForm[result[[1]]] gives NaN, and NumericQ[InputForm[result[[1]]]] gives False.

share|improve this question
@R.M Yes! As long as I load the ComputerArithmetic package before I call the external function, it works. Please write up your answer. – JxB Jan 20 '12 at 22:49
Does that NaN have a backtick at the end? That's unusual, as normally only numbers would have that, not symbols. I am curious what is result's FullForm. – Szabolcs Jan 21 '12 at 0:04
I think it should be mentioned here that 1.0`30 indicates 1.0 to 30 digits of precision. 1` just indicated a machine precision number (same as 1.0). – Szabolcs Jan 21 '12 at 0:08
1  
@Szabolcs There is indeed a backtick suffix. The FullForm evaluates to NaN`. – JxB Jan 21 '12 at 2:03

2 Answers

up vote 9 down vote accepted

NaN (or Not-a-Number is used in floating point arithmetic to represent values that are undefined or unrepresentable, such as $0/0,\ \infty/\infty$, etc. Mathematica typically returns Indeterminate for these, but several other languages return NaN.

To work with NaNs, you must load the ComputerArithmetic package as <<ComputerArithmetic` prior to calling your external function. If you don't do so, then Mathematica will treat the NaNs like any other symbol (or perhaps with other, unknown consequences depending on the setup). Loading the package will give you the results as expected, and pattern matching is pretty straightforward too.

enter image description here

share|improve this answer
Is it a bug that Mathematica correctly interprets the IEEE double encoding of a NaN as not-a-number, but stores it in the list as something that you can't even enter as input directly? I wonder if there are any cases when you would not want that nan to be automatically converted to Indeterminate. – JxB Jan 21 '12 at 19:11
@JxB I don't know if it's a bug or not, as I don't have anything to reproduce it, but since there are several WRI folks around here, one of them will probably comment if it is indeed one. Re: converting to Indeterminate, if you're using Mathematica as an intermediate step to process the data before feeding it into another software/language, you'd probably want to keep them as NaN so as to ensure that the other program uses it correctly. – rm -rf Jan 21 '12 at 19:21

The best way to handle NaNs coming in from MathLink is to replace all NaNs with a symbol such as Indeterminate. One way this can be achieved is using the following piece of code:

NaNQ[x_] :=
 Round[x] == -2147483648;

ReplaceNaNs[x_] := x /. y_?NaNQ :> Indeterminate;

You can then use the ReplaceNaNs function to replace any NaNs that you don't want:

In[1]:= result = externalFunction[<some input>]
Out[1]= {NaN`, 0.18225}
In[2]:= ReplaceNaNs[result]
Out[2]= {Indeterminate, 0.18225}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.