Scyllarus: C++ Hyperspectral Processing Library
Hyperspectral Image Processing Pipeline
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
utility_imp.h
Go to the documentation of this file.
1 /****************************************************************************************
2  * SCYLLARUS : C++ HYPERSPECTRAL PROCESSING LIBRARY
3  * utility_imp.h - Implementations of Template functions
4  *
5  * This computer code is subject to copyright:
6  * (c) National ICT Australia Limited (NICTA) 2013-2014 All Rights Reserved.
7  *
8  * Jeremy Oorloff, National ICT Australia (NICTA)
9  *
10  ***************************************************************************************/
11 
12 #ifndef UTILITY_IMP_H_
13 #define UTILITY_IMP_H_
14 
15 #include <armadillo>
16 
17 namespace scyl
18 {
19 
24  template <class T> void nan_to_zero(T & in)
25  {
26  for(unsigned long i = 0; i < in.n_elem; i++)
27  {
28  if (!arma::is_finite(in(i)))
29  {
30  in(i) = 0;
31  }
32  }
33 
34  }
35 
36 
41  template <class T> void zero_to_one(T & in)
42  {
43  float eps=arma::Datum<float>::eps;
44  for(unsigned long i = 0; i < in.n_elem; i++)
45  {
46  if (in(i) <= 0.0f + eps and in(i) >= 0.0f - eps)
47  {
48  in(i) = 1.0f;
49  }
50  }
51  }
52 
53 
61  template <class T> int arma_cmp_num(const T & a,
62  const T & b,
63  float eps=arma::Datum<float>::eps,
64  bool verbose=false)
65  {
66  unsigned int total_count = 0;
67  unsigned int count = 0;
68  unsigned int first_five = 0;
69  if (a.n_elem != b.n_elem)
70  {
71  return a.n_elem; // Non matching objects, all elements are 'incorrect'
72  }
73  for (unsigned int i = 0; i < a.n_elem; i++)
74  {
75  if (!(a(i) <= b(i) + eps and a(i) >= b(i) - eps))
76  {
77  count++;
78  if (verbose && first_five <= 5)
79  {
80  std::cout.precision(15);
81  std::cout << "diff pixel " << i << " (" << a(i) << " -> " << b(i) << ")" << std::endl;
82 
83  if (first_five == 5)
84  {
85  std::cout << "etc..." << std::endl;
86  }
87  first_five += 1;
88  }
89  }
90  total_count++;
91  }
92 
93  if (verbose)
94  {
95  std::cout << count << "/" << total_count << " elements differ ("
96  << (static_cast<float>(count)/total_count)*100.0 << "%)" << std::endl;
97  T rms = arma::sqrt(arma::square(a) - arma::square(b));
98  std::cout << "Max difference was: " << rms.max() << "(epsilon " << eps << ")" << std::endl;
99  }
100  return count;
101  }
102 
110  template <class T> bool arma_cmp(const T & a,
111  const T & b,
112  const bool verbose=false,
113  float eps=arma::Datum<float>::eps)
114  {
115  if (a.n_elem != b.n_elem)
116  {
117  return false;
118  }
119  for (unsigned int i = 0; i < a.n_elem; i++)
120  {
121  if (!(arma::is_finite(a(i))) && !(arma::is_finite(b(i))))
122  {
123  // Both nan or inf, so are the same
124  continue;
125  }
126  if (!(a(i) <= b(i) + eps and a(i) >= b(i) - eps))
127  {
128  arma_cmp_num(a, b, eps, verbose);
129  return false;
130  }
131  }
132  return true;
133  }
134 
143  template <class T> float arma_cmp_sig_figs(const T & a,
144  const T & b,
145  int num_sig_figs=6)
146  {
147  unsigned int total_count = 0;
148  unsigned int count = 0;
149  unsigned int first_five = 0;
150  bool failed = false;
151  if (a.n_elem != b.n_elem)
152  {
153  return 100.0;
154  }
155  for (unsigned int i = 0; i < a.n_elem; i++)
156  {
157  double scale = 0;
158  if (a(i) != 0)
159  {
160  scale = pow(10.0, -1*ceil(log10(fabs(static_cast<double>(a(i))))));
161  }
162  double tolerance = pow(10.0, -1*num_sig_figs);
163  double a_scaled = a(i)*scale;
164  double b_scaled = b(i)*scale;
165 
166  if (!(a_scaled <= b_scaled + tolerance and a_scaled >= b_scaled - tolerance))
167  {
168  // Print information about which pixels have failed.
169  count++;
170  if (first_five <= 5)
171  {
172  std::cout.precision(15);
173  std::cout << "Diff pixel " << i << " (" << a(i) << " -> " << b(i) << ")" << std::endl;
174 
175  if (first_five == 5)
176  {
177  std::cout << "etc..." << std::endl;
178  }
179  first_five += 1;
180  }
181  failed = true;
182  }
183  total_count++;
184  }
185  if (failed)
186  {
187  float percent_count = (static_cast<float>(count)/total_count)*100.0;
188  std::cout << count << "/" << total_count << " elements differ ("
189  << percent_count << "%)" << std::endl;
190  T rms = arma::sqrt(arma::square(a) - arma::square(b));
191  std::cout << "Max difference was: " << rms.max() << "(sig figs " << num_sig_figs << ")" << std::endl;
192  return percent_count;
193  }
194  return 0.0;
195  }
196 }
197 
198 #endif /* UTILITY_IMP_H_ */
void nan_to_zero(T &in)
nan_to_zero removes NaN values from a Armadillo data structure, replacing them with 0...
Definition: utility_imp.h:24
void zero_to_one(T &in)
zero_to_one replaces 0's in an Armadillo data structure with 1's.
Definition: utility_imp.h:41
bool arma_cmp(const T &a, const T &b, const bool verbose, float eps)
arma_cmp compares two Armadillo objects for equality +- epsilon.
Definition: utility_imp.h:110
int arma_cmp_num(const T &a, const T &b, float eps)
float arma_cmp_sig_figs(const T &a, const T &b, int num_sig_figs)
arma_cmp compares two Armadillo objects for equality. Instead of using a tolerance, test number of significant figures.
Definition: utility_imp.h:143