Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 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 : 20 : #ifndef LIBMESH_STATISTICS_H 21 : #define LIBMESH_STATISTICS_H 22 : 23 : // Local includes 24 : #include "libmesh/libmesh_common.h" 25 : #include "libmesh/id_types.h" 26 : 27 : // C++ includes 28 : #include <vector> 29 : #include <cstdlib> // *must* precede <cmath> for proper std:abs() on PGI, Sun Studio CC 30 : #include <cmath> 31 : 32 : namespace libMesh 33 : { 34 : 35 : /** 36 : * The StatisticsVector class is derived from the std::vector<> and 37 : * therefore has all of its useful features. It was designed to not 38 : * have any internal state, i.e. no public or private data members. 39 : * Also, it was only designed for classes and types for which the 40 : * operators +,*,/ have meaning, specifically floats, doubles, ints, 41 : * etc. The main reason for this design decision was to allow a 42 : * std::vector<> to be successfully cast to a StatisticsVector, 43 : * thereby enabling its additional functionality. We do not 44 : * anticipate any problems with deriving from an stl container which 45 : * lacks a virtual destructor in this case. 46 : * 47 : * Where manipulation of the data set was necessary (for example 48 : * sorting) two versions of member functions have been implemented. 49 : * The non-const versions perform sorting directly in the data set, 50 : * invalidating pointers and changing the entries. const versions of 51 : * the same functions are generally available, and will be 52 : * automatically invoked on const StatisticsVector objects. A 53 : * draw-back to the const versions is that they simply make a copy of 54 : * the original object and therefore double the original memory 55 : * requirement for the data set. 56 : * 57 : * Most of the actual code was copied or adapted from the GNU 58 : * Scientific Library (GSL). More precisely, the recursion relations 59 : * for computing the mean were implemented in order to avoid possible 60 : * problems with buffer overruns. 61 : * 62 : * \author John W. Peterson 63 : * \date 2002 64 : * \brief A std::vector derived class for implementing simple statistical algorithms. 65 : */ 66 : template <typename T> 67 0 : class StatisticsVector : public std::vector<T> 68 : { 69 : public: 70 : 71 : /** 72 : * Call the std::vector constructor. 73 : */ 74 : explicit 75 56553 : StatisticsVector(dof_id_type i=0) : std::vector<T> (i) {} 76 : 77 : /** 78 : * Call the std::vector constructor, fill each entry with \p val. 79 : */ 80 0 : StatisticsVector(dof_id_type i, T val) : std::vector<T> (i,val) {} 81 : 82 : /** 83 : * Destructor. Virtual so we can derive from the \p StatisticsVector 84 : */ 85 29729 : virtual ~StatisticsVector () = default; 86 : 87 : 88 : /** 89 : * \returns The l2 norm of the data set. 90 : */ 91 : virtual Real l2_norm() const; 92 : 93 : /** 94 : * \returns The minimum value in the data set. 95 : */ 96 : virtual T minimum() const; 97 : 98 : /** 99 : * \returns The maximum value in the data set. 100 : */ 101 : virtual T maximum() const; 102 : 103 : /** 104 : * \returns The mean value of the data set using a recurrence 105 : * relation. 106 : * 107 : * Source: GNU Scientific Library 108 : */ 109 : virtual Real mean() const; 110 : 111 : /** 112 : * \returns The median (e.g. the middle) value of the data set. 113 : * 114 : * This function modifies the original data by sorting, so it can't 115 : * be called on const objects. Source: GNU Scientific Library. 116 : */ 117 : virtual Real median(); 118 : 119 : /** 120 : * A const version of the median function. Requires twice the memory 121 : * of original data set but does not change the original. 122 : */ 123 : virtual Real median() const; 124 : 125 : /** 126 : * \returns The variance of the data set. 127 : * 128 : * Uses a recurrence relation to prevent data overflow for large 129 : * sums. 130 : * 131 : * \note The variance is equal to the standard deviation squared. 132 : * Source: GNU Scientific Library. 133 : */ 134 0 : virtual Real variance() const 135 0 : { return this->variance(this->mean()); } 136 : 137 : /** 138 : * \returns The variance of the data set where the \p mean is 139 : * provided. 140 : * 141 : * This is useful for efficiency when you have already calculated 142 : * the mean. Uses a recurrence relation to prevent data overflow for 143 : * large sums. 144 : * 145 : * \note The variance is equal to the standard deviation squared. 146 : * Source: GNU Scientific Library. 147 : */ 148 : virtual Real variance(const Real known_mean) const; 149 : 150 : /** 151 : * \returns The standard deviation of the data set, which is simply 152 : * the square-root of the variance. 153 : */ 154 0 : virtual Real stddev() const 155 0 : { return std::sqrt(this->variance()); } 156 : 157 : /** 158 : * \returns Computes the standard deviation of the data set, which 159 : * is simply the square-root of the variance. 160 : * 161 : * This method can be used for efficiency when the \p mean has 162 : * already been computed. 163 : */ 164 0 : virtual Real stddev(const Real known_mean) const 165 0 : { return std::sqrt(this->variance(known_mean)); } 166 : 167 : /** 168 : * Divides all entries by the largest entry and stores the result. 169 : */ 170 : void normalize(); 171 : 172 : /** 173 : * \returns A histogram with n_bins bins for the data set. 174 : * 175 : * For simplicity, the bins are assumed to be of uniform size. Upon 176 : * return, the bin_members vector will contain unsigned integers 177 : * which give the number of members in each bin. WARNING: This 178 : * non-const function sorts the vector, changing its order. Source: 179 : * GNU Scientific Library. 180 : */ 181 : virtual void histogram (std::vector<dof_id_type> & bin_members, 182 : unsigned int n_bins=10); 183 : 184 : /** 185 : * Generates a Matlab/Octave style file which can be used to 186 : * make a plot of the histogram having the desired number of bins. 187 : * Uses the histogram(...) function in this class 188 : * WARNING: The histogram(...) function is non-const, and changes 189 : * the order of the vector. 190 : */ 191 : void plot_histogram(const processor_id_type my_procid, 192 : const std::string & filename, 193 : unsigned int n_bins); 194 : 195 : /** 196 : * A const version of the histogram function. 197 : */ 198 : virtual void histogram (std::vector<dof_id_type> & bin_members, 199 : unsigned int n_bins=10) const; 200 : 201 : /** 202 : * \returns A vector of dof_id_types which corresponds 203 : * to the indices of every member of the data set 204 : * below the cutoff value "cut". 205 : */ 206 : virtual std::vector<dof_id_type> cut_below(Real cut) const; 207 : 208 : /** 209 : * \returns A vector of dof_id_types which corresponds to the 210 : * indices of every member of the data set above the cutoff value 211 : * cut. 212 : * 213 : * I chose not to combine these two functions since the interface is 214 : * cleaner with one passed parameter instead of two. 215 : */ 216 : virtual std::vector<dof_id_type> cut_above(Real cut) const; 217 : }; 218 : 219 : } // namespace libMesh 220 : 221 : #endif // LIBMESH_STATISTICS_H