Anasazi Version of the Day
Tsqr_TimeStats.cpp
00001 #include <Tsqr_TimeStats.hpp>
00002 #include <Tsqr_MessengerBase.hpp>
00003 #include <limits>
00004 
00007 
00008 namespace TSQR {
00009 
00010   TimeStats::TimeStats() { init(); }
00011 
00012   void
00013   TimeStats::init () {
00014     min_ = std::numeric_limits< double >::infinity();
00015     max_ = -std::numeric_limits< double >::infinity();
00016     mean_ = double (0);
00017     total_ = double (0);
00018     count_ = int (0);
00019   }
00020 
00021   void
00022   TimeStats::update (const double curTime) {
00023     total_ += curTime;
00024     count_++;
00025 
00026     if (curTime < min_)
00027       min_ = curTime;
00028     if (curTime > max_)
00029       max_ = curTime;
00030 
00031     // Mean(1:n) = ((n-1) / n) * Mean(1:n-1) + x(n) / n.
00032     //
00033     // Casting int to double is exact.
00034     const double scale = double(count_ - 1) / double(count_);
00035     mean_ = scale * mean_ + curTime / double(count_);
00036   }
00037 
00038   void
00039   TimeStats::print (std::ostream& out, 
00040         const bool humanReadable,
00041         const std::string& label,
00042         const std::string& labelLabel,
00043         const bool printHeaders) const
00044   {
00045     using std::endl;
00046 
00047     if (humanReadable)
00048       {
00049   const char prefix[] = "-- ";
00050   out << label << ":" << endl;
00051   if (count() == 0)
00052     out << prefix << "No values collected" << endl;
00053   else if (count() == 1)
00054     out << prefix << "One value collected: " << min() << endl;
00055   else
00056     {
00057       out << prefix << "Count: " << count() << endl
00058     << prefix << "Min:   " << min() << endl
00059     << prefix << "Mean:  " << mean() << endl
00060     << prefix << "Max:   " << max() << endl
00061     << prefix << "Total: " << total() << endl;
00062     }
00063       }
00064     else
00065       {
00066   // "%" identifies this line as a "comment" line to filter out.
00067   // First print field labels on one line, then print field
00068   // values on the next line.
00069   if (printHeaders)
00070     {
00071       out << "%" << labelLabel
00072     << "," << "count"
00073     << "," << "min"
00074     << "," << "mean"
00075     << "," << "max"
00076     << "," << "total" 
00077     << endl;
00078     }
00079   out << label
00080       << "," << count() 
00081       << "," << min() 
00082       << "," << mean()
00083       << "," << max()
00084       << "," << total()
00085       << endl;
00086       }
00087   }
00088 
00089   TimeStats
00090   TimeStats::globalTimeStats (MessengerBase< double >* const comm,
00091             const TimeStats& localStats)
00092   {
00093     TimeStats globalStats;
00094 
00095     // Casting int to double is exact.
00096     const double localCount = static_cast<double> (localStats.count());
00097     const double minCount = comm->globalMin (localCount);
00098     const double maxCount = comm->globalMax (localCount);
00099     if (minCount != maxCount)
00100       throw std::logic_error ("Global stats don\'t make sense, because counts differ");
00101     globalStats.count_ = localStats.count();
00102       
00103     // Casting int to double is exact.
00104     const double P = static_cast<double> (comm->size());
00105     globalStats.mean_ = comm->globalSum (localStats.mean() / P);
00106 
00107     globalStats.min_ = comm->globalMin (localStats.min());
00108     globalStats.max_ = comm->globalMax (localStats.max());
00109     // Note that this is not the sum of the totals of all the
00110     // processes, but rather the "global total."  I've chosen to
00111     // define that as the max of the totals.
00112     globalStats.total_ = comm->globalMax (localStats.total());
00113 
00114     return globalStats;
00115   }
00116 
00117 
00118 } // namespace TSQR
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends