core/vnl/vnl_c_na_vector.txx
Go to the documentation of this file.
00001 // This is core/vnl/vnl_c_na_vector.txx
00002 #ifndef vnl_c_na_vector_txx_
00003 #define vnl_c_na_vector_txx_
00004 //:
00005 // \file
00006 // \author Andrew W. Fitzgibbon, Ian Scott
00007 // \date   3 Nov 2010
00008 //
00009 //-----------------------------------------------------------------------------
00010 
00011 #include "vnl_c_na_vector.h"
00012 #include <vcl_cmath.h>     // vcl_sqrt()
00013 #include <vnl/vnl_math.h>
00014 #include <vnl/vnl_na.h>
00015 #include <vnl/vnl_complex_traits.h>
00016 #include <vnl/vnl_numeric_traits.h>
00017 
00018 
00019 template <class T>
00020 T vnl_c_na_vector<T>::sum(T const* v, unsigned n)
00021 {
00022   T tot(0);
00023   bool any_valid(false);
00024   for (const T* end = v+n; v != end; v++)
00025   {
00026     if (!vnl_na_isna(*v))
00027     {
00028       tot += *v;
00029       any_valid=true;
00030     }
00031   }
00032   return any_valid ? tot : vnl_na(T());
00033 }
00034 
00035 template <class T>
00036 T vnl_c_na_vector<T>::mean(T const *p, unsigned n)
00037 {
00038   T tot(0);
00039   unsigned n_finite=0;
00040   for (const T* end = p+n; p != end; p++)
00041     if (!vnl_na_isna(*p))
00042     {
00043       tot += *p;
00044       n_finite++;
00045     }
00046   return n_finite ? tot/abs_t(n_finite) : vnl_na(T());
00047 }
00048 
00049 
00050 //------------------------------------------------------------
00051 
00052 
00053 template <class T, class S>
00054 void vnl_c_na_vector_two_norm_squared(T const *p, unsigned n, S *out)
00055 {
00056   S val = 0;
00057   bool any_valid(false);
00058   for(T const * end = p+n; p != end; p++)
00059   {
00060     if (!vnl_na_isna(*p))
00061     {
00062       val += S(vnl_math_squared_magnitude(*p));
00063       any_valid=true;
00064     }
00065   }
00066   *out = any_valid ? val : vnl_na(T());
00067 }
00068 
00069 template <class T, class S>
00070 void vnl_c_na_vector_rms_norm(T const *p, unsigned n, S *out)
00071 {
00072   S val = 0;
00073   unsigned n_finite=0;
00074   for (T const* end = p+n; p != end; p++)
00075   {
00076     if (!vnl_na_isna(*p))
00077     {
00078       val += S(vnl_math_squared_magnitude(*p));
00079       n_finite++;
00080     }
00081   }
00082   typedef typename vnl_numeric_traits<S>::real_t real_t;
00083   *out = n_finite ? S(vcl_sqrt(real_t(val/n_finite))) : vnl_na(T());
00084 }
00085 
00086 template <class T, class S>
00087 void vnl_c_na_vector_one_norm(T const *p, unsigned n, S *out)
00088 {
00089   T val = 0;
00090   bool any_valid(false);
00091   for (T const* end = p+n; p != end; p++)
00092   {
00093     if (!vnl_na_isna(*p))
00094     {
00095       val += vnl_math_abs(*p++);
00096       any_valid=true;
00097     }
00098   }
00099   *out = any_valid ? val : vnl_na(T());
00100 }
00101 
00102 template <class T, class S>
00103 void vnl_c_na_vector_two_norm(T const *p, unsigned n, S *out)
00104 {
00105   vnl_c_na_vector_two_norm_squared(p, n, out);
00106   typedef typename vnl_numeric_traits<S>::real_t real_t;
00107   *out = S(vcl_sqrt(real_t(*out)));
00108 }
00109 
00110 
00111 template <class T, class S>
00112 void vnl_c_na_vector_inf_norm(T const *p, unsigned n, S *out)
00113 {
00114   T val = 0;
00115   bool any_valid(false);
00116   for (T const* end = p+n; p != end; p++)
00117   {
00118     S v = vnl_math_abs(*p);
00119     if (v > val) // don't need to test for NA, because NA > x is always false.
00120     {
00121       v = val;
00122       any_valid=true;
00123     }
00124   }
00125   *out = any_valid ? val : vnl_na(T());
00126 }
00127 
00128 
00129 //---------------------------------------------------------------------------
00130 
00131 template<class T>
00132 vcl_ostream& print_na_vector(vcl_ostream& s, T const* v, unsigned size)
00133 {
00134   if (size != 0) vnl_na_insert(s, *v++);
00135   for (T const* end = v+size-1; v != end; v++)
00136   {
00137     s << ' ';
00138     vnl_na_insert(s, *v);  // Output data element
00139   }
00140   return s;
00141 }
00142 
00143 //---------------------------------------------------------------------------
00144 
00145 #define VNL_C_NA_VECTOR_INSTANTIATE_norm(T, S) \
00146 template void vnl_c_na_vector_two_norm_squared(T const *, unsigned, S *); \
00147 template void vnl_c_na_vector_two_norm(T const *, unsigned, S *); \
00148 template void vnl_c_na_vector_one_norm(T const *, unsigned, S *); \
00149 template void vnl_c_na_vector_rms_norm(T const *, unsigned, S *); \
00150 template void vnl_c_na_vector_inf_norm(T const *, unsigned, S *)
00151 
00152 #undef VNL_C_NA_VECTOR_INSTANTIATE_ordered
00153 #define VNL_C_NA_VECTOR_INSTANTIATE_ordered(T) \
00154 VNL_C_NA_VECTOR_INSTANTIATE_norm(T, vnl_c_na_vector<T >::abs_t); \
00155 template class vnl_c_na_vector<T >; \
00156 template vcl_ostream& print_na_vector(vcl_ostream &,T const *,unsigned)
00157 
00158 
00159 #undef VNL_C_NA_VECTOR_INSTANTIATE_unordered
00160 #define VNL_C_NA_VECTOR_INSTANTIATE_unordered(T)
00161 
00162 #if 0
00163 VCL_DO_NOT_INSTANTIATE(T vnl_c_na_vector<T >::max_value(T const *, unsigned), T(0)); \
00164 VCL_DO_NOT_INSTANTIATE(T vnl_c_na_vector<T >::min_value(T const *, unsigned), T(0)); \
00165 VCL_DO_NOT_INSTANTIATE(unsigned vnl_c_na_vector<T >::arg_max(T const *, unsigned), 0U); \
00166 VCL_DO_NOT_INSTANTIATE(unsigned vnl_c_na_vector<T >::arg_min(T const *, unsigned), 0U); \
00167 VNL_C_NA_VECTOR_INSTANTIATE_norm(T, vnl_c_na_vector<T >::abs_t); \
00168 template class vnl_c_na_vector<T >; \
00169 VCL_UNINSTANTIATE_SPECIALIZATION(T vnl_c_na_vector<T >::max_value(T const *, unsigned)); \
00170 VCL_UNINSTANTIATE_SPECIALIZATION(T vnl_c_na_vector<T >::min_value(T const *, unsigned)); \
00171 VCL_UNINSTANTIATE_SPECIALIZATION(unsigned vnl_c_na_vector<T >::arg_max(T const *, unsigned)); \
00172 VCL_UNINSTANTIATE_SPECIALIZATION(unsigned vnl_c_na_vector<T >::arg_min(T const *, unsigned))
00173 #endif
00174 
00175 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00176 #undef VNL_C_NA_VECTOR_INSTANTIATE
00177 #define VNL_C_NA_VECTOR_INSTANTIATE(T) extern "no such macro; use e.g. VNL_C_NA_VECTOR_INSTANTIATE_ordered instead"
00178 #endif // DOXYGEN_SHOULD_SKIP_THIS
00179 
00180 #endif // vnl_c_na_vector_txx_