* thread-local.
* </ul>
*
- * <h3>LogStream and reproducible regression test output</h3>
- *
- * Generating reproducible floating point output for regression tests is
- * mildly put a nightmare. In order to make life a little easier, LogStream
- * implements a few features that try to achieve such a goal. These features
- * are turned on by calling test_mode(), and it is not recommended to use them
- * in any other environment. Right now, LogStream implements the following:
- *
- * <ol>
- * <li> A double number very close to zero will end up being output in
- * exponential format, although it has no significant digits. The parameter
- * #double_threshold determines which numbers are too close to zero to be
- * considered nonzero.
- * <li> For float numbers holds the same, but with a typically larger
- * #float_threshold.
- * <li> Rounded numbers become unreliable with inexact arithmetics. Therefore,
- * adding a small number before rounding makes results more reproducible,
- * assuming that numbers like 0.5 are more likely than 0.49997.
- * </ol>
- * It should be pointed out that all of these measures distort the output and
- * make it less accurate. Therefore, they are only recommended if the output
- * needs to be reproducible.
- *
* @ingroup textoutput
* @author Guido Kanschat, Wolfgang Bangerth, 1999, 2003, 2011
*/
void detach ();
- /**
- * Setup the logstream for regression test mode.
- *
- * This sets the parameters #double_threshold, #float_threshold, and #offset
- * to nonzero values. The default values being used have been determined
- * experimentally.
- *
- * Called with an argument <tt>false</tt>, switches off test mode and sets
- * all involved parameters to zero.
- */
- void test_mode (const bool on = true,
- const double double_threshold = 1.e-10,
- const float float_threshold = 1.e-7f,
- const double offset = 1.e-7);
-
-
/**
* Gives the default stream (<tt>std_out</tt>).
*/
bool log_thread_id (const bool flag);
- /**
- * Set a threshold for the minimal absolute value of double values. All
- * numbers with a smaller absolute value will be printed as zero.
- *
- * The default value for this threshold is zero, i.e. numbers are printed
- * according to their real value.
- *
- * This feature is mostly useful for automated tests: there, one would like
- * to reproduce the exact same solution in each run of a testsuite. However,
- * subtle difference in processor, operating system, or compiler version can
- * lead to differences in the last few digits of numbers, due to different
- * rounding. While one can avoid trouble for most numbers when comparing
- * with stored results by simply limiting the accuracy of output, this does
- * not hold for numbers very close to zero, i.e. zero plus accumulated
- * round-off. For these numbers, already the first digit is tainted by
- * round-off. Using the present function, it is possible to eliminate this
- * source of problems, by simply writing zero to the output in this case.
- */
- void threshold_double(const double t);
-
-
- /**
- * The same as threshold_double(), but for float values.
- */
- void threshold_float(const float t);
-
-
/**
* set the precision for the underlying stream and returns the previous
* stream precision. This function mimics
std::ios::fmtflags flags(const std::ios::fmtflags f);
- /**
- * Output double precision numbers through this stream.
- *
- * If they are set, this function applies the methods for making floating
- * point output reproducible as discussed in the introduction.
- */
- LogStream &operator << (const double t);
-
-
- /**
- * Output single precision numbers through this stream.
- *
- * If they are set, this function applies the methods for making floating
- * point output reproducible as discussed in the introduction.
- */
- LogStream &operator << (const float t);
-
-
/**
* Treat ostream manipulators. This passes on the whole thing to the
* template function with the exception of the <tt>std::endl</tt>
*/
double last_time;
- /**
- * Threshold for printing double values. Every number with absolute value
- * less than this is printed as zero.
- */
- double double_threshold;
-
- /**
- * Threshold for printing float values. Every number with absolute value
- * less than this is printed as zero.
- */
- float float_threshold;
-
- /**
- * An offset added to every float or double number upon output. This is done
- * after the number is compared to #double_threshold or #float_threshold,
- * but before rounding.
- *
- * This functionality was introduced to produce more reproducible floating
- * point output for regression tests. The rationale is, that an exact output
- * value is much more likely to be 1/8 than 0.124997. If we round to two
- * digits though, 1/8 becomes unreliably either .12 or .13 due to machine
- * accuracy. On the other hand, if we add a something above machine accuracy
- * first, we will always get .13.
- *
- * It is safe to leave this value equal to zero. For regression tests, the
- * function test_mode() sets it to a reasonable value.
- *
- * The offset is relative to the magnitude of the number.
- */
- double offset;
-
/**
* Flag for printing thread id.
*/
-
-inline
-LogStream &
-LogStream::operator<< (const double t)
-{
- std::ostringstream &stream = get_stream();
-
- // drop small numbers or skew them away from zero.
- // we have to make sure that we don't catch NaN's and +-Inf's with the
- // test, because for these denormals all comparisons are always false.
- if (! numbers::is_finite(t))
- stream << t;
- else if (std::fabs(t) < double_threshold)
- stream << '0';
- else
- stream << t*(1.+offset);
-
- return *this;
-}
-
-
-
-inline
-LogStream &
-LogStream::operator<< (const float t)
-{
- std::ostringstream &stream = get_stream();
-
- // we have to make sure that we don't catch NaN's and +-Inf's with the
- // test, because for these denormals all comparisons are always false.
- // thus, for a NaN, both t<=0 and t>=0 are false at the same time, which
- // can't be said for any other number
- if (! (t<=0) && !(t>=0))
- stream << t;
- else if (std::fabs(t) < float_threshold)
- stream << '0';
- else
- stream << t*(1.+offset);
-
- return *this;
-}
-
-
inline
LogStream::Prefix::Prefix(const std::string &text, LogStream &s)
: