vnl_na.h
Go to the documentation of this file.
1 // This is core/vnl/vnl_na.h
2 #ifndef vnl_na_h_
3 #define vnl_na_h_
4 
5 
6 #include <iosfwd>
7 #ifdef _MSC_VER
8 # include <vcl_msvc_warnings.h>
9 #endif
10 #include "vnl/vnl_export.h"
11 
12 //:
13 // \file
14 // \brief NA (Not Available) is a particular double (or single-precision) NaN to represent missing data.
15 // For example, where a vnl_vector<double> represents a series of samples from an image,
16 // NA could be used to represent places where the measurement was taken outside the image.
17 //
18 // NA is distinct from the two other standard meanings of NaN - Indeterminate and Error.
19 // It is entirely up to each algorithm to treat NA values meaningfully. Unless
20 // a function's interpretation of NA is explicitly documented, you should assume that
21 // it will be treated similarly to every other NaN.
22 // The IEEE754 bit value used to represent NA in double-precision is 0x7ff00000000007a2, the
23 // same as used by Octave and R. Initial values of NA are stored as signalling NaNs, but
24 // many uses will convert this to the non-signalling variant 0x7ff80000000007a2. vnl_isna()
25 // will accept either variant.
26 //
27 // The single precision NA is stored as 0x7f8007a2. I cannot find any external support for
28 // this or any other value for single precision NA. There is no automatic conversion between
29 // the NA values during casting, promotion, etc. If you want to convert a float to double,
30 // whilst preserving the NA-ness of the value, you will have to test for and set the new NA
31 // value explicitly.
32 //
33 // You can read and write floating point values from a stream using standard operators
34 // by using a conversion manipulator.
35 // \verbatim
36 // double x, y;
37 // is >> vnl_na_stream(x) >> vnl_na_stream(x);
38 // os << vnl_na_stream(x) << ' ' << vnl_na_stream(x);
39 // \endverbatim
40 
41 
42 //: qNaN to indicate value Not Available.
43 // Don't assume that any VXL functions will do something sensible in the face of NA, unless
44 // explicitly documented.
45 VNL_EXPORT double vnl_na(double dummy);
46 
47 //: qNaN to indicate value Not Available.
48 // Don't assume that any VXL functions will do something sensible in the face of NA, unless
49 // explicitly documented.
50 VNL_EXPORT float vnl_na(float dummy);
51 
52 //: True if parameter is specific NA qNaN.
53 // Tests for bit pattern 0x7ff00000000007a2, as used by Octave and R
54 VNL_EXPORT bool vnl_na_isna(double);
55 
56 //: True if parameter is specific NA qNaN.
57 // Tests for bit pattern 0x7f8007a2
58 VNL_EXPORT bool vnl_na_isna(float);
59 
60 
61 //: Replace NaNs with NA, leave other values alone.
62 VNL_EXPORT double vnl_na_nan_to_na(double v);
63 
64 //: Replace NaNs with NA, leave other values alone.
65 VNL_EXPORT float vnl_na_nan_to_na(float v);
66 
67 
68 //: Read a floating point number or "NA" from a stream.
69 // Should behave exactly like a>>x, if the extraction operator was aware of the
70 // character sequence \code NA.
71 VNL_EXPORT void vnl_na_extract(std::istream &is, double& x);
72 
73 
74 //: Write a floating point number or "NA" to a stream.
75 // Should behave exactly like a<<x, if the insertion operator was aware of the
76 // character sequence \code NA.
77 VNL_EXPORT void vnl_na_insert(std::ostream &is, double x);
78 
79 //: Read a floating point number or "NA" from a stream.
80 // Should behave exactly like a>>x, if the extraction operator was aware of the
81 // character sequence \code NA.
82 VNL_EXPORT void vnl_na_extract(std::istream &is, float& x);
83 
84 
85 //: Write a floating point number or "NA" to a stream.
86 // Should behave exactly like a<<x, if the insertion operator was aware of the
87 // character sequence \code NA.
88 VNL_EXPORT void vnl_na_insert(std::ostream &is, float x);
89 
90 
91 //: Wrapper around a double or float that handles streaming NA.
92 template <class T>
93 struct vnl_na_stream_t
94 {
95  T& x_;
96  vnl_na_stream_t(T& x): x_(x) {}
97 };
98 
99 //: Wrapper around a double or float that handles streaming NA.
100 template <class T>
101 struct vnl_na_stream_const_t
102 {
103  const T& x_;
104  vnl_na_stream_const_t(const T& x): x_(x) {}
105 };
106 
107 //: Wrap a double or float to handle streaming NA.
108 template <class T>
109 inline vnl_na_stream_t<T> vnl_na_stream(T& x)
110 {
111  return vnl_na_stream_t<T>(x);
112 }
113 
114 //: Wrap a double or float to handle streaming NA.
115 template <class T> inline vnl_na_stream_const_t<T> vnl_na_stream(const T& x)
116 {
117  return vnl_na_stream_const_t<T>(x);
118 }
119 
120 //: Insert wrapped double or float into stream, whilst handling NA.
121 template <class T> inline std::ostream& operator <<(std::ostream &os, const vnl_na_stream_t<T>& ns)
122 {
123  vnl_na_insert(os, ns.x_);
124  return os;
125 }
126 
127 //: Insert wrapped double or float into stream, whilst handling NA.
128 template <class T> inline std::ostream& operator <<(std::ostream &os, const vnl_na_stream_const_t<T>& ns)
129 {
130  vnl_na_insert(os, ns.x_);
131  return os;
132 }
133 
134 //: Extract wrapped double or float from stream, whilst handling NA.
135 template <class T> inline std::istream& operator >>(std::istream &is, const vnl_na_stream_t<T>& ns)
136 {
137  vnl_na_extract(is, ns.x_);
138  return is;
139 }
140 
141 #endif // vnl_na_h_
void vnl_na_extract(std::istream &is, double &x)
Definition: vnl_na.cxx:151
void vnl_na_insert(std::ostream &os, double x)
Write a floating point number or "NA" to a stream.
Definition: vnl_na.cxx:155
std::ostream & operator<<(std::ostream &s, vnl_decnum const &r)
decimal output.
Definition: vnl_decnum.h:393
#define v
Definition: vnl_vector.h:42
VNL_EXPORT bool vnl_na_isna(double)
True if parameter is specific NA qNaN.
Definition: vnl_na.cxx:54
VNL_EXPORT double vnl_na_nan_to_na(double v)
Replace NaNs with NA, leave other values alone.
Definition: vnl_na.cxx:75
VNL_EXPORT double vnl_na(double dummy)
qNaN to indicate value Not Available.
Definition: vnl_na.cxx:17