00001
00002 #ifndef vnl_c_na_vector_txx_
00003 #define vnl_c_na_vector_txx_
00004
00005
00006
00007
00008
00009
00010
00011 #include "vnl_c_na_vector.h"
00012 #include <vcl_cmath.h>
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)
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);
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_