// The libMesh Finite Element Library. // Copyright (C) 2002-2020 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // C++ includes #include // for std::min_element, std::max_element #include // std::ofstream #include // std::accumulate // Local includes #include "libmesh/statistics.h" #include "libmesh/int_range.h" #include "libmesh/libmesh_logging.h" namespace libMesh { // ------------------------------------------------------------ // StatisticsVector class member functions template Real StatisticsVector::l2_norm() const { Real normsq = 0.; const dof_id_type n = cast_int(this->size()); for (dof_id_type i = 0; i != n; ++i) normsq += ((*this)[i] * (*this)[i]); return std::sqrt(normsq); } template T StatisticsVector::minimum() const { LOG_SCOPE ("minimum()", "StatisticsVector"); const T min = *(std::min_element(this->begin(), this->end())); return min; } template T StatisticsVector::maximum() const { LOG_SCOPE ("maximum()", "StatisticsVector"); const T max = *(std::max_element(this->begin(), this->end())); return max; } template Real StatisticsVector::mean() const { LOG_SCOPE ("mean()", "StatisticsVector"); const dof_id_type n = cast_int(this->size()); Real the_mean = 0; for (dof_id_type i=0; i((*this)[i]) - the_mean ) / static_cast(i + 1); } return the_mean; } template Real StatisticsVector::median() { const dof_id_type n = cast_int(this->size()); if (n == 0) return 0.; LOG_SCOPE ("median()", "StatisticsVector"); std::sort(this->begin(), this->end()); const dof_id_type lhs = (n-1) / 2; const dof_id_type rhs = n / 2; Real the_median = 0; if (lhs == rhs) { the_median = static_cast((*this)[lhs]); } else { the_median = ( static_cast((*this)[lhs]) + static_cast((*this)[rhs]) ) / 2.0; } return the_median; } template Real StatisticsVector::median() const { StatisticsVector sv = (*this); return sv.median(); } template Real StatisticsVector::variance(const Real mean_in) const { const dof_id_type n = cast_int(this->size()); LOG_SCOPE ("variance()", "StatisticsVector"); Real the_variance = 0; for (dof_id_type i=0; i((*this)[i]) - mean_in ); the_variance += (delta * delta - the_variance) / static_cast(i + 1); } if (n > 1) the_variance *= static_cast(n) / static_cast(n - 1); return the_variance; } template void StatisticsVector::normalize() { const dof_id_type n = cast_int(this->size()); const Real max = this->maximum(); for (dof_id_type i=0; i((*this)[i] / max); } template void StatisticsVector::histogram(std::vector & bin_members, unsigned int n_bins) { // Must have at least 1 bin libmesh_assert (n_bins>0); const dof_id_type n = cast_int(this->size()); std::sort(this->begin(), this->end()); // The StatisticsVector can hold both integer and float types. // We will define all the bins, etc. using Reals. Real min = static_cast(this->minimum()); Real max = static_cast(this->maximum()); Real bin_size = (max - min) / static_cast(n_bins); LOG_SCOPE ("histogram()", "StatisticsVector"); std::vector bin_bounds(n_bins+1); for (auto i : index_range(bin_bounds)) bin_bounds[i] = min + Real(i) * bin_size; // Give the last bin boundary a little wiggle room: we don't want // it to be just barely less than the max, otherwise our bin test below // may fail. bin_bounds.back() += 1.e-6 * bin_size; // This vector will store the number of members each bin has. bin_members.resize(n_bins); dof_id_type data_index = 0; for (auto j : index_range(bin_members)) // bin vector indexing { // libMesh::out << "(debug) Filling bin " << j << std::endl; for (dof_id_type i=data_index; i void StatisticsVector::plot_histogram(const processor_id_type my_procid, const std::string & filename, unsigned int n_bins) { // First generate the histogram with the desired number of bins std::vector bin_members; this->histogram(bin_members, n_bins); // The max, min and bin size are used to generate x-axis values. T min = this->minimum(); T max = this->maximum(); T bin_size = (max - min) / static_cast(n_bins); // On processor 0: Write histogram to file if (my_procid==0) { std::ofstream out_stream (filename.c_str()); out_stream << "clear all\n"; out_stream << "clf\n"; //out_stream << "x=linspace(" << min << "," << max << "," << n_bins+1 << ");\n"; // abscissa values are located at the center of each bin. out_stream << "x=["; for (auto i : index_range(bin_members)) { out_stream << min + (Real(i)+0.5)*bin_size << " "; } out_stream << "];\n"; out_stream << "y=["; for (auto bmi : bin_members) { out_stream << bmi << " "; } out_stream << "];\n"; out_stream << "bar(x,y);\n"; } } template void StatisticsVector::histogram(std::vector & bin_members, unsigned int n_bins) const { StatisticsVector sv = (*this); return sv.histogram(bin_members, n_bins); } template std::vector StatisticsVector::cut_below(Real cut) const { LOG_SCOPE ("cut_below()", "StatisticsVector"); const dof_id_type n = cast_int(this->size()); std::vector cut_indices; cut_indices.reserve(n/2); // Arbitrary for (dof_id_type i=0; i std::vector StatisticsVector::cut_above(Real cut) const { LOG_SCOPE ("cut_above()", "StatisticsVector"); const dof_id_type n = cast_int(this->size()); std::vector cut_indices; cut_indices.reserve(n/2); // Arbitrary for (dof_id_type i=0; i cut) cut_indices.push_back(i); return cut_indices; } //------------------------------------------------------------ // Explicit Instantiations template class StatisticsVector; template class StatisticsVector; #ifdef LIBMESH_DEFAULT_TRIPLE_PRECISION template class StatisticsVector; #endif #ifdef LIBMESH_DEFAULT_QUADRUPLE_PRECISION template class StatisticsVector; #endif template class StatisticsVector; template class StatisticsVector; } // namespace libMesh