libMesh
statistics.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 // C++ includes
20 #include <algorithm> // for std::min_element, std::max_element
21 #include <fstream> // std::ofstream
22 #include <numeric> // std::accumulate
23 
24 // Local includes
25 #include "libmesh/statistics.h"
26 #include "libmesh/int_range.h"
27 #include "libmesh/libmesh_logging.h"
28 
29 namespace libMesh
30 {
31 
32 
33 
34 // ------------------------------------------------------------
35 // StatisticsVector class member functions
36 template <typename T>
38 {
39  Real normsq = 0.;
40  const dof_id_type n = cast_int<dof_id_type>(this->size());
41  for (dof_id_type i = 0; i != n; ++i)
42  normsq += ((*this)[i] * (*this)[i]);
43 
44  return std::sqrt(normsq);
45 }
46 
47 
48 template <typename T>
50 {
51  LOG_SCOPE ("minimum()", "StatisticsVector");
52 
53  const T min = *(std::min_element(this->begin(), this->end()));
54 
55  return min;
56 }
57 
58 
59 
60 
61 template <typename T>
63 {
64  LOG_SCOPE ("maximum()", "StatisticsVector");
65 
66  const T max = *(std::max_element(this->begin(), this->end()));
67 
68  return max;
69 }
70 
71 
72 
73 
74 template <typename T>
76 {
77  LOG_SCOPE ("mean()", "StatisticsVector");
78 
79  const dof_id_type n = cast_int<dof_id_type>(this->size());
80 
81  Real the_mean = 0;
82 
83  for (dof_id_type i=0; i<n; i++)
84  {
85  the_mean += ( static_cast<Real>((*this)[i]) - the_mean ) /
86  static_cast<Real>(i + 1);
87  }
88 
89  return the_mean;
90 }
91 
92 
93 
94 
95 template <typename T>
97 {
98  const dof_id_type n = cast_int<dof_id_type>(this->size());
99 
100  if (n == 0)
101  return 0.;
102 
103  LOG_SCOPE ("median()", "StatisticsVector");
104 
105  std::sort(this->begin(), this->end());
106 
107  const dof_id_type lhs = (n-1) / 2;
108  const dof_id_type rhs = n / 2;
109 
110  Real the_median = 0;
111 
112 
113  if (lhs == rhs)
114  {
115  the_median = static_cast<Real>((*this)[lhs]);
116  }
117 
118  else
119  {
120  the_median = ( static_cast<Real>((*this)[lhs]) +
121  static_cast<Real>((*this)[rhs]) ) / 2.0;
122  }
123 
124  return the_median;
125 }
126 
127 
128 
129 
130 template <typename T>
132 {
133  StatisticsVector<T> sv = (*this);
134 
135  return sv.median();
136 }
137 
138 
139 
140 
141 template <typename T>
143 {
144  const dof_id_type n = cast_int<dof_id_type>(this->size());
145 
146  LOG_SCOPE ("variance()", "StatisticsVector");
147 
148  Real the_variance = 0;
149 
150  for (dof_id_type i=0; i<n; i++)
151  {
152  const Real delta = ( static_cast<Real>((*this)[i]) - mean_in );
153  the_variance += (delta * delta - the_variance) /
154  static_cast<Real>(i + 1);
155  }
156 
157  if (n > 1)
158  the_variance *= static_cast<Real>(n) / static_cast<Real>(n - 1);
159 
160  return the_variance;
161 }
162 
163 
164 template <typename T>
166 {
167  const dof_id_type n = cast_int<dof_id_type>(this->size());
168  const Real max = this->maximum();
169 
170  for (dof_id_type i=0; i<n; i++)
171  (*this)[i] = static_cast<T>((*this)[i] / max);
172 }
173 
174 
175 
176 
177 
178 template <typename T>
179 void StatisticsVector<T>::histogram(std::vector<dof_id_type> & bin_members,
180  unsigned int n_bins)
181 {
182  // Must have at least 1 bin
183  libmesh_assert (n_bins>0);
184 
185  const dof_id_type n = cast_int<dof_id_type>(this->size());
186 
187  std::sort(this->begin(), this->end());
188 
189  // The StatisticsVector can hold both integer and float types.
190  // We will define all the bins, etc. using Reals.
191  Real min = static_cast<Real>(this->minimum());
192  Real max = static_cast<Real>(this->maximum());
193  Real bin_size = (max - min) / static_cast<Real>(n_bins);
194 
195  LOG_SCOPE ("histogram()", "StatisticsVector");
196 
197  std::vector<Real> bin_bounds(n_bins+1);
198  for (auto i : index_range(bin_bounds))
199  bin_bounds[i] = min + Real(i) * bin_size;
200 
201  // Give the last bin boundary a little wiggle room: we don't want
202  // it to be just barely less than the max, otherwise our bin test below
203  // may fail.
204  bin_bounds.back() += 1.e-6 * bin_size;
205 
206  // This vector will store the number of members each bin has.
207  bin_members.resize(n_bins);
208 
209  dof_id_type data_index = 0;
210  for (auto j : index_range(bin_members)) // bin vector indexing
211  {
212  // libMesh::out << "(debug) Filling bin " << j << std::endl;
213 
214  for (dof_id_type i=data_index; i<n; i++) // data vector indexing
215  {
216  //libMesh::out << "(debug) Processing index=" << i << std::endl;
217  Real current_val = static_cast<Real>( (*this)[i] );
218 
219  // There may be entries in the vector smaller than the value
220  // reported by this->minimum(). (e.g. inactive elements in an
221  // ErrorVector.) We just skip entries like that.
222  if (current_val < min)
223  {
224  // libMesh::out << "(debug) Skipping entry v[" << i << "]="
225  // << (*this)[i]
226  // << " which is less than the min value: min="
227  // << min << std::endl;
228  continue;
229  }
230 
231  if (current_val > bin_bounds[j+1]) // if outside the current bin (bin[j] is bounded
232  // by bin_bounds[j] and bin_bounds[j+1])
233  {
234  // libMesh::out.precision(16);
235  // libMesh::out.setf(std::ios_base::fixed);
236  // libMesh::out << "(debug) (*this)[i]= " << (*this)[i]
237  // << " is greater than bin_bounds[j+1]="
238  // << bin_bounds[j+1] << std::endl;
239  data_index = i; // start searching here for next bin
240  break; // go to next bin
241  }
242 
243  // Otherwise, increment current bin's count
244  bin_members[j]++;
245  // libMesh::out << "(debug) Binned index=" << i << std::endl;
246  }
247  }
248 
249 #ifdef DEBUG
250  // Check the number of binned entries
251  const dof_id_type n_binned = std::accumulate(bin_members.begin(),
252  bin_members.end(),
253  static_cast<dof_id_type>(0),
254  std::plus<dof_id_type>());
255 
256  if (n != n_binned)
257  {
258  libMesh::out << "Warning: The number of binned entries, n_binned="
259  << n_binned
260  << ", did not match the total number of entries, n="
261  << n << "." << std::endl;
262  }
263 #endif
264 }
265 
266 
267 
268 
269 
270 template <typename T>
272  const std::string & filename,
273  unsigned int n_bins)
274 {
275  // First generate the histogram with the desired number of bins
276  std::vector<dof_id_type> bin_members;
277  this->histogram(bin_members, n_bins);
278 
279  // The max, min and bin size are used to generate x-axis values.
280  T min = this->minimum();
281  T max = this->maximum();
282  T bin_size = (max - min) / static_cast<T>(n_bins);
283 
284  // On processor 0: Write histogram to file
285  if (my_procid==0)
286  {
287  std::ofstream out_stream (filename.c_str());
288 
289  out_stream << "clear all\n";
290  out_stream << "clf\n";
291  //out_stream << "x=linspace(" << min << "," << max << "," << n_bins+1 << ");\n";
292 
293  // abscissa values are located at the center of each bin.
294  out_stream << "x=[";
295  for (auto i : index_range(bin_members))
296  {
297  out_stream << min + (Real(i)+0.5)*bin_size << " ";
298  }
299  out_stream << "];\n";
300 
301  out_stream << "y=[";
302  for (auto bmi : bin_members)
303  {
304  out_stream << bmi << " ";
305  }
306  out_stream << "];\n";
307  out_stream << "bar(x,y);\n";
308  }
309 }
310 
311 
312 
313 template <typename T>
314 void StatisticsVector<T>::histogram(std::vector<dof_id_type> & bin_members,
315  unsigned int n_bins) const
316 {
317  StatisticsVector<T> sv = (*this);
318 
319  return sv.histogram(bin_members, n_bins);
320 }
321 
322 
323 
324 
325 template <typename T>
326 std::vector<dof_id_type> StatisticsVector<T>::cut_below(Real cut) const
327 {
328  LOG_SCOPE ("cut_below()", "StatisticsVector");
329 
330  const dof_id_type n = cast_int<dof_id_type>(this->size());
331 
332  std::vector<dof_id_type> cut_indices;
333  cut_indices.reserve(n/2); // Arbitrary
334 
335  for (dof_id_type i=0; i<n; i++)
336  {
337  if ((*this)[i] < cut)
338  {
339  cut_indices.push_back(i);
340  }
341  }
342 
343  return cut_indices;
344 }
345 
346 
347 
348 
349 template <typename T>
350 std::vector<dof_id_type> StatisticsVector<T>::cut_above(Real cut) const
351 {
352  LOG_SCOPE ("cut_above()", "StatisticsVector");
353 
354  const dof_id_type n = cast_int<dof_id_type>(this->size());
355 
356  std::vector<dof_id_type> cut_indices;
357  cut_indices.reserve(n/2); // Arbitrary
358 
359  for (dof_id_type i=0; i<n; i++)
360  if ((*this)[i] > cut)
361  cut_indices.push_back(i);
362 
363  return cut_indices;
364 }
365 
366 
367 
368 
369 //------------------------------------------------------------
370 // Explicit Instantiations
371 template class StatisticsVector<float>;
372 template class StatisticsVector<double>;
373 #ifdef LIBMESH_DEFAULT_TRIPLE_PRECISION
374 template class StatisticsVector<long double>;
375 #endif
376 #ifdef LIBMESH_DEFAULT_QUADRUPLE_PRECISION
377 template class StatisticsVector<Real>;
378 #endif
379 template class StatisticsVector<int>;
380 template class StatisticsVector<unsigned int>;
381 
382 } // namespace libMesh
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::StatisticsVector::l2_norm
virtual Real l2_norm() const
Definition: statistics.C:37
libMesh::StatisticsVector::cut_above
virtual std::vector< dof_id_type > cut_above(Real cut) const
Definition: statistics.C:350
libMesh::index_range
IntRange< std::size_t > index_range(const std::vector< T > &vec)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:106
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::StatisticsVector::plot_histogram
void plot_histogram(const processor_id_type my_procid, const std::string &filename, unsigned int n_bins)
Generates a Matlab/Octave style file which can be used to make a plot of the histogram having the des...
Definition: statistics.C:271
libMesh::StatisticsVector::variance
virtual Real variance() const
Definition: statistics.h:134
end
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end.
Definition: variant_filter_iterator.h:343
std::sqrt
MetaPhysicL::DualNumber< T, D > sqrt(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::StatisticsVector::mean
virtual Real mean() const
Definition: statistics.C:75
libMesh::StatisticsVector::histogram
virtual void histogram(std::vector< dof_id_type > &bin_members, unsigned int n_bins=10)
Definition: statistics.C:179
libMesh::StatisticsVector::cut_below
virtual std::vector< dof_id_type > cut_below(Real cut) const
Definition: statistics.C:326
libMesh::StatisticsVector::normalize
void normalize()
Divides all entries by the largest entry and stores the result.
Definition: statistics.C:165
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::StatisticsVector::median
virtual Real median()
Definition: statistics.C:96
libMesh::processor_id_type
uint8_t processor_id_type
Definition: id_types.h:104
libMesh::StatisticsVector::minimum
virtual T minimum() const
Definition: statistics.C:49
libMesh::StatisticsVector
The StatisticsVector class is derived from the std::vector<> and therefore has all of its useful feat...
Definition: statistics.h:67
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::out
OStreamProxy out
libMesh::StatisticsVector::maximum
virtual T maximum() const
Definition: statistics.C:62