vnl_c_na_vector.hxx
Go to the documentation of this file.
1 // This is core/vnl/vnl_c_na_vector.hxx
2 #ifndef vnl_c_na_vector_hxx_
3 #define vnl_c_na_vector_hxx_
4 //:
5 // \file
6 // \author Andrew W. Fitzgibbon, Ian Scott
7 // \date 3 Nov 2010
8 //
9 //-----------------------------------------------------------------------------
10 
11 #include <cmath>
12 #include "vnl_c_na_vector.h"
13 #ifdef _MSC_VER
14 # include <vcl_msvc_warnings.h>
15 #endif
16 #include <vnl/vnl_math.h>
17 #include <vnl/vnl_na.h>
18 #include <vnl/vnl_complex_traits.h>
19 #include <vnl/vnl_numeric_traits.h>
20 
21 
22 template <class T>
23 T vnl_c_na_vector<T>::sum(T const* v, unsigned n)
24 {
25  T tot(0);
26  bool any_valid(false);
27  for (const T* end = v+n; v != end; v++)
28  {
29  if (!vnl_na_isna(*v))
30  {
31  tot += *v;
32  any_valid=true;
33  }
34  }
35  return any_valid ? tot : vnl_na(T());
36 }
37 
38 template <class T>
39 T vnl_c_na_vector<T>::mean(T const *p, unsigned n)
40 {
41  T tot(0);
42  unsigned n_finite=0;
43  for (const T* end = p+n; p != end; p++)
44  if (!vnl_na_isna(*p))
45  {
46  tot += *p;
47  n_finite++;
48  }
49  return n_finite ? tot/abs_t(n_finite) : vnl_na(T());
50 }
51 
52 
53 //------------------------------------------------------------
54 
55 
56 template <class T, class S>
57 void vnl_c_na_vector_two_norm_squared(T const *p, unsigned n, S *out)
58 {
59  S val = 0;
60  bool any_valid(false);
61  for (T const * end = p+n; p != end; p++)
62  {
63  if (!vnl_na_isna(*p))
64  {
65  val += S(vnl_math::squared_magnitude(*p));
66  any_valid=true;
67  }
68  }
69  *out = any_valid ? val : vnl_na(T());
70 }
71 
72 template <class T, class S>
73 void vnl_c_na_vector_rms_norm(T const *p, unsigned n, S *out)
74 {
75  S val = 0;
76  unsigned n_finite=0;
77  for (T const* end = p+n; p != end; p++)
78  {
79  if (!vnl_na_isna(*p))
80  {
81  val += S(vnl_math::squared_magnitude(*p));
82  n_finite++;
83  }
84  }
85  typedef typename vnl_numeric_traits<S>::real_t real_t;
86  *out = n_finite ? S(std::sqrt(real_t(val/n_finite))) : vnl_na(T());
87 }
88 
89 template <class T, class S>
90 void vnl_c_na_vector_one_norm(T const *p, unsigned n, S *out)
91 {
92  T val = 0;
93  bool any_valid(false);
94  for (T const* end = p+n; p != end; p++)
95  {
96  if (!vnl_na_isna(*p))
97  {
98  val += vnl_math::abs(*p++);
99  any_valid=true;
100  }
101  }
102  *out = any_valid ? val : vnl_na(T());
103 }
104 
105 template <class T, class S>
106 void vnl_c_na_vector_two_norm(T const *p, unsigned n, S *out)
107 {
109  typedef typename vnl_numeric_traits<S>::real_t real_t;
110  *out = S(std::sqrt(real_t(*out)));
111 }
112 
113 
114 template <class T, class S>
115 void vnl_c_na_vector_inf_norm(T const *p, unsigned n, S *out)
116 {
117  T val = 0;
118  bool any_valid(false);
119  for (T const* end = p+n; p != end; p++)
120  {
121  S v = vnl_math::abs(*p);
122  if (v > val) // don't need to test for NA, because NA > x is always false.
123  {
124  v = val;
125  any_valid=true;
126  }
127  }
128  *out = any_valid ? val : vnl_na(T());
129 }
130 
131 
132 //---------------------------------------------------------------------------
133 
134 template<class T>
135 std::ostream& print_na_vector(std::ostream& s, T const* v, unsigned size)
136 {
137  if (size != 0) vnl_na_insert(s, *v++);
138  for (T const* end = v+size-1; v != end; v++)
139  {
140  s << ' ';
141  vnl_na_insert(s, *v); // Output data element
142  }
143  return s;
144 }
145 
146 //---------------------------------------------------------------------------
148 #define VNL_C_NA_VECTOR_INSTANTIATE_norm(T, S) \
149 template VNL_EXPORT void vnl_c_na_vector_two_norm_squared(T const *, unsigned, S *); \
150 template VNL_EXPORT void vnl_c_na_vector_two_norm(T const *, unsigned, S *); \
151 template VNL_EXPORT void vnl_c_na_vector_one_norm(T const *, unsigned, S *); \
152 template VNL_EXPORT void vnl_c_na_vector_rms_norm(T const *, unsigned, S *); \
153 template VNL_EXPORT void vnl_c_na_vector_inf_norm(T const *, unsigned, S *)
154 
155 #undef VNL_C_NA_VECTOR_INSTANTIATE_ordered
156 #define VNL_C_NA_VECTOR_INSTANTIATE_ordered(T) \
157 VNL_C_NA_VECTOR_INSTANTIATE_norm(T, vnl_c_na_vector<T >::abs_t); \
158 template class vnl_c_na_vector<T >; \
159 template std::ostream& print_na_vector(std::ostream &,T const *,unsigned)
160 
161 
162 #undef VNL_C_NA_VECTOR_INSTANTIATE_unordered
163 #define VNL_C_NA_VECTOR_INSTANTIATE_unordered(T)
164 
165 #ifndef DOXYGEN_SHOULD_SKIP_THIS
166 #undef VNL_C_NA_VECTOR_INSTANTIATE
167 #define VNL_C_NA_VECTOR_INSTANTIATE(T) extern "no such macro; use e.g. VNL_C_NA_VECTOR_INSTANTIATE_ordered instead"
168 #endif // DOXYGEN_SHOULD_SKIP_THIS
169 
170 #endif // vnl_c_na_vector_hxx_
void vnl_c_na_vector_two_norm(T const *p, unsigned n, S *out)
void vnl_c_na_vector_rms_norm(T const *p, unsigned n, S *out)
void vnl_c_na_vector_inf_norm(T const *p, unsigned n, S *out)
void vnl_na_insert(std::ostream &os, double x)
Write a floating point number or "NA" to a stream.
Definition: vnl_na.cxx:155
Templated zero/one/precision.
To allow templated algorithms to determine appropriate actions of conjugation, complexification etc.
void vnl_c_na_vector_two_norm_squared(T const *p, unsigned n, S *out)
void vnl_c_na_vector_one_norm(T const *p, unsigned n, S *out)
Namespace with standard math functions.
vnl_numeric_traits< T >::abs_t abs_t
static T mean(T const *p, unsigned n)
NA (Not Available) is a particular double (or single-precision) NaN to represent missing data.
vnl_bignum squared_magnitude(vnl_bignum const &x)
Definition: vnl_bignum.h:433
VNL_EXPORT std::ostream & print_na_vector(std::ostream &, T const *, unsigned)
Input & output.
#define v
Definition: vnl_vector.h:42
Math on blocks of memory.
bool vnl_na_isna(double x)
True if parameter is specific NA qNaN.
Definition: vnl_na.cxx:54
vnl_bignum abs(vnl_bignum const &x)
Definition: vnl_bignum.h:432
double vnl_na(double)
A particular qNaN to indicate not available.
Definition: vnl_na.cxx:17
static T sum(T const *v, unsigned n)