Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

SgStatisticsVlt.h

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file SgStatisticsVlt.h
00003     Specialized versions of some classes in SgStatistics.h for volatile
00004     member variables. Previous versions of Fuego used instantiations like
00005     @c SgStatisticsBase<volatile double,volatile double>, but this has the
00006     effect that local variables in member functions and types in explicit
00007     conversions also use the volatile qualifier, and it caused a warning with
00008     Visual C++ (C4197: top-level volatile in cast is ignored). Unfortunately,
00009     the only way to avoid this is to create exact copies of the classes in
00010     SgStatistics with the only difference that the member variables are
00011     declared volatile. */
00012 //----------------------------------------------------------------------------
00013 
00014 #ifndef SG_STATISTICSVLT_H
00015 #define SG_STATISTICSVLT_H
00016 
00017 #include <cmath>
00018 #include <iostream>
00019 #include <limits>
00020 #include <map>
00021 #include <sstream>
00022 #include <string>
00023 #include <vector>
00024 #include "SgException.h"
00025 #include "SgWrite.h"
00026 
00027 //----------------------------------------------------------------------------
00028 
00029 /** Specialized version of SgStatisticsBase for volatile member variables.
00030     @see SgStatisticsVlt.h SgStatisticsBase */
00031 template<typename VALUE, typename COUNT>
00032 class SgStatisticsVltBase
00033 {
00034 public:
00035     SgStatisticsVltBase();
00036 
00037     /** Create statistics initialized with values.
00038         Note that value must be initialized to 0 if count is 0.
00039         Equivalent to creating a statistics and calling @c count times
00040         Add(val) */
00041     SgStatisticsVltBase(VALUE val, COUNT count);
00042 
00043     void Add(VALUE val);
00044 
00045     void Remove(VALUE val);
00046 
00047     /** Add a value n times */
00048     void Add(VALUE val, COUNT n);
00049 
00050     /** Remove a value n times. */
00051     void Remove(VALUE val, COUNT n);
00052 
00053     void Clear();
00054 
00055     COUNT Count() const;
00056 
00057     /** Initialize with values.
00058         Equivalent to calling Clear() and calling @c count times
00059         Add(val) */
00060     void Initialize(VALUE val, COUNT count);
00061 
00062     /** Check if the mean value is defined.
00063         The mean value is defined, if the count if greater than zero. The
00064         result of this function is equivalent to <tt>Count() > 0</tt>, for
00065         integer count types and <tt>Count() > epsilon()</tt> for floating
00066         point count types. */
00067     bool IsDefined() const;
00068 
00069     VALUE Mean() const;
00070 
00071     /** Write in human readable format. */
00072     void Write(std::ostream& out) const;
00073 
00074     /** Save in a compact platform-independent text format.
00075         The data is written in a single line, without trailing newline. */
00076     void SaveAsText(std::ostream& out) const;
00077 
00078     /** Load from text format.
00079         See SaveAsText() */
00080     void LoadFromText(std::istream& in);
00081 
00082 private:
00083     volatile COUNT m_count;
00084 
00085     volatile VALUE m_mean;
00086 };
00087 
00088 template<typename VALUE, typename COUNT>
00089 inline SgStatisticsVltBase<VALUE,COUNT>::SgStatisticsVltBase()
00090 {
00091     Clear();
00092 }
00093 
00094 template<typename VALUE, typename COUNT>
00095 inline SgStatisticsVltBase<VALUE,COUNT>::SgStatisticsVltBase(VALUE val, COUNT count)
00096     : m_count(count),
00097       m_mean(val)
00098 {
00099 }
00100 
00101 template<typename VALUE, typename COUNT>
00102 void SgStatisticsVltBase<VALUE,COUNT>::Add(VALUE val)
00103 {
00104     // Write order dependency: at least one class (SgUctSearch in lock-free
00105     // mode) uses SgStatisticsVltBase concurrently without locking and assumes
00106     // that m_mean is valid, if m_count is greater zero
00107     COUNT count = m_count;
00108     ++count;
00109     SG_ASSERT(! std::numeric_limits<COUNT>::is_exact
00110               || count > 0); // overflow
00111     val -= m_mean;
00112     m_mean +=  val / VALUE(count);
00113     m_count = count;
00114 }
00115 
00116 template<typename VALUE, typename COUNT>
00117 void SgStatisticsVltBase<VALUE,COUNT>::Remove(VALUE val)
00118 {
00119     // Write order dependency: at least on class (SgUctSearch in lock-free
00120     // mode) uses SgStatisticsVltBase concurrently without locking and assumes
00121     // that m_mean is valid, if m_count is greater zero
00122     COUNT count = m_count;
00123     if (count > 1) 
00124     {
00125         --count;
00126         m_mean += (m_mean - val) / VALUE(count);
00127         m_count = count;
00128     }
00129     else
00130         Clear();
00131 }
00132 
00133 template<typename VALUE, typename COUNT>
00134 void SgStatisticsVltBase<VALUE,COUNT>::Remove(VALUE val, COUNT n)
00135 {
00136     // Write order dependency: at least on class (SgUctSearch in lock-free
00137     // mode) uses SgStatisticsVltBase concurrently without locking and assumes
00138     // that m_mean is valid, if m_count is greater zero
00139     COUNT count = m_count;
00140     if (count > n) 
00141     {
00142         count -= n;
00143         m_mean += VALUE(n) * (m_mean - val) / VALUE(count);
00144         m_count = count;
00145     }
00146     else
00147         Clear();
00148 }
00149 
00150 template<typename VALUE, typename COUNT>
00151 void SgStatisticsVltBase<VALUE,COUNT>::Add(VALUE val, COUNT n)
00152 {
00153     // Write order dependency: at least one class (SgUctSearch in lock-free
00154     // mode) uses SgStatisticsVltBase concurrently without locking and assumes
00155     // that m_mean is valid, if m_count is greater zero
00156     COUNT count = m_count;
00157     count += n;
00158     SG_ASSERT(! std::numeric_limits<COUNT>::is_exact
00159               || count > 0); // overflow
00160     val -= m_mean;
00161     m_mean +=  VALUE(n) * val / VALUE(count);
00162     m_count = count;
00163 }
00164 
00165 template<typename VALUE, typename COUNT>
00166 inline void SgStatisticsVltBase<VALUE,COUNT>::Clear()
00167 {
00168     m_count = 0;
00169     m_mean = 0;
00170 }
00171 
00172 template<typename VALUE, typename COUNT>
00173 inline COUNT SgStatisticsVltBase<VALUE,COUNT>::Count() const
00174 {
00175     return m_count;
00176 }
00177 
00178 template<typename VALUE, typename COUNT>
00179 inline void SgStatisticsVltBase<VALUE,COUNT>::Initialize(VALUE val, COUNT count)
00180 {
00181     SG_ASSERT(count > 0);
00182     m_count = count;
00183     m_mean = val;
00184 }
00185 
00186 template<typename VALUE, typename COUNT>
00187 inline bool SgStatisticsVltBase<VALUE,COUNT>::IsDefined() const
00188 {
00189     if (std::numeric_limits<COUNT>::is_exact)
00190         return m_count > 0;
00191     else
00192         return m_count > std::numeric_limits<COUNT>::epsilon();
00193 }
00194 
00195 template<typename VALUE, typename COUNT>
00196 void SgStatisticsVltBase<VALUE,COUNT>::LoadFromText(std::istream& in)
00197 {
00198     in >> m_count >> m_mean;
00199 }
00200 
00201 template<typename VALUE, typename COUNT>
00202 inline VALUE SgStatisticsVltBase<VALUE,COUNT>::Mean() const
00203 {
00204     SG_ASSERT(IsDefined());
00205     return m_mean;
00206 }
00207 
00208 template<typename VALUE, typename COUNT>
00209 void SgStatisticsVltBase<VALUE,COUNT>::Write(std::ostream& out) const
00210 {
00211     if (IsDefined())
00212         out << Mean();
00213     else
00214         out << '-';
00215 }
00216 
00217 template<typename VALUE, typename COUNT>
00218 void SgStatisticsVltBase<VALUE,COUNT>::SaveAsText(std::ostream& out) const
00219 {
00220     out << m_count << ' ' << m_mean;
00221 }
00222 
00223 //----------------------------------------------------------------------------
00224 
00225 #endif // SG_STATISTICSVLT_H


Sun Mar 13 2011 Doxygen 1.7.1