Seth on Simulink

February 4th, 2009

How do I test for NaN in my model?

This week I want to pose a brainteaser that my colleague Jeff had to solve this week.  Imagine you need to detect the condition where a signal value might become NaN (Not A Number).  How do you test for that in Simulink?

What is a NaN?

NaN means Not-A-Number.  In general math terms, this is the result for special cases, which are undefined.  In general computing terms, operations return NaN for invalid inputs.  For example:

>> Inf*0
ans =
   NaN
>> 0/0
ans =
   NaN
>> Inf/Inf
ans =
   NaN
>> Inf-Inf
ans =
   NaN
 

If you are writing code and need to protect against invalid inputs, detecting this could be important.

ISNAN?

In MATLAB we have the function ISNAN.  ISNAN is a MATLAB function, which we could call from Simulink.

>> x = 0/0
x =
   NaN
>> isnan(x)
ans =
     1

In some ways, that feels like cheating.  If we were developing this algorithm to run on an embedded system, MATLAB will not be available.

First try, Diagnostics

The first idea I had was to look at the diagnostics.  I remembered seeing a warning about NaNs once during a simulation, so there might be a way to turn on a diagnostic to detect this.

Simulink configuration parameters

We found the diagnostic in the Data Validity page of the Configuration Parameters.  This diagnostic will check for Inf or NaN signals in a block output, but that doesn’t help if we want the model to do something reactive with that information.  This diagnostic is purely informative.

NaN has a specific bit pattern

What about testing the bit pattern?  Using MATLAB I can see what that pattern is in HEX:

>> format hex
>> NaN
ans =
   fff8000000000000

We did try the bit operations, but ran into some difficulties.  NaN is a floating-point number, and all the bit processing blocks are built for working with integers.  In this case, working with a floating-point number would require some contortions to get the bit pattern.  Once we had it, we could use the other Bitwise Operator block to test for the pattern we were looking for, but we didn’t get that working before we had another realization.

Comparison with NaN is different from all other numbers

That was the “Eureka!” moment: NaN has special properties!  Math operations performed with NaN result in a NaN  (x+NaN = NaN).  Comparisons to a NaN return false.  For example:

>> NaN<1
ans =
     0
>> NaN<=Inf
ans =
     0

Comparison with Inf is pretty interesting because we couldn’t think of any other numbers that would return FALSE for X<=Inf, except NaN.  Even if X=Inf, this should return TRUE.  In Simulink, the test model looked like this:

ISNAN built with Simulink blocks using a Compare to Constant block and Logical Operator

Using the logical operation, NOT, we can pass any signal through these blocks and make our own ISNAN block.  Another interesting property of NaN is that it is the ONLY number not equal to itself.  An alternative model, arguably more streamlined, uses just the Relational Operator to test the NOT Equals condition and compares the signal to itself.

ISNAN built with Simulink blocks using the Relational Operator

All numbers EXCEPT NaN should return FALSE for this test.  We double-checked it by sending infinity through the same construct.

The Final Answer?

Have you done any interesting mathematical operations to deal with special floating-point numbers?  Can you think of another way to do this?  Did you ever have to deal with quiet NaNs versus signaling NaNs?  Tell me about it with a comment here.

7 Responses to “How do I test for NaN in my model?”

  1. wei replied on :

    Seth,
    Dealing with string in Simulink may be an interesting topic.

  2. Andres Feito replied on :

    Seth,

    We dealt with Nan problems and to protect our model against this kind of problems we built a similar Nan detector. We develop flight control embedded software and we wanted to be protected against it in the remote case it could appear. So when a Nan is detected we made two actions:

    We freeze the output of the model so that the Nan will not have the oportunity to leave the model and affect other parts of the system.

    We also raise a flag, then the current model is not taken into account and another simpler backup model is executed from this moment on. The Nan problem is not likely to occur in this latter model.

  3. Seth replied on :

    @wei - Thanks for the topic suggestion. Can you tell me more about how you want to use strings in your model? I have heard about people wanting to pass error codes and messages around from system to system as strings. Is that what you are looking to do?

    @Andres Feito - Providing a fail-safe back up model makes a lot of sense. Thanks for sharing the description of your system!

  4. wei replied on :

    @Seth - multimedia play list is another example. Richer data structure has to be considered if not just as traditional control development tool, but core software tool as well.

  5. Paul J. replied on :

    Seth,

    Hope you’re still checking responses to this topic. Newsgroup comp.lang.c++.moderated has recently discussed this issue quite a bit. A lot of people suggested the “if (x != x)” approach, i.e., x != x is true only if x is NaN. However, a lot of experts came up with some good reasons, not all of which I understood, to explain why this approach could be problematic. The most obvious reason is that if Simulink generates this code in C, it’s possible that a compiler for the embedded platform will optimize it away. Depends on the compiler and what optimization flags are turned on, IEE7554 compliance, different types of NaNs, etc. Also, there were lots of other considerations as well. Does the Simulink approach given above work for different data types (double, int, etc.)? How is isnan implmented in Matlab? Could that implementation be redone in Simulink? After reading those newsgroup articles, I get the impression that NaN detection is not trivial, particularly for developers using Simulink to develop embedded code for platforms that might have specialized compilers.

    Paul

  6. Seth replied on :

    @Paul - The approach above is not universal for all kind of NaN testing. The (x != x) approach can be problematic. The standard way to do this sort of thing is to use isnan(), isinf(), isfinite(), isnormal(), or fpclassify() and associated enums and constants - available via IEEE math.h include files. Those functions exist for a reason, and that is consistent detection. The S-Function builder block provides an easy way to incorporate C functions into your model, and it would only require a couple lines of code.

    The issues of detecting NaNs on embedded systems will require specific knowledge of the system, and integration with the operations available on your target hardware.

    Thanks for the great discussion!

  7. Seth replied on :

    @Paul - R2009b has added the ability to detect NaN’s to the relational operator. I posted an update on this topic in a new post here.

Leave a Reply

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>

If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).


Seth Popinchalk is an Application Engineer for The MathWorks. He writes here about Simulink and other MathWorks tools used in Model-Based Design.
  • wei: @Ashish, I agree with your observation on compiler optimization but fail to see why Han’s code would be...
  • Ashish Sadanandan: Han, Sorry for butting in with a reply, but the modification to the for-loop you’ve...
  • arun kumar: dear seth i have been involved in developing and simulating asynchronous systems for my VLSI lab. in...
  • Han Geerligs: Hi Aarti, thanks for providing the example! I was just wondering why the lines model_YDim = model_XDim;...
  • Seth: @Han - Aarti’s response is in a post titled Generated Code for Variable Size Signals.
  • garla: what is advantage of exporting the bus object with the format as “cell” and “object” ....
  • J.r: @ Guy - Example sent to your account. Thank you.
  • Guy: @ J.r - The ability for atomic subsystems and Model Reference to remove the “fake algebraic loop”...
  • J.r: Sorry to hit an old thread, but this seems like the best place to solicit help on this topic. Is there supposed...
  • Bindu: please tell me how can i get the sampling time used in simulation

These postings are the author's and don't necessarily represent the opinions of The MathWorks.