statistics.C
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 // C++ includes 00020 #include <algorithm> // for std::min_element, std::max_element 00021 #include <fstream> // std::ofstream 00022 #include <numeric> // std::accumulate 00023 00024 // Local includes 00025 #include "libmesh/statistics.h" 00026 #include "libmesh/libmesh_logging.h" 00027 00028 namespace libMesh 00029 { 00030 00031 00032 00033 // ------------------------------------------------------------ 00034 // StatisticsVector class member functions 00035 template <typename T> 00036 Real StatisticsVector<T>::l2_norm() const 00037 { 00038 Real normsq = 0.; 00039 for (dof_id_type i = 0; i != this->size(); ++i) 00040 normsq += ((*this)[i] * (*this)[i]); 00041 00042 return std::sqrt(normsq); 00043 } 00044 00045 00046 template <typename T> 00047 T StatisticsVector<T>::minimum() const 00048 { 00049 START_LOG ("minimum()", "StatisticsVector"); 00050 00051 const T min = *(std::min_element(this->begin(), this->end())); 00052 00053 STOP_LOG ("minimum()", "StatisticsVector"); 00054 00055 return min; 00056 } 00057 00058 00059 00060 00061 template <typename T> 00062 T StatisticsVector<T>::maximum() const 00063 { 00064 START_LOG ("maximum()", "StatisticsVector"); 00065 00066 const T max = *(std::max_element(this->begin(), this->end())); 00067 00068 STOP_LOG ("maximum()", "StatisticsVector"); 00069 00070 return max; 00071 } 00072 00073 00074 00075 00076 template <typename T> 00077 Real StatisticsVector<T>::mean() const 00078 { 00079 START_LOG ("mean()", "StatisticsVector"); 00080 00081 const dof_id_type n = this->size(); 00082 00083 Real the_mean = 0; 00084 00085 for (dof_id_type i=0; i<n; i++) 00086 { 00087 the_mean += ( static_cast<Real>((*this)[i]) - the_mean ) / 00088 static_cast<Real>(i + 1); 00089 } 00090 00091 STOP_LOG ("mean()", "StatisticsVector"); 00092 00093 return the_mean; 00094 } 00095 00096 00097 00098 00099 template <typename T> 00100 Real StatisticsVector<T>::median() 00101 { 00102 const dof_id_type n = this->size(); 00103 00104 if (n == 0) 00105 return 0.; 00106 00107 START_LOG ("median()", "StatisticsVector"); 00108 00109 std::sort(this->begin(), this->end()); 00110 00111 const dof_id_type lhs = (n-1) / 2; 00112 const dof_id_type rhs = n / 2; 00113 00114 Real the_median = 0; 00115 00116 00117 if (lhs == rhs) 00118 { 00119 the_median = static_cast<Real>((*this)[lhs]); 00120 } 00121 00122 else 00123 { 00124 the_median = ( static_cast<Real>((*this)[lhs]) + 00125 static_cast<Real>((*this)[rhs]) ) / 2.0; 00126 } 00127 00128 STOP_LOG ("median()", "StatisticsVector"); 00129 00130 return the_median; 00131 } 00132 00133 00134 00135 00136 template <typename T> 00137 Real StatisticsVector<T>::median() const 00138 { 00139 StatisticsVector<T> sv = (*this); 00140 00141 return sv.median(); 00142 } 00143 00144 00145 00146 00147 template <typename T> 00148 Real StatisticsVector<T>::variance(const Real mean_in) const 00149 { 00150 const dof_id_type n = this->size(); 00151 00152 START_LOG ("variance()", "StatisticsVector"); 00153 00154 Real the_variance = 0; 00155 00156 for (dof_id_type i=0; i<n; i++) 00157 { 00158 const Real delta = ( static_cast<Real>((*this)[i]) - mean_in ); 00159 the_variance += (delta * delta - the_variance) / 00160 static_cast<Real>(i + 1); 00161 } 00162 00163 if (n > 1) 00164 the_variance *= static_cast<Real>(n) / static_cast<Real>(n - 1); 00165 00166 STOP_LOG ("variance()", "StatisticsVector"); 00167 00168 return the_variance; 00169 } 00170 00171 00172 template <typename T> 00173 void StatisticsVector<T>::normalize() 00174 { 00175 const dof_id_type n = this->size(); 00176 const Real max = this->maximum(); 00177 00178 for (dof_id_type i=0; i<n; i++) 00179 { 00180 (*this)[i] = static_cast<T>((*this)[i] / max); 00181 } 00182 } 00183 00184 00185 00186 00187 00188 template <typename T> 00189 void StatisticsVector<T>::histogram(std::vector<dof_id_type>& bin_members, 00190 unsigned int n_bins) 00191 { 00192 // Must have at least 1 bin 00193 libmesh_assert (n_bins>0); 00194 00195 const dof_id_type n = this->size(); 00196 00197 std::sort(this->begin(), this->end()); 00198 00199 // The StatisticsVector can hold both integer and float types. 00200 // We will define all the bins, etc. using Reals. 00201 Real min = static_cast<Real>(this->minimum()); 00202 Real max = static_cast<Real>(this->maximum()); 00203 Real bin_size = (max - min) / static_cast<Real>(n_bins); 00204 00205 START_LOG ("histogram()", "StatisticsVector"); 00206 00207 std::vector<Real> bin_bounds(n_bins+1); 00208 for (unsigned int i=0; i<bin_bounds.size(); i++) 00209 bin_bounds[i] = min + i * bin_size; 00210 00211 // Give the last bin boundary a little wiggle room: we don't want 00212 // it to be just barely less than the max, otherwise our bin test below 00213 // may fail. 00214 bin_bounds.back() += 1.e-6 * bin_size; 00215 00216 // This vector will store the number of members each bin has. 00217 bin_members.resize(n_bins); 00218 00219 dof_id_type data_index = 0; 00220 for (unsigned int j=0; j<bin_members.size(); j++) // bin vector indexing 00221 { 00222 // libMesh::out << "(debug) Filling bin " << j << std::endl; 00223 00224 for (dof_id_type i=data_index; i<n; i++) // data vector indexing 00225 { 00226 // libMesh::out << "(debug) Processing index=" << i << std::endl; 00227 Real current_val = static_cast<Real>( (*this)[i] ); 00228 00229 // There may be entries in the vector smaller than the value 00230 // reported by this->minimum(). (e.g. inactive elements in an 00231 // ErrorVector.) We just skip entries like that. 00232 if ( current_val < min ) 00233 { 00234 // libMesh::out << "(debug) Skipping entry v[" << i << "]=" 00235 // << (*this)[i] 00236 // << " which is less than the min value: min=" 00237 // << min << std::endl; 00238 continue; 00239 } 00240 00241 if ( current_val > bin_bounds[j+1] ) // if outside the current bin (bin[j] is bounded 00242 // by bin_bounds[j] and bin_bounds[j+1]) 00243 { 00244 // libMesh::out.precision(16); 00245 // libMesh::out.setf(std::ios_base::fixed); 00246 // libMesh::out << "(debug) (*this)[i]= " << (*this)[i] 00247 // << " is greater than bin_bounds[j+1]=" 00248 // << bin_bounds[j+1] << std::endl; 00249 data_index = i; // start searching here for next bin 00250 break; // go to next bin 00251 } 00252 00253 // Otherwise, increment current bin's count 00254 bin_members[j]++; 00255 // libMesh::out << "(debug) Binned index=" << i << std::endl; 00256 } 00257 } 00258 00259 #ifdef DEBUG 00260 // Check the number of binned entries 00261 const dof_id_type n_binned = std::accumulate(bin_members.begin(), 00262 bin_members.end(), 00263 static_cast<dof_id_type>(0), 00264 std::plus<dof_id_type>()); 00265 00266 if (n != n_binned) 00267 { 00268 libMesh::out << "Warning: The number of binned entries, n_binned=" 00269 << n_binned 00270 << ", did not match the total number of entries, n=" 00271 << n << "." << std::endl; 00272 //libmesh_error(); 00273 } 00274 #endif 00275 00276 00277 STOP_LOG ("histogram()", "StatisticsVector"); 00278 } 00279 00280 00281 00282 00283 00284 template <typename T> 00285 void StatisticsVector<T>::plot_histogram(const std::string& filename, 00286 unsigned int n_bins) 00287 { 00288 // First generate the histogram with the desired number of bins 00289 std::vector<dof_id_type> bin_members; 00290 this->histogram(bin_members, n_bins); 00291 00292 // The max, min and bin size are used to generate x-axis values. 00293 T min = this->minimum(); 00294 T max = this->maximum(); 00295 T bin_size = (max - min) / static_cast<T>(n_bins); 00296 00297 // On processor 0: Write histogram to file 00298 if (libMesh::processor_id()==0) 00299 { 00300 std::ofstream out_stream (filename.c_str()); 00301 00302 out_stream << "clear all\n"; 00303 out_stream << "clf\n"; 00304 //out_stream << "x=linspace(" << min << "," << max << "," << n_bins+1 << ");\n"; 00305 00306 // abscissa values are located at the center of each bin. 00307 out_stream << "x=["; 00308 for (unsigned int i=0; i<bin_members.size(); ++i) 00309 { 00310 out_stream << min + (i+0.5)*bin_size << " "; 00311 } 00312 out_stream << "];\n"; 00313 00314 out_stream << "y=["; 00315 for (unsigned int i=0; i<bin_members.size(); ++i) 00316 { 00317 out_stream << bin_members[i] << " "; 00318 } 00319 out_stream << "];\n"; 00320 out_stream << "bar(x,y);\n"; 00321 } 00322 } 00323 00324 00325 00326 template <typename T> 00327 void StatisticsVector<T>::histogram(std::vector<dof_id_type>& bin_members, 00328 unsigned int n_bins) const 00329 { 00330 StatisticsVector<T> sv = (*this); 00331 00332 return sv.histogram(bin_members, n_bins); 00333 } 00334 00335 00336 00337 00338 template <typename T> 00339 std::vector<dof_id_type> StatisticsVector<T>::cut_below(Real cut) const 00340 { 00341 START_LOG ("cut_below()", "StatisticsVector"); 00342 00343 const dof_id_type n = this->size(); 00344 00345 std::vector<dof_id_type> cut_indices; 00346 cut_indices.reserve(n/2); // Arbitrary 00347 00348 for (dof_id_type i=0; i<n; i++) 00349 { 00350 if ((*this)[i] < cut) 00351 { 00352 cut_indices.push_back(i); 00353 } 00354 } 00355 00356 STOP_LOG ("cut_below()", "StatisticsVector"); 00357 00358 return cut_indices; 00359 } 00360 00361 00362 00363 00364 template <typename T> 00365 std::vector<dof_id_type> StatisticsVector<T>::cut_above(Real cut) const 00366 { 00367 START_LOG ("cut_above()", "StatisticsVector"); 00368 00369 const dof_id_type n = this->size(); 00370 00371 std::vector<dof_id_type> cut_indices; 00372 cut_indices.reserve(n/2); // Arbitrary 00373 00374 for (dof_id_type i=0; i<n; i++) 00375 { 00376 if ((*this)[i] > cut) 00377 { 00378 cut_indices.push_back(i); 00379 } 00380 } 00381 00382 STOP_LOG ("cut_above()", "StatisticsVector"); 00383 00384 return cut_indices; 00385 } 00386 00387 00388 00389 00390 //------------------------------------------------------------ 00391 // Explicit Instantions 00392 template class StatisticsVector<float>; 00393 template class StatisticsVector<double>; 00394 #ifdef LIBMESH_DEFAULT_TRIPLE_PRECISION 00395 template class StatisticsVector<long double>; 00396 #endif 00397 template class StatisticsVector<int>; 00398 template class StatisticsVector<unsigned int>; 00399 00400 } // namespace libMesh
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:48 UTC
Hosted By: