$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r80870 - in sandbox/SOC/2007/quan: . boost boost/quan boost/quan/impl libs libs/quan libs/quan/doc libs/quan/doc/doxygen libs/quan/example libs/quan/example/quan_simple libs/quan/test
From: pbristow_at_[hidden]
Date: 2012-10-05 10:48:19
Author: pbristow
Date: 2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
New Revision: 80870
URL: http://svn.boost.org/trac/boost/changeset/80870
Log:
New quan package for type unc encoding uncertainty requires by visualization SVG_plot package.
Added:
   sandbox/SOC/2007/quan/
   sandbox/SOC/2007/quan/boost/
   sandbox/SOC/2007/quan/boost/quan/
   sandbox/SOC/2007/quan/boost/quan/impl/
   sandbox/SOC/2007/quan/boost/quan/impl/meas.ipp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/impl/unc.ipp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/impl/unc_input.ipp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/impl/unc_output.ipp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/impl/xiostream.ipp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/meas.hpp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/meas2.hpp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/pair_io.hpp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/rounding.hpp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/si_units.hpp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/type_erasure_printer.hpp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/unc.hpp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/unc_init.hpp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/uncbools.hpp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/uncdata.hpp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/uncs.hpp   (contents, props changed)
   sandbox/SOC/2007/quan/boost/quan/xiostream.hpp   (contents, props changed)
   sandbox/SOC/2007/quan/libs/
   sandbox/SOC/2007/quan/libs/quan/
   sandbox/SOC/2007/quan/libs/quan/doc/
   sandbox/SOC/2007/quan/libs/quan/doc/doxygen/
   sandbox/SOC/2007/quan/libs/quan/doc/doxygen/draft.png   (contents, props changed)
   sandbox/SOC/2007/quan/libs/quan/doc/doxygen/draft.svg   (contents, props changed)
   sandbox/SOC/2007/quan/libs/quan/doc/doxygen/important.png   (contents, props changed)
   sandbox/SOC/2007/quan/libs/quan/doc/doxygen/proposed_for_boost.png   (contents, props changed)
   sandbox/SOC/2007/quan/libs/quan/doc/doxygen/quan_doxyfile.txt   (contents, props changed)
   sandbox/SOC/2007/quan/libs/quan/doc/doxygen/quan_doxygen.css   (contents, props changed)
   sandbox/SOC/2007/quan/libs/quan/doc/doxygen/quan_doxygen_footer.html   (contents, props changed)
   sandbox/SOC/2007/quan/libs/quan/doc/doxygen/quan_doxygen_header.html   (contents, props changed)
   sandbox/SOC/2007/quan/libs/quan/example/
   sandbox/SOC/2007/quan/libs/quan/example/quan_simple/
   sandbox/SOC/2007/quan/libs/quan/example/quan_simple/quan_simple.cpp   (contents, props changed)
   sandbox/SOC/2007/quan/libs/quan/test/
   sandbox/SOC/2007/quan/libs/quan/test/Quan1In.txt   (contents, props changed)
   sandbox/SOC/2007/quan/libs/quan/test/TestQuan1.cpp   (contents, props changed)
   sandbox/SOC/2007/quan/libs/quan/test/test_rounding.cpp   (contents, props changed)
   sandbox/SOC/2007/quan/libs/quan/test/unc_tests.cpp   (contents, props changed)
Added: sandbox/SOC/2007/quan/boost/quan/impl/meas.ipp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/impl/meas.ipp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,485 @@
+/*! \file 
+   \brief Class for measurement using uncertain class - definitions.
+   \details class meas with UReal and measurement ID, order & time.
+*/
+
+// meas.ipp 
+// Copyright Paul A. Bristow 2003, 2012
+
+#ifndef MEAS_IPP
+#define MEAS_IPP
+
+#ifdef _MSC_VER
+#  pragma warning (push)
+#pragma warning (disable : 4189) // local variable is initialized but not referenced TODO!
+#  pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
+#  pragma warning (disable : 4305) //C4305: 'initializing' : truncation from 'unsigned int' to 'short'.
+#  pragma warning (disable : 4309) // C4309: 'initializing' : truncation of constant value.
+#endif
+
+#include <boost/date_time/gregorian/gregorian.hpp> //include all types plus i/o
+#include <boost/date_time/posix_time/posix_time.hpp> //include all types plus i/o
+
+//using namespace boost::gregorian;
+//using namespace boost::posix_time;
+
+#include <iostream>
+#include <cmath> // for fabs
+#include <functional> // for binary_function min
+
+#include <boost/quan/unc.hpp> // Declarations of class unc.
+#include <boost/quan/meas.hpp>  // Declarations of class Meas, which calls this file.
+
+class Meas;  // Measured uncertain value AND its id and order and/or time-date stamp.
+
+//using std::cout;
+//using std::cerr;
+//using std::endl;
+//using std::istream;
+//using std::ostream;
+//using std::min;
+//using std::binary_function; // <functional>
+
+// Global control of format output by class Meas.
+
+//const char timeFormatString[] =	"%H:%M:%S"; // 12:20:55 time HH:MM:SS == "%X"
+  // "%H:%M"; // time as 12:26 HH:MM only, no seconds.
+  // "%X"; // 12:20:55 time HH:MM:SS
+  // "%d %b %y %H:%M:%S"; // 20 Apr 01 12:16:17
+  // "%d %b %y %H:%M"; // 20 Apr 01 12:16 // no seconds.
+  // "%a %b %d %m %Y %H:%M:%S %p"; // Fri Apr 20 04 2001 12:18:48 PM
+  // "%x"; // 04/20/01  US style MM/DD/YY.
+  // "%d %b %y"; //  date as 20 Apr 01
+  // "%H:%M"; // time as 12:26 HH:MM only, no seconds.
+
+typedef double real_type;  // or
+// typedef float real_type; 
+
+// class Meas definitions
+// Measured value, id and its order and/or time-date.
+
+std::ostream& operator<< (std::ostream& os, const unc<false>& ud);
+// Need to instantiate for UReal<false> (might need for UReal<true> too).
+
+/*
+Meas::Meas()
+{ // Default constructor Usage: Meas z; (not Meas z()!) is exact zero.
+  value_ = 0.;
+  uncertainty_ = 0.F;
+  degFree_ = 0;
+  unctypes_ =  UNC_KNOWN | UNC_EXPLICIT| DEG_FREE_EXACT | DEG_FREE_KNOWN;
+  time_ = ptime(not_a_date_time);  // Time not known, and cannot be calculated from order.
+  order_ = -1;  // Order not known, and cannot be calculated from time.
+  id_ = "";
+} // Meas::Meas()
+*/
+
+Meas::Meas(double d)
+{ // Constructor from double - needed by Meas(0.) lessAbs.
+  value_ = d;
+  uncertainty_ = 0.F;
+  degFree_ = 0;
+  unctypes_ =  UNC_KNOWN | UNC_EXPLICIT| DEG_FREE_EXACT | DEG_FREE_KNOWN;
+  time_ = boost::gregorian::not_a_date_time;  // Time not known, and cannot be calculated from order.
+  order_ = -1;  // Order not known, and cannot be calculated from time.
+  id_ = "";
+#ifdef CD_TRACE
+    cerr << "Construct Meas from just double value " << value_ << "." << endl;
+#endif
+}
+/*
+Meas::Meas(uncun u)
+{ // Constructor from uncertain.
+  value_ = u.value_;
+  uncertainty_ = u.uncertainty_;
+  degFree_ = u.degFree_;
+  unctypes_ =  u.unctypes_;
+  time_ = not_a_date_time;  // Time not known, and cannot be calculated from order.
+  order_ = -1;  // Order not known, and cannot be calculated from time.
+  id_ = "";
+#ifdef CD_TRACE
+  {
+    cerr << "Construct Meas from uncertain uncun " << value_ << "." << endl;
+  }
+#endif
+}
+
+Meas::Meas(uncun u, string id, ptime ti)
+:   id_(id), time_(ti)
+{ // Constructor value, id & time (but NOT order) with default values.
+  order_ = -1; // order not known.
+  // (but may be calculated from time if in a sequence).
+  value_ = u.value_;
+  degFree_ =u.degFree_;
+  unctypes_ =u.unctypes_;
+  uncertainty_ = u.uncertainty_;
+#ifdef CD_TRACE
+  {
+   cerr << "Construct Meas using known time " << time_ << "." << endl;
+  }
+#endif
+}
+*/
+
+Meas::Meas(uncun u, string id, boost::posix_time::ptime ti /* = (boost::gregorian_time::not_a_date_time)*/, int order)
+:   id_(id), time_(ti), order_(order)
+{ // Constructor value, id & order (but NOT time) with default values.
+  time_ = ti; // time not known, & cannot be calculated from order.
+  value_ = u.value_;
+  degFree_ =u.degFree_;
+  unctypes_ =u.unctypes_;
+  uncertainty_ = u.uncertainty_;
+#ifdef CD_TRACE
+  cerr << "Construct Meas using time AND known order " << time_ << ", " << order_ << "." << endl;
+#endif
+}
+
+/*
+Meas::Meas(uncun u, string id, int o)
+:   id_(id), order_(o)
+{ // Constructor value, id & order (but NOT time) with default values.
+  time_ = boost::posix_time::not_a_date_time; // time not known, & cannot be calculated from order.
+  value_ = u.value_;
+  degFree_ =u.degFree_;
+  unctypes_ =u.unctypes_;
+  uncertainty_ = u.uncertainty_;
+  if(cdtrace)
+  {
+    cerr << "Construct Meas using known order " << time_ << "." << endl;
+  }
+}
+*/
+
+Meas::Meas(const Meas& rhs)  
+{ // Copy constructor.
+  value_ = rhs.value_; 
+  uncertainty_ = rhs.uncertainty_;
+  degFree_ = rhs.degFree_;
+  unctypes_ = rhs.unctypes_;
+  id_ = rhs.id_;
+  order_ = rhs.order_;
+  time_ = rhs.time_;
+  id_ = rhs.id_;
+}
+
+Meas::~Meas()
+{  // Default destructor used.
+}
+
+// Operators.
+
+// Meas& operator= (Meas&);  // Assignment operator.
+Meas& Meas::operator= (const Meas& rhs)  // Assignment operator.
+{ // Deep copy.
+  if (this == &rhs) return *this;  // Assign to self, so do nothing.
+  value_ = rhs.value_;
+  uncertainty_ = rhs.uncertainty_;
+  degFree_ = rhs.degFree_;
+  unctypes_ = rhs.unctypes_;
+  order_ = rhs.order_;
+  time_ = rhs.time_; 
+  id_ = rhs.id_;
+  return *this;
+}
+
+// Meas& abs (Meas&);  // abs Assignment operator.
+Meas& Meas::abs(const Meas& rhs)  // abs Assignment operator.
+{ 
+  value_ = fabs(rhs.value_);
+  uncertainty_ = rhs.uncertainty_;
+  degFree_ = rhs.degFree_;
+  unctypes_ = rhs.unctypes_;
+  order_ = rhs.order_;
+  time_ = rhs.time_;
+  id_ = rhs.id_;
+  return *this;
+}
+
+// Meas& abs (Meas&);  // abs operator.
+Meas& Meas::abs(Meas& rhs)  // abs Assignment operator.
+{ 
+  double d = rhs.value_;
+  //rhs.value_ = abs(d); // Not OK for reasons unclear  - trying to use std::abs?
+  rhs.value_ = fabs(rhs.value_); // OK
+ return rhs;
+}
+
+bool Meas::operator== (const Meas& p) const
+{ // Exact Meas value Equality Comparison.
+  return (p.value_ == value_);
+  // What about checking if time the same too?
+} // Meas::operator==
+
+bool Meas::operator!= (const Meas& p) const
+{ // Comparison.
+  return (p.value_ != value_);  // meas value differ (order  && (p.order_ != order_).
+}  // Meas::operator!=
+
+bool Meas::operator< (const Meas& rhs) const 
+{// less uses operator< the most probable central value.
+  // member function so  *this.value_ < *this.rhs.value_;
+  return (value_ < rhs.value_);  // Comparison criterion.
+    // Only uses the measured value, not order.
+} //  Meas::operator< 
+
+bool Meas::operator> (const Meas& rhs) const 
+{// greater uses operator> using the most probable value.
+  // member function so  *this.value_ < rhs.value_;
+  return (value_ > rhs.value_);
+    // Comparison only uses the measured value (not order, nor time).
+} // Meas::operator>
+
+/*
+// What is meaning of adding measurements? 
+// Has no meaning - can only add the values and uncertainty to get a new uncertain.
+// And time and order number can't be added, so
+// doubtful if operator+ and operator- are wise for Meas.
+bool Meas::operator- (const Meas& rhs) const 
+{// Binary minus value using the most probable values.
+  // member function so  *this.value_ < rhs.value_;
+  return value_ - rhs.value_; <<<  wrong here <<<<<<<<<<<<
+  // Only uses the measured value (not order, nor time).
+} // Meas::operator>
+
+
+*/
+
+// Member predicate functions.
+
+// less uses template binary_function and operator<
+    /*
+    // TEMPLATE STRUCT less in functional
+template<class _Ty>
+  struct less
+    : public binary_function<_Ty, _Ty, bool>
+  {	// functor for operator<
+  bool operator()(const _Ty& _Left, const _Ty& _Right) const
+    {	// apply operator< to operands
+    return (_Left < _Right);
+    }
+  };
+  // So this function is the same as less<Meas> and so not needed.
+  bool Meas::lessM(const Meas& l, const Meas& r) // == less
+  {	// Only uses the central measured value (not order, nor time).
+    return l.value_ < r.value_; // Comparison criterion.
+  }
+  // similarly nor is greater needed.
+  */
+
+bool Meas::lessAbsM(const Meas& l, const Meas& r)
+{	// Only uses the absolute central measured value, not order.
+  return ((l.value_ < 0.) ? -l.value_ : l.value_ ) < ((r.value_ < 0.) ? -r.value_ : r.value_);
+  //	return std::abs(l.value_) < std::abs(r.value_);  // Comparison criterion.
+  // but avoid abs because less efficient.
+} // bool Meas::lessAbsM(const Meas& l, const Meas& r)
+
+bool Meas::precedes(const Meas& l, const Meas& r) 
+{ // Comparison criterion is order of measurement.
+  return l.order_ < r.order_;
+}
+
+/*  Do we need this?
+bool Meas::succeeds(const Meas& l, const Meas& r) 
+{ // Comparison criterion is order of measurement.
+  return l.order_ > r.order_;
+}
+*/
+
+// Call this "before"?
+bool Meas::earlier(const Meas& l, const Meas& r) 
+{ // Comparison criterion is time of measurement.
+  // (Opposite, like greater, might be called 'later' - if needed).
+  if (l.time_ == boost::posix_time::not_a_date_time) return true; // not_a_date_time < any other time.
+  if (r.time_ == boost::posix_time::not_a_date_time) return false; // l.time_ IS a time, so r.time_ NOT <
+  return l.time_ < r.time_;
+} // bool Meas::earlier(const Meas& l, const Meas& r);
+
+bool Meas::less(const Meas& l, const Meas& r) 
+{ // less using only value comparison.
+  // Note if lhi == rlo same then difference is 1.49012e-9 = numeric_limits<float>::epsilon
+  // (See also Meas::lessU and Meas::lessU2 which handle one and two standard deviations).
+
+  return l.value_ < r.value_;
+} // bool Meas::lessU(const Meas& l, const Meas& r)
+
+bool Meas::lessU(const Meas& l, const Meas& r) 
+{ // less using comparison criterion including ONE standard deviation.
+  // Note if lhi == rlo then difference is 1.49012e-9 = numeric_limits<float>::epsilon
+  // (See also Meas::lessU2 which compares using TWO standard deviations).
+  double lhi = (l.value_ + l.uncertainty_);  // Upper confidence limit of left.
+  double rlo = (r.value_ - r.uncertainty_);	// Lower confidence limit of right.
+  //	double diff = (l.value_ + l.uncertainty_) - (r.value_ - r.uncertainty_);
+  // diff = lhi - rlo;
+  //	double tol = hypot(l.uncertainty_, r.uncertainty_); // Middle of two uncertainties.
+  bool isLess =  lhi < (rlo + hypot(l.uncertainty_, r.uncertainty_)); // == less
+  if (true)
+  { // Output diagnostic info.
+    std::cerr << "<U #" << l.order_ << space << l.value_ << "="
+    << lhi // (l.value_ + l.uncertainty_)
+    << space << ((isLess) ? " < " : " !< ")
+    // << (r.value_ - r.uncertainty_) == rlo
+    << space << rlo << space << rlo + hypot(l.uncertainty_, r.uncertainty_) // tol
+    << " #" << r.order_ << "=" << r.value_ 
+  //	<< space << tol 
+  //	<< space << diff 
+  // For example: <U #1 1.1 1.2  !<  1.05 1.19142 #2 1.15
+    << std::endl;
+  }
+  return isLess;
+} // bool Meas::lessU(const Meas& l, const Meas& r)
+
+bool Meas::less2U(const Meas& l, const Meas& r)
+{ // less Comparison criterion including TWO standard deviations.
+  double lhi = (l.value_ + l.uncertainty_);  // Upper confidence limit of left.
+  double rlo = (r.value_ - r.uncertainty_);	// Upper confidence limit of right.
+  double diff = (l.value_ + l.uncertainty_) - (r.value_ - r.uncertainty_);
+  double tol = hypot(l.uncertainty_, r.uncertainty_);
+  // Might chose smallest, or largest uncertainty, or this compromise.
+  // Reverses the order when small uncertainty compared to large uncertainty and large chosen for tol.
+  bool isLess =  lhi < (rlo + 0.0 * hypot(l.uncertainty_, r.uncertainty_)); // == less
+  if (true)
+  {
+    std::cerr << "<2U #" << l.order_ << "=" << l.value_ << space
+    << (l.value_ + l.uncertainty_)
+    << space << ((isLess) ? " < " : " !< ")
+    << (r.value_ - r.uncertainty_)
+    << space << rlo + 2.0 * tol
+    << " #" << r.order_ << "=" << r.value_ 
+//		<< space << diff 
+    << std::endl;
+  }
+  return isLess;	
+} // bool Meas::lessU2(const Meas& l, const Meas& r)
+
+bool Meas::greaterU(const Meas& l, const Meas& r)
+{ // l > r
+  // Uses Uncertain measured value, not order.
+  double lhi = (l.value_ + l.uncertainty_);  // Upper confidence limit of left.
+  double rlo = (r.value_ - r.uncertainty_);	// Lower confidence limit of right.
+  double diff = (l.value_ + l.uncertainty_) - (r.value_ - r.uncertainty_);
+  double tol = hypot(l.uncertainty_, r.uncertainty_);
+  // Might chose smallest, or largest uncertainty, or this compromise.
+  // Reverses the order when small uncertainty compared to large uncertainty and large chosen for tol.
+  bool isLess =  lhi < (rlo + 0. * hypot(l.uncertainty_, r.uncertainty_)); // == less
+  return isLess;
+} // bool Meas::greater(const Meas& l, const Meas& r)
+
+bool Meas::equal_toUnc(const Meas& l, const Meas& r)
+{ // l ~== r equal within uncertainty.
+  // Uses Uncertain measured value, not order.
+  double lhi = (l.value_ + l.uncertainty_);  // Upper confidence limit of left.
+  double rlo = (r.value_ - r.uncertainty_);	// Lower confidence limit of right.
+  double diff = (l.value_ + l.uncertainty_) - (r.value_ - r.uncertainty_);
+  double tol = hypot(l.uncertainty_, r.uncertainty_);
+  // Might chose smallest, or largest uncertainty, or this compromise.
+  // Reverses the order when small uncertainty compared to large uncertainty and large chosen for tol.
+  bool isLess =  lhi < (rlo + 0. * hypot(l.uncertainty_, r.uncertainty_)); // == less
+  return isLess;
+} // bool Meas::greater(const Meas& l, const Meas& r)
+
+// Global Output Meas::operator<<
+std::ostream& operator<< (std::ostream& os, const Meas& p)  // Definition.
+{ 
+  // Uses:
+//  std::ostream& operator<< (std::ostream& os, boost::posix_time::ptime); 
+//  std::ostream& operator<< (std::ostream& os, const unc<false>&);
+
+   // std::cout << p; is transformed to operator<< (std::cout, c); which does this:
+
+    //os << p.value_ << " "
+    //<< "+/-" << p.uncertainty_
+    //<< " (" << p.degFree_ << ")"
+    ////<< showuncflags // to display.	
+    //<< " {" << std::hex << p.unctypes_ << std::dec << "}";
+    ////<< " {" 
+    ////<< showUncTypes(p.unctypes_)
+    ////<< "}";
+
+    uncun u(p.value_, p.uncertainty_, p.degFree_, p.unctypes_);
+    os << u;
+
+  if(p.id_.size() != 0) 
+  {// string identifier (if any).
+      os << " " << p.id_;
+  }
+  if (p.order_ >= 0)
+  { // means order is defined.
+    os << " #" << p.order_; // For example # 17
+  }
+  else
+  { // order undefined.
+    // So no output?
+  }
+  if (p.time_ != boost::posix_time::not_a_date_time)
+  { 
+   os << ", " << p.time_;  // Output t
+  }
+  // else don't output anything.
+  return os;  //  Allow chaining concatenation of << ... << .
+} // operator<<
+
+istream& operator>> (istream& is, Meas& p)
+{  
+  uncun u;
+  is >> u;
+  p.value_ = u.value_;
+  p.uncertainty_ = u.uncertainty_;
+  p.degFree_ = u.degFree_;
+  p.unctypes_ = u.unctypes_;
+  is >> p.order_;
+  is >> p.id_;
+  is >> p.time_;
+
+  // 2 3 (could make smarter and/or require [2,3]).
+    return is;  //  Allow chaining concatention of >> ... >>.
+} // operator<<
+
+// Defined in unc.hpp, for example:
+
+//template <class T>
+//const double value_of(T&);
+
+template<>
+double value_of(Meas v) //! \return Meas.value() as a double.
+{ //! \return Meas.value() as a double.
+  return v.value();
+}
+
+template<>
+double unc_of(Meas u) //! \return Meas.std_dev() as a double.
+{
+  return u.std_dev();
+}
+
+//! Get values of a pair of values.
+template <> //! \tparam T1 and T2 Built-in floating-point types Meas and unc.
+std::pair<double, double> values_of(std::pair<Meas, uncun> vp)
+{
+  return std::make_pair<double, double>(value_of(vp.first), value_of(vp.second));
+}
+
+template <> //! \tparam T1 and T2 Built-in floating-point types Meas and unc.
+std::pair<double, double> values_of(std::pair<Meas const, uncun> vp)
+{
+  return std::make_pair<double, double>(value_of(vp.first), value_of(vp.second));
+}
+
+//! Get uncertainties (standard deviation) of a pair of values.
+template <> //! \tparam T Built-in floating-point type or unc.
+std::pair<double, double> uncs_of(std::pair<Meas, uncun> vp)
+{
+  return std::make_pair<double, double>(unc_of(vp.first), unc_of(vp.second));
+}
+
+template <> //! \tparam T Built-in floating-point type or unc.
+std::pair<double, double> uncs_of(std::pair<Meas const, uncun> vp)
+{
+  return std::make_pair<double, double>(unc_of(vp.first), unc_of(vp.second));
+}
+
+
+#if defined (BOOST_MSVC)
+#  pragma warning(pop)
+#endif
+
+#endif // MEAS_IPP
Added: sandbox/SOC/2007/quan/boost/quan/impl/unc.ipp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/impl/unc.ipp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,880 @@
+/*!
+  \file
+  \brief Uncertain class definitions.
+  \details Class for simple Propagation of Uncertainties
+     according to a pure Gaussian model.
+     Uncertain subroutines, manipulators & applicators.
+     but not <iomanip> because defined here (as a copy of code in Std iomanip).
+*/
+
+// Copyright Paul A. Bristow 1998, 2012.
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// unc.ipp
+
+//#ifndef UNC_IPP
+//#define UNC_IPP
+
+#include <boost/quan/unc.hpp> // Declarations of uncertain items.
+
+#include <iostream>
+//using std::ostream;
+
+//! 'Unique' value used to check xalloc initialised iwords are OK, and are not corrupted.
+const long indexID = 0x48dbaf8;  //! Random id value.
+
+/*!
+  \brief Set 16 default values for uncertain output flags.
+  Might be best to make setUncDefaults also set ios_base defaults
+  with void setiosDefaults(ostream&);\n
+  Usage: \code setUncDefaults(cout); \endcode
+  \warning  \c setUncDefaults() MUST be called before using a stream.
+  \details
+     Default iword(*) values are all zero - these are not usable.
+     Function \c setUncDefaults() sets some defaults
+     Can set individual value, for example, for 3 sig Digits, os.iword(sigDigitsIndex) = 3;
+     \note Index values must have been initialised by xalloc calls.
+*/
+void setUncDefaults(std::ios_base& os)
+{   
+  os.iword(zeroIndex) = indexID; // Mark stream starting to set to defaults:
+
+  os.iword(uncFlagsIndex) = 0;  // long& uncFlags == iword(1)
+  // uncFlags defaults mean flex, not set_scaled, not auto_scaled, not +/-,
+  // no symbol, no prefix, no noisy, not setSigDigits.
+  os.iword(oldUncFlagsIndex) = 0;  // Old  - not set yet. long& oldUncFlagsIndex == iword(2)
+  os.iword(sigDigitsIndex) = 3;  // Default 3 significant digits for value.
+  os.iword(oldSigDigitsIndex) = 3;  // Old @b set 3 significant digits for value.
+  os.iword(setSigDigitsIndex) = 3;  // Default @b set 3 significant digits for value.
+  os.iword(uncSigDigitsIndex) = 2;  // Default @b set 3 significant digits for value.
+  os.iword(setUncSigDigitsIndex) = 2;  // Default 2 significant digits, as ISO standard.
+  os.iword(oldUncSigDigitsIndex) = -1;  // No previous value for unc stdDev.
+  os.iword(scaleIndex) = 0;  // Zero scale means was not scaled.
+  os.iword(oldScaleIndex) = -1;  // No previous scale.
+  os.iword(setScaleIndex) = 0;  // Assigned by uncSetScale(9).
+  os.iword(uncWidthIndex) = 10;  // Default width 10 to allow +1.23E+12 & 1 fill_char.
+  os.iword(oldUncWidthIndex) = -1;
+  os.iword(oldUncSetWidthIndex) = -1;  // Not used?
+  os.iword(usedIndex) = 0; //  No chars output = used.
+  os.iword(oldUncUsedIndex) = -1;  //  No previous value.
+  os.iword(widthIndex) = -1; // ios setwidth
+  os.iword(oldWidthIndex) = -1; // previous ios setwidth
+  os.iword(roundingLossIndex) = 50; // 0.01 * 1000; // == 0.01
+  os.iword(confidenceIndex) = 50000; // == 0.05 * 1e6
+
+  os.iword(topIndex) = indexID;  // last .iword(16) == iword(0)
+  // marking that all have been set to defaults.
+  if (os.iword(zeroIndex) != indexID)
+  { // Initialization of iwords failed!
+    std::cerr << "os.iword(0) = "  << std::hex << os.iword(0)
+      << " not expected ID " << indexID << '!' 
+      << "\nMissing call of setUncDefaults(ostream)?" << std::endl;
+    // throw; some exception TODO
+  }
+} // void setUncDefaults(std::ios_base& stream)
+
+/*! Output ALL the os.word() values to the ostream log.
+  \param os Current stream to be displayed in log.
+  \param logstream for log.
+*/
+void outUncValues(std::ostream& os, std::ostream& log)
+{ // Output ALL the os.word() values to the ostream log.
+  log //<< hex << "zero " << os.iword(zeroIndex)  << dec // = indexID; // Mark if has been set to defaults.
+    << " " "UncValues: "
+    <<  "uncFlags " << std::hex << os.iword(uncFlagsIndex) << std::dec //= 0;  // iword(1)
+    << ", setSigDigits " << os.iword(setSigDigitsIndex) // = 3;  // Default set 3 sig digits.
+    << ", uncWidth " << os.iword(uncWidthIndex) // = 10;  // Default width 10 to allow +1.234E12
+    << ", uncSetWidth " << os.iword(oldUncSetWidthIndex) // = 0;  // Not used
+    << ", uncScale " << os.iword(scaleIndex) // = 0;  // Zero scaling means was not scaled.
+    << ", uncSetScale " << os.iword(setScaleIndex) // = 0;  // Zero scaling means not scaled.
+    << ", uncUsed " << os.iword(usedIndex) // = 0; //  None used.
+    // Values saved by previous calls of uncprint.
+    << ", uncOldFlags " << os.iword(oldUncFlagsIndex) // = 0;  // 0xFFFFFFFF to mean not valid?
+    << ", uncOldUncWidth " << os.iword(oldUncWidthIndex) // = 0;
+    << ", uncOldScale " << os.iword(oldScaleIndex) // = 0;
+    << ", uncSigDigits " << os.iword(setUncSigDigitsIndex) // = 2;  // Default 2 sig digits.
+    << ", uncoldSigDigits " << os.iword(oldUncSigDigitsIndex) // = 0;  //  No previous value.
+    << ", oldUncUsed " << os.iword(oldUncUsedIndex) // = 0;  //  No previous value.
+    << ", oldStdDevSigDigits " << os.iword(oldUncSigDigitsIndex) // = 0;  // No previous value for unc stdDev.
+    << ", setUncSigDigits " << os.iword(setUncSigDigitsIndex)
+    << ", roundingLossIndex " << os.iword(roundingLossIndex) / 1.e3
+    << ", confidenceIndex " << os.iword(confidenceIndex) / 1.e6
+  
+    // << ", top " << hex << os.iword(topIndex) << dec
+    << std::endl;// = indexID;  // last .iword(16) as check.
+} // void outUncValues()
+
+//! Description as a word of each bit in unc type, using enum unc_types.
+const char* uncTypeWords[16] =
+{ 
+    "zero", //!< 0 VALUE_ZERO value is zero.
+    "integer", //!< 1 VALUE_INTEGER value is an integer.
+    "rational", //!< 2 VALUE_RATIONAL value is rational.
+    "-only", //!< 3 VALUE_NEGATIVE_ONLY Value can ONLY be < 0.. ? or <=0?
+    "+only",  //!< 4 VALUE_POSITIVE_ONLY Value can ONLY be >=0.
+    "uncKnown", //!< 5 UNC_KNOWN Uncertainty known
+    "noPlus", //!< 6 UNC_NOPLUS Uncertainty can only be < value, + = zero.
+    "noMinus", //!< 7 UNC_NOMINUS certainty can only be > value - = zero.
+    "quantize10", //!< 8 UNC_QUAN_DECIMAL Quantised by least significant decimal digit.
+    "quantize2", //!< 9 UNC_QUAN_BINARY Quantised by least significant binary digit.
+    "explicit",  //!< 10 UNC_EXPLICIT not inferred from sig digits.
+    "uniform", //!< 11 UNC_UNIFORM uniform  (or rectangular) probability distribution.
+    "triangular", //!< 12 UNC_TRIANGULAR Triangular probability distribution.
+    //! If neither bits set, then distribution type is normal (or gaussian).
+    //! If BOTH bits are, the distribution is undefined (as yet).
+    "df_exact", //!< 13 DEG_FREE_EXACT Exactly known number of observations.
+    "df_known", //!< 14 DEG_FREE_KNOWN Degrees of freedom defined.
+    "spare" //!<  15 SPARE
+};
+
+/*! Output word description for each unc_type bit.\n
+  Usage:  outUncTypes(unc.getUncTypes(), cerr); // logs to cerr.
+  \param uncTypes uncertain types as a short int.
+  \param os ostream for output, default = cerr
+*/
+void outUncTypes(unsigned short int uncTypes, std::ostream& os = std::cerr)
+{// Usage:  outUncTypes(unc.getUncTypes(), cerr); // logs to cerr.
+  const int count = 16;  // because using 16-bit unsigned short int.
+  os << "uncTypes ("  << std::showbase << std::hex << uncTypes << std::dec << ")" ;
+  for(int i = 0, j = 1; i < count; ++i)
+  {
+    if ((uncTypes & j) != 0)
+    {
+      os << ' ' << uncTypeWords[i] ;
+    }
+    j <<= 1;
+  } // for
+  os << ".";
+}  // outUncTypes
+
+/*!
+   Usage: `out << showUncTypes(uncType)` 
+  \param t Uncertain type flags.
+*/
+showUncTypes::showUncTypes(unsigned short int t) : types(t)
+{ // Constructor.
+}
+
+/*!
+  \nUsage: `out << showUncTypes(uncType)`
+  \param ut Uncertain type flags.
+  \param std::ostream for output of types as words.
+*/
+std::ostream& operator<< (std::ostream& os, const showUncTypes& ut)  // Define.
+{
+  const int count = 16;  // because using 16-bit unsigned short int.
+  unsigned short int uncTypes = ut.types;
+  os << "uncTypes (" << std::showbase << std::hex << uncTypes  << std::dec << ")";
+  for (int i = 0, j = 1; i < count; ++i)
+  {
+    if ((uncTypes & j) != 0)
+    {
+      os  << ' ' << uncTypeWords[i];
+    }
+    j <<= 1;
+  } // for
+  os << ".";
+  return os;
+} // ostream& operator<< (ostream& os, const showUncTypes& ut)
+
+/*! Show all the std io stream flags settings as words.\n
+  Usage:   \code outIosFlags(cout.flags(), cerr); // logs cout's flag to cerr. \endcode
+  \param flags Iostream flags.
+  \param os Ostream for output.
+  */
+void outIosFlags(long flags, std::ostream& os = std::cerr)
+{ // Show all the std io stream flags settings as words.
+    os << "iosflags (" << flags << ")" << std::dec;
+  if (flags & std::ios_base::boolalpha) //  Show bool as word strings "true" or "false".
+    os << " boolalpha";
+  if (flags & std::ios_base::skipws) //   Skip white space on input.
+    os << " skipwhite";
+  if (flags & std::ios_base::left) //  Left-align values; pad on the right with the fill character.
+    os << " left";
+  if (flags & std::ios_base::right) //   Right-align values; pad on the left with the fill character (default alignment).
+    os << " right";
+  if (flags & std::ios_base::internal) // Add fill characters after any leading sign or base indication, but before the value.
+    os << " internal";
+  if (flags & std::ios_base::dec) // Format numeric values as base 10 (decimal) (default radix).
+    os << " dec";
+  if (flags & std::ios_base::oct) // Format numeric values as base 8 (octal).
+    os << " oct";
+  if (flags & std::ios_base::hex) // Format numeric values as base 16 (hexadecimal).
+    os << " hex";
+  if (flags & std::ios_base::showbase) // Display numeric constants in a format that can be read by the C++ compiler.
+    os << " showbase";
+  if (flags & std::ios_base::showpoint) // Show decimal point and trailing zeros for floating-point values.
+    os << " showpoint";
+  if (flags & std::ios_base::showpos) // Display plus sign in non-negative field.
+    os << " showpos";
+  if (flags & std::ios_base::uppercase) //  Display uppercase A through F for hexadecimal values and E for scientific values.
+    os << " upper";
+  if (flags & std::ios_base::showpos) // Show plus signs (+) for positive values.
+    os << " show +";
+  if (flags & std::ios_base::scientific) // Display floating-point numbers in scientific format, for example: 1.23457e+001.
+    os << " scientific";
+  if (flags & std::ios_base::fixed) // Display floating-point numbers in fixed format, for example: 12.3456.
+    os << " fixed";
+  if ((flags & std::ios_base::scientific) && (flags & std::ios_base::fixed)) // Display floating-point numbers in hex format.
+    os << " hexFloat";
+  // TR1 adds both fixed and scientific as hexfloat.
+  // This is 15 - fmtflag appears to be limited by Dinkumware/MS fmtflags = 0xffff and most significant bit 15 is also used internally :-(
+  os << ".";
+}  // out ios_base::flags(long flags, ostream&)
+
+
+/*! Show the set uncertain class io stream flags settings as words.
+  \param uncFlags Output flags to be displayed as words.
+  \param os Ostream for output.
+  Usage:   \code outUncFlags(cout.flags(), cerr); // logs cout's flag to cerr. long& uncFlags = os.iword(uncFlagsIndex); \endcode
+*/
+void outUncFlags(long uncFlags, std::ostream& os = std::cerr)
+{ 
+  os << "uncFlags (" << std::showbase << std::hex << uncFlags << std::dec << ")";
+  os << ((uncFlags & firm) ? " firm" : "" );
+  if (uncFlags & setScaled) os << " set_scaled";
+  if (uncFlags & autoScaled) os << " auto_scaled";
+  if (uncFlags & plusMinus) os << " add_+/- ";
+  //if (uncFlags & addSISymbol) os << " add_SI_symbol";
+  //if (uncFlags & addSIPrefix) os << " add_SI_prefix";
+  if (uncFlags & limits) os << " addlimits";
+  if (uncFlags & noisyDigit) os << " addnoisy";
+  if (uncFlags & useSetSigDigits) os << " set_sigDigits";
+  if (uncFlags & useSetUncSigDigits) os << " set_uncsigDigits";
+  if (uncFlags & degfree) os << " adddegfree";
+
+  os << '.';
+} //
+
+// Parameterless manipulators to switch format to switch uncFlag bits,
+// flex - width just enough to display, suitable for non-tables,
+// or firm to fit into a set width, suitable for tables,
+// & similarly for scale and autoscale flag bits.
+// Note all lowercase to match convention of hex, oct ...
+
+std::ios_base& flexform(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) &= ~firm;  // clear bit 0 = 0 to mean flex.
+  return iostr;
+}
+
+std::ios_base& firmform(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) |= firm;  // set bit 0 = 1 to mean firm not flex.
+  return iostr;
+}
+
+std::ios_base& scale(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) |= setScaled;  // set bit 1 = 1 to mean scaled.
+  return iostr;
+}
+
+std::ios_base& noscale(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) &= ~setScaled;  // clear bit 1 = 0 to mean not scaled.
+  return iostr;
+}
+
+std::ios_base& autoscale(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) |= autoScaled;  // set bit 2 = 1 to mean auto.
+  return iostr;
+}
+
+std::ios_base& noautoscale(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) &= ~autoScaled;  // clear bit 2 = 0 to mean fixed.
+  return iostr;
+}
+
+std::ios_base& plusminus(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) |= plusMinus;  // set bit 3 = 1 to mean plusminus.
+  return iostr;
+}
+
+std::ios_base& noplusminus(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) &= ~plusMinus;  // clear bit 3 = 0 to mean not.
+  return iostr;
+}
+
+std::ios_base& addsisymbol(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) |= addSISymbol;  // set bit 4 = 1 to add SI symbol.
+  return iostr;
+}
+
+std::ios_base& nosisymbol(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) &= ~addSISymbol;  // clear bit 4 = 0 for no SI symbol.
+  return iostr;
+}
+
+std::ios_base& addsiprefix(std::ios_base& iostr)
+{ // Prefix (like kilo) used rather than Symbol (like k) if both SI prefix & symbol set.
+  iostr.iword(uncFlagsIndex) |= addSIPrefix;  // set bit 5 = 1 to add SI prefix
+  return iostr;
+}
+
+std::ios_base& nosiprefix(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) &= ~addSIPrefix;  // clear bit 5 = 0 for NO prefix.
+  return iostr;
+}
+
+std::ios_base& addnoisyDigit(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) |= noisyDigit;  // set bit 6 = 1 to add noisy digit
+  return iostr;
+}
+
+std::ios_base& nonoisyDigit(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) &= ~noisyDigit;  // clear bit 6 = 0 for NO noisy digit.
+  return iostr;
+}
+
+std::ios_base& autosigdigits(std::ios_base& iostr)
+{ // Use auto (calculated from uncertainty) not sig digits stored with `<< setSigDigits(6)` for value.
+  iostr.iword(uncFlagsIndex) &= ~useSetSigDigits;  // clear bit 7 = 0 for auto sigdigits.
+  return iostr;
+}
+
+std::ios_base& setsigdigits(std::ios_base& iostr)
+{ // Use sig digits stored with `<< setSigDigits(6)` for value (not calculated from uncertainty). 
+  iostr.iword(uncFlagsIndex) |= useSetSigDigits;  // set bit 7 = 1 to use set sigdigits.
+  return iostr;
+}
+
+std::ios_base& autouncsigdigits(std::ios_base& iostr)
+{ // Calculate stdDev sig digits from uncertainty.
+  iostr.iword(uncFlagsIndex) &= ~useSetUncSigDigits;  // clear bit 8 = 0 for auto unc sigdigits.
+  return iostr;
+}
+
+std::ios_base& setuncsigdigits(std::ios_base& iostr)
+{ //!< Use stdDev sigDigits stored with `<< useSetUncSigDigits(2) ...`
+  iostr.iword(uncFlagsIndex) |= useSetUncSigDigits;  // set bit 8 = 1 to use set uncsigdigits.
+  return iostr;
+}
+
+std::ios_base& adddegfree(std::ios_base& iostr)
+{  // Add degrees of freedom as `(99)`.
+  iostr.iword(uncFlagsIndex) |= degfree;  // set bit 9 = 1 to mean show degrees of freedom.
+  return (iostr);
+}
+
+std::ios_base& nodegfree(std::ios_base& iostr)
+{ // Do not add degrees of freedom
+  iostr.iword(uncFlagsIndex) &= ~degfree;  // clear bit 9 = 0 to mean no degrees of freedom.
+  return (iostr);
+}
+
+std::ios_base& addreplicates(std::ios_base& iostr)
+{ // Show replicates (but only if if > 1).
+  iostr.iword(uncFlagsIndex) |= replicates;  // set bit 0xA = 1 to mean replicates > 1.
+  return (iostr);
+}
+
+std::ios_base& noreplicates(std::ios_base& iostr)
+{ 
+  iostr.iword(uncFlagsIndex) &= ~replicates;  // clear bit 0xA = 0 to mean no replicates.
+  // BUT still show degrees of freedom if required.
+  return (iostr);
+}
+
+std::ios_base& addlimits(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) |= limits;  // Set bit 0xB = 0 to mean show limits.
+  return (iostr);
+}
+
+std::ios_base& nolimits(std::ios_base& iostr)
+{
+  iostr.iword(uncFlagsIndex) &= ~limits;  // clear bit 0xB = 0 to mean no limits shown.
+  return (iostr);
+}
+
+// May need istream operator>> versions too?
+
+std::ios_base& showuncflags(std::ios_base& iostr)
+{
+  showUncFlags(static_cast<unsigned short>(iostr.iword(uncFlagsIndex)));
+  return iostr;
+}
+
+// Two overloaded uFlags functions, like ios_base setf.
+// (1st just returns current, other sets & returns old).
+long uFlags(std::ios_base& str)
+{
+  return str.iword(uncFlagsIndex);  // Return streams current unc flags.
+  //  Unlike ios_base member function fmtflags ios_base::flags(),
+  //  these need to know their ios_base.
+}
+
+long uFlags(std::ios_base& str, long flags) // Assign new & return old.
+{
+  // lock();  may be required for multitasking (MT defined).
+  long oldflags = str.iword(uncFlagsIndex);  // Save to return
+  str.iword(uncFlagsIndex) = flags;  // Assign all bits.
+  // unlock();
+  return oldflags;  // Previous flags.
+}
+
+long setuFlags(std::ios_base& str, long flags)  // Set selected bits & return old.
+{
+  long oldflags = str.iword(uncFlagsIndex);  // Save to return.
+  // lock();
+  str.iword(uncFlagsIndex) |= flags;  // OR Set = 1 specific bits.
+  // unlock();
+  return oldflags;  // Previous;
+}
+
+long resetuFlags(std::ios_base& str, long flags)  // Reset bits & return old.
+{
+  long oldflags = str.iword(uncFlagsIndex);  // to return
+  // lock();
+  str.iword(uncFlagsIndex) &= (~flags);  // reset specified bits.
+  // unlock();
+  return oldflags;  // Previous.
+}
+
+// Manipulator creation using class whose name is that of the manipulator
+// and << and >> operators.
+// Steve Teale p 182 suggests that this is longer code than using template
+// O, I or Smanip, but simpler to code and understand, and will run faster.
+
+// Manipulator uncFlags. Usage: out << showUncFlags(flags)
+
+// Class showUncFlags whose name is that of the manipulator & << >> operators,
+// defined in unc.hpp header, but constructor defined in unc.cpp.
+
+showUncFlags::showUncFlags(unsigned short int f) : flags(f)
+{ //! Constructor.
+  //! Usage: out << showUncFlags(static_cast<long>(is.iword(uncFlagsIndex))) ...
+}
+
+std::ostream& operator<< (std::ostream& os, const showUncFlags& uf)  // Define.
+{ // Output uncFlags to this ostream.
+  unsigned short uncFlags = uf.flags;
+  os << "uncFlags ("<< std::hex << uncFlags << std::dec << ")";
+  os << ((uncFlags & firm) ? " firm" : "" );
+  if (uncFlags & setScaled) os << " setScaled";
+  if (uncFlags & autoScaled) os << " autoScaled";
+  if (uncFlags & plusMinus) os << " add_+/-";
+  if (uncFlags & addSISymbol) os << " add_SI_symbol";
+  if (uncFlags & addSIPrefix) os << " add_SI_prefix";
+  if (uncFlags & noisyDigit) os << " add_noisy";
+  if (uncFlags & useSetSigDigits) os << " use_set_sigfig";
+  if (uncFlags & useSetUncSigDigits) os << " use_set_uncsigfig";
+  os << ".";
+  return os;
+} // ostream& operator<< (ostream& os, const showUncFlags&)
+  //long& uncFlags = os.iword(uncFlagsIndex);
+
+
+// setAllUncflags(int flags);
+// Usage: out << setAllUncFlags(0x5a) ...
+setAllUncFlags::setAllUncFlags(int w) : flags(w) {}
+// Constructor initialisation assigns flags = w.
+
+std::ostream& operator<< (std::ostream& os, const setAllUncFlags& sf)
+{
+  os.iword(oldUncFlagsIndex) = os.iword(uncFlagsIndex);  // Save all old flags.
+  os.iword(uncFlagsIndex) = sf.flags;  // Set all flags.
+  return os;
+}
+
+std::istream& operator>> (std::istream& is, const setAllUncFlags& sf)
+{
+  is.iword(oldUncFlagsIndex) = is.iword(uncFlagsIndex);  // Save all old flags.
+  is.iword(uncFlagsIndex) = sf.flags;  // Set all flags.
+  return is;
+}
+
+// setUncflags(int flags, int mask);
+// Usage: out << setUncFlags(0x7) ...
+setUncFlags::setUncFlags(int w) : flags(w)
+{ // Constructor initialisation flags = w.
+
+}
+
+std::ostream& operator<< (std::ostream& os, const setUncFlags& sf)
+{
+  os.iword(oldUncFlagsIndex) = os.iword(uncFlagsIndex);  // Save all oldflags.
+  os.iword(uncFlagsIndex) |= sf.flags;  // Set (OR in) selected flags.
+  return os;
+}
+
+std::istream& operator>> (std::istream& is, const setUncFlags& sf)
+{
+  is.iword(oldUncFlagsIndex) = is.iword(uncFlagsIndex);  // Save all old flags.
+  is.iword(uncFlagsIndex) |= sf.flags;   // Set (OR in) selected flags.
+  return is;
+}
+
+// setMaskedUncflags(int flags, int mask);
+// Usage: out << setMaskedUncFlags(0xFFFF, 0x7) ...
+setMaskedUncFlags::setMaskedUncFlags(int w, int m) : flags(w), mask(m) {}
+// flags = w; mask = m; in effect.
+
+std::ostream& operator<< (std::ostream& os, const setMaskedUncFlags& sf)
+{
+  os.iword(oldUncFlagsIndex) = os.iword(uncFlagsIndex);  // Save all flags.
+  os.iword(uncFlagsIndex) =
+    (sf.flags & sf.mask) | (sf.flags & ~sf.mask);  // Set selected flags to mask.
+  return os;
+}
+
+std::istream& operator>> (std::istream& is, const setMaskedUncFlags& sf)
+{
+  is.iword(oldUncFlagsIndex) = is.iword(uncFlagsIndex);  // Save all flags.
+  is.iword(uncFlagsIndex) =
+    (sf.flags & sf.mask) | (sf.flags & ~sf.mask);  // Set selected flags to mask.
+  return is;
+}
+
+// resetUncflags(int flags);
+// Usage: out << setMaskedUncFlags(0xF) ...
+resetUncFlags::resetUncFlags(int w) : flags(w) {}  // Constructor initialisation flags = w.
+
+std::ostream& operator<< (std::ostream& os, const resetUncFlags& sf)
+{
+  os.iword(oldUncFlagsIndex) = os.iword(uncFlagsIndex);  // Save previous.
+  os.iword(uncFlagsIndex) &= ~sf.flags;  // Clear specific bits = 0.
+  return os;
+}
+
+std::istream& operator>> (std::istream& is, const resetUncFlags& sf)
+{
+  is.iword(oldUncFlagsIndex) = is.iword(uncFlagsIndex);  // Save previous.
+  is.iword(uncFlagsIndex) &= ~sf.flags;  //  Clear specific bits = 0.
+  return is;
+}
+
+// setMaskedUncflags(int flags, int mask);
+// Usage: out << setMaskedUncFlags(0xFFFF, 0x7) ...
+resetMaskedUncFlags::resetMaskedUncFlags(int w, int m) : flags(w), mask(m) {}
+// Constructor initialisation flags = w.
+
+std::ostream& operator<< (std::ostream& os, const resetMaskedUncFlags& sf)
+{
+  os.iword(oldUncFlagsIndex) = os.iword(uncFlagsIndex);  // Save all flags.
+  os.iword(uncFlagsIndex) =
+    (sf.flags & sf.mask) & ~(sf.flags & ~sf.mask);  // Clear selected flags to mask.
+  return os;
+}
+
+std::istream& operator>> (std::istream& is, const resetMaskedUncFlags& sf)
+{
+  is.iword(oldUncFlagsIndex) = is.iword(uncFlagsIndex);  // Save all flags.
+  is.iword(uncFlagsIndex) =
+    (sf.flags & sf.mask) & ~(sf.flags & ~sf.mask);  // Clear selected flags to mask.
+  return is;
+}
+
+// Usage: out << setUncWidth(12) ...
+setUncWidth::setUncWidth(int w) : uncWidth(w)
+  { // Constructor.
+  }
+
+std::ostream& operator<< (std::ostream& os, const setUncWidth& sw)
+{
+  os.iword(oldUncWidthIndex) = os.iword(uncWidthIndex);  // Save old.
+  os.iword(uncWidthIndex) = sw.uncWidth;  // Set new uncertain width.
+  return os;
+}
+
+std::istream& operator>> (std::istream& is, const setUncWidth& sw)
+{
+  is.iword(oldUncWidthIndex) = is.iword(uncWidthIndex);  // Save old.
+  is.iword(uncWidthIndex) = sw.uncWidth;
+  return is;
+}
+
+// setScale(int scale);
+// Usage: out << setScale(6)  ... // == 10**6
+// & << scale to use this set scale value, or << noscale to ignore.
+setScale::setScale(int scale) : scale(scale)
+{ // Constructor.
+}
+
+std::ostream& operator<< (std::ostream& os, const setScale& sc)
+{ //
+  os.iword(oldScaleIndex) = os.iword(setScaleIndex);  // Save old.
+  os.iword(setScaleIndex) = sc.scale;
+  return os;
+}
+
+std::istream& operator>> (std::istream& is, const setScale& sc)
+{
+  is.iword(oldScaleIndex) = is.iword(setScaleIndex);  // Save old.
+  is.iword(setScaleIndex) = sc.scale;
+  return is;
+}
+
+/*! setSigDigits(int sigDigits);
+\brief Set the number of significant digits that can be used.
+(If required by `<< sigfiged` then use set sigDigits value, or noSigfiged to @b NOT use sigDigits).
+// Usage: `out << setSigDigits(5) << setsigdigits ...`
+// & either `<< setsigdigits` to use set sigDigits value, or ` << nosetsigdigits` to not use the set sigDigits.
+*/
+setSigDigits::setSigDigits(int w) : sigDigits_(w)
+{  // Constructor sigDigits = w;
+}
+
+std::ostream& operator<< (std::ostream& os, const setSigDigits& sf)
+{
+  os.iword(oldSigDigitsIndex) = os.iword(setSigDigitsIndex);  // Save previous.
+  os.iword(setSigDigitsIndex) = sf.sigDigits_;  // Set new sigDigits for value.
+  return os;
+}
+
+std::istream& operator>> (std::istream& is, const setSigDigits& sf)
+{
+  is.iword(oldSigDigitsIndex) = is.iword(setSigDigitsIndex);  // Save previous.
+  is.iword(setSigDigitsIndex) = sf.sigDigits_;  // Set new sigDigits.
+  return is;
+}
+
+//! setUncSigDigits(int sigDigits);
+//! Usage: `out << setUncSigDigits(3) ...`
+// has the effect `cout.iword[setUncSigDigitsIndex] = 3;`
+setUncSigDigits::setUncSigDigits(int w) // : uncSigDigits_(w)
+{
+  if (w == 0)
+  { 
+    w = 2;  // ISO default.
+  }
+  else if (w > 3)
+  {
+    w = 3;  // Limit to biggest that makes sense.
+  }
+  // Passes negative values through to allow 
+  // an auto mode for w < 0 that chooses from degrees of freedom,
+  // (can't read degfree from here).
+  // From table H page 457 in Oliver & Goldsmith, confidence interval
+  // of standard deviation is about +/- 20% at 10 degrees of freedom,
+  // and only < +/- 10% above 100 observations (needing 2 stdDev sig Digits).
+  uncSigDigits_ = w;
+} // Constructor sets uncSigDigits = w.
+
+std::ostream& operator<< (std::ostream& os, const setUncSigDigits& usf)
+{
+  os.iword(oldUncSigDigitsIndex) = os.iword(setUncSigDigitsIndex); // Save previous.
+  os.iword(setUncSigDigitsIndex) = usf.uncSigDigits_;  // Set new uncSigDigits.
+  return os;
+}
+
+//! setroundingLoss(double eps);
+//! Usage: out << setroundingLoss(0.01) ... = cout.iword[roundingLoss] = 0.01;
+setRoundingLoss::setRoundingLoss(double eps)
+{ // Constructor sets roundingLoss = parameter eps (scaled by operator<<).
+ 
+   roundingloss_= eps;
+}  
+std::ostream& operator<< (std::ostream& os, const setRoundingLoss& sl)
+{ //! \note Can't store `double` in a `long`, so scale up to an integer.
+  os.iword(roundingLossIndex) = static_cast<long>(sl.roundingloss_ * 1.e3);
+  return os;
+}
+
+//! setConfidence(double alpha);
+//! Usage: out << setConfidence(0.01) ... = cout.iword[confidence] = 0.01;
+setConfidence::setConfidence(double alpha)
+{  // Constructor sets confidence = parameter alpha (scaled by operator<<).
+   confidence_= alpha;
+}
+
+std::ostream& operator<< (std::ostream& os, const setConfidence& sl)
+{ //! \note Can't store `double` in a `long`, so scale up to an integer.
+  os.iword(confidenceIndex) = static_cast<long>(sl.confidence_ * 1.e6);
+  return os;
+}
+
+std::istream& operator>> (std::istream& is, const setUncSigDigits& usf)
+{
+  is.iword(oldUncSigDigitsIndex) = is.iword(setUncSigDigitsIndex); // Save previous.
+  is.iword(setUncSigDigitsIndex) = usf.uncSigDigits_;  // Set new uncSigDigits.
+  return is;
+}
+
+// These all fail to link when placed here???? So left in unc.hpp until understand why.
+
+//! Squared function, notationally convenient for a^2, but overflow possible?
+//template <typename Type>
+//inline Type sqr(const Type& a)
+//{ 
+//  return a * a;
+//}
+
+//! Cubed function, notationally convenient for x^3, but overflow possible?
+//template <typename Type>
+//inline Type cube(const Type& a)
+//{
+//  return a * a * a;
+//}
+
+////! Quaded function, notationally convenient for x^4, but overflow possible?
+////! Used by Welch-Satterthwaite formula.
+//template <typename Type>
+//inline Type pow4(const Type& a)
+//{
+//  return a * a * a * a;
+//} 
+/*! Hypot or Square root of the sum of the squares of two numbers,
+   which is equal to the length of the hypotenuse of a right
+   triangle if the two arguments are the lengths of the legs.
+   Used for uncertainty propagation.
+*/
+//template <typename Type>
+//inline Type sqrtSumSqrs (const Type& a, const Type& b)
+//{
+//  return (Type)sqrt(a * a + b * b);
+//}
+//
+
+// Definitions for explicit instantiation for double uncun, mMeas.
+// Definitions must only be in .cpp if unc.hpp included more than once
+// or will get link error "already defined".
+
+//
+//!< \tparam T value type convertible to double.
+template<>
+double value_of(double v)
+{ //! \return value as a double.
+  return double(v);
+}
+
+template <class T> //!< \tparam T value type convertible to double.
+double value_of(T v)
+{ //! \return value as a double.
+  double result = static_cast<double>(v.value());
+  return result;
+}
+
+template<>
+double value_of(unc<true> v)
+{ //! \return unc.value() as a double.
+  return v.value();
+}
+
+template<>
+double value_of(unc<false> v)
+{ //! \return unc.value() as a double.
+  return v.value();
+}
+
+template <class T>
+double unc_of(T v)
+{ //! \return zero if no uncertainty information is available (for built-in double, float, or long double).
+  return v.std_dev();
+}
+
+template <>
+double unc_of(double)
+{ //! \return zero if no uncertainty information is available (for built-in double, float, or long double).
+  return 0.F;
+}
+
+template <>
+double unc_of(float)
+{ //! \return zero if no uncertainty information is available (for built-in double, float, or long double).
+  return 0.F;
+}
+
+template <>
+double unc_of(uncun u)
+{ //! \return zero if no uncertainty information is available (for built-in double, float, or long double).
+  return u.std_dev();
+}
+
+// Pairs of values.
+
+template <> //! \tparam T Built-in floating-point type, float, double, long double or unc or Meas.
+std::pair<double, double> values_of(std::pair<double, double> vp)
+{ //!< \return values of a pair of double values.
+  return std::make_pair(value_of(vp.first), value_of(vp.second));
+}
+
+// Const vrsion
+template <> //! \tparam T Built-in floating-point type, float, double, long double or unc or Meas.
+std::pair<double, double> values_of(std::pair<double const, double> vp)
+{ //!< \return values of a pair of double values.
+  return std::make_pair(value_of(vp.first), value_of(vp.second));
+}
+
+template <> //! \tparam T Built-in floating-point type, float, double, long double or unc or Meas.
+std::pair<double, double> values_of(std::pair<uncun, uncun> vp)
+{ //!< \return values of a pair of double values.
+  return std::make_pair(value_of(vp.first), value_of(vp.second));
+}
+
+template <> //! \tparam T Built-in floating-point type, float, double, long double or unc or Meas.
+std::pair<double, double> values_of(std::pair<uncun const, uncun> vp)
+{ //!< \return values of a pair of double values.
+  return std::make_pair(value_of(vp.first), value_of(vp.second));
+}
+
+//! Get uncertainties (standard deviation) of a pair of values.
+template <> //! \tparam T Built-in floating-point type or unc.
+std::pair<double, double> uncs_of(std::pair<double, double> vp)
+{
+  return std::make_pair<double, double>(unc_of(vp.first), unc_of(vp.second));
+}
+
+//! Get uncertainties (standard deviation) as a pair of double values.
+template <> //! \tparam T Built-in floating-point type or unc.
+std::pair<double, double> uncs_of(std::pair<uncun, uncun> vp)
+{
+  return std::make_pair<double, double>(unc_of(vp.first), unc_of(vp.second));
+  //! \return uncs_of uncertainties (standard deviation) as a pair of double values.
+}
+
+//! Get uncertainties (standard deviation) as a pair of const float values.
+template <class T> //! \tparam T Builtin-floating point type or unc.
+const std::pair<float, float> uncs_of(std::pair<const T, T> vp)
+{ //! \return uncertainty parts (if any) as a pair of floats.
+  // so can write
+  // std::pair<const float, float> minmax = values_of(*result.first); // min unc & max unc for example/
+  // whether T is built-in or unc.
+  return std::make_pair(vp.first.unc(), vp.second.unc());
+  //! \return uncs_of uncertainties (standard deviation) as a pair of @b float values.
+}
+
+//// Diagnostic printout version of constructors here just for testing.
+//
+//// Note both correlated and uncorrelated versions needed unless use a template.
+//// C2906: 'unc<is_correlated>::~unc(void)' : explicit specialization requires 'template <>'
+//template<> unc<true>::~unc()  // Definition.
+//{
+//#ifdef UNC_CD_TRACE
+//  {
+//    cerr << "\n___ Destruct unc<true> members: "
+//      << value_ << ", Unc " << float(uncertainty_)
+//      << ", df " << dec << degFree_
+//      << showUncTypes(unctypes_)
+//      << endl;
+//  }
+//#endif
+//}  // Destructor
+//
+//template<> unc<false>::~unc()  // Definition.
+//{
+//#ifdef UNC_CD_TRACE
+//  {
+//    cerr << "\n___ Destruct unc<false> members: "
+//      << value_ << ", Unc " << float(uncertainty_)
+//      << ", df " << dec << degFree_
+//      << showUncTypes(unctypes_)
+//      << endl;
+//  }
+//#endif
+//}  // Destructor
+//#endif // UNC_IPP
Added: sandbox/SOC/2007/quan/boost/quan/impl/unc_input.ipp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/impl/unc_input.ipp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,421 @@
+/*!
+  \file 
+  \brief Testing uncertain classes using Boost Test Tool.
+  \details Class for simple Propagation of Uncertainties
+     according to a pure Gaussian model.
+*/
+
+// Copyright Paul A. Bristow 1998, 2012.
+
+// unc_input.cpp 
+
+#include <iosfwd>
+//#include <boost/quan/unc.hpp>
+
+void unc_input(
+                   double& value,  // mean, central or most probable value.
+                   double& stdDev, // float& ??
+                   unsigned short int& degreesOfFreedom,  // 1 observation.
+                   unsigned short int& types, // TODO settings bits.
+                   std::istream& is = std::cin)
+{	// Inputs uncertainty as value, (implicitly exact, std deviation = 0).
+  // & optionally [[+]|[-] <standard deviation * 2. >], 
+  // (1.0 implies 1. +|- 0.5 and sd of 0.5,
+  // 1.00 implies 1. +|- 0.05 and sd of 0.05)
+
+  // & optionally degrees of freedom [(<short int>)] like (99)
+  // Used by istream& operator>> (istream&, unc<is_correlated>&)
+  // Original simple version:
+  //char plus, slash, minus;
+  //s >> value >> plus >> slash >> minus >> stdDev;
+  //if ((plus != '+') || (slash != '/') || (minus != '-'))	
+  //{
+  //cerr << "Unexpected characters encountered in reading "
+  //"value +/- stdDev !" << endl;
+  //is.setf(ios_base::failbit);
+  //}
+
+  using std::istream;
+  using std::ostream;
+  using std::ios_base;
+  using std::char_traits;
+  using std::cout;
+  using std::cerr;
+  using std::cin;
+  using std::endl;
+  using std::flush;
+  using std::ws;
+  using std::streamsize;
+  using std::boolalpha;
+  using std::dec;
+  using std::hex;
+  using std::showbase;
+  using std::fixed;
+  using std::scientific;
+  using std::right;
+  using std::showpos;
+  using std::noshowpos;
+  using std::noshowbase;
+  using std::noshowpoint;
+  using std::showpoint;
+
+  std::streamsize avail = is.rdbuf()->in_avail();
+  if (avail == 0)
+  {
+    std::cerr << "No input available!" << std::endl;
+    value = std::numeric_limits<double>::quiet_NaN();
+    stdDev = std::numeric_limits<float>::quiet_NaN();
+    degreesOfFreedom = 0;
+    types = 0U;
+    return;  // todo 
+  }
+
+  // 'Default' values for unc_input arguments.
+  value = 0.;	// double mean, central or most probable value.
+  stdDev = 0.f;  // Exact float std deviation, unless find otherwise.
+  degreesOfFreedom = 1U;  // Default == 1 observation.
+  types = 0U; 
+    //static_cast<unsigned short>(~(VALUE_ZERO | VALUE_INTEGER | VALUE_RATIONAL| VALUE_NEGATIVE_ONLY | VALUE_POSITIVE_ONLY | UNC_KNOWN | UNC_NOPLUS
+    //	| UNC_NOMINUS | UNC_QUAN_DECIMAL | UNC_QUAN_BINARY | UNC_EXPLICIT | UNC_UNIFORM | UNC_TRIANGULAR | DEG_FREE_EXACT | DEG_FREE_KNOWN));
+
+  // All these need to be 'global' to uncertainRead, so declared here.
+  // char_traits<char>::int_type c;
+  // no_unused_variable_warning(c);
+  int iv = 0;  // Integer part of floating point number.
+  double fv = 0.;  // Fractional part of floating point number.
+  int exponent = 0; // Exponent power of 10, default 10 ^ 0 = 1.
+//	bool isPositive = true; // Value input is >= 0.
+  bool isNegativeValue = false; // Value input < 0.
+  bool isPlusMinus = false;  // Normal case is +/- or +|-.
+  bool isPlus = false; // +0
+  bool isMinus = false; // -0
+  bool isExactValue = true; // Assume no digits follow.
+  bool isZeroValue = true; // Until find either integer or fractional part != 0
+  bool isIntegerValue = false;
+  bool isExponent = false;
+  //	bool isValueZero = false;
+  // Rationale for doing own read rather than using standard is to be able to distinguish
+  // integer "0" or "123" implicitly exact from real "0." implicitly +/- 0.5.
+  // Read integer part as one integer, option decimal as another, and fractional part as another,
+  // then optional exponential part,
+  // before any +/- and degrees of freedom as (999).
+
+  is >> ws;  // Skip any leading whitespace.
+  is >> iv;  // & read integer part of value (perhaps ii part of floating point number ii.ffe+ddd).
+  // if (is.bad()) // Not useful to distinguish overflow etc.
+  // if (is.eof()) // Sets fail for overflow, so not useful.
+  if (!is)
+  { // No integer part of value.
+    cerr << "No numeric value input! " << showiostate << endl;
+    value = std::numeric_limits<double>::quiet_NaN();
+    stdDev = std::numeric_limits<float>::quiet_NaN();
+    types = static_cast<unsigned short>(~(VALUE_ZERO | VALUE_INTEGER | VALUE_RATIONAL| VALUE_NEGATIVE_ONLY | VALUE_POSITIVE_ONLY | UNC_KNOWN | UNC_NOPLUS
+      | UNC_NOMINUS | UNC_QUAN_DECIMAL | UNC_QUAN_BINARY | UNC_EXPLICIT | UNC_UNIFORM | UNC_TRIANGULAR | DEG_FREE_EXACT | DEG_FREE_KNOWN));
+    // == 0U; // None of the above are true.
+    // is.fail() == true;  is.good() == false; // already
+    return;
+  } // is.failed
+  isIntegerValue = true; // but may be negated if find a decimal point later.
+  types |= UNC_KNOWN;
+  types &= ~UNC_EXPLICIT; // Clear bit because implicit from
+  //  number of significant decimal digits - unless + or - provided.
+
+  isNegativeValue = (iv < 0) ? true : false;
+  // Overflow possible here if > numeric_limits<long>::max() == 2147483647
+  // for example, 99999999999999.
+  if (is.fail())
+  {  // Check for overflow & other problems.
+    std::cerr << "\t" "Uncertain value input failed! "<< showiostate << std::endl;
+    value = std::numeric_limits<double>::quiet_NaN();
+    stdDev = std::numeric_limits<float>::quiet_NaN();
+    types = static_cast<unsigned short>(~(VALUE_ZERO | VALUE_INTEGER | VALUE_RATIONAL| VALUE_NEGATIVE_ONLY | VALUE_POSITIVE_ONLY | UNC_KNOWN | UNC_NOPLUS
+      | UNC_NOMINUS | UNC_QUAN_DECIMAL | UNC_QUAN_BINARY | UNC_EXPLICIT | UNC_UNIFORM | UNC_TRIANGULAR | DEG_FREE_EXACT | DEG_FREE_KNOWN));
+    // == 0U; // None of the above true.
+    return;
+  } // is.fail
+
+  if (is.peek() == '.')   // locale.decimal_point[0] better.
+  {  // A decimal fractional part may follow.
+    is.get();  // Get (and discard) decimal_point.
+    isIntegerValue = false; // Because . follows digit, so "9" is exact integer but "9." is not,
+    // Even if no digits follow.
+    isExactValue = false;
+    stdDev = 0.5; // Implicit +/- if "9.", implies sd = 0.5.
+    types |= UNC_QUAN_DECIMAL;  // Quantised by least significant decimal digit.
+    types &= ~UNC_EXPLICIT;  // Clear - explicit because implied by significant digits.
+    int count = 0; // Number of digits.  TODO ?? is this info used?
+    if (isdigit(is.peek()))
+    {  // There is a decimal fraction part.
+      double fracTen = 1.;
+      while (isdigit(is.peek()))
+      {
+        ++count;
+        stdDev *= 0.1f; // Implicitly 1. means +/- 0.5 == stdDev = 0.05, 0.005 ...
+        fracTen *= 0.1;
+        int digit = (is.get() -'0');
+        fv += digit * fracTen;
+        // Potential for underflow to zero here?
+      }
+      if (isNegativeValue) fv = -fv;
+      if (fv != 0) 
+      {
+        isIntegerValue = false;
+      }
+    }  // Is a fraction part.
+  }  // Is a decimal_point.
+  else if (is.peek() == '/')
+  { // Is a fraction, for example 2/3, so flag as a rational.
+    is.get();  // Get (and discard) /.
+    int denom;
+    is >> denom;
+    if (denom != 0)
+    {
+      value = static_cast<double>(iv)/denom;
+      iv = 0;
+      fv = 0;
+      types |= VALUE_RATIONAL;
+      types &= ~VALUE_ZERO;
+    }
+  }
+  value += iv + fv; // Combine integer and fractional parts.
+
+  if ((is.peek() & 0x5F ) == 'E') // 'e' or 'E'
+  { // Exponential part.
+    is.get();  // and discard 'e' or 'E'.
+    is >> exponent;
+    isExponent = true;
+  }  // Exponent
+
+  if (value == 0) 
+  { 
+    isZeroValue = false;
+    types |= VALUE_ZERO;
+  }
+
+  if (isIntegerValue)
+  {
+    value = iv;
+    types |= (UNC_KNOWN | VALUE_INTEGER | VALUE_RATIONAL );
+//   types |= (UNC_KNOWN | VALUE_INTEGER | VALUE_RATIONAL | UNC_NOPLUS | UNC_NOMINUS);
+#ifdef UNC_TRACE
+    { // Implicitly exact +/- 0
+      std::cerr << "    URead: Exact integer = " << value << std::endl;
+    }
+#endif
+  }
+  else
+  { // Real NOT integer.
+    types |= UNC_KNOWN; // Known.
+    types &= ~(VALUE_INTEGER | VALUE_RATIONAL | UNC_NOPLUS | UNC_NOMINUS );
+#ifdef UNC_TRACE
+    {
+      std::cerr << "    URead: " << value << " implicit +/- " << stdDev << ". ";
+    }
+#endif
+  } // integer or not.
+
+  is >> ws; // Skip optional whitespace between "123.45" and "+/-".
+
+  //	Check if explicit uncertainty +/- (or +|-, or +-) or + or - follows,
+  //	& read uncertainty if it does.
+  double expUnc = 0.; // Explicit uncertainty.
+  // 0x0F1 is files code for the single char '+-' symbol,
+  if (!is.eof())
+  { // Uncertainty (standard deviation) and degrees of freedom may follow.
+    if ((is.peek() == '+') || (is.peek() == '-'))
+    { // Some uncertainty, for example: +0.123, -0.456 or "+/-2.34"
+      std::char_traits<char>::int_type c = is.get(); // '+' or '-' read and discard.
+      if(c == '+')
+      {
+       isPlus = true;
+      }
+      if(c == '-')
+      {
+       isMinus = true;
+      }
+      std::char_traits<char>::int_type p = is.peek();
+      // 0xdd is File code for | vertical bar.
+      // 0x0F1 is single char in files for '+-' symbol.
+      if (p == '/' || p == '|' || p == '\\' || p == 0xDD || p == 0x0F1)
+      { // Skip over any separator.
+        std::char_traits<char>::int_type c = is.get(); // '/' or '|' or '\' chars.
+        if (c ==  0x0F1)
+        { // '+-' symbol, so must be both + and -.
+          isPlus = true;
+          isMinus = true;
+        }
+        // is >> ws; // Ignore any layout. Bad idea to allow "+/ -"
+        p = is.peek(); // Expect + or - after separator.
+        if (p == '+' || p == '-')
+        { // +/- and +|- both allowed (or -/+ or -|+).
+          // Assume +/+ uncertainty means just + and -/-, and uncertainty just -.
+          std::char_traits<char>::int_type c = is.get(); // expect 2nd '+' or '-' char.
+          if (c == '+')
+          {
+            isPlus = true;
+            // else "*/+"
+            is >> expUnc;  // Input Explicit uncertainty.
+            if (!is.fail())
+            { // Read OK, set bits.
+              types |= (UNC_KNOWN | UNC_EXPLICIT | UNC_QUAN_DECIMAL | UNC_KNOWN );
+            }
+            else
+            { // Reading uncertainty (standard deviation) value was not OK, so clear.
+              types &= ~(UNC_KNOWN | UNC_EXPLICIT | UNC_QUAN_DECIMAL | UNC_KNOWN );
+            }
+          }  // == '+'
+          else if (c == '-')
+          {// else "*/-"
+            isMinus = true;
+            is >> expUnc; // Input Explicit negative uncertainty (have already consumed the - sign).
+            if (!is.fail())
+            { // Read OK, set bits.
+              types |= (UNC_KNOWN | UNC_EXPLICIT | UNC_QUAN_DECIMAL | UNC_KNOWN );
+            }
+            else
+            { // NotOK, so clear.
+              types &= ~(UNC_KNOWN | UNC_EXPLICIT | UNC_QUAN_DECIMAL | UNC_KNOWN );
+            }
+          } // == '-'
+        }
+        else
+        { // Unexpected char (not + or -) after separator!
+          //  TODO Need to signal fail!
+        }
+      }
+      else if (c == '+')
+      { // Positive uncertainty only, for example: "+0.123"
+        isPlus = true;
+        is >> expUnc; // Will consume the + sign.
+        if (!is.fail())
+        { // Read OK, set bits.
+          types |= (UNC_KNOWN | UNC_EXPLICIT | UNC_QUAN_DECIMAL | UNC_KNOWN | UNC_NOMINUS);
+        }
+        else
+        { // NotOK, so clear.
+          types &= ~(UNC_KNOWN | UNC_EXPLICIT | UNC_QUAN_DECIMAL | UNC_KNOWN | UNC_NOMINUS);
+        }
+      }
+      else if (c == '-')
+      { // // Negative uncertainty only, for example: "-0.123"
+        isMinus = true;
+        is >> expUnc;
+        // expUnc = -expUnc; // Have already consumed the '-' sign! But stddev is always positive.
+        if (!is.fail())
+        { // OK, so set uncertain type flags.
+          types |= (UNC_KNOWN | UNC_EXPLICIT | UNC_QUAN_DECIMAL | UNC_KNOWN );
+        }
+        else
+        { // NotOK so clear  flags.
+          types &= ~(UNC_KNOWN | UNC_EXPLICIT | UNC_QUAN_DECIMAL | UNC_KNOWN );
+        }
+      }  // == '-'
+    }
+
+    if (isPlus || isMinus)
+    { // Some plus and/or minus value has been input.
+      types |= (UNC_KNOWN | UNC_EXPLICIT);
+      if ((isPlus) && (isMinus))
+      {
+        isPlusMinus = true;  // If both plus and minus uncertainty.
+        types &= ~(UNC_NOMINUS | UNC_NOPLUS); // Clear both exclusive,
+        stdDev = static_cast<float>(expUnc);
+      }
+      else
+ //   if (!isPlusMinus)  // Only + or -, but not both.
+      {
+        if (isPlus)
+        {
+            types |= UNC_NOMINUS;
+        }
+        else if (isMinus)
+        {
+            types |= UNC_NOPLUS;
+        }
+        stdDev = static_cast<float>(expUnc);
+      } // not both.
+    } //  isPlus or isMinus
+    else
+    { // Implicit.
+      stdDev = static_cast<float>(stdDev);  // 
+    }
+
+#ifdef UNC_TRACE
+      {
+        std::cerr << "    Explicit uncertainty ";
+        if (isPlusMinus)
+        {
+          std::cerr << " +/- "; 
+        }
+        else
+        {
+          std::cerr << ((isPlus) ? "+ " : "");
+          std::cerr << ((isMinus) ? "- " : "");
+        }
+        std::cerr  << expUnc << ", stdDev " << stdDev << endl;
+
+      } // trace
+#endif
+    // Degrees of freedom?
+    is >> ws; // Eat any whitespace before "(99)".
+    if (!is.eof())
+    { // Degrees of freedom as "(99)" may follow.
+      // (Default degreesOfFreedom = 0; == 1 observation.
+      if (is.peek() == '(')
+      { // 99) follows
+        std::char_traits<char>::int_type  c =	is.get();  // Discard '('
+        long df; // degreesOfFreedom is only unsigned short 16 bit integer, so might overflow,
+        is >> df;  // but read into a temporary long int to do some checks.
+        if (is.fail())
+        { // long int not read OK.
+          degreesOfFreedom = (std::numeric_limits<unsigned short int>::max)(); // 0xFFFF; = Not known.
+          types &= ~(DEG_FREE_KNOWN | DEG_FREE_EXACT); // Clear these flags.
+        }
+        else
+        {  // long degrees of freedom read OK, so check >=0, and not too big.
+          if (df < 0) 
+          { // Can't have negative degrees of freedom!
+            degreesOfFreedom = (std::numeric_limits<unsigned short int>::max)(); // 0xFFFF; = Not known.
+            types &= ~(DEG_FREE_KNOWN | DEG_FREE_EXACT); // NOT defined.
+          }
+          else
+          { // df >= 0
+            degreesOfFreedom =
+              (df >= (std::numeric_limits<unsigned short int>::max)()) ?
+              (std::numeric_limits<unsigned short int>::max)() -1
+              // max df allowed.
+              : static_cast<unsigned short int>(df); // 1 observation == 1 degfree.
+          }
+          c =	is.peek();  // Expect ')'
+          if (c == ')')
+          {
+            is.get();  // Discard ')'
+            types |= (DEG_FREE_KNOWN | DEG_FREE_EXACT);  // deg_free IS known and integer so exact.
+          }
+          if (c != ')' || (is.fail()) )
+          { // (99 OK but missing bracket.
+            degreesOfFreedom = (std::numeric_limits<unsigned short int>::max)(); // 0xFFFF; = Not known.
+            types &= ~(DEG_FREE_KNOWN | DEG_FREE_EXACT); // NOT defined.
+          }
+        }
+      } // (99)
+      else
+      { // is EOF so NO (df)
+        types |= DEG_FREE_KNOWN ;  // deg_free IS implicitly known == 0.
+        // degreesOfFreedom = 0U;  // Default == 1 observation.
+      }
+    } // eof
+  } // eof
+#ifdef UNC_TRACE
+  {
+    std::cerr << "\n### unc_input:""\n""\t" "value "
+      << value
+      << ", stdDev " << stdDev
+      << ", df " << dec << degreesOfFreedom << ", "
+      << showUncTypes(types) << ", "
+      << showUncFlags(static_cast<unsigned short>(is.iword(uncFlagsIndex)))
+      << std::endl;
+  } // trace
+#endif
+  // Restore is stream flags - if altered.
+} // void unc_input(double&, double&, unsigned short&, unsigned short&, std::istream&);
Added: sandbox/SOC/2007/quan/boost/quan/impl/unc_output.ipp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/impl/unc_output.ipp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,552 @@
+/*! \file unc_print.cpp
+  \brief Output of uncertain values.
+  \details Definitions of unc_input declarations in unc.hpp.\n
+    Outline:
+    ~~~~~~~~
+    1 Get ios info: width, fill & precision, save to restore..
+    2 Get the requested info from uncflags.
+    3 Get the value, stddev, degfree & uncTypes..
+    4 Check value & stdDev for Nan, inf, zero, neg.
+    5 Determine significant digits and stdDeviation significant digits.
+    6 Round.
+    7 Determine padding.
+
+    Output.
+    ~~~~~~
+    Output leading padding.
+    output rounded value & exponent.
+    output +/- value, if requested.
+    output trailing padding, if required.
+    Output degrees of freedom, if required.
+
+    Record width used etc.
+*/
+
+// Copyright Paul A. Bristow 2009, 2012.
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/quan/unc.hpp>
+
+#include <boost/math/special_functions/fpclassify.hpp>
+  //using boost::math::isnan;
+  //using boost::math::isinf;
+  //using boost::math::isfinite;
+  //using boost::math::isnormal; // isfinite and not denormalised.
+
+#include <boost/math/special_functions/sign.hpp>
+ // using boost::math::signbit;
+ // using boost::math::sign;
+ // using boost::math::copysign;
+
+// Restore ios fill and precision, and set width to zero, as if used.
+#include <boost/io/ios_state.hpp>
+
+#include <cassert>
+#include <ostream>
+#include <sstream>
+ // using std::stringstream;
+
+/*! 
+  \brief Output to stream given value as a decimal digit string,
+  rounding properly using the uncertainty information in stdDev,
+  and optionally including uncertainty as +/-, and degrees of freedom,
+  with addition control from additional unc stream manipulators.
+
+  \param value  Mean or most likely value.
+  \param stdDev Uncertainty estimate as standard deviation.
+  \param degFree Degrees of freedom -1. (Default zero for 1 observation).
+  \param uncTypes 16 Uncertain type flags about the value.
+  \param os Output stream, default is to `std::ostream`.
+  \exception Throws `std::bad_alloc()` if 'os::iword' has not been initialised correctly,
+  or has been corrupted.
+*/
+void unc_output(double value, // Mean or most likely value.
+                float stdDev, // Standard deviation (uncertainty).
+                unsigned short int degFree, // Degrees of freedom -1.
+                unsigned short int uncTypes, // 16 Uncertain type flags.
+                std::ostream& os = std::cout)  // Output stream.
+{
+  using boost::math::isnan;
+  using boost::math::isfinite;
+
+  using std::setprecision;
+  using std::setw;
+  using std::resetiosflags;
+  
+  using std::istream;
+  using std::ostream;
+  using std::ios_base;
+  using std::char_traits;
+  using std::cout;
+  using std::cerr;
+  using std::cin;
+  using std::endl;
+  using std::flush;
+  using std::ws;
+  using std::streamsize;
+  using std::boolalpha;
+  using std::dec;
+  using std::hex;
+  using std::showbase;
+  using std::fixed;
+  using std::scientific;
+  using std::right;
+  using std::showpos;
+  using std::noshowpos;
+  using std::noshowbase;
+  using std::noshowpoint;
+  using std::showpoint;
+  using std::noadjust;  // Restore to default state.
+  using std::nofixed;  // Restore to default state.
+  using std::noscientific;  // Restore to default state.
+  using std::defaultfloat; // Restore fixed & scientific to default state.
+  using std::hexbase;
+  using std::lowercase;
+
+  // Check iwords are setup correctly.
+  if ((os.iword(zeroIndex) != indexID) || (os.iword(topIndex) != indexID))
+  { // iwords are corrupt!
+    cerr << "\n!!! unc_output: " "iword corrupt!" << endl;
+    outUncValues(os, cerr);  // Log all the iword values to cerr.
+    os << "?????" << endl;
+    throw std::bad_alloc(); // Or which other exception?
+    // This means the function `setUncDefaults(os)` has not been called for the stream os!
+    return; // int notOK might be better?
+  }
+  // References to os.iword()
+  long& uncWidth = os.iword(uncWidthIndex); // Width required for uncertain value.
+  long& oldUncWidth = os.iword(oldUncWidthIndex); // Width required for previous uncertain value.
+  long& uncFlags = os.iword(uncFlagsIndex); //  
+  long& Width = os.iword(widthIndex); // Width specified by setw(99).
+  long& oldWidth = os.iword(oldWidthIndex); // width previously specified by setw(99)
+  long& setSigDigits = os.iword(setSigDigitsIndex); // Specified number of digits to use for value.
+  long& setStdDevSigDigits = os.iword(setUncSigDigitsIndex); // Specified number of digits to use for sd.
+  long& setScale = os.iword(setScaleIndex); // Scale factor, stored by `<< setScale(6)`
+  // Only actually scale multiple, if also request to set scale with `out << setscale ...`
+
+  // bools showing output requirements specified using unc additional ostream manipulators.
+  // Note that these bools are NOT initialised here,
+  // assuming compiler will warn if used before being initialised.
+  /*
+    \var bool isNoisyDigit
+    \brief Add an extra 'noisy' guard digit to reduce risk of information loss.
+  */
+  bool isNoisyDigit; 
+  bool isPlusMinus;//!< Uncertainty as +/- is required too (but ignore if value is exact or integer).
+  bool isUppercase; //!< Exponential format is, for example, 1E6 else 1e6.
+  bool isScientificFormat;  //!< Taken to mean that exponential format wanted (always possible).
+  bool isShowPoint;  //!< Means decimal point is always shown, for example 900. even if not needed.
+  bool isShowPos; //!< Show + sign always because ios flag was set with `<< showpo`s.
+  bool isFixed; //!< `os << fixed ...` ios decimal fixed d.dddd format (rather than scientific).
+  bool isWidthSet; //!< `os << setw(9)` has prescribed a width (rather than default width == 0).
+  bool isNoAdjust;  //!< std = default but unc usage not defined yet, center?
+  bool isRightJustify; //!< right justify, prepend leading pad before. `<< right << ...`
+  bool isLeftJustify; //!< left justify, append trailing pad after. `<< left ...`
+  bool isInternalJustify;  //!< Not defined yet, but use to center in field?
+  bool isCenter; //!< center if BOTH left and right specified.
+  bool isAlign; //!< Align on decimal point?
+
+  // bools showing state of arguments value, stdDev, df.
+  // Note that these bools are NOT initialised here,
+  // assuming the compiler will warn if use before initialized.
+  // They all need to be 'global' to `unc_output`.
+  bool isValueExact = false; //! value is exact (integer, rational, zero stdDev or noplus & nominus).
+  bool isValueInteger = false; //! value is an integer, or stdDev = 0.f.
+  bool isUncKnown = false; //!< StdDev or uncertainty is valid.
+  bool isValueNaN = false; //!< value is NaN.
+  bool isValueInfinite = false; //!< Value is infinite (postive or negative).
+  bool isValueNegative  = false; //!< Value is negative.
+  bool isValueZero = false; //!< Value is zero.
+  bool isValueNearZero = false; //!< So near to zero that can't calculate relative stdDev.
+  bool isValueTooBigforUnc = false;  //!< Magnitude > 1e38
+  bool isValueTooBigforSI = false;  //!< magnitude > 1e24
+  bool isValueZeroFractional = false; //!< Value to output has a non-zero fractional part.
+  bool isStdDevNaN = false; //!< StdDev is NaN.
+  bool isStdDevInf = false; //!< StdDev is inf.
+
+  //int sigDigits = std::numeric_limits<double>::max_digits10; // Default significant digits for value.
+  // Show all potentially significant?
+  int sigDigits = 6; // Default significant digits for value.
+  // For non-zero: 3 means ddd0. or ddd. or dd.d or d.dd or d.dd or 0.ddd or 0.0ddd ...
+  // For zero, sigDigits = 1 means just 0, 2 means 0.0, 3 means 0.00 ...
+  // If sigDigits < 0 means significant digits is undefined.
+  int stdDevSigDigits = 1;  // Default significant digits for stdDev.
+
+#ifdef UNC_TRACE
+  { // Log the unc_output arguments:
+    std::cerr << "\n  <<< unc_output: "
+      << setprecision(2 + std::numeric_limits<double>::digits * 3010/10000) // aka max_digits10
+      << value // scientific if necessary.
+      << ", stdDev " << stdDev
+      << ", df " << degFree
+      << " ";
+    // and log the info from the unc iwords:
+    outUncFlags(uncFlags, std::cerr);
+    std::cerr << "  ";
+    outUncTypes(uncTypes, std::cerr);
+    outUncValues(os, std::cerr);
+  }
+#endif
+  //const int savedUncFlags = uncFlags; // Save to restore.
+  //const int savedUncWidth = os.iword(uncWidthIndex); // Save to restore.
+  // Why restore? - passed by value, so can alter if want to.
+
+  // Width, precision, flags & fillChar data from stream os. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  streamsize iosWidth = os.width(); //!< \warning Width must be read BEFORE any use of os
+  // which would reset width back to zero!
+  // & prevent any ios formatting during os << ...
+  // because unc_output does all its own formatting.
+  isWidthSet = (iosWidth > 0); // For example by os << setw(99)
+  // Fixed width field suits tables.
+  // For example: os << setw(10) means fit into a width of 10, with padding if necessary.
+  // stream width <= 0 means no justification or padding.
+  // Since default width = 0 after each item output so ostream,
+  // defaults to flex format, suitable for flexible non-tabulated layout.
+  const std::streamsize iosPrecision = os.precision();
+  // Number of significant decimal digits prescribed by \c setprecision(int), Default is 6.
+  const char iosFillChar = os.fill(); // Default is a space.
+  // Save format flags from \c ostream, so can restore on exit, and set \c ios default values.
+  const int iosFlags = os.flags();  // Save fmtflagsin case need to restore.
+  os.width(0); // Would be zeroed by any previous use like << avalue ...
+  os.flags(ios_base::dec | ios_base::skipws); // All other format flags are zero (cleared bits).
+  // Leaving fill and precision as on entry.
+#ifdef UNC_TRACE
+  { // Log ios fillchar, precision & width.
+    // fill char set by \c os.fill('~'); or \c << \c setfill('~')
+    // precision by \c << setprecision(10)  or cout.precision(10),
+    // width by \c setw(10) or \c cout.width(10)
+    std::cerr <<  "  IOstream: "
+      "fill char " << hex << showbase
+      << int(iosFillChar) << space
+      << '\'' << iosFillChar<< '\''<< dec
+      << ", precision " << iosPrecision << ", width " << iosWidth << ", "
+      << std::endl;
+    std::cerr << "  "; outFmtFlags(os.flags(), std::cerr, ".\n");
+    std::cerr << "  "; outIOstates(os.rdstate(), std::cerr, ".\n");
+  } // trace
+#endif
+
+  // Get print format requirements from std::ios flags. ****************************
+  isUppercase = static_cast<bool>(iosFlags & ios_base::uppercase); // E not e.
+  // TODO No mechanism to change uppercase at present in round_* functions.
+  isScientificFormat = static_cast<bool>(iosFlags & ios_base::scientific); // exp format wanted.
+  isFixed = static_cast<bool>(iosFlags & ios_base::fixed); // `<< fixed` Fixed format wanted.
+  // means d.dddd format wanted, if possible, rather than scientific or exp format.
+  isNoAdjust = !static_cast<bool>(iosFlags & ios_base::adjustfield); // `<< noadjust`
+  // no adjustfield flags are set (default, and == << right - a waste!).
+  isLeftJustify = static_cast<bool>(iosFlags & ios_base::left);
+  // left justify, append trailing padding with fillchar after.
+  isRightJustify = static_cast<bool>(iosFlags & ios_base::right);
+  // right justify, prepend leading padding with fillchar before.
+  isInternalJustify = static_cast<bool>(iosFlags & ios_base::internal);
+  // IO streams use to output fill char between sign and 1st digit.
+  // And meaning of more than one bit is specially defined for unc_output:
+  isCenter = isLeftJustify && isRightJustify;
+  // center if BOTH left and right ios specified.
+  // Done with ` << ` center rather than `<< left << right ... `.
+  isAlign = isInternalJustify && isLeftJustify && isRightJustify;
+  // Align decimal point with previous value?
+
+  isShowPoint = static_cast<bool>(iosFlags & ios_base::showpoint);
+  // Means decimal point is always shown, for example 900. even if not needed.
+  isShowPos = static_cast<bool>(iosFlags & ios_base::showpos);
+  // Show + sign always.
+
+  // Get print format requirements from unc flags. 
+  isNoisyDigit = static_cast<bool>(uncFlags & noisyDigit); // `<< addNoisyDigit`
+  isPlusMinus = static_cast<bool>(uncFlags & plusMinus); // `<< plusminus`
+  // Uncertainty as +/- is required too (but ignore if integer).
+
+  int exponent = 0; // To hold calculated 10 ^ exponent.
+  size_t used = 0; // Count of chars actually output to stream os.
+
+#ifdef UNC_TRACE
+  { // Log display options.
+   std:: cerr << "  " "Display: "
+      << (isPlusMinus ? "+/- " : "")
+      << (isUppercase ? "upper " : "lower ")
+      << (isScientificFormat ? "expFormat " : "")
+      << (isWidthSet ? "set_width" : "")
+      << (isFixed ? "fix " : " ")
+      << (isNoAdjust ? "no_adjust " : "")
+      << (isLeftJustify  ? "left " : "")
+      << (isRightJustify ? "right " : "")
+      << (isInternalJustify ? "internal " : "")
+      << (isCenter ? "center " : "")
+      << (isAlign ? "align " : "")
+      << (isShowPos ? "show_+ " : "" )
+      << (isShowPoint ? "show_. " : "")
+      << std::endl;
+  } // trace
+#endif
+
+  // Check value, stdDev & unc types for finite, zero, integer, exact. @@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
+  // Check value features first.
+  const double savedValue = value;  // Save in case need original (signed & unscaled).
+  isValueInteger = static_cast<bool>(uncTypes & VALUE_INTEGER); // Explicitly flagged as integer.
+  isValueExact = static_cast<bool>
+    (( ((uncTypes & (UNC_NOPLUS | UNC_NOMINUS)) == (UNC_NOPLUS | UNC_NOMINUS))// Both NOPLUS & NOMINUS bits set == 1,
+    || (uncTypes & VALUE_EXACT) == VALUE_EXACT) // or flagged as exact VALUE_EXACT, like 2.54
+    || ((uncTypes & (VALUE_INTEGER | VALUE_RATIONAL)) != 0) );  // Both integers (99) & rationals (22/7) are implicitly exact,
+  // But zero values, for example 0.000 (implicitly +/- 0.0005) or 0. +/- 0.05f
+  // are NOT exact (nor integer), unless stdDev = 0.f, or integer constructed from "0".
+
+  if (isValueExact)
+  { // By convention, uncTypes take precedence over any value of stdDev.
+    // But should also cross-check if VALUE_EXACT and stdDev != 0.f
+    stdDev = 0.f; // Ensuring it is finite in test below.
+    degFree = (unsigned short)0;
+    // By convention, exact values have 1 reading & so degfree == 0
+    if (isValueInteger)
+    { // No +/- because is integer, even if requested y << plusminus.
+      isPlusMinus = false;
+    } //
+  } // isValueExact
+
+  // Check if value is finite.
+  if (!isfinite(static_cast<double>(value)))
+  { // (value == NaN) || (value == SNaN) || (value == INFINITY)
+    if (isnan(value))
+    { // NaN
+      isValueNaN = true;
+      isValueNegative = false; // By convention, only positive zero and positive NaNs.
+    }
+    else
+    { // If not NaN then assume  + or - infinity.
+      isValueInfinite = true;
+      isValueNaN = false;
+      // Unlike zero and NaN, can have negative infinity.
+    } // isNaN?
+    isValueZero = false;
+    isValueExact = false;
+    isUncKnown = false;
+  } // value not finite.
+  else
+  { // value IS finite, so can test if value is negative or zero, too big or too small.
+    isValueInfinite = false;
+    isValueNaN = false;
+    isValueZero = (0. == value);
+    if (isValueZero)
+    { // Keep display of zero value simple (& avoid risk of divide by zero!).
+      isValueNegative = false; // By convention, only +0 and +NaNs.
+      isValueNearZero = true; // Use to avoid relative std deviation.
+      isScientificFormat = false;
+      exponent = 0;
+    }  // is ZeroValue.
+
+    if (value < 0.)
+    { // is Negative (OK to use < 0. test here because have already eliminated NaN and inf).
+      isValueNegative = true;
+      value = fabs(value); // Can now ignore effect of negativeness, adding sign for output.
+    }  // value < 0.
+
+    isValueNearZero = (value < numeric_limits<double>::min() * 10.);
+    // May cause divide-by-zero trouble if use relative std deviation.
+
+  } // value zero, finite, NaN, outsize tests.
+
+  // Check on features of stdDev.
+  isUncKnown = uncTypes && UNC_KNOWN; // Uncertainty is flagged as KNOWN from uncType,
+  // (but still need to check that stdDev is finite).
+  if (!isfinite(stdDev))
+  { // stdDev is NaN or infinity.
+    isValueInteger = false; // ???
+    isValueExact = false; // Uncertainty must be zero for exact, sp can't be exact if uncertainty is undefined, .
+    uncTypes &= ~(UNC_KNOWN | UNC_NOPLUS | UNC_NOMINUS | UNC_QUAN_DECIMAL | UNC_QUAN_BINARY | UNC_UNIFORM | UNC_TRIANGULAR);
+    // and clear many bits for unc_types which cannot be correct.
+    isUncKnown = false; // Despite uncType flag UNC_KNOWN.
+    if (isnan(stdDev))
+    {
+      isStdDevNaN = true; // (So uncertainty undefined)
+      // but value is OK, so leave the value as is.
+    }
+    else // If stdDev not NaN then assume stdDev is infinite (+ or -).
+    { // If stdDev == infinity, then, by convention, value == NaN.
+      value = numeric_limits<double>::quiet_NaN(); // So the value becomes undefined too.
+      isValueNaN = true;
+      isStdDevInf = true;
+    } // stdDev is NaN or infinity.
+  } // stdDev NOT finite.
+  else
+  { // stdDev is finite (normal case).
+    isStdDevInf = false;
+    isStdDevNaN = false;
+    isUncKnown = true;
+    if ((0.f == stdDev) && isUncKnown)
+    { // stdDev is finite zero (& uncertainty is known) so
+      isValueExact = true; // value explicitly exact.
+#ifdef UNC_TRACE
+        {
+          std::cerr << "  " "StdDev exact value "<< value;
+        } // trace
+#endif
+    } // stddev finite
+    else
+    { // stdDev != 0, so value cannot be exact.
+      isValueExact = false;
+    }
+  } // End checks on stdDev.
+
+#ifdef UNC_TRACE
+  { // Show output settings.
+    std::cerr
+      << "  " "Output Settings: " << boolalpha << dec
+      << (isWidthSet ? "width is set, " : "no width set, ")
+      << (isPlusMinus ? " +/- " : "")
+      << (isUppercase ? "upper " : "lower ")
+      << (isScientificFormat ? "expFormat " : "")
+      << (isFixed ? "fix " : " ")
+      << (isLeftJustify  ? "left " : "")
+      << (isNoAdjust ? "no adjust " : "")
+      << (isRightJustify ? "right " : "")
+      << (isInternalJustify ? "int " : "")
+      << (isShowPos ? "show_+ " : "" )
+      << (isShowPoint ? "show . " : "")
+      << (isValueZero ? "isValueZero " : "" )
+      << (isValueNearZero ? "isValueNearZero " : "" )
+      << (isValueExact ? "isValueExact " : "" )
+      << (isValueInteger ? "isValueInteger " : "" )
+      << (isValueNegative ? "isValueNegative " : "" )
+      << (isValueInfinite? "isValueInfinite " : "" )
+      << (isValueNaN ? "isValueNaN " : "" )
+      << (isStdDevNaN ? "isStdDevNaN " : "" )
+      << (isValueTooBigforSI ? "Too_big for_SI " : "")
+      << (isValueTooBigforUnc ? "Too_big_for_unc " : "")
+      << (isUncKnown ? "isUncKnown " : "uncUnknown" )
+      << std::endl;
+
+      std::cerr << "  " "Value " << setprecision(18) << value << (isValueNearZero ? "isValueNearZero " : "");
+  } // trace
+#endif
+  // Scale the value, if required by unc flags setScaled or autoScaled. __________________________
+  // 0 == scale10 means (not)scaled by unity. 3 means divided by 1000 ...
+  if (!isValueInteger && !isValueZero && !isValueInfinite && !isValueNaN)
+  { // autoscaled or set scaled.
+    // but NOT isValueInteger, so means output 10000 m not 10.000 km,
+    // nor zero because pointless.
+  } // if (isScaled && !isValueInteger)
+
+  // ScaledValue is in range OK, exponent == 0
+  // so find power of ten of ms digit, 9 = 10 ^ 0, 90 = 10 ^ 2
+  // int stdDevExponent = 0;  // If value is d.d, then exponent = 0.
+
+  // Calculate how many significant digits for value, and then for stdDev. 
+  // Or, if requested, use the set values.
+
+  // int sigDigits; // Significant digits for value,
+  // for example: 3 means ddd0. or ddd. or dd.d or d.dd or d.dd or 0.ddd or 0.0ddd ...
+  // For zero, sigDigits = 1 means just 0, 2 means 0.0, 3 means 0.00 ...
+  // int stdDevSigDigits;  // Significant digits for stdDev.
+  if (isValueInteger)
+  { // Integer 9876
+    stdDevSigDigits = 0; // No uncertainty known!
+    // But even if << plusminus, do NOT output "9 +/- 0" for an integer.
+    // Do output decimal point if requested by showpoint.
+    // Do we want to scale integers if requested by << setscale?  TODO
+    sigDigits = exponent + 1; // So for integers 1 to 9: exponent = 0 & sigDigits = 1,
+    //                              for integers 10 to 19, exponent = 1, sigDigits = 2 ...
+    isPlusMinus = false; // Never show "2 +/-0" for integer value 2.
+    // (even if requested with out << plusminus << integer ... !).
+  } // isValueInteger.
+  else if (isValueExact)
+  { // Show full precision, but NO trailing zeros, so get "2.54" not "2.5400000000000"
+    sigDigits = 1;
+    // sigDigits = numeric_limits<double>::digits10; // Typically 15 digits are guaranteed.
+    // (Although max_digits10 are perhaps significant).
+    // Show "+/-0" if requested for real exact for example: "2.54 +/-0"
+    // (unlike NOT for integer).
+    stdDevSigDigits = 0; // "+/-0" not "+/-0.", "+/-0.0", "+/-0.1" ...
+    exponent = 0;
+  } // isValueExact.
+
+  if (os.iword(uncFlagsIndex) && useSetSigDigits)
+  { // Use set sig digits instead of calculated from uncertainty.
+    sigDigits = setSigDigits;
+    os << setprecision(setSigDigits) << value;
+  }
+
+  // Inexact and known uncertainty (including 0.0000 +/- 0.00019 case).
+#ifdef UNC_TRACE
+  { // scaling.
+    std::cerr << std::setprecision(sigDigits+2) << dec
+      << "  "
+      << ", sigDigits " << sigDigits
+      << ", stdDevSigDigits " << stdDevSigDigits;
+      if (os.iword(uncFlagsIndex) && useSetSigDigits);
+      { // Only if flag set.
+        std::cerr << ", setSigDigits " << setSigDigits;
+      }
+      if (os.iword(uncFlagsIndex) && setStdDevSigDigits))
+      { // 
+        std::cerr << ", useSetUncSigDigits " << setStdDevSigDigits; 
+        << std::endl;
+      }
+  } // trace
+#endif
+
+  const char signChar = (isValueNegative) ? '-': // Always show '-' sign.
+  (isShowPos ? '+' :  // show '+' only if isShowPos.
+  //(isWidthSet ? ' ' : 0 ) ); // space where sign char would be only for isWidthSet.
+  (isWidthSet ? 0 : 0 ) ); // zero where sign char would be only for isWidthSet.
+
+  // Save previous before actually output anything, so can restore on exit.
+  os.iword(oldSigDigitsIndex) = os.iword(sigDigitsIndex);  // Save previous sigDigitsIndex.
+  os.iword(sigDigitsIndex) = sigDigits;  // Save or 'return' sigDigits used next.
+
+  // ###################  Actually Output value (append +/- if isPlusMinus). ####################################
+
+#ifdef UNC_TRACE
+  {
+    std::cerr << "  " " ios Width " << iosWidth
+      << ", ios fill char " << showbase << hex << int(iosFillChar) << dec
+      << (isprint(iosFillChar) ? iosFillChar : '  ')
+      << ", signChar (" << showbase << hex << int(signChar) << dec << noshowbase << ") " << ((signChar != 0) ? signChar : ' ')
+      << std::endl;
+  } // trace
+#endif
+
+  std::ostringstream oss; // Value etc string to really output, with pre & /or after padding, if necessary.
+
+  bool beenPointed = false; // Decimal point has not been output yet.
+  // Might use this later for alignment of table the decimal points.
+
+  if (isValueInfinite)
+  {
+    oss << ((isValueNegative) ? "-infinity" : "+infinity");
+  }
+  else if(isValueNaN)
+  {
+    oss << "NaN"; // "NaN"
+  }
+  boost::io::ios_precision_saver precision_saver(os); // Save and restore on exit.
+  boost::io::ios_flags_saver flags_saver(os);
+    
+    // round here.
+    //os << val.value() << "(+/-" << val.uncertainty() << ")";
+
+  //os << oss.str(); // "1.23 +/- 0.1 (9) mV"
+
+  used = oss.str().size();
+
+#ifdef UNC_TRACE
+  {
+    std::cerr << "  " << dec << used << " chars used in total."  << std::endl;
+  } // trace
+#endif
+
+  os.iword(oldUncUsedIndex) = os.iword(usedIndex); // Save previous used.
+  os.iword(usedIndex) = static_cast<long>(used);  // Record chars actually output to os.
+  // This may be needed to calculate layout of a table,
+  // Std behaviour is to return to default width.
+  // Field width reverts to its default behavior, width = 0
+  // (the necessary width) after one field has been printed,
+  // so must be last item before a ';' to be read.  Not ideal!!
+  // os.width = savedWidth; // Restoring width is pointless.
+  os.flags(iosFlags);  // Restore ios flags.
+} // void unc_output(double value, float stdDev,
+// unsigned short int degFree, unsigned short int uncTypes, ostream& os);
Added: sandbox/SOC/2007/quan/boost/quan/impl/xiostream.ipp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/impl/xiostream.ipp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,339 @@
+/*! \file 
+  \brief Extra iostream manipulators.
+  \details Definitions of declarations in xiostream.hpp.
+
+  \author Paul A. Bristow
+
+*/
+// file /impl/xiostream.ipp
+
+// Copyright Paul A. Bristow 2009
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//#include <boost/quan/xiostream.hpp> // Declarations of items defined below.
+// included from this file.
+
+#ifndef XIOSTREAM_IPP
+#define XIOSTREAM_IPP
+
+#include <boost/math/special_functions/fpclassify.hpp>
+
+std::ios_base& lowercase(std::ios_base& _I)
+{	// lowercase is the inverse of std::ios_base::uppercase.
+  _I.unsetf(std::ios_base::uppercase); // Default is lowercase.
+  return _I;
+} // lowercase
+
+// Function to set base hex & showbase & uppercase too.
+// Usage: out << hexbase << ... for 1234ABCD
+// equivalent to out << hex << showbase << uppercase ...
+std::ios_base& hexbase(std::ios_base& _I)
+{
+  _I.setf(std::ios_base::hex | std::ios_base::showbase | std::ios_base::uppercase, // setbits,
+    std::ios_base::basefield | std::ios_base::showbase | std::ios_base::uppercase); // mask.
+  // Care: std::ios_base::basefield); doesn't set showbase & uppercase!
+  return _I;
+}
+
+// Manipulator template.
+// Copy of template for manipulator (from std iomanip)
+// Usage:  omanip<int>setw(int);
+template<typename T> class omanip  // Manipulator for ostream.
+{
+  friend std::ostream& operator<< (std::ostream&, const omanip<T>&);
+public:
+  omanip(std::ostream&(*f)(std::ostream&, T), T v) : func(f), val(v)
+  {
+  }
+private:
+  std::ostream&(*func)(std::ostream&, T);  // Function like setw
+  T val;  // Parameter like width.
+}; // class omanip
+// Could also provide an istream version for operator >>
+
+// Applicator is a class that stores a pointer to a function that takes
+// a reference to an std::ios_base (or derived translator) argument, and
+// an argument of the type for which the applicator is parameterized.
+// Applicator classes have the function call operator overloaded
+// so as to simulate a function call with the argument of the parameter type.
+// Use, for example: oapp<int> spaces(_spaces);  // allows << spaces(5) ...
+// where function is std::ostream& _spaces(std::ostream&, int);
+
+// Global ostream applicator using template oapp instantiated for type int,
+// & initialised with the addresss of function with one int parameter.
+// Possible to use oapp<int> spaces(_spaces);  which allows << spaces(5) ...
+// but instead spaces, stars & chars done a simpler way, see S Teale p 181-3.
+template<class T> class oapp  // Applicator for ostream.
+{
+public:
+  oapp(std::ostream&(*f)(std::ostream&, T)) : func(f)
+  {
+  };
+  //  : func(f) {} added from Watcom version to initialise & define.
+  omanip<T> operator()(T v)
+  {
+    return omanip<T>(func, v);
+  }
+private:
+  std::ostream&(*func)(std::ostream&, T);
+}; // class oapp
+
+// Template Manipulator Inserter <<
+template<class T> std::ostream& operator<< (std::ostream& os, const omanip<T>& m)
+{
+  (*m.func)(os, m.val);
+  return os;
+};
+
+// C++ Std Parameterless manipulators not used.
+// std::ostream& operator<<(std::ostream& (*)(std::ostream&) );
+// See \include\ostream for manipulator template eg endl
+// & instantiations of endl, ends, flush near end of file.
+// only narrow char instantiated here, may need wide version too.
+
+//  Manipulator with no arguments which inserts into ostream.
+//  See MSVC++ 7 "Writing your own manipulators without arguments".
+//  No class derivation nor macros.
+//  Relies on std::ostream defining overloading of operator<< to accept
+//  function type, for example, std::ostream& bold(std::ostream&); declared in unc.h
+//  inline std::ostream& ostream::operator<<(std::ostream& (__cdecl * _f)(std::ostream&)) { (*_f)(*this); return *this; }
+//  inline std::ostream& ostream::operator<<(std::ios_base& (__cdecl * _f)(std::ios_base& )) { (*_f)(*this); return *this; }
+//  Usage: cout << "regular" << bold << "now bold" << endl;
+// std::ostream& bold(std::ostream& os)  // perhaps inline
+// {
+//  return os << '\033' << '[';  // Use if have ANSI terminal emulation.
+// }
+
+// Manipulators like dec, oct, dec ... see \include\std::ios_base
+// Parameterless manipulators like dec, hex ...
+// std::ios_base& (*)(std::ios_base&)
+// Pointer to function taking std::ios_base reference argument
+// & returning std::ios_base reference.
+// These apply to both istream and ostream.
+//
+// std::ostream& (*)(std::ostream&)  and istream& (*)(istream&)
+// Pointer to function taking ostream (or istream) reference argument
+// & returning ostream (or istream) reference, but NOT BOTH.
+// Inserters and extractors:
+// std::ostream& operator<<( std::ios_base&(*)(std::ios_base&) )
+// istream& operator<<( std::ios_base&(*)(std::ios_base&) )
+// Eg std::ios_base& dec(std::ios_base& s){s.setf(std::ios_base::dec, std::ios_base::basefield);}
+
+spaces::spaces(int n) : num(n)
+{ // Constructor.
+}
+
+std::ostream& operator<< (std::ostream& os, const spaces& s)
+{
+  for (int i = s.num; i > 0; i--) os << ' ';
+  return os;
+}
+
+tabs::tabs(int n) : num(n)
+{ // Constructor.
+}
+
+std::ostream& operator<< (std::ostream& os, const tabs& s)
+{
+  for (int i = s.num;  i > 0; i--) os << '\t';
+  return os;
+}
+
+stars::stars(int n) : num(n)
+{ // Constructor.
+}
+
+std::ostream& operator<< (std::ostream& os, const stars& s)
+{
+  for (int i = s.num; i > 0; i--) os << '*';
+  return os;
+}
+
+// Two parameter manipulator chars (not using template, as spaces)
+// Usage: << chars(5,'_') ...  for 5 underlines.
+chars::chars(int n, char c) : num(n) , character(c)
+{ // Constructor.
+}
+
+std::ostream& operator<< (std::ostream& os, const chars& s)
+{
+  for (int i = s.num;  i > 0; i--) os << s.character;
+  return os;
+}
+
+// Manipulator to set specified base and to show base letter O or X uppercase.
+// Usage: out << setupperbase(16) ...
+setupperbase::setupperbase(int b) : base(b)
+{ // Constructor.
+}
+
+std::ostream& operator<< (std::ostream& os, const setupperbase& s)
+{
+  os.setf(std::ios_base::showbase | std::ios_base::uppercase |
+    ( 16 == s.base ? 1 :  // std::ios_base::hex :std::ios_base::oct;
+       8 == s.base ? std::ios_base::oct : std::ios_base::dec) ,  // default dec if not 8 or 16
+    std::ios_base::basefield | std::ios_base::showbase | std::ios_base::uppercase );  // mask
+  return os;
+} // std::ostream& operator<< (std::ostream& os, const setupperbase& s)
+
+void outIOstates(std::ios_base::iostate rdState, std::ostream& os, const char* term)
+{ // Usages:
+  // Default logs cout iostate to cerr, for example "IOstate: good", or "IOstate: fail"
+  // outIOstates(); // Same as:
+  // outIOstates(cout.rdState(), cerr, ".\n");
+  // outIOstates(cin.rdState());
+  // outIOstates(cerr.rdState(), cout, ", ");
+  // outIOstates(cout.rdState(), cerr, " iostate.\n ");
+  std::ios_base::fmtflags const savedflags = os.flags();  // Save to restore.
+  // Clear any unused and invalid bits in rdState.
+  rdState &= std::ios_base::goodbit | std::ios_base::eofbit | std::ios_base::failbit | std::ios_base::goodbit;
+  // enum _Iostate {goodbit = 0x0, eofbit = 0x1,	failbit = 0x2, badbit = 0x4, _Statmask = 0x7};
+  // but use std::ios_base::goodbit; for portability.
+  // MSVC /Dinkumware defines _Statmask 0x17, _Hardfail also added recently.
+  os << "rdState ("<< std::showbase << std::hex << rdState << ") " << std::dec ;
+  if (rdState == std::ios_base::goodbit)
+  {
+    os << "good"; // 1st so no leading space.
+  }
+  else
+  { // At least one bit set, so all need a space first.
+    if ((rdState & std::ios_base::eofbit) != 0)
+    {
+      os << " eof";
+    }
+    if ((rdState & std::ios_base::failbit) != 0)
+    {
+      os << " fail";
+    }
+    if ((rdState & std::ios_base::badbit) != 0)
+    {
+      os << " bad";
+    }
+  }
+  os << term; // eg "\n" or ", " or " ".
+  os.flags(savedflags); // Restore.
+}  // outIOstates
+
+const char* fmtFlagWords[16] =
+{ // Descriptions of each bit.
+  "skipws", "unitbuf", "uppercase","showbase","showpoint","showpos","left","right",
+    "internal","dec","oct","hex","scientific","fixed","boolalpha", "?"
+    /*
+    enum _Fmtflags
+    { // Show action when bit set == 1
+    skipws = 0x0001,  //   Skip white space on input.
+    unitbuf = 0x0002, // Output each char - unbuffered.
+    uppercase = 0x0004,// Display uppercase A through F for hexadecimal values and E for scientific values
+    showbase = 0x0008, // Display numeric constants in a format that can be read by the C++ compiler.
+    showpoint = 0x0010, // Show decimal point and trailing zeros for floating-point values.
+    showpos = 0x0020, // Show plus signs (+) for positive values.
+    left = 0x0040, // Left-align values; pad on the right with the fill character.
+    right = 0x0080,// Right-align values; pad on the left with the fill character (default alignment).
+    internal = 0x0100, // Add fill characters after any leading sign or base indication, but before the value.
+    dec = 0x0200, // Format numeric values as base 10 (decimal) (default radix).
+    oct = 0x0400, // Format numeric values as base 8 (octal).
+    hex = 0x0800, // Format numeric values as base 16 (hexadecimal).
+    scientific = 0x1000,// Display floating-point numbers in scientific format.
+    fixed = 0x2000, // Display floating-point numbers in fixed format.
+    boolalpha = 0x4000, // Show bool as word true or false.
+    // 0x8000 un-used. // show as ?
+    adjustfield = 0x01c0,
+    basefield = 0x0e00,
+    floatfield = 0x3000,
+    _Fmtmask = 0x7fff,
+    _Fmtzero = 0
+    };
+    */
+}; // const char* fmtFlagWords
+
+void outFmtFlags(std::ios_base::fmtflags fmtFlags, std::ostream& os, const char* term)
+{// Usage: 	outFmtFlags(flags, cerr);
+  // For example, logs to cerr "FormatFlags: skipws showbase right dec"
+  // Defaults in xiostream.hpp:
+  // void outFmtFlags(fmtflags fmtFlags = cout.flags(), std::ostream& os = cerr, const char* term = ".\n");
+  const int count = 16;  // because using unsigned short int.
+  std::ios_base::fmtflags flags = os.flags(); // save to restore.
+  fmtFlags &= static_cast<std::ios_base::fmtflags>(0x7FFF);  // _Fmtmask // clear un-used bits.
+  os << "iosFormatFlags (" << std::showbase << std::hex << fmtFlags << std::dec << ")" ; // hex value.
+  if (fmtFlags != 0)
+  {
+    for(int i = 0, j = 1; i < count; ++i)
+    {
+      if ((fmtFlags & j) != 0)
+      {
+          os << ' ' << fmtFlagWords[i];
+      }
+      j <<= 1;
+    }
+  }
+  os << term; // eg "\n" or ". "
+  os.flags(flags);  // Restore.
+}  // outFmtFlags
+
+std::ostream& showiostate(std::ostream& os)
+{ // Show IO stream state in words for this stream.
+  // Usage: cout << showiostate ...
+  outIOstates(static_cast<std::ios_base::iostate>(os.rdstate()), os, ". ");
+  // May be problem with output if state is bad!
+  return os;
+}
+
+std::ostream& showformat(std::ostream& os)
+{ // Show IO stream format flags in words for this stream.
+  // Usage:	cout << showformat ...
+  outFmtFlags(static_cast<std::ios_base::fmtflags>(os.flags()), os, ". ");
+  return os;
+}
+
+void setiosDefaults(std::ostream& os)
+{ // Return state and flags to same as when initialised.
+  // Would like to use std::ios_base::init, but is protected.
+  // See also setUncDefaults.
+  using std::ios_base;
+  // basic_streambuf<char, char_traits<char> >* os_buf = os.rdbuf();
+  // basic_ios<char, char_traits<char> >::init(os.rdbuf(), true);
+  // Cannot access protected member declared in class.
+  os.clear(std::ios_base::goodbit); // Clearing any 'bad' bits.
+  os.fill(' '); // Default fill char.
+  os.precision(6); // Default precision.
+  os.width(0); // Would be zeroed by any previous use like << 99 ...
+  os.flags(std::ios_base::dec | std::ios_base::skipws); // All others are zero (cleared bits).
+} // setiosDefaults(std::ostream& os)
+
+void outFpClass(double value, std::ostream& os);
+
+std::ostream& FPclass(std::ostream& os, double value)
+{ // Show Floating point type or value.
+  // Usage:	cout << FPclass(NaN) ...
+  outFpClass(value, os);
+  return os;
+} // std::ostream& FPclass(std::ostream& os, double value)
+
+void outFpClass(double value, std::ostream& os = std::cerr)
+// Usage: outFpClass(x, std::cerr);
+{  // Custom outputs for NaN, inf ... (rather than default 1#IND ...)
+  
+  if (boost::math::isfinite(value))
+  {
+    os << value;
+  }
+  else if (boost::math::isnan(value))
+  {
+    os << "NaN";
+
+  }
+  else if ( boost::math::isinf(value))
+  {
+    os << "inf";
+  }
+  else
+  {
+    os << "?" << value << "?";
+  }
+}  // OutFpclass
+
+#endif // #define XIOSTREAM_IPP
Added: sandbox/SOC/2007/quan/boost/quan/meas.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/meas.hpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,109 @@
+/*! \file 
+   \brief Class for measurement using uncertain class.
+   \details class meas with uncertain type UReal and measurement order & time-stamp.
+*/
+
+// meas.hpp 
+// Copyright Paul A. Bristow 2012
+
+#ifndef MEAS_HPP
+#define MEAS_HPP
+
+#include <boost/date_time/gregorian/gregorian.hpp> // include all types plus i/o.
+#include <boost/date_time/posix_time/posix_time.hpp> // include all types plus i/o.
+
+#include <boost/quan/unc.hpp>
+
+// Declaration.
+//class Meas;  // Measured uncertain value AND its id and order and/or time-date stamp.
+
+#include <iostream>
+  using std::ostream;
+  using std::istream;
+#include <string>
+  using std::string;  // date notadate(not_a_date_time);
+
+typedef unc<false> uncun; // Uncertain Uncorrelated (the normal case).
+
+/*!
+ \brief Measured uncertain value AND its id and order and/or time-date stamp.
+*/
+
+class Meas : public uncun
+{ 
+  friend ostream& operator<< (ostream&, const Meas&);
+  friend istream& operator>> (istream&, Meas&);
+
+public:
+  //Meas(); // Constructor - all defaults.
+  Meas(double const d = 0.);   // Constructor from double (no extra info).
+  //Meas::Meas(uncun u);  // Constructor from uncertain uncun.
+  //	Meas(int const);   // Constructor from int - use automatic conversion int to double.
+  // Meas(uncun u, string id = "", boost::posix_time::ptime ti = boost::posix_time::not_a_date_time);
+  Meas(uncun u, string id = "", boost::posix_time::ptime ti = (boost::posix_time::not_a_date_time), int o = -1);
+  //Meas(uncun u, string id = "", int o = -1);
+  Meas(const Meas&);   // Copy constructor.
+  ~Meas();  // Default destructor.
+  
+  // Operators.
+  Meas& operator= (const Meas& rhs); //!< Assignment operator.
+  Meas& abs (const Meas& rhs); // abs assignment operator.
+  Meas& abs (Meas& rhs); // abs operator.
+
+  bool operator== (const Meas& p) const; // Equality operator.
+  bool operator!= (const Meas& p) const; // Inequality.
+  bool operator< (const Meas& rhs) const; // Used by less.
+  bool operator> (const Meas& rhs) const; // Used by greater.
+  Meas operator+ (const Meas&) const // Unary +
+  { // All members remain unchanged.
+    return *this; 
+  }
+  Meas operator- (void) const // Unary -
+  {  // uncun measValue; 
+    Meas m(*this); // copy. 
+    m.value(-m.value()); // Negate only the value.
+    return m;
+  }
+  Meas operator- (void)  // Unary -
+  {  // Avoid copy but cannot be const. 
+    Meas m(*this); // copy. 
+    m.value(-m.value()); // Negate only the value.
+    return *this;
+  }
+
+  // Meas Member functions.
+  // Note static as only one instance of functions for all Meas objects.
+  // Usage: Meas::lessU(a, b);
+  static bool less(const Meas& l, const Meas& r); // l < r value (ignoring uncertainty).
+  static bool lessU(const Meas& l, const Meas& r); // < uncertain value.
+  static bool less2U(const Meas& l, const Meas& r); // < 2 * uncertainty .
+  static bool precedes(const Meas& l, const Meas& r); // < order.
+  static bool earlier(const Meas& l, const Meas& r);  // < time.
+  static bool greaterU(const Meas& l, const Meas& r); // > uncertain value.
+  static bool greater2U(const Meas& l, const Meas& r); // > 2 * uncertain value.
+  static bool equal_toUnc(const Meas& l, const Meas& r); // 
+  static bool lessAbsM(const Meas& l, const Meas& r); // abs value < abs value.
+
+ // Meas Member variables.
+public: // Inconvenient to make private?
+  std::string id_; // Identification info, if any, else "".
+
+  // Time and order values could be:
+  // 1 no known order.
+  // 2 known order, but no times.
+  // 3 times, from which order can be calculated,
+  // or both order and times given, so may need to be checked for consistency.
+
+  int order_;  // Index from 0 (or 1 perhaps?)  -1 == unknown?
+  // time_t m_time; // Time too as time_t, notaTime if not known.
+  boost::posix_time::ptime time_; // Posix time from Boost.Date_time.
+}; // class Meas
+
+// Output and input operator<< & operator>> 
+ostream& operator<< (ostream& os, const Meas& m);
+istream& operator>> (istream& is, Meas& m);
+
+// Definitions in meas.ipp.
+#include <boost/quan/impl/meas.ipp>
+
+#endif // MEAS_HPP
Added: sandbox/SOC/2007/quan/boost/quan/meas2.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/meas2.hpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,48 @@
+/*! \file 
+   \brief Class for measurement using @b two uncertain class items.
+   \details class meas2 with @b two uncertain type UReal and measurement order & time-stamp.
+*/
+
+// meas2.hpp 
+// Copyright Paul A. Bristow 2012
+
+#ifndef MEAS2_HPP
+#define MEAS2_HPP
+
+#include <boost/quan/meas.hpp>
+
+class meas2;
+
+class meas2
+{
+  friend ostream& operator<< (ostream&, const Meas&);
+  friend istream& operator>> (istream&, Meas&);
+
+  public:
+  //Meas(); // Constructor - all defaults.
+  meas2(uncun ux, uncun uy, string id = "", boost::posix_time::ptime ti= (boost::posix_time::not_a_date_time), int o = -1);
+  // Construct from two values and all other info
+
+   // Meas Member variables.
+public: 
+  uncun m_uncx;
+  uncun m_uncy;
+
+  // Time and order values could be:
+  // 1 no known order.
+  // 2 known order, but no times.
+  // 3 times, from which order can be calculated,
+  // or both order and times given, so may need to be checked for consistency.
+
+  std::string m_id; // Identification info, if any, else "".
+
+  int m_order;  // Index from 0 (or 1 perhaps?)  -1 == unknown?
+  // time_t m_time; // Time too as time_t, notaTime if not known.
+  boost::posix_time::ptime m_time; // Posix time from Boost.Date_time.
+}; // class meas2
+
+// Output and input operator<< & operator>> 
+ostream& operator<< (ostream& os, const meas2& m);
+istream& operator>> (istream& is, meas2& m);
+
+#endif // MEAS2_HPP
\ No newline at end of file
Added: sandbox/SOC/2007/quan/boost/quan/pair_io.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/pair_io.hpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,28 @@
+ /*! \file pair_io.hpp
+  \brief Provide operator<< to output pair, surrounded by < > and separated by comma, 
+  for example: "<1.23, 4.56>".
+  Typically used to show confidence intervals around a mean.
+  \details Polite to keep this a private detail namespace to avoid clash with other implementations!
+ \author Paul A. Bristow
+ \date Oct 2009, 2012
+*/
+
+#include <utility>
+ // using std::pair;
+
+// 
+template<typename charT, typename traits, typename T1, typename T2>
+inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const std::pair<T1, T2>& p)
+{
+  return os << "<" << p.first << ", " << p.second << '>'; // Separated by comma & space.
+}
+
+// Explicit specialization for pair of doubles.
+template<typename charT, typename traits>
+inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const std::pair<double, double>& p)
+{
+  return os << "<" << p.first << ", " << p.second << '>'; // Separated by comma & space.
+}
+
+
+
Added: sandbox/SOC/2007/quan/boost/quan/rounding.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/rounding.hpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,1458 @@
+/*!
+  \file
+  \brief Common rounding
+  \details
+    http://www.diycalculator.com/popup-m-round.shtml#A3
+    all rounding types, including round-to-half and asymmetric and symmetric versions.\n
+    http://www.chem1.com/acad/webtext/pre/mm3.html
+     "The purpose in rounding off is to avoid expressing a value to a greater degree of precision
+     than is consistent with the uncertainty in the measurement."
+     "Observed values should be rounded off to the number of digits
+     that most accurately conveys the uncertainty in the measurement."
+  \author Paul A. Bristow
+ */
+
+//   \file rounding.hpp
+
+// Copyright Paul A. Bristow 2009, 2012.
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*! \mainpage <b> Proper rounding testbed documentation. </b>
+ *
+ * \section intro_sec Introduction to proper rounding.
+
+   This is a testbed for the epsilon-Proper rounding for a few distributions
+   assumed to be appropriate for the data observations.\n\n
+   Based on:\n
+    Gejza Wimmer, Viktor Witkovsky, Tomas Duby \n
+    Measurement Science and Technolology, 11 (2000) pages 1659-1665.
+    ISSN 0957-0233 S0957-233(00)13838-X.\n
+    Proper rounding of the measurement results under normality assumptions.\n\n
+    Gejza Wimmer, Viktor Witkovsky, Proper rounding of the measurement result
+    under the assumption of uniform distribution, \n
+    Measurement Science Review, Vol 2, section 1, (2002), pages 1 - 7.\n\n
+    Gejza Wimmer, Viktor Witkovsky, Proper rounding of the measurement result
+    under the assumption of triangular distribution, \n
+    Measurement Science Review, Vol 2, section 1, (2002), pages 21 to 31.\n
+ */
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4127) // conditional expression is constant.
+#pragma warning(disable: 4180) // qualifier applied to function type has no meaning; ignored.
+//#  pragma warning(disable: 4702) // unreachable code.
+//#  pragma warning(disable: 4511) // copy constructor could not be generated.
+//#  pragma warning(disable: 4512) // assignment operator could not be generated.
+//#  pragma warning(disable: 4521) // alignment of a member was sensitive to packing.
+//#  pragma warning(disable: 4121) // alignment of a member was sensitive to packing.
+//#  pragma warning(disable: 4100) // unreferenced formal parameter.
+//#  pragma warning(disable: 4701) // local variable may be used without having been initialized.
+//#  pragma warning(disable: 4189) // local variable is initialized but not referenced.
+//#  pragma warning(disable: 4996) // '' was declared deprecated.
+#endif
+
+#include <boost/math/tr1.hpp>
+// using boost::math::tr1::round;  // round floating-point to integer.
+// using std::floor;
+// using std::pow;
+// using std::log10;
+
+#include <boost/math/special_functions/fpclassify.hpp>
+//using boost::math::isnan;
+//using boost::math::isinf;
+//using boost::math::isfinite;
+//using boost::math::isnormal; // isfinite and not denormalised.
+
+#include <boost/math/special_functions/sign.hpp>
+// using boost::math::signbit;
+// using boost::math::sign;
+// using boost::math::copysign;
+
+#include <boost/math/distributions/students_t.hpp>
+// using boost::math::students_t;
+#include <boost/math/distributions/normal.hpp>
+#include <boost/math/distributions/uniform.hpp>
+#include <boost/math/distributions/triangular.hpp>
+// using boost::math::normal;
+//#include "pair_io.hpp"
+// operator<<
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_floating_point.hpp> // is_floating_point trait
+#include <boost/concept_check.hpp>
+#include "boost/quan/xiostream.hpp" // Extra std items, defaultfloat & fixed.
+//#include "boost/quan/si_units.hpp"
+//#include "libs/quan/src/si_units.cpp"
+
+#include <iostream>
+//using std::cout;
+//using std::cerr;
+//using std::cin;
+//using std::endl;
+//using std::ends;
+//using std::dec;
+//using std::hex;
+//using std::fixed;
+//using std::left;
+//using std::right;
+//using std::showpoint;
+//using std::nofixed;
+//using std::noscientific;
+//using std::defaultfloat;
+//using std::noadjust;
+//using std::scientific;
+//using std::boolalpha;
+//using std::showpos;
+//using std::noshowpos;
+
+#include <iomanip>
+//using std::setprecision;
+//using std::setw;
+#include <string>
+//using std::string;
+
+#include <fstream>  // for fstream
+//using std::fstream;
+//using std::ofstream;
+
+#include <sstream> // stream
+//using std::ostringstream;
+//using std::string;
+//using std::basic_string;
+//using std::ios_base;
+
+#include <limits>
+//using std::numeric_limits;
+
+#include <locale>
+// default loc for isdigit
+
+BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559); // Assume IEEE 754 ONLY.
+// _STATIC_ASSERT (numeric_limits<double>::is_iec559); // and MS STATIC assert.
+// Might also work by checking that std::numeric_limits is specialized?
+
+BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_specialized); //
+
+#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
+// No support for std::numeric_limits<double>::max_digits10,
+const unsigned int maxdigits10 = 2 + std::numeric_limits<double>::digits * 3010 / 10000;
+#else
+// std::numeric_limits<double>::max_digits10; IS supported.
+// Any noisy or guard digits needed to display any difference are included in max_digits10.
+const unsigned int maxdigits10 = std::numeric_limits<double>::max_digits10;
+#endif
+
+// Explicit specialization for pair of doubles.
+
+std::ostream& operator<<(std::ostream& os, std::pair<double, double>& p) { /*! Output a pair of `double`s, using < > angle brackets and comma separator, using current stream's precision..
+  \detail Explicit specialization for `std::pair` for `double`s.\n
+  For example: <97.8725, 157.798>
+  \param p Pair of doubles.
+  \param os std::ostream for string output.
+  */
+  return os << "<" << p.first << ", " << p.second << '>'; // Angle bracketed, separated by comma & space.
+}
+
+// Explicit specialization for pair of const doubles.
+
+std::ostream& operator<<(std::ostream& os, const std::pair<double, double>& p) { /*! Output a pair of `double`s, using < > angle brackets and comma separator, using current stream's precision..
+  \detail Explicit specialization for @b`const` `std::pair` for `double`s.\n
+  For example: <97.8725, 157.798>
+  \param p Pair of `double`s.
+  \param os `std::ostream` for string output.
+  */
+  return os << "<" << p.first << ", " << p.second << '>'; // Angle bracketed, separated by comma & space.
+}
+
+// Two rounding algorithms returning double values (not strings).
+template<typename FPT> FPT round_sig(FPT v, int n); // v rounded to n significant decimal digits.
+template<typename FPT> FPT round_to_n(FPT v, int p); // Round value v to p decimal digits *after the decimal point*.
+
+// Rounding algorithms returning strings.
+template<typename FPT> std::string round_f(FPT v, int sigdigits); // Round fixed (not-exponential) to sigdigits decimal digits to string.
+template<typename FPT> std::string round_e(FPT v, int sigdigits); // Round fixed (exponential) to sigdigits decimal digits to string.
+template<typename FPT> std::string round_ms(FPT v, int m); // Round not-exponential to order m.
+
+template<typename FPT>
+FPT round_sig(FPT v, int n) { /*! \brief Returns v rounded to n significant decimal digits.\n
+   http://www.jason.mock.ws/wordpress/2007/02/22/round-a-float-to-of-significant-digits,
+   David A. Pimentel
+   \details These use log10 and pow and so are vulnerable to binary rounding errors,
+   as the value may not be exactly representable for the type specified.
+   Should give the same value as printf precision.
+   (int)(x < 0 ? x - 0.5 : x + 0.5))
+   So do we need to do something different for negative doubles?
+   The difference between symmetric and asymmetric rounding?
+  */
+  // Will fail if FPT is not a floating-point type (because will not output in scientific format!).
+  BOOST_STATIC_ASSERT(boost::is_floating_point<FPT>::value);
+
+  using std::pow;
+  using std::log10;
+  using std::ceil;
+  if (n < 0) { // Probably a program error, so might throw?
+    return 0;
+  } else if (n == 0) { // Might also be an error, but make some sense, so
+    return 0.;
+  } else if (n > std::numeric_limits<FPT>::digits10) { // We might use max_digits10, but only digits10 are guaranteed.
+    n = std::numeric_limits<FPT>::digits10;
+    return v; // or just return value as is?
+  }
+  if (v == 0) {
+    return 0.;
+  }
+  FPT l10 = log10(v);
+  int l = static_cast<int> (ceil(l10));
+  int pow10 = n - l;
+  FPT p10 = pow(10., pow10);
+  FPT f = v * pow(10., pow10) + 0.5;
+  f = floor(f);
+  FPT r = f / p10;
+  return r;
+  // return floor(v * pow(10., pow10) + 0.5) / pow(10., pow10);
+} // FPT round_sig(FPT v, int n)
+
+template<typename FPT>
+FPT round_to_n(FPT v, int p) { /*! Round value v to p decimal digits *after the decimal point*.
+    http://www.jason.mock.ws/wordpress/2007/02/22/round-a-float-to-of-significant-digits
+    \note These use log10 and pow and so are vulnerable to binary rounding errors,
+    as the value v may not be exactly representable for the type specified.
+    Should give the same value as printf precision.
+  */
+  // Will fail if FPT is not a floating-point type (because will not output in scientific format!).
+  BOOST_STATIC_ASSERT(boost::is_floating_point<FPT>::value);
+
+  using std::pow;
+  return static_cast<FPT> (floor(v * pow(10., p) + 0.5) / pow(10., p));
+} // template<typename FPT> FPT round_to_n(FPT v, int p)
+
+template<typename FPT>
+std::string round_e(FPT d, int sigdigits) { /*! \brief Show only `sigdigits` digits, in minimal scientific or 'e' format only,
+     rounded asymmetric (round-half-up, arithmetic rounding).\n
+     Round asymmetric avoids values like 0.15,
+     which cannot be stored exactly in binary IEEE 754 floating-point format
+     and are stored internally as 1.499999999999, being rounded unexpectedly to 0.1 rather than 0.2.
+     For example: format -1.2345e12 or 1.2345e-123.
+
+     \note the difference in meaning of precision from default, fixed and scientific, for example:
+     `d = 19.99;` \n
+     `cerr << setprecision(2) << d << endl; // 20 // rounded`\n
+     `cerr << fixed << setprecision(1) << d << endl; // 20.0 - rounded up.`\n
+     `cerr << fixed << setprecision(2) << d << endl; // 19.99 - 2 digits after decimal point.`\n
+     `cerr << scientific << setprecision(2) << d << endl; // 2.00e+001 - 2 digits after decimal point`
+
+    \details Also remove all redundant exponent characters and digits,
+    See http://en.wikipedia.org/wiki/Rounding .
+
+    \note The normal rounding provided by C and C++ is chosen to avoid loss of accuracy and bias
+    in any further *binary* calculations.
+    The rounded decimal digit *strings* returned are provided solely for *b human viewing
+    and should NOT be used for input to other calculations when one or
+    two extra noisy digits are needed to avoid loss of information by rounding.
+    If it is necessary to provide a decimal digit string for input,
+    it should use `std::numeric_limits<FPT>::max_digits10` in C++0x,
+    or `2 + std::numeric_limits<FPT>::digits * 3010/10000`
+    if the platform implementation of C++ Standard IOstream library does not yet provide this.
+    For 64-bit double, `max_digits10` is 17, so write `cout.precision(17)`.
+    This will avoid any bias or loss of accuracy in statistical calculations caused by rounding.
+
+    \note The C++ Standard IOstream library does not specify any guarantee about input
+    from a decimal digits string to internal floating-point format like `double`.\n
+    The compiler will always convert a literal floating-point to the *nearest
+    representable value*, but the C++ Standard IOstream library is not required do this.
+    In particular, MSVC 8.0 (2007) and 10.0 (2010) do not quite always achieve this
+    for `defaultfloat` format -
+    about 1/3 third of significand values in the range 0.0001 to 0.003894 are not
+    input to the nearest representable double, but are 1-bit different.
+
+    It is impracticable to test all floating-point values in a useful time,
+    so random values were tested.
+
+    For details see:
+
+    http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=7bf2f26d-171f-41fe-be05-4169a54eef9e
+
+    aka http://tinyurl.com/mpk72
+
+    This is very significant if you wish to 'round-trip'
+    (outputting a value and reading it back in again)
+    for example with lexical_cast or using Boost.Serialization.
+    A test like
+
+       assert(value_output == value_reinput)
+
+    will fail *very* intermittently.
+
+    So if this is important to you, use the scientific (exponential) format
+    with precision max_digits10 (17 for double) where random tests have not revealed any differences.
+
+    Logic of using C++ std printf-style rounding to start with a decimal digit string with rounded value
+    of digits10, only the guaranteed correct digits
+    to get the best estimate of the digit to be used for the final rounding.
+    Hopefully, any imprecision caused by inexact presentation is (binary) rounded away.
+
+    \note Only lowercase letter e is used, and positive exponents are not preceeded by + sign,
+    and leading zeros are omitted.\n
+    This is done to make the display as compact as possible.\n
+    If a fixed width is needed, the user program must provide any necessary padding,
+    using the size (length) of the string.
+
+    \param d value to be converted to decimal digit string.
+    \param sigdigits number of significant digits to show in string.
+    \return std::string containing value rounded and converted to `sigdigits` decimal digits in exponential format.
+  */
+  // Will fail if FPT is not a floating-point type (because will not output in scientific format!).
+  BOOST_STATIC_ASSERT(boost::is_floating_point<FPT>::value);
+
+  if (boost::math::tr1::isinf(d)) {
+    return (boost::math::tr1::signbit(d) ? "-Inf" : "Inf");
+  }
+  if (boost::math::tr1::isnan(d)) {
+    return (boost::math::tr1::signbit(d) ? "-NaN" : "NaN");
+  }
+  if (sigdigits <= 0) {
+    std::cout << "Trying to display " << sigdigits << " significant decimal digits!" << std::endl;
+    return ""; // Or throw?
+  }
+
+  //const unsigned int max_digits10 = 2 + std::numeric_limits<FPT>::digits * 3010/10000;
+  if (sigdigits >= std::numeric_limits<FPT>::digits10) // C++0X provides std::numeric_limits<double>::max_digits10;
+  {
+    sigdigits = std::numeric_limits<FPT>::digits10; // digits10 (15 for double) decimal digits
+    // *after* the decimal point, so a total of 16 digits (plus a decimal point).
+  }
+
+  BOOST_STATIC_ASSERT(boost::is_floating_point<FPT>::value);
+  // Will fail if FPT is not a floating-point type (because will not output in scientific format!).
+
+  std::ostringstream ss;
+  ss << std::scientific // use 9.99e+123 format
+          << std::showpoint // force decimal point and trailing zeros.
+          //<< setprecision(sigdigits)
+          // output precision decimal digits *after the leading digit and decimal point*
+          //  in scientific mode, so this is one more than significant digits.
+          // Or should this be digits10 so that any imprecision
+          // caused by inexact presentation is rounded away?
+          << std::setprecision(std::numeric_limits<FPT>::digits10) //
+          // output precision is
+          // decimal digits *after the leading digit and decimal point*, total digits10+1 digits.
+          << d;
+  std::string s = ss.str(); // "1.294567890123457e+006"
+  // std::cout <<'|' << s <<'|' << ' ' << s.size() << std::endl;
+  //assert(s.size() == std::numeric_limits<FPT>::digits10 + 1 + 1 + 5); // == 22 if positive
+
+  std::string::iterator is = s.begin(); // 1st most significant digit before decimal point.
+  if ((*is) == '-') { // Skip over minus sign.
+    // Can ignore + case as won't ever be output because default std::ostringstream is std::noshowpos.
+    is++;
+  }
+  char s1 = *is; // Copy 1st digit before decimal point.
+  std::string::iterator is1 = is; // Copy 1st digit before decimal point.
+  assert((*is1 >= '0') && (*is1 <= '9'));
+  is++; // Move to decimal point.
+  assert((*is) == '.');
+  // Do not delete decimal point - it will be needed.
+  std::string::iterator isp = is; // Decimal point. Implied position after 1st most significant digit is known.
+  assert((*isp) == '.');
+
+  // Read the exponent part first into an integer.
+  std::string::iterator se = is1 + std::numeric_limits<FPT>::digits10 + 2;
+  assert(*se == 'e');
+  se++; // skip 'e'.
+  // Read exponent into an integer.
+  bool neg_exp = ((*se) == '-') ? true : false;
+  se++; // Skip over sign of exponent.
+  std::locale loc;
+  int exp = 0;
+  do
+  {
+
+    if (std::isdigit(*se, loc))
+    {
+      exp = exp * 10 + (*se - '0');
+    }
+    se++;
+  }
+  while (se != s.end());
+
+  if (neg_exp)
+  {
+    exp = -exp; // Make exponent signed.
+  }
+
+  // std::cout << "Exponent " << ((neg_exp) ? '-' : '+') << exp << std::endl;
+
+  std::string::iterator is2 = is1 + 2; // 2nd digit (after decimal point).
+  assert((*is2 >= '0') && (*is2 <= '9'));
+  std::string::iterator isr = is2 + sigdigits - 1; // 2nd digit (after decimal point) if sigdigits == 1.
+  assert((*isr >= '0') && (*isr <= '9'));
+  int rounder = (*isr) - '0';
+  // std::cout << "rounder " << rounder << std::endl;
+  is = isr; // Least significant digit.
+  is--;
+  if (is == isp)
+  { // Skip back over decimal point.
+    is--;
+  }
+  assert((*is >= '0') && (*is <= '9'));
+
+  s.erase(isr, s.end()); // Erase all the insignificant trailing decimal digits, and exponent.
+
+  // Round the non-exponent part, in case a carry means we must increment the exponent.
+  // For example, 9.9e0 will round up to 10. and so become 1e1.
+  bool carry = false;
+  if (rounder >= 5) {
+    carry = true; // Increment next most significant digit.
+    do {
+      if (*is < '9') // 0 to 8.
+      {
+        (*is)++; // round up by 1.
+        carry = false;
+      } else if (*is == '9') {
+        *is = '0';
+        carry = true;
+      } else {
+        std::cout << "wrong ! *is = " << *is << std::endl;
+        break;
+      }
+      if (is == is1) { // No more significant digit(s).
+        break;
+      }
+      is--; // Next more significant digit.
+      if (is == isp) { // Skip over decimal point.
+        is--;
+      }
+      if (is == is1) {
+        break;
+      }
+    } while (carry == true);
+  } else { // Rounder = 0 to 4, so nothing to do.
+    carry = false;
+  }
+  if (carry == true) { // Add one to 1st most significant digit.
+    if (s1 == '9') { // Carry to most significant 1st digit '9' means now preceeded by a '1' digit.
+      *is1 = '1';
+      exp++; // Add one to signed exponent.
+      // What if it exceeds max exponent?
+    } else { // 0 to 8, so just add one.
+      (*is1)++;
+    }
+  }
+  if (exp != 0) { // Add e, - sign if necessary and exponent
+    s += ('e'); // Since the stream is not known, there is no way to know if to use uppercase 'E'.
+    if (neg_exp) { // Make unsigned.
+      s += ('-');
+      exp = -exp;
+    }
+    if (exp >= 100) { // Need exponent hundreds digit.
+      int ed = exp / 100;
+      s += static_cast<char> (ed + '0');
+    }
+    exp %= 100;
+    if (exp >= 10) { //  // Need exponent tens digit.
+      int ed = exp / 10;
+      s += static_cast<char> (ed + '0');
+    }
+    exp %= 10; //  // Always need exponent units digit.
+    s += static_cast<char> (exp + '0');
+  }
+  // std::cout << "s = " << s << std::endl;
+  return s; // Rounded decimal digits string.
+} // string round_e(FPT d, unsigned int sigdigits)
+
+template<typename FPT>
+std::string round_ms(FPT v, signed int m) { /*! \brief Round floating-point v (not-exponential) to order m.  (m is the index of the rounder digit).
+    This is variously called 'common rounding', 'round_5_up'.
+    \details Gejza Wimmer, Viktor Witkovsky, Tomas Duby\n
+    Measurement Science and Technology, 11 (2000) 1659-1665. ISSN 0957-0233 S0957-233(00)13838-X\n
+    Proper rounding of the measurement results under normality assumptions.\n
+    Uncertainty of measurement -- Part 3: Guide to the expression of uncertainty in measurement (GUM:1995)\n
+    ISO Guide 98 (1995) and updated version 2008.\n\n
+
+    \note `m` is the index of the rounder digit, that is the just insignificant digit
+    used to decide if the m+1th digit is to be rounded up or left as is.
+    So `m == 0` means that the rounder digit is the units digits, used to round the tens digit,
+    `m == +1` the rounder is the tens digit, and the rounded digit is the hundreds digit
+    `m == -1` rounder is the tenths digit (0.1), rounding the hundredths digit (0.01).
+
+    (Other authors specify the nth digit to be significant, where n = m + 1).
+
+    \param v Value to convert to decimal digit string after rounding.
+    \param m Signed digit position to round.
+    \return `std::string` decimal digit string of rounded value.
+  */
+  BOOST_STATIC_ASSERT(boost::is_floating_point<FPT>::value);
+  // Will fail if FPT is not a floating-point type (because will not output in scientific format!).
+
+  // Use Boost.Math portable functions for testing infinity, NaN and their signs.
+  using boost::math::signbit;
+  using boost::math::isnan;
+  using boost::math::isinf;
+  int is_neg = signbit(v);
+  if (isnan(v)) { //! \note that the most significant sign bit of NaN is recognized by using function signbit,
+    //! 'sign' of NaNs cannot reliably and portably be tested using "x < 0"
+    //! because all comparisons using NaN are false - by definition.
+    return (is_neg) ? "-NaN" : "NaN";
+  } else if (isinf(v)) {
+    return (is_neg) ? "-inf" : "inf";
+  }
+  // Treat denormal differently too?
+
+  // m can be up to about exponent 308.
+  //  static  const int maxDecimalDigits = 1 + 1 + numeric_limits<double>::max_exponent + (2 + numeric_limits<double>::digits * 3010/10000)+1+1;
+  // Number of decimal digits to display FPT max in fixed format with lots of trailing zeros & decimal point.
+  // ostringstream smax;
+  //  smax << setprecision(17) << fixed << -numeric_limits<double>::max() << endl; // numeric_limits<double>::max() = 1.7976931348623157e+308 but using fixed.
+  // std::cout << smax.str() << std::endl;
+  //-179769313486231610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00000000000000000
+  // std:: << "length of smax " << smax.str().size() << std::endl; // 329
+  // sign + max_digits10 (17+1 = 18) + 293  significant zeros + decimal point + 17 trailing digits (zeros).
+  // max_exponent = 308, so expect 308 +1 = 309 digits before decimal point.
+  // of these 309, 17 may be non-zero, but always have one digit so only 16, so 293 zeros.
+  // 329 is longest decimal digit string that possibly can be output with double exponent.
+  // But this function never wants to output the 'noisy' extra digits, so limit to digits10 not max_digits10.
+  // So want sign + digits10 (15)
+  //   + (max_exponent10 - digits10) (308-15 = 293) significant zeros
+  //   + decimal point,
+  //   and upto digits10 trailing zeros.
+  static const int maxDecimalDigits = 1 + (std::numeric_limits<FPT>::max_exponent10
+          - std::numeric_limits<FPT>::digits10) + 1 + std::numeric_limits<FPT>::digits10;
+  //std::cout << "max dec " << maxDecimalDigits << std::endl; // 310
+
+  if (m > maxDecimalDigits) { // limit abs(m) to maxDecimalDigits.
+    m = maxDecimalDigits;
+  }
+  if (m < -maxDecimalDigits) {
+    m = -maxDecimalDigits;
+  }
+
+  std::ostringstream ss;
+  ss << std::scientific // Use scientific E format.
+          << std::showpoint; // Force decimal point and trailing zeros.
+  // skipws showpoint dec scientific
+
+  ss.precision(std::numeric_limits<FPT>::digits10); // Output digits10 precision decimal digits (and decimal point).
+  // std::numeric_limits<double>::digits10 is 15 for 64-bit double.
+  // output precision decimal digits *after the leading digit and decimal point*, total digits10+1 digits.
+  ss << v;
+  std::string s = ss.str();
+
+  std::string::iterator is = s.begin();
+  if ((*is) == '-') { // delete minus sign.
+    // Can ignore + case as won't ever be output as default std::ostringstream is std::noshowpos.
+    // is_neg = true; already noted above using signbit.
+    s.erase(is); // is++;
+  }
+  // std::cout <<'|' << s <<'|' << ' ' << s.size() << std::endl; // For example: |1.797693134862316e+308| 22
+  /*
+
+  MSVC always has 3 exponent digits
+  4.206884193232336e+000
+  1.797693134862316e+308
+
+  gcc can have two or three exponent digits.
+  0.00000000000000000e+00
+  1.23456789012345669e+00
+  1.23456789012345666e+03
+  1.23456789012345671e-03
+  1.23456789012345658e+200
+  1.23456789012345671e-200
+   */
+
+#ifdef _MSC_VER
+  if (s.size() != std::numeric_limits<FPT>::digits10 + 1 + 1 + 5) { // for double == 22 (would be 23 if value was negative, but we are only dealing with abs value).
+    // 1.23000000000000000e+00
+    outFmtFlags(ss.flags());
+    std::cout << "\n" << v << ", " << m << ", " << s << ", "
+            << s.size() << ", " << std::numeric_limits<FPT>::digits10 + 1 + 1 + 5 << std::endl;
+    assert(s.size() == std::numeric_limits<FPT>::digits10 + 1 + 1 + 5);
+    // This happens if type FPT passed is not floating point (integer?).
+    return s;
+  }
+#endif
+#ifdef __GNUC__
+  // Format varies with size of exponent - either two or three digits.
+  if ((s.size() != std::numeric_limits<FPT>::digits10 + 1 + 1 + 4) // e+00
+          && (s.size() != std::numeric_limits<FPT>::digits10 + 1 + 1 + 5)) // e+308
+  { // for double == 21 (would be 22 if negative).
+    outFmtFlags(ss.flags());
+    std::cout << "\n" << v << ", " << m << ", " << s << ", "
+            << s.size() << ", " << std::numeric_limits<FPT>::digits10 + 1 + 1 + 4 << std::endl;
+    return s;
+  }
+#endif
+  std::string::iterator is1 = s.begin(); // 1st digit.
+  assert(*is1 >= '0');
+  assert(*is1 <= '9');
+  is++;
+  assert(*is == '.');
+  s.erase(is); // Erase decimal point. Implied position after 1st most significant digit is known.
+  std::string::iterator ie = s.begin() + std::numeric_limits<FPT>::digits10 + 1;
+  assert(*ie == 'e');
+  std::string::iterator se = s.end(); // After last exponent digit.
+  se--; // Least significant exponent 'units' digit.
+  assert(*se >= '0');
+  assert(*se <= '9');
+  int exp = (*se - '0'); // Exponent units digit's value.
+  se--;
+  assert(*se >= '0');
+  assert(*se <= '9');
+  std::locale loc;
+  if (std::isdigit(*se, loc))
+  { // Exponent tens.
+    exp += (*se - '0') * 10; // Exponent tens.
+  }
+  se--; // Previous might be exponent hundreds digit (always for MSVC), or sign.
+  if (std::isdigit(*se, loc))
+  { // Exponent tens digit.
+    exp += (*se - '0') * 100; // Exponent hundreds.
+    se--;
+  }
+  if (*se == '-') {
+    exp = -exp;
+  } else if (*se == '+') {
+    exp = +exp;
+  } else {
+    std::cout << "Function round_ms expected digit or sign!" << *se << std::endl;
+  }
+  se--; // Must be the letter 'e' next forward.
+  // std::cout << "exponent " << exp << std::endl;
+  assert((*se == 'e') || (*se == 'E')); // Check is 'e' or 'E'.
+  s.erase(se, s.end()); // Delete all exponent field: "e+123" or "e-01".
+  // leaving an digits10 + 1 = 16 decimal digit string ,
+  // with implied decimal point after the 1st digit, for example 1234567890123456.
+  // std::cout << "digits string = " << s << std::endl;
+  // Now round the string at m.
+  int p = exp - m; // Offset.
+  if (p <= 0) {
+    return "0.";
+  }
+
+  std::string::iterator sr = s.begin(); //
+  int o = (exp - m);
+  assert(o > 0);
+  if (o > std::numeric_limits<FPT>::digits10) { // No rounding possible.
+    o = std::numeric_limits<FPT>::digits10;
+  }
+  sr += (o);
+  // sr* is the rounding digit d subscript m.
+
+  int rounder = *sr - '0'; // Rounding digit.
+  std::string::iterator sis = sr; // Note position of the insignificant trailing decimal digits.
+  s.erase(sis, s.end()); // Erase all the insignificant trailing decimal digits.
+
+  //sr--; // Least significant digit.
+  bool carry = false;
+  if (rounder >= 5) {
+    carry = true; // Increment next most significant digit.
+    do {
+      sr--; // more significant digit.
+      if (*sr < '9') // 5 to 8
+      {
+        (*sr)++; // round up by 1.
+        carry = false;
+      } else
+      if (*sr == '9')
+      { // 9 will cause a carry.
+        *sr = '0';
+        carry = true;
+      } else {
+        std::cout << "wrong ! *sr = " << *sr << std::endl;
+        break;
+      }
+    } while (carry == true && sr != s.begin());
+  } else { // nothing to do.
+    carry = false;
+  }
+  if (carry == true) { // Carry to most significant digit means now preceed by a '1' digit.
+    s.insert(s.begin(), '1');
+    exp++;
+  }
+  if (m >= 0) { // May need zeros before decimal point.
+    int z = exp - s.size() + 1; // Number of significant zeros before decimal point.
+    if (z > 0) { // More efficient to check if any zeros needed before calling insert?
+      s.insert(sis, z, '0'); // Insert any significant zeros.
+    }
+  } else {// Any trailing zeros are already in the string.
+  }
+  std::string::iterator sd = s.begin();
+  if (exp > 0) { // Will try to insert off the end of the string if > maxdigits10+1!
+    sd += exp + 1;
+    s.insert(sd, '.'); // Insert decimal point.
+  } else if (exp == 0) { //
+    sd += exp + 1;
+    s.insert(sd, '.'); // Insert decimal point.
+  } else { // exp < 0
+    // Zero before decimal point might be optional?
+    s.insert(sd, '0'); // Insert zero before point.
+    sd++;
+    s.insert(sd, '.'); // Insert decimal point.
+    sd++;
+    int z = -exp - 1;
+    if (z > 0) {
+      s.insert(sd, z, '0'); // Insert any zeros before significant digits (0.001234).
+    }
+  }
+  if (is_neg) {
+    s.insert(s.begin(), '-');
+  }
+  //std::cout << "Final digits string " << s << std::endl;
+
+  return s;
+} // template <typename FPT> string round_ms(FPT v, signed int m)
+
+bool scaled = true; // want to scale and use prefix to avoid >1000 or < 1.
+
+template <typename FPT>
+std::string round_f(FPT v, int sigdigits) { /*! \brief Round floating-point value `v` (fixed, not-exponential) to `sigdigits` significant digits.
+   This is variously called 'common rounding', 'round_5_up'.
+
+  \details Gejza Wimmer, Viktor Witkovsky, Tomas Duby\n
+    Measurement Science and Technology, 11 (2000) 1659-1665. ISSN 0957-0233 S0957-233(00)13838-X\n
+    Proper rounding of the measurement results under normality assumptions.\n
+
+    Uncertainty of measurement -- Part 3: Guide to the expression of uncertainty in measurement (GUM:1995)\n
+    ISO Guide 98 (1995) and updated version 2008.
+
+    \param v Value to be converted to a decimal digit string, rounded to sigdigits significant digits.
+    \param sigdigits Number of significant digits after rounding.
+    \return `std::string` containing decimal digit string, properly rounded.
+
+    \note All these functions are templated on floating-point type and are not intended to be called
+    (and thus instantiated) for integral (or other) types.
+    This is because the value will not be output in scientific format, assumed by the code.
+    A check is_floating_point == true is provide that will fail in debug mode.
+    (A compile time check would be better).
+  */
+
+  // Will fail if FPT is not a floating-point type (because will not output in scientific format!).
+  BOOST_STATIC_ASSERT(boost::is_floating_point<FPT>::value);
+
+  // Use Boost.Math TR1 portable functions for testing infinity, NaN and their signs.
+  using boost::math::signbit;
+  int is_neg = signbit(v);
+  using boost::math::isnan;
+  using boost::math::isinf;
+
+  if (isnan(v)) { // Note that the most significant sign bit of NaN is recognized by using function signbit.
+    return (is_neg) ? "-NaN" : "NaN";
+    // 'sign' of NaNs cannot reliably and portably be tested using "x < 0"
+    // because all comparisons using NaN are false - by definition.
+  } else if (isinf(v)) {
+    return (is_neg) ? "-infinity" : "infinity";
+  }
+  // Treat denormal differently too?
+
+  // sign + max_digits10 (17+1 = 18) + 293  significant zeros + decimal point + 17 trailing digits (zeros).
+  // max_exponent = 308, so expect 308 +1 = 309 digits before decimal point.
+  // of these 309, 17 may be non-zero, but always have one digit so only 16, so 293 zeros.
+  // 329 is longest decimal digit string that possibly can be output with double exponent.
+  // But this function never wants to output the 'noisy' extra digits, so limit to digits10 not max_digits10.
+  // So want sign + digits10 (15) + (max_exponent10 - digits10) (308-15 = 293) significant zeros + decimal point, and digits10 trailing zeros.
+  static const int maxDecimalDigits = 1 + (std::numeric_limits<FPT>::max_exponent10
+          - std::numeric_limits<FPT>::digits10) + 1 + std::numeric_limits<FPT>::digits10;
+  //std::cout << "max dec " << maxDecimalDigits << std::endl; // 310
+
+  /*! \note C++0X provides @c std::numeric_limits<double>::max_digits10;
+    which is maximum possibly significant,
+    but only @c digit10 are guaranteed to be significant,
+    so limit @c sigdigits to @c digits10 (15 for IEEE 64-bit double).
+   */
+  if (sigdigits > std::numeric_limits<FPT>::digits10) {
+    std::cout << "Maximum significant digits is " << std::numeric_limits<FPT>::digits10 << std::endl;
+    sigdigits = std::numeric_limits<FPT>::digits10; // digits10 (15 for double) decimal digits after the decimal point.
+  }
+
+  if (sigdigits < 0) { // Must be a mistake.
+    std::cout << "Trying to output " << sigdigits << " significant digits!" << std::endl;
+    return "";
+  } else if (sigdigits == 0) { // Might handle zero case differently from sigdigits < 0?
+    std::cout << "Trying to output zero significant digits!" << std::endl;
+    return "";
+  }
+  //else sigdigits > 0, so usable.
+
+  std::ostringstream ss;
+  ss << std::scientific // Use scientific format to get all the value as potentially significant decimal digits.
+          << std::showpoint // Force decimal point and trailing zeros.
+          << std::setprecision(std::numeric_limits<FPT>::digits10) // Output `digits10` precision decimal digits (and decimal point).
+          // `std::numeric_limits<double>::digits10` is 15 for 64-bit double.
+          // output precision decimal digits *after the leading digit and decimal point*, total digits10+1 digits (16 for double).
+          << v;
+  std::string s = ss.str(); // digit string like -1.797693134862316e+308.
+  std::string::iterator is = s.begin();
+  if ((*is) == '-') { // delete minus sign.
+    // Can ignore + case as won't ever be output as default std::ostringstream is std::noshowpos.
+    //is_neg = true; already noted using signbit.
+    s.erase(is); // is++;
+  }
+  // std::cout <<'|' << s <<'|' << ' ' << s.size() << std::endl; // |1.234567890123457e+000| 22
+  assert(
+    (s.size() == std::numeric_limits<FPT>::digits10 + 1 + 1 + 5) // == 22
+    ||( s.size() == std::numeric_limits<FPT>::digits10 + 1 + 1 + 4) // == 21
+    ); // == 21
+  // Might be only two exponent digits on some platforms.
+
+  std::string::iterator is1 = is; // 1st digit.
+  assert(*is1 >= '0');
+  assert(*is1 <= '9');
+  is++;
+  assert(*is == '.');
+  s.erase(is); // erase decimal point.  Implied position after 1st most significant digit is known.
+  //std::cout << "digit & exponent string " << s << std::endl;
+
+  // Read the exponent part first into an integer.
+  std::string::iterator se = is1 + std::numeric_limits<FPT>::digits10 + 1;
+  std::string::iterator ie = is1 + std::numeric_limits<FPT>::digits10 + 1;
+
+  assert(*se == 'e');
+  se++; // skip 'e'.
+  // Read exponent into an integer.
+  bool neg_exp = ((*se) == '-') ? true : false;
+  se++; // Skip over sign of exponent.
+  std::locale loc;
+  int exp = 0;
+  do
+  {
+
+    if (std::isdigit(*se, loc))
+    {
+      exp = exp * 10 + (*se - '0');
+    }
+    se++;
+  }
+  while (se != s.end());
+
+  if (neg_exp)
+  {
+    exp = -exp; // Make exponent signed.
+  }
+
+  //std::cout << "exponent " << exp << std::endl;
+  //se = s.end();
+  //se -= 5;
+  s.erase(ie, s.end()); // delete everything from e to end, "e+123" or "e-01"
+  // leaving an digits10+1 decimal digit string,
+  // with implied decimal point after the 1st digit, for example 1234567890123457.
+  // std::cout << "decimal digits string " << s << std::endl;
+  // now round the string at nth decimal digit.
+
+  std::string::iterator sr = s.begin(); //
+  int o = sigdigits;
+  assert(o > 0);
+  if (o > std::numeric_limits<FPT>::digits10)
+  { // No rounding possible.
+    o = std::numeric_limits<FPT>::digits10;
+  }
+  sr += (o);
+  // sr* is the rounding digit d subscript sigdigits+1.
+
+  int rounder = *sr - '0'; // rounding digit.
+  std::string::iterator sis = sr; // Note position of the insignificant trailing decimal digits.
+  s.erase(sis, s.end()); // Erase all the insignificant trailing decimal digits.
+
+  //sr--; // Least significant digit.
+  bool carry = false;
+  if (rounder >= 5) {
+    carry = true; // Increment next most significant digit.
+    do {
+      sr--; // more significant digit.
+      if (*sr < '9') // 5 to 8
+      {
+        (*sr)++; // round up by 1.
+        carry = false;
+      } else if (*sr == '9') {
+        *sr = '0';
+        carry = true;
+      } else {
+        std::cout << "wrong ! *sr = " << *sr << std::endl;
+        break;
+      }
+    } while (carry == true && sr != s.begin());
+  } else { // nothing to do.
+    carry = false;
+  }
+  if (carry == true) { // Carry to most significant digit means now preceed by a '1' digit.
+    s.insert(s.begin(), '1');
+    exp++;
+  }
+  // Check if are to change exponent and use prefix,
+  // or to change to exponential format?
+  //int multiple3 = 0;
+  //bool is_scaled = false;
+  //  if (scaled == true)
+  //  { // If necessary change to use a prefix so value is in range 1.000000.. to 999.99999..
+  //    if (exp > SImaxPowerTen)
+  //    { // No SI names above yocto, so need to use exponential format 1.23e+25.
+  //    }
+  //    else if (exp < SIminPowerTen)
+  //    { // No SI names below yotta, so need to use exponential format 1.23e-25.
+  //    }
+  //    else if (abs(exp) >= 3)
+  //    { // Value >= 1000.0, so can use nearest abbreviation, kilo, mega...
+  //      int powerten = exp / 3;
+  //      multiple3 = powerten * 3;
+  //      exp %= 3; // nearest 10^3 can only be 1.20, 12.0 120.0
+  ///*
+  //      const char* symbol = SIsymbols[multiple3 + SImaxPowerTen];
+  //      const char* prefix = SIprefixes[multiple3 + SImaxPowerTen];
+  //      std::cout << powerten << ' ' << symbol << ' ' << prefix << std::endl;
+  //*/    is_scaled = true;
+  //    }
+  //     else if (exp < 0)
+  //     { // value < 1.0000000000000
+  //     }
+  //  }
+  // Now have the rounded decimal digit string, but may need some zeros.
+  if (sigdigits >= 0) { // May need zeros *before* decimal point.
+    int z = exp - s.size() + 1; // Number of significant zeros before decimal point.
+    if (z > 0) { // More efficient to check if any zeros are needed before calling insert.
+      s.insert(sis, z, '0'); // Insert any significant zeros.
+    }
+  } else {// Any trailing zeros are already in the string.
+  }
+
+  std::string::iterator sd = s.begin();
+  if (exp > 0) {
+    sd += exp + 1;
+    s.insert(sd, '.'); // Insert decimal point.
+  } else if (exp == 0) { //
+    sd += exp + 1;
+    s.insert(sd, '.'); // Insert decimal point.
+  } else { // exp < 0
+    // Zero before decimal point might be optional?
+    s.insert(sd, '0'); // Insert zero before point.
+    sd++;
+    s.insert(sd, '.'); // Insert decimal point.
+    sd++;
+    int z = -exp - 1; // May need zeros after decimal point, before significant digit(s).
+    if (z > 0) {
+      s.insert(sd, z, '0'); // Insert any zeros before significant digit(s) (0.001234).
+    }
+  }
+  if (is_neg) {
+    s.insert(s.begin(), '-');
+  }
+  //if (is_scaled == true)
+  //{ // Append symbol and prefix and trailing space.
+  //  bool add_symbol = true;
+  //   //  const char* symbol = SIsymbols[multiple3 + SImaxPowerTen]; // kilo, mega ...
+  //   //  const char* prefix = SIprefixes[multiple3 + SImaxPowerTen]; // k, M m ...
+  //     // std::cout << ' ' << symbol << ' ' << prefix << std::endl;
+  //     if (multiple3 != 0)
+  //     {
+  //       s.append(" "); // separator between last digit and symbol.
+  //       s.append((add_symbol ? symbol : prefix));
+  //     }
+  //}
+
+  //std::cout << "Final digits string " << s << std::endl;
+
+  return s;
+} // string round_f(FPT v, signed int m)
+
+
+// Round number v *at* d th decimal place.
+// Note d is different (roundED digit) from the Wimmer definition of m (roundER digit).
+
+inline double round_nth(double v, unsigned int d) { //! round value v to d digits after decimal point, using d+1 digit to round.
+  return std::floor(v * std::pow(10., static_cast<int> (d)) + 0.5) / std::pow(10., static_cast<int> (d));
+}
+
+// Three explicit  versions which may be slightly more efficient.
+
+inline double round_1(double v) { //! round value v to 1 digit after decimal point, using 1st digit to round.
+  return std::floor(v * 10. + 0.5) / 10.;
+}
+
+inline double round_2(double v) { //! round value v to 2 digit2 after decimal point, using 2nd digit to round.
+  return std::floor(v * 100. + 0.5) / 100.;
+}
+
+inline double round_3(double v) { //! round value v to 3 digit2 after decimal point, using 3rd digit to round.
+  return std::floor(v * 1000. + 0.5) / 1000.;
+}
+
+enum distribution_type { /*! \brief Distribution type, encoded into two bits in `short int unc_types`.
+   \note `gaussian` name is chosen rather than `normal` to avoid name clash
+   from name of bit 11 and bit 12 in `enum unc_types`.
+  */
+  gaussian = 0, //!< `unc_types` bit 11 and bit 12 == 0, aka normal.
+  uniform = 1, //!< `unc_types` bit 11 == 1, aka rectangular.
+  triangular = 2, //!< `unc_types` bit 12 == 1.
+  undefined = 3 //!< `unc_types` bit 11 and bit 12 == '11' == 3.
+};
+
+double delta(double epsilon, double gamma, distribution_type distrib = gaussian) { /*! \brief Calculate Wimmer delta function using equation 24, p 1664.
+    \details Gejza Wimmer, Viktor Witkovsky, Tomas Duby\n
+    Measurement Science and Technology, 11 (2000) pages 1659-1665.
+    ISSN 0957-0233 S0957-233(00)13838-X.\n
+    Proper rounding of the measurement results under normality assumptions.\n
+    Gejza Wimmer, Viktor Witkovsky, Proper rounding of the measurement result under the assumption of uniform distribution,\n
+    Measurement Science Review, Vol 2, section 1, (2002), pages 1 - 7.\n
+    Gejza Wimmer, Viktor Witkovsky, Proper rounding of the measurement result under the assumtpion of triangular distribution,\n
+    Measurement Science Review, Vol 2, section 1, (2002), pages 21 to 31.\n
+
+    \param epsilon Proper-rounding increase of confidence interval because of rounding, must be positive and 'small'.
+    \note epsilon is usually 0.05 or 95%, values in range 0.2 to 0.01 make good sense,
+       0.2 (80%) risks a fair bit of loss from rounding, 0.01 (1%) causes almost no loss.
+    \param gamma Ratio rounded / unrounded (gamma is assumed <= 1).
+    \param distrib Distribution type, normal or gaussian(default), uniform, triangular, or laplace.
+
+    \return Approximation of Wimmer delta function using equation 24, p 1664,
+    for normal distribution, and similar for triangular and uniform.
+    Returns -1 if epsilon is too 'tight' so must be increased for delta to be calculated.
+    Throwing an exception might be better here>
+
+  */
+  // gamma > rounded gamma (so gamma < 1.?)
+  // Approximation error is less than 0.0123 for 0.005 <= epsilon < 0.1
+  // and gamma > rounded gamma for this epsilon - see table 1.
+  // assert(gamma > rounded_gamma);
+
+  //assert (gamma <= 1);
+  using std::sqrt;
+  double d;
+  double x;
+  double threshold;
+  double sqrt_3 = 1.7320508075688772935274463415058723669428052543712;
+
+  // TODO use boost.math constant.
+
+  switch (distrib) {
+    case gaussian: // equation 24, p 1664.
+      // Gejza Wimmer, Viktor Witkovsky, Tomas Duby
+      // Measurement Science and Technology, 11 (2000) 1659-1665.
+      // ISSN 0957-0233 S0957-233(00)13838-X.
+
+      d = (1.348 + 0.9886 * epsilon + 0.2288 * sqrt(epsilon));
+      x = gamma - 1.0001 + 2.058 * epsilon - 1.93 * epsilon * epsilon;
+      if (x < (std::numeric_limits<double>::min)() * 100.) // Small value allows for approximation uncertainty.
+      { // Not possible to have epsilon this small!
+        threshold = x; // ???
+        std::cout << "Epsilon " << epsilon << " is too small for gamma rounded/unrounded ratio " << gamma << ", threshold is " << threshold << " for gaussian distribution." << std::endl;
+        // For example:
+        // "Epsilon 0.01 is too small for gamma rounded/unrounded ratio 0.981226, threshold is 0.99."
+        return -1.; // Not sure how to signal the problem here. Throw?
+      }
+      x = sqrt(x);
+      d = d * x;
+      return d; // sqrt(gamma - 1.0001 + 2.058 * epsilon - 1.93 * epsilon * epsilon);
+      break;
+    case uniform:
+      // Gejza Wimmer, Viktor Witkovsky, Proper rounding of the measurement result under the assumption of uniform distribution,
+      // Measurement Science Review, Vol 2, section 1, (2002), pages 1 - 7.
+      threshold = 1 - epsilon; // Wimmer equation 17, page 5
+      if (gamma < threshold) {
+        std::cout << "Epsilon " << epsilon << " is too small for gamma rounded/unrounded ratio " << gamma << ", threshold is " << threshold << " for uniform distribution." << std::endl;
+        return -1; // Not sure how to signal the problem here.
+      }
+      d = sqrt_3 * (gamma + 2 * epsilon - 1); // Wimmer equation 20, page 6.
+      return d;
+    case triangular:
+      // Gejza Wimmer, Viktor Witkovsky, Proper rounding of the measurement result under the assumtpion of triangular distribution,
+      // Measurement Science Review, Vol 2, section 1, (2002), pages 21 to 31.
+      threshold = (1 - gamma) / (1 + gamma);
+      if (epsilon < threshold) {
+        std::cout << "Epsilon " << epsilon << " is too small for gamma rounded/unrounded ratio " << gamma << ", threshold is " << threshold << " for triangular distribution." << std::endl;
+        return -1; // Not sure how to signal the problem here.
+      }
+      // d = sqrt(6 * (epsilon - ((1 - gamma) /(1 + gamma)))); // Wimmer equation 18, page 27.
+      d = sqrt(6 * (epsilon - threshold));
+      return d;
+    default:
+      // Might add one more (4th) distribution here - assuming distribution type is encoded using 2 bits in unc class.
+      return -1;
+  } // switch
+} // double delta(double epsilon, double gamma, distribution_type distrib = gaussian)
+
+double gamma(double rounded, double value) {/*! \brief Calculate Wimmer gamma rounded/unrounded function p 1664.
+  \details Measurement Science and Technolology, 11 (2000) 1659-1665. ISSN 0957-0233 S0957-233(00)13838-X.
+    Gejza Wimmer, Viktor Witkovsky, Tomas Duby
+    Proper rounding of the measurement results under normality assumptions.
+
+  \param rounded Value (as `double`) after rounding.
+  \param value Value (as `double`) before rounding. Assumes `rounded < unrounded value`.
+  \return Ratio rounded / value, a measure of loss of information caused by rounding.
+  */
+  // Is this OK for negative values?  Need to check or swap so result is <= 1.
+  // Use abs?
+  if (value == 0.) { // Avoid divide by zero (or very close to zero too?).
+    return 0.;
+  }
+  double g = rounded / value;
+  if (g > 1.) { // This seems necessary for some cases???
+    //std::cout << "value " << value << ", rounded " << rounded << std::endl;
+    g = 1. / g;
+  }
+  if (g > 1.) { // This seems necessary for some cases???
+    std::cerr << "value " << value << ", rounded " << rounded << std::endl;
+    //   assert(g <= 1.); // Assumes rounded < unrounded.
+  }
+
+  return g;
+} // double gamma(double rounded, double value)
+
+int round_m(double epsilon = 0.01, double sigma = 0., unsigned int sigma_sigdigits = 2U, distribution_type distrib = gaussian) { /*! \brief Calculate the Wimmer rounding digit m using delta and gamma functions p 1661, equation 12.
+  \details Measurement Science and Technology, 11 (2000) 1659-1665. ISSN 0957-0233 S0957-233(00)13838-X.
+  Gejza Wimmer, Viktor Witkovsky, Tomas Duby\n
+  Proper rounding of the measurement results under normality assumptions.
+
+  \param epsilon Rounding loss (as fraction) accepted (default is 0.01 or 1%).
+  \param sigma Uncertainty as standard deviation.
+  \param sigmasigdigits Number of significant decimal digits
+  for uncertainty to be rounded (range 1 to 4, default = 2), depending on degrees of freedom.\n
+  If degrees_of_freedom <= 2, then 1, else if degrees_of_freedom > 1000, then 3 else default = 2.
+  \param distribution_type Type of distribution (default gaussian, or triangular or uniform).
+
+   \return m Signed position of the digit to be used for rounding,
+    `m == 0` means use the units digit for rounding the tens digit.
+  */
+  if ((sigma_sigdigits < 1) || (sigma_sigdigits > 4)) { // sigma_sigdigits is too big to be plausible from the confidence interval of uncertainty.
+    sigma_sigdigits = 4; // or throw?
+  }
+  // \boost_1_40_0\libs\math\example\chi_square_std_dev_test.cpp
+
+  //Confidence level (two-sided) =  0.0500000
+  //Standard Deviation           =  1.0000000
+  //_____________________________________________
+  //Observations        Lower          Upper
+  //                    Limit          Limit
+  //_____________________________________________
+  //         2         0.4461        31.9102
+  //         3         0.5207         6.2847
+  //         4         0.5665         3.7285
+  //         5         0.5991         2.8736
+  //         6         0.6242         2.4526
+  //         7         0.6444         2.2021
+  //         8         0.6612         2.0353
+  //         9         0.6755         1.9158
+  //        10         0.6878         1.8256
+  //        15         0.7321         1.5771
+  //        20         0.7605         1.4606
+  //        30         0.7964         1.3443
+  //        40         0.8192         1.2840
+  //        50         0.8353         1.2461
+  //        60         0.8476         1.2197
+  //       100         0.8780         1.1617
+  //       120         0.8875         1.1454
+  //      1000         0.9580         1.0459
+  //     10000         0.9863         1.0141
+  //     50000         0.9938         1.0062
+  //    100000         0.9956         1.0044
+  //   1000000         0.9986         1.0014
+
+  // and in Owen L. Davies and Peter L. Goldsmith, Statistical Methods in Research and production, ISBN 0 05 002437, p 457 (1972)
+
+  // So for 2 observations, the uncertainty might be 30 times, or half the central estimate,
+  // meaning that a second digit is not likely to be significant.
+  // But for the more common several degrees of freedom,
+  // a second digit might be significant.
+  // So the ISO GUM pragmatically states that 2 significant decimal digits should be used for the standard uncertainty.
+  // It only when 1000 observations are available (and there are no problems with drift)
+  // a fractional relative standard deviation of uncertainty is about 0.05
+  // and that 3 significant decimal digits are needed avoid loss from rounding.
+  double sigma_rounded = round_sig(sigma, sigma_sigdigits);
+  // ISO GUM always rounds uncertainty to n=2 significant digits,
+  // but elsewhere Wimmer et al round to only *one* significant digit.
+  // So sigdigits is parameterized to allow variation from (possibly very many)
+  // (possibly known) degrees of freedom?
+
+  // Wimmer uses only one significant digit to round sigma, for reasons unclear.
+  // So tests that compare to the paper do not fail when epsilon has values in example 5, p1662.
+
+  double g = gamma(sigma_rounded, sigma);
+  // Check against limits in table 1, page 1662.
+  double gl;
+  double e = epsilon;
+  if (e >= 0.1) { // <= 10% loss from rounding accepted.
+    gl = 0.81271;
+  } else if (e >= 0.05) {
+    gl = 0.90175;
+  } else if (e >= 0.02) {
+    gl = 0.95951;
+  } else if (e >= 0.01) {
+    gl = 0.97954;
+  } else { // // <= 1% loss from rounding accepted.
+    gl = 0.98972;
+  }
+  if (gl > g) {
+    std::cout << "Cannot return a rounding m because epsilon " << e << " is too small!" << std::endl;
+    return -9999;
+  }
+  // Or throw?
+
+  double d = delta(epsilon, g, distrib);
+  if (d < 0.) { // Chosen epsilon is too small! (for example, e = 0.01 loss is too demanding, so try 0.02).
+    std::cout << "Cannot compute a rounding digit index m because epsilon " << epsilon << " is too small!" << std::endl;
+    return -9999; // or throw.
+  }
+  d = d * sigma_rounded / (5 * g); // Wimmer equation 12, page 1661.
+  // (and same for triangular distribution equation 10, page 24,
+  // and uniform distribution equation 22, page 6).
+  d = log10(d);
+  return static_cast<int> (floor(d)); // \return m the position of the digit to be used for rounding.
+  // m == 0 means use the units digit for rounding the tens digit...
+} // int round_m(double epsilon, double sigma, unsigned int sigdigits)
+
+std::string round_ue(double v, double sigma, double epsilon = 0.01, unsigned int sigdigits = 2U) { /*! \brief Properly round value to a decimal digit `std::string`.
+  \details Measurement Science and Technolology, 11 (2000) 1659-1665. ISSN 0957-0233 S0957-233(00)13838-X.\n
+    Gejza Wimmer, Viktor Witkovsky, Tomas Duby,
+    Proper rounding of the measurement results under normality assumptions.
+    p 1661, equation 12.
+
+    \param v Central value, often estimate of mean.
+    \param sigma Uncertainty of value, usually standard deviation.
+    \param epsilon Fraction of loss of accuracy from rounding permitted (default 1%).
+    \param sigdigits Number of digits that are significant (default 2).
+
+    \return Decimal digit `std::string` containing rounded value.
+  */
+  //int round_m(double epsilon, double unc, unsigned int sigdigits, distribution_type t);
+  int m = round_m(epsilon, sigma, sigdigits, gaussian);
+  std::string r = round_ms(v, m);
+  return r;
+} // string round_ue(double v, double unc, double epsilon = 0.01, unsigned int sigdigits = 2U)
+
+std::pair<double, double> conf_interval(double mean, double sigma, double df = 1., double alpha = 0.05, distribution_type distrib = gaussian) { /*!
+    \brief Calculate confidence interval for chosen alpha confidence level and chosen distribution type.
+    \details Uses confidence interval equations from:\n
+       Gejza Wimmer, Viktor Witkovsky, Tomas Duby
+       Measurement Science and Technolology, 11 (2000) 1659-1665. ISSN 0957-0233 S0957-233(00)13838-X.
+       Proper rounding of the measurement result under the assumption of gaussian distribution,\n
+       Confidence interval equation 6, p 1660.
+
+       Gejza Wimmer, Viktor Witkovsky, Tomas Duby\n
+       Measurement Science and Technolology, 11 (2000) 1659-1665. ISSN 0957-0233 S0957-233(00)13838-X.\n
+       Proper rounding of the measurement result under the assumption of triangular distribution,\n
+       Measurement Science Review, Vol 2, section 1, (2002), pages 21 to 31.\n
+       Confidence interval Equation 12, page 25.\n
+
+       Gejza Wimmer, Viktor Witkovsky,\n
+       Proper rounding of the measurement result under the assumption of uniform distribution,\n
+       Measurement Science Review, Vol 2, section 1, (2002), pages 1 - 7.\n
+       Confidence interval, page 5, equation 13.\n
+
+    \param mean Interval estimate for mean mu.
+    \param unc Standard uncertainty sigma from variance sigma σ ².
+    \param df Degrees of freedom (usually number of observations -1).
+    \param alpha Confidence (0. < unc < 1.), typically 0.05 for 95% confidence.
+      alpha/2 = 0.025 quantile = -1.96, and 1 - alpha/2 is 1.96 for normal distribution,
+      so typically confidence interval is roughly twice unc either side (+ or - ) of mean.
+    \param distrib distribution type, gaussian(default), uniform, triangular, laplace.
+    \return Confidence interval upper and lower limits as a `std::pair` of doubles.
+  */
+  assert(alpha >= 0.);
+  assert(alpha <= 1.);
+  std::pair<double, double> ci;
+  switch (distrib) {
+    case gaussian:
+    { // Gejza Wimmer, Viktor Witkovsky, Tomas Duby
+      // Measurement Science and Technolology, 11 (2000) 1659-1665. ISSN 0957-0233 S0957-233(00)13838-X.
+      // Wimmer p 1660, equation 6.
+      using boost::math::normal;
+      normal dist; // zero mean and unit sd. == normal dist(0., 1.);
+      // Divide alpha by 2 because estimating upper and lower bounds.
+      double t = quantile(complement(dist, alpha / 2));
+      // std::cout << t << endl; // 1.95996 for alpha 0.05
+      // one-sided confidence interval.
+      double u = (df > 1) ? sigma / sqrt(df) : sigma;
+      double w = t * u; //
+      ci.first = mean - w;
+      ci.second = mean + w;
+      return ci;
+    }
+      break;
+    case triangular:
+    { // Gejza Wimmer, Viktor Witkovsky,
+      // Proper rounding of the measurement result under the assumption of triangular distribution,
+      // Measurement Science Review, Vol 2, section 1, (2002), pages 21 to 31.
+      // Confidence interval Equation 12, page 25.
+      using boost::math::triangular;
+      // boost::math version of triangular includes the mode c, as well as the limits a and b
+      // We really want the symmetric_triangular, but approximate with a = -1, c = 0 and b = +1.
+      // This NOT the boost::math default.
+      // Or could implement symmetric_triangular?
+      double u = (df > 1) ? sigma / sqrt(df) : sigma;
+      static const double sqrt_6 = 2.4494897427831780981972840747058913919659474804966; // sqrt(6)
+      triangular dist(-sqrt_6, 0., +sqrt_6); // Wimmer page 23, below eq 6.
+      double tlo = quantile(complement(dist, alpha / 2));
+      double thi = quantile(dist, alpha / 2);
+      // Wimmer page 24, quantile function (cdf inverse), equation 8.
+      ci.first = mean - tlo * u;
+      ci.second = mean - thi * u;
+      return ci;
+    }
+    case uniform: // aka rectangular distribution.
+    { // Gejza Wimmer, Viktor Witkovsky,
+      // Proper rounding of the measurement result under the assumption of uniform distribution,
+      // Measurement Science Review, Vol 2, section 1, (2002), pages 1 - 7.
+      // Confidence interval, page 5, equation 13.
+      static const double sqrt_3 = 1.7320508075688772935274463415058723669428052543712; // sqrt(3)
+      double u = (df > 1) ? sigma / sqrt(df) : sigma;
+      using boost::math::uniform;
+      uniform udist(-sqrt_3, +sqrt_3);
+      double tlo = quantile(complement(udist, alpha / 2)); // effectively quantile(1 - alpha/2)
+      double thi = quantile(udist, alpha / 2);
+      ci.first = mean - tlo * u;
+      ci.second = mean - thi * u;
+      return ci;
+    }
+    default: // As yet undefined distribution.
+      ci.first = std::numeric_limits<double>::quiet_NaN();
+      ci.second = std::numeric_limits<double>::quiet_NaN();
+      break;
+  } //   switch (distribution_type)
+  return ci;
+} // std::pair<double, double> conf_interval(double value, double unc, double alpha = 0.05)
+
+static const double sqrt_2 = 1.4142135623730950488016887242096980785696718751217; // sqrt(2)
+static const double sqrt_6 = 2.4494897427831780981972840747058913919659474804966; // sqrt(6)
+static const double oneDivSqrtSix = 0.40824829046386301636621401245098189866099124674943; // 1/sqrt(6)
+static const double oneDivTwoSqrtSix = 0.20412414523193150818310700622549094933049562337472; // 1/(2*sqrt(6))
+static const double sqrt_3 = 1.7320508075688772935274463415058723669428052543712; // sqrt(3)
+
+double cdf_uni(double z) { /*! Cumulative distribution Function of uniform distribution Un(-sqrt_3, + sqrt_3),
+   with an expectation of mean zero and variance unity.
+    Gejza Wimmer & Victor Witkovsky, Measurement Science Review, volume 2 section 1 2002, page 3, equation 5.
+   \return Cumulative distribution Function of uniform distribution.
+  */
+  if (z <= -sqrt_3) {
+    return 0.;
+  } else if (z >= sqrt_3) {
+    return 1.;
+  } else if (z == 0.) {
+    return 0.5;
+  }
+  return (z + sqrt_3) / (2 * sqrt_3);
+} // double cdf_uni(double z)
+
+double quantile_uni(double alpha) { /*! Quantile of uniform distribution Uniform(-sqrt_3, + sqrt_3), expectation or mean zero and variance unity.
+   Wimmer & Witkovsky, Measurement Science Review, volume 2 section 1 2002, page 3, eq 6.
+   \return Quantile of uniform distribution.
+  */
+  static const double sqrt_3 = 1.7320508075688772935274463415058723669428052543712; // sqrt(3)
+  assert(alpha >= 0.);
+  assert(alpha <= 1.);
+  return sqrt_3 * (2 * alpha - 1);
+} // double quantile_uni(double alpha)
+
+double cdf_tri(double z) { /*! Cumulative distribution function CDF of triangular distribution.
+    Gejza Wimmer, Viktor Witkovsky, Tomas Duby,
+    Proper rounding of the measurement result under the assumption of triangular distribution,
+    Measurement Science Review, Vol 2, section 1, (2002), page 24, equation 7.
+
+    \param z
+    \return CDF of triangular distribution.
+  */
+
+  if (z < -sqrt_6) {
+    return 0.;
+  } else if (z > sqrt_6) {
+    return 1.;
+  } else if (z == 0.) { // Or might check if very near zero too?
+    return 0.5;
+  }
+  double zz = oneDivTwoSqrtSix * z * z;
+  if (z < 0.) {
+    return 0.5 + oneDivSqrtSix * (z + zz);
+  } else { //  if (z > 0.)
+    return 0.5 + oneDivSqrtSix * (z - zz);
+  }
+} // double cdf_tri(double z)
+
+double quantile_tri(double alpha) { /*! Quantile or Inverse of cumulative distribution function CDF of triangular distribution.
+  Gejza Wimmer, Viktor Witkovsky, Tomas Duby,
+  Proper rounding of the measurement result under the assumption of triangular distribution,
+  Measurement Science Review, Vol 2, section 1, (2002), page 24, equation 8.
+
+  \param alpha Confidence level.
+  \return Quantile or Inverse of cumulative distribution function CDF.
+  */
+  assert(alpha >= 0.);
+  assert(alpha <= 1.);
+
+  if (alpha < 0.5) { // 0<= alpha < 0.5
+    return sqrt_6 * (sqrt(2. * alpha) - 1.);
+  } else { // 0.5 < alpha < 1.
+    return sqrt_6 * (1. - sqrt(2. * (1. - alpha)));
+  }
+} // double quantile_tri(double z)
+
+void out_confidence_interval(std::pair<double, double> ci, int m, std::ostream& os = std::cout) { /*! Output to os, confidence interval enclosed in brackets and separated by comma.
+      The precision is controlled by the rounding order `m` used for the mean
+      but with one extra decimal digit of precision, so rounding to m-1 th place.
+      For example: <99.5, 156.5> rounding to -1 position
+      (where the mean was rounded with m == 0,
+      using the units digit to round the tens digit to "128.")
+
+      \param ci Confidence interval or limits.
+      \param m Signed position for rounding.
+      \param os `std::ostream` for output.
+  */
+  std::streamsize osp = os.precision(); // Save to restore.
+  os.precision(3); // Uncertainty always rounded to 2 decimal digits.
+  using boost::lexical_cast;
+  os << "<" << lexical_cast<double>(round_ms(ci.first, m - 1)) << ", "
+          << lexical_cast<double>(round_ms(ci.second, m - 1)) << ">";
+  os.precision(osp); // Restore saved.
+} // void out_confidence_interval(std::pair ci)
+
+void out_value_limits(double mean, double unc, std::pair<double, double> ci, int m, std::ostream& os = std::cout) { /*! Output mean, uncertainty and confidence interval.
+  For example: \verbatim  128. +/- 15 <99.5, 156.5>  \endverbatim
+
+    \param mean Mean or central estimate of value.
+    \param unc Uncertainty estimate as standard deviation.
+    \param Signed position for rounding.
+    \param m
+    \param os `std::ostream` for output.
+  */
+  std::streamsize osp = os.precision(); // Save to restore.
+  os.precision(2); // Uncertainty always rounded to 2 decimal digits.
+  double unc_rounded = round_sig(unc, 2); // Round to 2 significant digit - ISO rules.
+  // TODO increase here if noisydigit wanted,
+  // and/or if degress of freedom > 100.
+  os << round_ms(mean, m) << " +/- " << unc_rounded;
+  os.precision(6); //
+  using boost::lexical_cast;
+  os << " <" << lexical_cast<double>(round_ms(ci.first, m - 1)) << ", "
+          << lexical_cast<double>(round_ms(ci.second, m - 1)) << ">";
+  os.precision(osp); // Restore saved.
+} // void out_value_limits
+
+void out_value_df_limits(double mean, double unc, int degfree = 1, std::ostream& os = std::cout) { /*! Output mean, uncertainty and confidence interval.
+  For example: \verbatim  128. +/- 15 <99.5, 156.5>  \endverbatim
+
+    \param mean Mean or central estimate of value.
+    \param unc Uncertainty estimate as standard deviation.
+    \param Signed position for rounding.
+    \param m
+    \param os `std::ostream` for output.
+  */
+  std::streamsize osp = os.precision(); // Save to restore.
+
+  int round_m(double epsilon, double unc, unsigned int sigdigits, distribution_type t);
+  // int round_m(double epsilon = 0.01, double unc = 0., unsigned int uncsigdigits = 2U, distribution_type distrib = gaussian)
+
+  double e = 0.01;
+  int m = round_m(e, unc, 2U, gaussian);
+
+  std::pair<double, double> ci;
+  ci = conf_interval(mean, unc, degfree);
+
+  os.precision(2); // Uncertainty always rounded to 2 decimal digits.
+  double unc_rounded = round_sig(unc, 2); // Round to 2 significant digit - ISO rules.
+  // TODO increase here if noisydigit wanted,
+  // and/or if degress of freedom > 100.
+  os << round_ms(mean, m) << " +/- " << unc_rounded;
+  os.precision(6); //
+  using boost::lexical_cast;
+  os << " <" << lexical_cast<double>(round_ms(ci.first, m - 1)) << ", "
+          << lexical_cast<double>(round_ms(ci.second, m - 1)) << ">";
+  os.precision(osp); // Restore saved.
+} // void out_value_limits
+
+// Above is missing degrees of freedom included in unc type.
Added: sandbox/SOC/2007/quan/boost/quan/si_units.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/si_units.hpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,281 @@
+/*!
+  \file
+  \brief SI Unit, names and abbreviations & conversion factors.
+
+  \details
+    See NIST 811 Special publication, Barry N Taylor (1995)
+    "Guide for the Use of the International System of Units (SI)
+    & ISO 31, a closely aligned document.
+    NIST version contains more on non-SI units and many useful notes.
+ */
+
+// Data & code to show units in si_units.cpp which includes this header.
+// Changed to unit starting with capital so time doesn't clash with C time()
+
+// SIunits.hpp
+
+// Copyright Paul A. Bristow 2009, 2012.
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef SIUNITS_HPP
+#define SIUNITS_HPP
+
+#ifdef _MSC_VER
+#  pragma once
+#endif
+
+#include <iostream>  // Used by show units functions.
+using std::ostream;
+using std::string;
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::size_t;
+
+const unsigned int notOK = 0xffffffff;
+
+const int maxPowerTen = 38;
+// == std::numeric_limits<float>::max_exponent10;
+// == FLT_MAX_10_EXP in float.h, so can represent FLT_MAX = 3.402823466e+38F;
+// to FLT_MIN_10_EXP in float.h, so can represent FLT_MIN = 1.175494351e38F;
+// Done to limit the size of the power of Ten lookup table below,
+// and make code same if store value in a 32-bit double.
+// For real-life data, value of a unit is unlikely to exceed 10**38,
+// despite DBL_MAX_10_EXP == 308.
+
+extern const double powersOfTen [maxPowerTen + 1 + maxPowerTen];
+ // 1 is middle zeroth power.
+const int maxRounds = 17;
+extern const double rounds[maxRounds];
+
+const int maxPowerTens = maxPowerTen + 1 + maxPowerTen;
+const int SImaxPowerTen = 24; // Define array sizes.
+// SImaxPowerTen < maxPowerTen, until new names invented for more units.
+const int SIminPowerTen = -24; // yotta & min 10**-24
+const char* SIprefixes[]; // [0] to [48], countof = 49 (defined in si_units.cpp).
+const char* SIsymbols [];
+const int SImaxPowers = SImaxPowerTen + 1 + SImaxPowerTen;
+const int SIprefixesLength = SImaxPowerTen + 1 + SImaxPowerTen;
+// = sizeof SIprefixes /sizeof (const char*);
+
+struct SImultiple;
+
+// Fundamental units: Mass, Length, Time, Charge, Temperature, Luminous Intensity & angle.
+
+struct unit
+{
+public:
+  const char* unitOf;  // "mass", "length", "time" ...
+    // unsigned char here causes need to int( )
+    // better to use short int?  
+    // if const.
+    // C2552: non-aggregates cannot be initialized with initializer list.
+    // but can't see why - looks aggregate enough to me. 
+  unsigned char unitSINameCount;  // Countof SI unitName (meter = 5 + 1 = 6).
+  // = length of SIunitsNames[0]  ????????? not used and wrong?
+  unsigned char unitAbbrevCount; // Count of chars in abbreviation (Hz = 2).
+  unsigned char unitNamesCount; // Count of units (no plurals or aliases or abbreviations)
+  // : meter, feet, inch...
+  // = length of array unitNames.
+  unsigned char unitsNamesCount;  // Total number of all names for all units. 
+  // (including plurals, abbreviations & aliases).
+  // None of these include terminating zero.
+  // Can't be const or triggered C2552 - wrongly?
+  // So instantiate as const unit ...
+  const int* unitLengths; // Count of aliases & abbreviations for each unit.
+  const char** SIunitNames;  // SI or preferred unit, for example: "meter"
+  // SI unit MUST be always FIRST in list of unitNames = unitsNames[0],
+  // & SI abbreviation second.
+  const char* SIunitAbbrev;  // "m", "Hz" = SIunitNames[1];
+  const char*** unitNames; // "meter", "feet", "mile" ...
+  // By convention, unitNames[0] is the base or full unit name, like meter,
+  // & unitNames[1] is the abbreviation, like m.
+  const double* unitToSIfactors;  // factors to convert to SI unit.
+  // Dimensions here? - see project algebra, but not workable with MSVC++5SP3.
+};
+
+// Attempts to define a structure
+// const char s[];
+// const int l;  // const here produces C2552
+// failed for compiler reasons - Quincy GNU seems to allow.
+// so for now keep array lengths separate from arrays themselves.
+
+// Definitions in SIunits.cpp for separate compilation.
+
+// Dimensionless units.
+extern const int noUnitCount;
+extern const char* noUnits [];
+extern const unit noUnit;
+extern const int perCentUnitCount;
+extern const char* perCentUnits [];
+extern const int perMilleUnitCount;
+extern const char* perMilleUnits [];
+extern const int perMillionUnitCount;
+extern const char* perMillionUnits[];
+extern const int perBillionUnitCount;
+extern const char* perBillionUnits [];
+extern const int perTrillionUnitCount;
+extern const char* perTrillionUnits [];
+extern const char** dimlessNoUnits []; 
+extern const int dimlessUnitsCounts[];
+extern const double NoUnitsFactors [];
+extern const unit noUnit;
+
+// Units of mass: gram, kg, ton, cwt, lb, oz...
+extern const int massUnitCount; 
+extern const int gramMassUnitCount;  
+extern const char* gramMassUnits [];
+extern const int tonMassUnitCount;
+extern const char* tonMassUnits[];
+extern const int cwtMassUnitCount;
+extern const char* cwtMassUnits[];
+extern const int lbMassUnitCount;
+extern const char* lbMassUnits [];
+extern const int ozMassUnitCount;
+extern const char* ozMassUnits [];
+extern const char** massUnits [];
+extern const int massUnitsCounts [];
+extern const double massToSIfactors[];
+extern const unit mass;
+
+// Units of Length.
+extern const int lengthUnitCount; // meter, mile, yard, feet, inch, point
+extern const int meterLengthUnitCount;
+extern const char* meterLengthUnits[];
+extern const int mileLengthUnitCount;
+extern const char* mileLengthUnits[];
+extern const int yardLengthUnitCount;
+extern const char* yardLengthUnits [];
+extern const int feetLengthUnitCount;
+extern const char* feetLengthUnits [];
+extern const int inchLengthUnitCount;
+extern const char* inchLengthUnits [];
+extern const int pointLengthUnitCount;
+extern const char* pointLengthUnits [];
+extern const double lengthToSIfactors[];
+extern const char** lengthUnits [];
+extern const int lengthUnitsCounts[];
+extern const unit length;
+
+// Units of time: second, minute, hour ...
+extern const int timeUnitCount;
+extern const int secondTimeUnitCount;
+extern const char* secondTimeUnits [];
+extern const int secondTimeUnitCount;
+extern const char* secondTimeUnits [];
+extern const int minuteTimeUnitCount;
+extern const char* minuteTimeUnits [];
+extern const int hourTimeUnitCount;
+extern const char* hourTimeUnits [];
+extern const int dayTimeUnitCount;
+extern const char* dayTimeUnits [];
+extern const int monthTimeUnitCount;
+extern const char* monthTimeUnits [];
+extern const int yearTimeUnitCount;
+extern const char* yearTimeUnits [];
+extern const int fortnightTimeUnitCount;
+extern const char* fortnightTimeUnits [];
+extern const double timeToSIfactors[];
+extern const char** timeUnits [];
+extern const int timeUnitsCounts [];
+extern const unit Time; // Upper case to avoid clash with C global time.
+// time() is in C time.h
+
+// Units of current: amp
+extern const int currentUnitCount;
+extern const int ampCurrentUnitCount;
+extern const char* ampCurrentUnits[];
+extern const double currentToSIfactors [];
+extern const char** currentUnits [];
+extern const int currentUnitsCounts [];
+extern const unit current;
+
+// Units of Temperature: degress Kelvin & Celsius
+extern const int temperatureUnitCount;
+extern const int kTemperatureUnitCount;
+extern const char* kelvinTemperatureUnits[];
+extern const int cTemperatureUnitCount;
+extern const char* celsiusTemperatureUnits[];
+extern const int fTemperatureUnitCount;
+extern const char* fahrenheitTemperatureUnits[];
+extern const double temperatureToSIfactors[];
+extern const char** temperatureUnits[];
+extern const int temperatureUnitsCounts [];
+extern const unit temperature;
+
+// Units of substance: Mole.
+extern const int substanceUnitCount;  // just moles
+extern const int molSubstanceUnitCount;
+extern const char* molSubstanceUnits[];
+extern const double substanceToSIfactors[];
+extern const char** substanceUnits [];
+extern const int substanceUnitsCounts [];
+extern const unit substance;
+
+// Units of luminous intensity: candela ...
+extern const int lumintensityUnitCount;;
+extern const int candelaLumintensityUnitCount;
+extern const char* candelaLumintensityUnits[];
+extern const double lumintensityToSIfactors[];
+extern const char** lumintensityUnits [];
+extern const int lumintensityUnitsCounts [];
+extern const unit lumintensity;
+
+// Frequency: Hertz.
+extern const int freqUnitCount;
+extern const int hertzFreqUnitCount;
+extern const char* hertzFreqUnits [];
+extern const double freqToSIfactors [];
+extern const char** freqUnits [];
+extern const int freqUnitsCounts [];
+extern const unit freq;
+
+  // Charge: Coulomb.
+extern const int chargeUnitCount;
+extern const int coulombChargeUnitCount;
+extern const char* coulombChargeUnits[];
+extern const int ampHourChargeUnitCount;
+extern const char* ampHourChargeUnits[];
+extern const double chargeToSIfactors[];
+extern const char** chargeUnits [];
+extern const int chargeUnitsCounts [];
+extern const unit charge;
+
+// Unknown unit.
+extern const int unknownUnitCount; 
+extern const int unknownCount;
+extern const char* unknownunit [];
+extern const int unknownUnitsCount;
+extern const char** unknownUnits []; 
+extern const int unknownUnitsCounts [];
+extern const double unknownUnitsFactors [];
+extern const unit unknownUnit;
+
+// Array of all units.
+extern const int unitsCount;
+extern const unit* unitps[];  // 7 SI base units: & then others.
+
+// Declarations of functions to show units (see SIunits.txt)
+extern void showAllUnits(const unit*, ostream&);  // mass, length, time ...
+extern void showSIunit(const unit*, ostream&);  //
+extern void showSIunits(const unit*, ostream&); // Show the SI unit & aliases.
+extern void showNonSIunits(const unit*, ostream&);
+  // Show just the base Non SI units, but not aliases.
+extern void showAllNonSIunits(const unit*, ostream&);
+  // Show all the Non SI units.
+
+unsigned int findUnit(const string, // multiple unit
+                      const unit*, // unit
+                      unsigned int&, // index of name, alias or abbrev given unit.
+                      unsigned int&); // SIindex.
+
+const unit& findAnyUnit(const string, // multiple unit
+                      unsigned int&, // index.
+                      unsigned int&, // index of name, alias or abbrev given unit.
+                      unsigned int&); // SIindex.
+
+#endif // SIUNITS_HPP
Added: sandbox/SOC/2007/quan/boost/quan/type_erasure_printer.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/type_erasure_printer.hpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,231 @@
+// Boost.TypeErasure decor printer
+//
+// Copyright 2011 Steven Watanabe
+// Copyright 2012 Paul A. Bristow
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// from \boost-sandbox\type_erasure\libs\type_erasure\example\print_sequence.cpp
+
+#ifndef BOOST_TYPE_ERASURE_PRINTER
+#define BOOST_TYPE_ERASURE_PRINTER
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/iterator.hpp>
+#include <boost/type_erasure/operators.hpp>
+#include <boost/type_erasure/tuple.hpp>
+#include <boost/type_erasure/same_type.hpp>
+#include <boost/type_erasure/callable.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/iterator.hpp>
+
+#include<iostream>
+#include <iomanip>
+
+using namespace boost::type_erasure;
+
+// Placeholders used by the abstract printer during specification of requirements.
+struct _t : boost::type_erasure::placeholder {};
+struct _iter : boost::type_erasure::placeholder {};
+struct _os : boost::type_erasure::placeholder {};
+// This is more readable than using the 'out of the box' _a, ... _g placeholders.
+// See placeholder.hpp.
+
+template<class T, class U = _self>
+struct base_and_derived
+{ // Template parameter for concept_interface.
+  // and in list of requirements in abstract printer.
+  // base_and_derived<std::ios_base, _os>, // _os must derive from std::ios_base.
+    static T& apply(U& arg) { return arg; }
+};
+
+namespace boost {
+namespace type_erasure {
+
+template<class T, class U, class Base>
+struct concept_interface<base_and_derived<T, U>, Base, U> : Base
+{
+    operator typename rebind_any<Base, const T&>::type() const
+    {
+        return call(base_and_derived<T, U>(), const_cast<concept_interface&>(*this));
+    }
+    operator typename rebind_any<Base, T&>::type()
+    {
+        return call(base_and_derived<T, U>(), *this);
+    }
+};
+
+// Fully specialized for const std::pair<const int, double>&
+//std::ostream& operator<< (std::ostream& os, const std::pair<const int, double>& p)
+//{ /*! Output a pair of values.
+//     \details For example: "1.23 , 3.45".
+//   */
+//  os << p.first << ", " << p.second;
+//  return os;
+//} // std::ostream& operator<<
+
+// But more useful is just providing the two template version:
+
+template <typename T1, typename T2>
+std::ostream& operator<< (std::ostream& os, const std::pair<T1, T2>& p)
+{ /*! Output a pair of values with space as delimiter.
+     \details For example: "1.23 3.45".
+   */
+  os << p.first << " " << p.second;
+  return os;
+} // std::ostream& operator<< (std::ostream& os, const std::pair<T1, T2>& p)
+
+// Or can use a version defined elsewhere, for example, in namespace my_detail?
+
+//  using my_detail::operator<<;
+
+// Partial specialization of struct ostreamable for pair<const int, double>:
+//template<class Os>
+//struct ostreamable<Os, std::pair<const int, double> >
+//{
+//    static void apply(Os& out, const std::pair<const int, double>& arg)
+//    {
+//      out << arg;
+//   }
+//};
+
+// Partial specialization of struct ostreamable for pair<T1, T2>:
+template<class Os, typename T1, typename T2>
+struct ostreamable<Os, std::pair<T1, T2> >
+{
+    static void apply(Os& out, const std::pair<T1, T2>& arg)
+    {
+      out << arg;
+   }
+};
+
+} // namespace type_erasure
+} // namespace boost
+
+/*! An abstract sequence printer - a 'template' that is inherited
+ to implement the examples of actual printers defined below.
+ */
+ 
+template< class CharT = char, class Traits = std::char_traits<char> >
+class abstract_printer
+{
+public:
+    //! \tparam Range must be a Forward Range whose elements can be printed to `ostream os`.
+    //! \param r Container to be printed, for example, a C array, std::vector, std::list ...
+    //! \param os  `std::ostream` for printing, for example std::cout.
+ 
+    template<class Range, class CharT, class Traits>
+    void print(const Range& r, std::basic_ostream<CharT, Traits>& os = std::cout) const
+    {
+        // Capture the print arguments.
+        // Range iterators.
+        typename boost::range_iterator<const Range>::type
+            first(boost::begin(r)),
+            last(boost::end(r));
+        // Assemble requirements into tuple: range pair of iterators and ostream.
+        tuple<requirements, _iter, _iter, _os&> args(first, last, os);
+        // and forward to the real implementation.
+        do_print(get<0>(args), get<1>(args), get<2>(args));
+        // get<0>() is first, get<1>() is last,  get<2>() is ostream.
+    }
+    virtual ~abstract_printer() {}
+protected:
+  // Define the requirements in an mpl::vector for containers to be printed.
+    typedef boost::mpl::vector<
+        base_and_derived<std::ios_base, _os>, // _os must derive from std::ios_base.
+        ostreamable<_os, _t>, // type _t must be ostreamable.
+        ostreamable<_os, const char*>, // C string must be ostreamable.
+        forward_iterator<_iter, const _t&>, // t range must have forward iterator.
+        same_type<_t, forward_iterator<_iter, const _t&>::value_type> // _t's type value and iterator must match.
+    > requirements;
+
+    // Use type_erasure::any to enforce the requirements onto ostream and iterator.
+    typedef boost::type_erasure::any<requirements, _os&> ostream_type;
+    typedef boost::type_erasure::any<requirements, _iter> iterator_type;
+    // Declare the pure virtual function `do_print` that is defined in all real printers.
+    virtual void do_print(iterator_type first, iterator_type last, ostream_type os) const = 0;
+}; // class abstract_printer
+
+/*!
+ Outputs items in a specified number of columns across rows with a separator (often comma and/or space(s)),
+ and a suffix (usually newline) every `num_column`s items.\n
+ Usage: `decor_printer simple_printer(3, 0, "\n", ", ", "\n", "\n");`\n
+ Provide a container to be printed: `double da[] = {1., 2., 3., 4., 5., 6.};`\n
+ Print to std::cout using: `simple_printer.print(std::cout, da);` \n
+ Output:\n
+ 1, 2, 3,\n
+ 4, 5, 6,\n
+ 7, 8, 9,\n 
+ 10, 11, 12\n
+ The order of parameters is chosen to try to allow use of the defaults as much as possible, 
+ including all defaults placing all items on one line or row separated by spaces.
+ 
+  \param num_columns number of columns (default 0, so all items are on the same line or row).
+  \param width ostream width to use to each items (default 0 so that columns may be jagged).
+  \param pre string to be output before the first column,
+  (default newline which ensures that the first item is at the left margin).
+  \param sep string to separate (or delimit) items on each row (default space).
+  \param suf suffix at the end of each row (default newline).
+  \param term string to terminate the last row
+*/
+class decor_printer : public abstract_printer<>
+{
+public:
+    explicit decor_printer(
+      std::size_t num_columns = 0,
+      std::size_t wid = 0,
+      const std::string& pre = "\n",
+      const std::string& sep = " ",
+      const std::string& suf = "\n",
+      const std::string& term = "\n")
+      :
+    cols(num_columns), width(wid), prefix(pre), separator(sep), terminator(term), suffix(suf)
+    { /*! Constructor.\n
+       Usage: for example: ``3, 10, "double testd[] = {\n    ", ", ", "\n    ", "\n  };\n"``
+       3 columns with width 10, prefix "double testd[] = {\n    ", separator string comma space,
+       suffix (newline at the end of a column),
+       and a terminator string "\n  };\n".\n
+       Defaults are provided for all parameters, so can contruct: `my_default_printer decor_printer;`\n
+       that places all items on one line or row with space between items, and a final newline.
+      */
+    }
+protected:
+  // Print all items in rows.
+    virtual void do_print(iterator_type first, iterator_type last, ostream_type os) const
+    {
+        os << prefix.c_str();
+        std::size_t count = 0;
+        for(; first != last; ++first)
+        {
+            if (width > 0)
+            {
+              static_cast<std::ios_base&>(os).width(width);
+            }
+            os << *first;
+            boost::type_erasure::any<requirements, _iter> temp = first;
+            ++temp;
+            if(temp != last)
+            {
+              os << separator.c_str();
+            }
+            ++count;
+            if((cols != 0) && (count % cols == 0))
+            { // Last column.
+                os << suffix.c_str(); // Usually newline at end of a row.
+            }
+        }
+        os << terminator.c_str(); // Perhaps useful to have a terminating newline?
+    }
+private:
+    std::size_t cols; // Set by constructor, number of columns (default 10).
+    std::size_t width; // Set by constructor, optional column width (default zero).
+    std::string prefix; // Set by constructor, for example, "{ ".
+    std::string separator; // Set by constructor, for example, ", ".
+    std::string suffix; // Set by constructor, for example "\n".
+    std::string terminator; // Set by constructor, for example, "}\n".
+}; // class decor_column_printer
+
+#endif // ifndef BOOST_TYPE_ERASURE_PRINTER
Added: sandbox/SOC/2007/quan/boost/quan/unc.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/unc.hpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,2114 @@
+/*! \file 
+   \brief Class for simple Propagation of Uncertainties according to a pure Gaussian model.
+
+    \details Based on code by Evan Manning (manning_at_[hidden])
+    Evan Marshal Manning, C/C++ Users Journal, March 1996 page 29 to 38.
+    original downloaded from ftp://beowulf.jpl.nasa.gov/pub/manning
+    This is a simple model of uncertainties, designed to
+    accompany an article published in C/C++ Users Journal March 1996
+    at http://www.ddj.com/cpp/184403147 .
+    A fuller collection of even fancier classes also given in unc.h.
+
+    Standard deviation & its uncertainty added Paul A Bristow 31 Mar 98 to May 2012.
+
+  \mainpage
+  \n
+  \b Boost.Quan
+
+This is the standalone Doxygen main page of the proposed Boost.Quan library.
+
+This library provides a collection of classes and functions for handling uncertain reals.
+
+Uncertainty as standard deviation and degrees of freedom are 
+propagated through calculations using the uncertain type,
+and are input and output including the uncertainty estimates.
+
+See Boost.Quan HTML Manual at
+
+  https://svn.boost.org/svn/boost/sandbox/quan/libs/quan/doc/html/index.html
+
+and/or equivalent PDF Manual at:
+
+  https://svn.boost.org/svn/boost/sandbox/quan/libs/quan/doc/quan.pdf
+
+Examples are in folder:
+
+  https://svn.boost.org/svn/boost/sandbox/quan/libs/quan/example/
+
+and C++ include files are in folder:
+
+  https://svn.boost.org/svn/boost/sandbox/quan/boost/quan/
+
+*/
+
+// unc.hpp
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// Copyright Paul A. Bristow 1998, 2012.
+
+#ifndef UNC_HPP
+#define UNC_HPP
+
+#ifdef _MSC_VER
+#  pragma once
+#  pragma warning (disable : 4127) // conditional expression is constant.
+#  pragma warning (disable : 4800)// forcing value to bool 'true' or 'false' (performance warning).
+#  pragma warning (disable : 4189) // local variable is initialized but not referenced.
+// Could use no_unused_variable_warning(x);
+//template<class T> // Avoid MSVC warning "C4189 variable initialised but not used".
+//inline void no_unused_variable_warning(const T&) {}
+#endif//  _MSC_VER
+
+#include <boost/math/special_functions/fpclassify.hpp>
+  //using boost::math::isnan;
+  //using boost::math::isinf;
+  //using boost::math::isfinite;
+  //using boost::math::isnormal; // isfinite and not denormalised.
+// Might instead use the std TR1 versions?
+
+#include <cstdlib>  //
+#include <cmath>   // for log, exp etc
+#include <iostream> //
+  //using std::istream;
+  //using std::ostream;
+  //using std::ios_base;
+  //using std::char_traits;
+  //using std::cout;
+  //using std::cerr;
+  //using std::cin;
+  //using std::endl;
+  //using std::flush;
+  //using std::ws;
+  //using std::streamsize;
+  //using std::boolalpha;
+  //using std::dec;
+  //using std::hex;
+  //using std::showbase;
+  //using std::fixed;
+  //using std::scientific;
+  //using std::right;
+  //using std::showpos;
+  //using std::noshowpos;
+  //using std::noshowbase;
+  //using std::noshowpoint;
+  //using std::showpoint;
+
+#include <iomanip>  //
+  //using std::setprecision;
+  //using std::setw;
+  //using std::resetiosflags;
+#include <algorithm>
+  //using std::max;
+  //using std::min;
+
+#include <sstream> //
+ // using std::ostringstream;
+#include <limits>  // for numeric_limits<unsigned short>::max() etc
+//  using std::numeric_limits;
+//#include <locale> // for . or , for decimal point
+#include <exception> //
+  //using std::exception;
+  //using std::bad_alloc;
+
+#include <boost/quan/xiostream.hpp> // for extra manipulators, spaces.
+// These extra manipulators have been placed in std for convenience.
+  //using std::noadjust;  // Restore to default state.
+  //using std::nofixed;  // Restore to default state.
+  //using std::noscientific;  // Restore to default state.
+  //using std::defaultfloat; // Restore fixed & scientific to default state.
+  //using std::hexbase;
+  //using std::lowercase;
+
+#include <boost/quan/unc_init.hpp> // Defines indexes to xalloc iword(index) variables.
+#include <boost/quan/rounding.hpp> // Rounding functions.
+#include <boost/lexical_cast.hpp>
+
+#include <boost/static_assert.hpp>
+BOOST_STATIC_ASSERT (std::numeric_limits<double>::is_iec559); // Assume IEEE 754 ONLY.
+// == _STATIC_ASSERT (numeric_limits<double>::is_iec559); // and MS STATIC assert.
+
+#include <boost/io/ios_state.hpp>
+#include <boost/units/io.hpp>
+#include <boost/units/static_rational.hpp>
+#include <boost/type_traits.hpp>
+
+void outIosFlags(long, std::ostream&); // Output ios flags.
+void outUncTypes(unsigned short int, std::ostream&);
+
+//namespace boost {
+//namespace units {
+
+// Forward declarations.
+template <bool is_correlated> // Default is uncertainties that are NOT correlated.
+class unc;
+
+// Two actual uncertain floating-point types for the user:
+
+typedef unc<false> uncun;  //! Uncertainties are NOT correlated.
+//! Uncorrelated is the normal case when uncertainties add.
+
+typedef unc<true> unccorr;   //! Uncertainties ARE correlated.
+//! This is the unusual case where the sum must be exact,
+//! so the uncertainties are subtracted.
+//! Example: two blocks which fit into a box perfectly.
+//! So if both have an uncertainties, they must cancel when the uncertainties are added.
+//! Also applies to items like concentrations which must add up to 100% or unity.
+
+// Obselete - now implemented directly as operator <<
+//void unc_output(double value, // Mean or most likely value.
+//                    float stdDev, // Standard deviation.
+//                    unsigned short int degFree, // Degrees of freedom.
+//                    unsigned short int uncTypes, // 16 Uncertain type flags.
+//                    ostream& os);  // Output stream, default std::cout.
+
+
+void unc_input(double& mean,  // mean (central or most probable) value.
+                   double& stdDev,
+                   unsigned short int& degreesOfFreedom,  // 1 observation.
+                   unsigned short int& uncTypes,
+                   std::istream& is);
+
+//template<typename correlated> std::ostream& operator<< (std::ostream& os, const unc<false>& u);
+//template<typename correlated> std::ostream& operator<< (std::ostream& os, const unc<false>& u);
+// Need to declare so that can make a friend (in unc), and thus access private data value_ etc.
+// See http://www.parashift.com/c++-faq-lite/templates.html#faq-35.16
+// This avoids failure to instantiate these operators, and thus link failures.
+// May need for input operator>> too.
+// template<typename correlated> std::istream& operator>> (std::istream& is, const unc<false>& u);
+// friend istream& operator>> (istream& is, UReal<correlated>& u)
+
+template <typename Type> inline Type sqr(const Type& a); 
+template <typename Type> inline Type cube(const Type& a);
+template <typename Type> inline Type pow4(const Type& a);
+
+// These should be defined elsewhere, but will not compile.
+//! Quaded function, notationally convenient for x^4, but overflow possible?
+//! Used by Welch-Satterthwaite formula.
+template <typename Type>
+inline Type pow4(const Type& a)
+{
+  return (Type)(a * a * a * a);
+} 
+
+template <typename Type> inline Type sqrtSumSqrs (const Type& a, const Type& b);
+template <typename Type>
+inline Type sqrtSumSqrs (const Type& a, const Type& b)
+{
+  return (Type)sqrt(a * a + b * b);
+}
+
+// SI units from CRC Handbook of Chemistry & Physics 76th edition 1995,
+// ISBN 08493 0476-8 page 1-22.
+
+// SI Usage, ISO 30-0 to 30-13:1992 is 'International Consensus Document'.
+
+// ANSI/IEEE Std 268-1992 Americal National Standard for Metric Practice,
+// (adopted for US Department of Defence)
+
+// ASTM E 380-93 now consolidated with ANSI 268.
+
+// NIST Special Publication 811,  Barry N Taylor
+// Guide for the Use of the International System of Units 1995
+// which was derived from IEEE Std 268, IEEE Standard Metric Practice (1982)
+
+// Most useful commentary on the these standards, and annotated bibliography.
+// (available from www.physics.NIST.gov)
+
+// ISO 2955 = BS 6430 :1983 (1988)
+// Method for representing SI and other units in information processing
+// system with limited character sets.
+
+// Gives two sets of representation, for SI units and other ISO 1000 units,
+// for use in data interchange by systems with limited graphic character sets.
+// Mainly important for allowing u instead of greek mu.
+
+// Gunther Schadow & Clement J. McDonald,
+// The Unified Code for Units of Measure,
+// A critique and proposals of ISO and ANSI, and ENV 12435
+// http://aurora.rg.iupui.edu/~schadow/units/UCUM/ucum.html
+
+void outUncValues(std::ostream& os, std::ostream& log); // Output uncertain values.
+void setUncDefaults(std::ios_base& os); // Set I=Unc class defaults for stream os.
+
+ //! 16 type bits used by unc uncTypes. Bit set = 1 means a positive attribute.
+enum unc_types
+{  
+  VALUE_ZERO = 1 << 0, //!< bit zero = 1 means value is zero.
+  //! (Too near zero to allow relsd = sd /mean.)
+  //! A few times std::numeric_limits<float>::min() may be a suitable limit?
+  VALUE_INTEGER = 1 << 1, //!< Exact integer 2,3,4 ... may not be possible to store `int` into `double`?
+  VALUE_RATIONAL = 1 << 2, /*!< Integers & Fractions 1/2, 1/3, 2/3, 5/4 ...
+   so don't need irrational - must be if not rational.
+   Irrational like pi, e ... represented as accurately as possible by the double floating-point type,
+   usually for 64-bit double, 15 to 17 decimal digits.
+  */
+  VALUE_NEGATIVE_ONLY = 1 << 3, //!< Value can ONLY be < 0.. ? or <=0?
+  VALUE_POSITIVE_ONLY = 1 << 4, //!< Value can ONLY be >=0..
+  UNC_KNOWN = 1 << 5, //!< Uncertainty known (but if not, value may still be known OK).
+  UNC_NOPLUS = 1 << 6, //!< Uncertainty can only be < value, + = zero.
+  UNC_NOMINUS = 1 << 7, /*!< Uncertainty can only be > value - = zero.
+   Integer, Rational or Exact by definition like 25.4 mm per inch,
+   if unc = 0.0f or both UNC_NOPLUS & UNC_NOMINUS.
+  */
+  UNC_QUAN_DECIMAL = 1 << 8, //!< Quantised by least significant decimal digit.
+  UNC_QUAN_BINARY = 1 << 9, //!< Quantised by least significant binary digit.
+  UNC_EXPLICIT = 1 << 10, /*!< If bit set = 1, uncertainty implicit from read significant digits,
+   for example: unc_input of 10.0 will set this bit and set uncertainty = 0.05,
+   or explicit if +/- or calculated (normal default case, bit = 0).
+  */
+  UNC_UNIFORM = 1 << 11, //!< Uncertainty has rectangular or uniform probability distribution.
+  UNC_TRIANGULAR = 1 << 12, //!< Uncertainty has triangular probability distribution.
+  //! If not rectangular or triangular bits set, then normal or Gaussian distribution, the default.
+  //! Both bits 11 and 12 == 1 then has distribution un-defined as yet.
+  //! Distribution type is used to estimate confidence intervals and rounding.
+  DEG_FREE_EXACT = 1 << 13, //!< Known number of observations -1,
+  //! so default zero means 1 observation.
+  //! else estimated, for example, using Welch-Satterthwaite.
+  DEG_FREE_KNOWN = 1 << 14, //!< Degrees of freedom is defined.
+  SPARE = 1 << 15 //!< This last unc_type is spare.
+}; // enum unc_types
+
+const unsigned short int VALUE_EXACT = (UNC_NOMINUS | UNC_NOPLUS);  //!< Both set.
+const unsigned short int UNC_DEF = (UNC_KNOWN | UNC_NOMINUS | UNC_NOPLUS | //!< Any defined means that uncertainty is defined.
+                                    UNC_QUAN_DECIMAL | UNC_QUAN_BINARY |
+                                    UNC_EXPLICIT //!< Not implicit from number of significant digits.
+                                    | UNC_UNIFORM | UNC_TRIANGULAR);  //
+const unsigned short int DEG_FREE_DEF = (DEG_FREE_EXACT | DEG_FREE_KNOWN);
+
+extern const char* uncTypeWords[];
+
+enum uncertainflags
+{  //! \enum uncertainflags Control of printing uncertain values, similar to ios flags.
+  defaults = 0, //!< Default.
+  firm = 1  << 0,  //!< bit 0: == 0 == false means flex, or firm == 1 == true.
+  setScaled = 1 << 1, //!< bit 1 Set scaled == 1 or not scaled == 0.
+  //! by fixed factor SetScale and << scale ...
+  //! power10 in range -max to +max.
+  autoScaled = 1 << 2,  //!< bit 2: auto = 1  with << autoscale ...
+  plusMinus = 1 << 3, /*!< bit 3 = 1 means add +/- uncertainty 
+  Usage: `std::cout << plusminus << u;`
+  */
+  addSISymbol = 1 << 4,  //!< bit 4 = 1, add suffix SI symbol G, M, k, m, u, n, p ...
+  //! If one is applicable, else = 0 do nothing.
+  addSIPrefix = 1 << 5,  //!< bit 5 = 1, add suffix SI prefix Giga, Mega, kilo ...
+  noisyDigit = 1 << 6, /*!< Add extra 'noisy' decimal digit to value & sd.
+   Usage: std::cout `<< addnoisyDigit << u;`
+   This means is suitable for input to other calculations because the
+   random extra 2 to 3 bits will approximate a continuous function.
+   Quantization to fewer digits would distort statistical calculations.
+   Default is to use minimum decimal digits for clearer display.
+   Extra digit also added when degrees of freedom > 10.
+  */
+  useSetSigDigits = 1 << 7, //!< if bit 7 = 1 use set sig digits else calculate from sd(isUseSetSigDigits).
+  useSetUncSigDigits = 1 << 8, //!< if bit 8 = 1 use set Unc sigfig (isStdDevSigDigitsSet).
+  //! else calculate from degrees of freedom.
+  degfree = 1 << 9, //!< 0x200, If bit 9 == 1, add output of degrees of freedom as (99).
+  // Usage: std::cout `<< adddegfree << u;`
+  replicates = 1 << 0xA, //!< 0x400 If == 1, add output of replicates as [99] if > 1.
+  limits = 1 << 0xB, //!< 0X800 add limits.
+  // 0xC, D, E and F spare - and iword is actually a long so could use 32 flags.
+}; // enum uncertainflags
+
+void outFpClass(double, std::ostream&);  // Special output for inf, NaN...
+
+// Declarations of parameterless Manipulators,
+// similar to ios_base flags but for uncertain printing.
+// Use upperand lower case convention for these,
+// but all lowercase for manipulators like hex, oct ...
+// Usage:  out << scale << noscale << autoscale << noautoscale
+// firmform << flexform << plusminus << noplusminus ....
+
+//! All ios_base functions declared below are defined in unc.ipp
+//! \note that all of these are entirely lower case names, like std::ios manipulators.
+
+std::ios_base& scale(std::ios_base&); //!< To use value set with setScale(int)
+std::ios_base& noscale(std::ios_base&);  //!< or not scale.
+std::ios_base& autoscale(std::ios_base&); //!<  Automatically Scale to suitable prefix symbol like M, k, m...
+std::ios_base& noautoscale(std::ios_base&);  // or not to scale to prefix symbol.
+std::ios_base& firmform(std::ios_base&);  //!< Firm fixed layout using setUncWidth.
+std::ios_base& flexform(std::ios_base&); //!< Flexible free format.
+std::ios_base& plusminus(std::ios_base&);  //!< Add +/- uncertainty.
+std::ios_base& noplusminus(std::ios_base&);  //!< Do not add +/- uncertainty
+std::ios_base& addsiprefix(std::ios_base&); //!< Add SI prefix like kilo, micro ..
+std::ios_base& nosiprefix(std::ios_base&);  //!< (Takes precedence over SI symbol if both set).
+std::ios_base& addsisymbol(std::ios_base&); //!< Add SI symbol like M, k, m.
+std::ios_base& nosisymbol(std::ios_base&);  //!< Do not add SI symbol like M, k, m.
+std::ios_base& addnoisyDigit(std::ios_base&);  //!< Add an extra 'noisy' digit for less risk of loss.
+std::ios_base& nonoisyDigit(std::ios_base&);  //!< No noisy to suit human reading.
+std::ios_base& autosigdigits(std::ios_base&);  //!< Calculate sigdigits from uncertainty (default).
+std::ios_base& setsigdigits(std::ios_base&);    //!< Use sig digits stored with `<< setSigDigits(6)` for value.
+std::ios_base& autouncsigdigits(std::ios_base&);  //!< Calculate stdDev sig digits from uncertainty.
+std::ios_base& uncsigdigits(std::ios_base&); //!< Use stdDev sigDigits stored with << useSetUncSigDigits(2) ...
+std::ios_base& adddegfree(std::ios_base&);  //!< Add degrees of freedom as (99).
+std::ios_base& nodegfree(std::ios_base&);  //!< Do not add degrees of freedom to output of value.
+// 
+std::ios_base& addlimits(std::ios_base&);  //!< Add lower and upper limits a 0.95 > 1.00 > 1.05.
+std::ios_base& nolimits(std::ios_base&);  //!< Do not add lower and upper limits.
+
+// Obselete
+//std::ios_base& confidence(std::ios_base&);
+/*!< Use stdDev sigDigits stored with `<< setconfidence( 0.01) ...`
+ or alpha to control estimation of confidence interval.  0.01 means 99% confidence.
+ */
+//std::ios_base& roundingloss(std::ios_base&);  //!< Set the acceptable loss from rounding.
+//std::ios_base& addreplicates(std::ios_base&);  //!< Add degrees of replicates > 1 as [99].
+//std::ios_base& noreplicates(std::ios_base&);  //!< Do not add degrees of freedom or replicates >1.
+
+/*! Functions to change uncertain flags on specified ios_base.
+  Usage: \code f = uFlags(out); f = uFlags(out, 0xFF);
+  f = setuFlags(out, 0xFF); f = resetuFlags(out, 0xFF);
+  \endcode
+*/
+long uFlags(std::ios_base&);  //!< Returns current uncertain flags.
+long uFlags(std::ios_base&, long); //!< Assigns all uncertain flags & returns previous.
+long setuFlags(std::ios_base&, long);  //!< Set specific flags = 1
+long resetuFlags(std::ios_base&, long);  //!< Reset/clear specific flags = 0
+
+// Forward declarations, defined in unc.ipp.
+class showUncFlags;  //!< Output uncertain flags to `ostream << showUncFlags `.
+class setAllUncFlags;  //!< Assign value to set (and/or clear) all unc flags.
+class setUncFlags;  //!< Set specific unc flags bits.
+class setMaskedUncFlags;  //!< Clear mask & then set unc flag bits.
+class resetUncFlags;  //!< Reset all unc flags bits.
+class resetMaskedUncFlags; //!< Reset specific unc flags bits.
+class setUncWidth; //!< Set width of uncertainty output.
+class setScale; //!< Set scaling factor like 1e3, 1e6 ... `<< setScale(6)`.
+class setSigDigits;  //!< sigdigits to use for value if `<< setsigdigits(4)`.
+class setUncSigDigits;  //!< sigdigits to use for uncertainty if `<< setuncsigdigits(1)`.
+class setRoundingLoss;  //!< Set acceptable loss due to rounding.
+class setConfidence;  //!< Set acceptable loss due to rounding.
+
+// Operator declarations, classes defined below, with constructors in unc.ipp.
+std::ostream operator<< (std::ostream, const showUncFlags&);
+std::ostream operator<< (std::ostream, const setAllUncFlags&); 
+std::istream operator>> (std::istream, const setAllUncFlags&);
+std::ostream operator<< (std::ostream, const setUncFlags&);
+std::istream operator>> (std::istream, const setUncFlags&);
+std::ostream operator<< (std::ostream, const setMaskedUncFlags&);
+std::istream operator>> (std::istream, const setMaskedUncFlags&);
+std::ostream operator<< (std::ostream, const resetUncFlags&);
+std::istream operator>> (std::istream, const resetUncFlags&);
+std::ostream operator<< (std::ostream, const resetMaskedUncFlags&);
+std::istream operator>> (std::istream, const resetMaskedUncFlags&);
+std::ostream operator<< (std::ostream, const setUncWidth&);
+std::istream operator>> (std::istream, const setUncWidth&);
+std::ostream operator<< (std::ostream, const setScale&);
+std::istream operator>> (std::istream, const setScale&);
+std::ostream operator<< (std::ostream, const setUncSigDigits&);
+std::istream operator>> (std::istream, const setUncSigDigits&);
+std::ostream operator<< (std::ostream, const setRoundingLoss&);
+std::ostream operator<< (std::ostream, const setConfidence&);
+std::ostream operator<< (std::ostream, const setSigDigits&);
+std::istream operator>> (std::istream, const setSigDigits&);
+
+void outUncFlags(long uncflags, std::ostream);
+
+class showUncFlags
+{  // Constructor & operator<< defined in unc.ipp
+  friend std::ostream operator<< (std::ostream, const showUncFlags&);
+public:
+  showUncFlags(unsigned short int);  // Definition in unc.ipp.
+  unsigned short int flags;
+};
+
+class showUncTypes
+{  // Constructor & operator<< defined in unc.ipp
+  // Usage: out << showUncTypes(unc) ...
+  friend std::ostream operator << (std::ostream, const showUncTypes&);
+public:
+  showUncTypes(unsigned short int);  // Definition in unc.ipp.
+  unsigned short int types;
+};
+
+// setAllUncflags(int flags, int mask);
+// Usage: out << setAllUncFlags(0x5a) ...
+class setAllUncFlags  // Set ALL uncertain flags (not just OR selected bits).
+{
+  friend std::ostream operator<< (std::ostream, const setAllUncFlags&);
+  friend std::istream operator>> (std::istream, const setAllUncFlags&);
+public:
+  setAllUncFlags(int); // w) : flags(w) {}  // Constructor initialisation flags = w.
+  int flags; // setAllUncFlags.flags used by operators << and >>
+};
+
+class setUncFlags  // Set selected uncertain flags.
+{// Usage: out << setUncFlags(0xFFFF, 0x7, 0x3) ...
+  // or setUncFlags(out, 0x7);
+
+  friend std::ostream operator<< (std::ostream, const setUncFlags&);
+  friend std::istream operator>> (std::istream, const setUncFlags&);
+public:
+  setUncFlags(int); // Constructor initialisation flags.
+  int flags; // setUncFlags.flags used by operators << and >>
+};
+
+// setMaskedUncflags(int flags, int mask);
+// Usage: out << setMaskedUncFlags(0xFFFF, 0x7, 0x3) ...
+// or setUncFlags(out, 0x7);
+class setMaskedUncFlags
+{
+  friend std::ostream operator<< (std::ostream, const setMaskedUncFlags&);
+  friend std::istream operator>> (std::istream, const setMaskedUncFlags&);
+public:
+  setMaskedUncFlags(int, int); // : flags(w), mask(m) {}  // Constructor initialisation flags = w.
+  int flags; // setMaskedUncFlags.flags used by operators << and >>
+  int mask;  // Selected bits to deal with by zeroing before setting flags.
+};
+
+class resetUncFlags  // Reset = 0 selected uncertain flags.
+{// Usage: out << resetUncFlags(0xFFFF, 0x7, 0x3) ...
+  // or setUncFlags(out, 0x7);
+
+  friend std::ostream operator<< (std::ostream, const resetUncFlags&); // Declarations
+  friend std::istream operator>> (std::istream, const resetUncFlags&);
+public:
+  resetUncFlags(int);// w) : flags(w) {}  // Constructor initialisation flags = w.
+  int flags; // setUncFlags.flags used by operators << and >>
+};
+
+// setMaskedUncflags(int flags, int mask);
+// Usage: out << resetMaskedUncFlags(0xFFFF, 0x7, 0x3) ...
+// or setUncFlags(out, 0x7);
+class resetMaskedUncFlags
+{
+  friend std::ostream operator<< (std::ostream, const resetMaskedUncFlags&);
+  friend std::istream operator>> (std::istream, const resetMaskedUncFlags&);
+public:
+  resetMaskedUncFlags(int, int); // : flags(w), mask(m) {}  // Constructor initialisation flags = w.
+  int flags; // setMaskedUncFlags.flags used by operators << and >>
+  int mask;  // Selected bits to deal with by zeroing before setting flags.
+};
+
+class setUncWidth // Set uncertain width.
+{
+  friend std::ostream operator<< (std::ostream, const setUncWidth&); // Declarations
+  friend std::istream operator>> (std::istream, const setUncWidth&); // Defined below.
+  // Allows ostream operator>> and << to access private member width.
+public:
+  setUncWidth(int);
+  int uncWidth; // setUncWidth used by operators << and >>
+};
+
+// setScale(int scale);
+// Usage: out << setScale(6)  // == 10**6) ...
+class setScale  // Set uncertain scale.
+{
+  friend std::ostream operator<< (std::ostream, const setScale&); // Declarations
+  friend std::istream operator>> (std::istream, const setScale&); // Defined below.
+  // Allows ostream operator>> and << to access private member scale.
+public:
+  setScale(int); // n) : scale(n) {}  // Constructor - initialisation scale = n.
+  int scale; // setScale.scale used by operators << and >>
+};
+
+// Usage via class: setSigDigits(int sigDigits);
+// Usage via operator << : out << setSigDigits(6) ...
+class setSigDigits
+{
+  friend std::ostream operator<< (std::ostream, const setSigDigits&); // Declarations
+  friend std::istream operator>> (std::istream, const setSigDigits&);
+public:
+  setSigDigits(int);// w) : sigDigits(w) {}  // Constructor in unc.ipp
+  // Initialisation means sigDigits = w.
+  int sigDigits_; // setSigDigits.flags used by operators << and >>
+};
+
+/*! setUncSigDigits(int uncSigDigits);
+  Permits choice of number of uncertain or stddev value:\n
+  2 is the ISO recommendation.\n
+    Uncertainty of measurement -- Part 3: Guide to the expression of uncertainty in measurement (GUM:1995)\n
+    ISO Guide 98 (1995) and updated version 2008.\n
+  1 is more appropriate for very small degrees of freedom,
+   (but it gives a big step when the value starts with 1 or 2,
+   when the difference between 1.4 (rounded to 1) and 1.6 (rounded to 2.) is a doubling.
+  3 is appropriate only for large degrees of freedoms, >= 1000.
+  \warning Values < 1 or > 3 are silently ignored.
+  -1 passes through to allow dymanic choice based on degress of freedom.
+  Usage: out << setUncSigDigits(3) ...
+*/
+class setUncSigDigits
+{
+  friend std::ostream operator<< (std::ostream, const setUncSigDigits&); // Declarations
+  friend std::istream operator>> (std::istream, const setUncSigDigits&);
+public:
+  setUncSigDigits(int);// w) : uncSigDigits(w) {}  // Constructor
+  // Initialisation means uncSigDigits = w.
+  //protected:
+  int uncSigDigits_; // Set by constructor.
+}; // class setUncSigDigits
+
+//! setRoundingLoss(int setRoundingLoss); to control the acceptable rounding loss.
+//! Usage: `out << setRoundingLoss(0.01)` ...
+
+class setRoundingLoss
+{
+  friend std::ostream operator<< (std::ostream, const setRoundingLoss&); // Declarations
+  friend std::istream operator>> (std::istream, const setRoundingLoss&);
+public:
+  setRoundingLoss(double);// eps) : setRoundingLoss(eps) {}  // Constructor
+  // Initialisation means setRoundingLoss = epsilon
+  //protected: 
+  double roundingloss_; // Set by constructor.
+}; // class setRoundingLoss
+
+//! setConfidence(int setConfidence); to control the confidence interval.
+//! Usage: `out << setConfidence(0.01)` ...
+
+class setConfidence
+{
+  friend std::ostream operator<< (std::ostream, const setConfidence&); // Declarations
+  friend std::istream operator>> (std::istream, const setConfidence&);
+public:
+  setConfidence(double);// alpha) : setConfidence(alpha) {}  // Constructor
+  // Initialisation means setConfidence = alpha
+  //protected: 
+  double confidence_; // Set by constructor.
+}; // class setConfidence
+
+
+/*! Uncertain number template class unc,
+   using mean and uncertainty (equivalent to std deviation if pure Gaussian),
+   but also includes information about uncertainty as degrees of freedom & distribution.
+*/
+template <bool is_correlated = false> //! \tparam  is_correlated if true, standard deviation is correlated, else not.
+class unc : public std::char_traits<char>
+{
+  typedef double value_type;
+
+
+  friend void unc_input(double& mean,  // Mean (central or most probable) value.
+                   double& stdDev, // Uncertainty estimate as Standard deviation.
+                   unsigned short int& degreesOfFreedom,  // Degrees of freedome -1. (Default zero for 1 observation).
+                   unsigned short int& types, // 16 Uncertain type flags showing type of value.
+                   std::istream& is);
+  //friend void unc_output(double value, // Mean(central or most probable) value.
+  //                  float stdDev, // Uncertainty estimate as Standard deviation.
+  //                  unsigned short int degFree, // Degrees of freedom.
+  //                  unsigned short int uncTypes, //  16 Uncertain type flagsshowing type of value.
+  //                  std::ostream& os);  // Output stream, default std::cout.
+
+  // using char_traits<char>::int_type; // Derivation from public \c std::char_traits<char> needed for \c int_type.
+
+//#pragma warning (disable : 4520) //!< 'unc<1>' : multiple default constructors specified.
+  // This is by design so that it is possible construct from integer or double.
+  // Doubtful if this is necessary or useful?  
+public:
+  /*! \note It is convenient to use 64-bit floating-point value
+     (so even really accurate values like weights are OK),
+     32-bit floating-point is ample accuracy for standard deviation fractional variation,
+     leaving two 16-bit for degrees of freedom and other flags,
+     so that total is same as two doubles & can be efficiently aligned.
+  */
+  double value_; //!< aka mean, estimate, or most likely value.
+  float uncertainty_; //!< Standard deviation, if known.
+  //! Reduced precision (float guarantees 6 decimal digits not 15) and range e38 not E304
+  //! should not be a problem unless value is (near) less than 1e38.
+  //! Can be zero, meaning exact, and can be negative or anti-correlated,
+  //! for example when values must add up to a total like 100%.
+  //! Relative (Fraction) Coefficent of variation =
+  //! Standard deviation / value (aka % +|- /100)
+  //! Relative is a problem if value near zero.
+  //! +|- is std deviation, so
+  //! for input of "1.0" implicit standard deviation and uncertainty limits +|- 0.05.
+  short unsigned int degFree_;  /*!< degrees of freedom, usually = number of observations;
+     so for 2 observations assign 1 to degFree_ degree of freedom.
+     Range from 1 (usally 1 observation) to 65534 = std::numeric_limits<unsigned short int>::max() - 1
+     Higher numbers of observations are indistinguishable from infinite observations.
+     Max unsigned value 0xFFFF == 65535 is used to indicate degFree_ is NOT meaningful.
+     Zero is as yet undefined?
+     BUT many programs seem to use NON-integer degrees of freedom,
+     so a float might seem better, but is 32 bits not 16, so use 16 for compact struct.
+     (Might use an explicit 16 bit unsigned integer type?)
+   */
+  short unsigned int unctypes_; //!<  Information about the value and uncertainty,
+  //! encoded as a bitmap 16 bits, 0 to 15 See enum unc_types,
+
+  //! \note These sizes mean that total size of a unc is 64 = 32 + 32 = 128 bits
+  // for IEEE-754 systems with 64-bit double.
+public:
+  // Member functions to get & value, stdDev, degfree & uncTypes.
+  //! \return Central estimate of value of uncertain type.
+  double value()
+  { 
+    return value_;
+  }
+  //! \return Estimate of uncertainty as standard deviation of value of uncertain type.
+  float std_dev()
+  {
+    return uncertainty_;
+  }
+  //! \return Estimate of number of degrees of freedom, usually = number of observations -1.
+  unsigned short int deg_free()
+  {
+    return degFree_;
+  }
+  //! \return Types of uncertain real, encoded as a bitmap.
+  unsigned short int types()
+  {
+    return unctypes_;
+  }
+
+  // Set functions.
+  //! \param  value Central estimate of value of uncertain type.
+  void value (double value)
+  {
+    value_ = value;
+  } // void setValue (double value)
+
+  //! \param unc Estimate of uncertainty as standard deviation of value of uncertain type.
+  void std_dev (float unc)
+  {
+    uncertainty_ = unc;
+    if (boost::math::isfinite(static_cast<double>(unc)))
+    {
+      unctypes_ |= UNC_KNOWN; // set unc is known
+      if (unc > 0.f)
+      { // NOT exact.
+        unctypes_ &= ~(VALUE_EXACT | VALUE_RATIONAL | VALUE_INTEGER | UNC_NOPLUS | UNC_NOMINUS); // Clear.
+      }
+      else
+      { // Exact.
+        unctypes_ |= (VALUE_EXACT | UNC_NOPLUS | UNC_NOMINUS); // Set
+      }
+    }
+    else
+    { // unc not finite!
+      unctypes_ &= ~UNC_KNOWN; // Clear as unc not known.
+
+    }
+  } // void std_dev (float unc)
+
+  //! \param df Number of degrees of degrees of freedom, usually = number of observations -1.
+  void deg_free (short unsigned int df)
+  {
+    degFree_ = df;
+    unctypes_ |= DEG_FREE_KNOWN; // set.
+  } // void deg_free (short unsigned int df)
+
+  // TODO rename these.
+  //! \param type bits indicating type of uncertain real.
+  void setUncTypes (short unsigned int type)
+  {
+    unctypes_ = type;
+  }  // Set all type flag(s).
+
+  void types (short unsigned int type)
+  {
+    unctypes_ &= ~type;
+  }  // Clear type flag(s).
+
+  // Constructors.
+
+ /*! Default constructor from double value & float uncertainty.
+     Constructor from just a double value assumed exact,
+     so behaves like a normal double.
+     Normal conversion from double to unc.
+     (See also constructor from integer which alone sets integer flag.)
+    */ 
+  unc(
+    // Default values: exact zero? with no uncertainty, 1 observation.
+    const double val,  //  = 0., // also const int = 0.
+    // Ignore warning C4520: 'unc<1>' : multiple default constructors specified
+    // (because they will be the same default values).
+    const float unc = 0.0f,  // Default value exact.
+    const short unsigned int df = 1,  // df means observations = 1.
+    const short unsigned int uncTypeFlags = UNC_KNOWN | UNC_EXPLICIT| DEG_FREE_EXACT | DEG_FREE_KNOWN) // unc type flags.
+    : value_(val), uncertainty_(unc), degFree_(df), unctypes_(uncTypeFlags)
+  {
+#ifdef UNC_CD_TRACE
+    {
+      cerr << "\n     ^^^ Construct from double value  " << dec << val << ", unc " << unc
+        << ", df " << df << ", types" << showUncTypes(uncTypeFlags) << endl;
+    }
+#endif
+    // Check on value.
+    if (
+      (boost::math::isfinite(value_)) // Value is finite, so neither infinity nor NaN!
+      && (0.0f == uncertainty_) // Uncertainty parameter is zero (default).
+      && (unctypes_ & UNC_KNOWN) // In case UNC_KNOWN flag is cleared by value of uncTypeFlags.
+      // default unc = 0.f to suit construction from a double uncun(2.)
+      // but NOT exact if more than one value or unc unknown signaled.
+      )
+    {  // Value is Exact double.
+      //unctypes_ |= VALUE_EXACT;
+      if (value_ == 0.)
+      {  // Speed simplest & common zero integer case.
+        unctypes_ |= (VALUE_ZERO | VALUE_INTEGER | VALUE_RATIONAL);
+      }
+      else
+      { // Not exact.
+        // Only if construct from int, then set flag as VALUE_INTEGER.
+        // Else leave unctypes_ as set by constructor, perhaps setting VALUE_INTEGER and/or VALUE_RATIONAL.
+      }
+    }
+    else
+    { // Value is Nan or Infinity.
+      // Use a flag here?  VALUE_NONFINITE ??
+    }
+
+    // Check if unc (std dev) is NaN or infinity.
+    if (!boost::math::isfinite(unc))
+    { // unc (std dev) is NaN or infinity.
+      unctypes_ &= ~(UNC_KNOWN | UNC_EXPLICIT| DEG_FREE_EXACT | DEG_FREE_KNOWN) ; // Clear all UNC_KNOWN flag.
+    }
+    else
+    {  // unc (stdDev) is finite.
+      if (unc == 0.0f)
+      {
+        unctypes_ |= VALUE_EXACT; // Set.
+      }
+      else if (unc < 0.0f)
+      { // Negative uncertainty.
+        if (!is_correlated) // NOT correlated case.
+        { // Error! Throw? Or set uncertainty to zero?
+          unctypes_ &= ~UNC_KNOWN;
+          std::cerr << "Negative uncertainty " << unc << ", Value " << val << "!" << std::endl;
+          // uncertainty_ = 0.0f; or NaN?
+        }
+        else // is correlated.
+        { // But CAN have negative uncertainty for correlated case.
+          std::cout << "Negative uncertainty for correlated case is not yet implemented." << std::endl;
+        }
+        if (unctypes_ && (UNC_NOPLUS | UNC_NOMINUS | UNC_QUAN_DECIMAL | UNC_QUAN_BINARY | UNC_UNIFORM | UNC_TRIANGULAR | UNC_EXPLICIT) != 0)
+        { // Any uncertainty specifier bit means uncertainty is known.
+          unctypes_ |= UNC_KNOWN;  // But do NOT specify as explicit.
+        }
+      }
+      if ((uncTypeFlags & VALUE_EXACT) == VALUE_EXACT)
+      { // Check for a valid uncertainty, but type parameter is exact.
+        if (uncertainty_ != 0.f)
+        {
+          std::cout << "Value " << value_ << " flagged as exact, but uncertainty " <<  uncertainty_ << " is not zero!" << std::endl;
+          uncertainty_ = 0.f;  // Override any unc provided.
+          // This indicates a programmer logic error!
+        }
+        if (degFree_ != 0)
+        {
+          std::cout << "Value " << value_ << " flagged as exact, but degfree " << degFree_ << " is not zero!" << std::endl;
+          degFree_ = 0;  // Override any degfree provided.
+          // This indicates a programmer logic error!
+        }
+      } // 
+    } // unc finite check
+#ifdef UNC_CD_TRACE
+    {
+      cerr << "  Constructed from double: value_ "
+        << value_ << ", m_unc " << uncertainty_ << ", m_df "
+        << dec << degFree_ << ", " << showUncTypes(unctypes_)
+        << endl;
+    }
+#endif
+  };  // unc constructor from double.
+ 
+  // A specific constructor from int (as well as double) leads to this warning.
+  // #pragma warning (disable : 4520) //!< 'unc<1>' : multiple default constructors specified.
+
+  //!< Constructor from integer value.
+  unc(
+    const int ivalue = 0, // Default value integer zero.
+    const float unc = 0.0f,  // Exact.
+    const short unsigned int df = 1,  // means observations = 1.
+    const short unsigned int uncTypeFlags =  // unc type flags.
+      DEG_FREE_DEF | // See also constructor from double.
+      VALUE_INTEGER | VALUE_RATIONAL |  // If integer, must be rational too.
+      UNC_NOPLUS | UNC_NOMINUS | UNC_KNOWN) // Both so Exact.
+    : value_(ivalue),
+      uncertainty_(unc), // Not quite sure if sensible to allow uncertainty?
+      degFree_(df) // OK to allow degrees of freedom (many integers).
+    , unctypes_(uncTypeFlags) // Don't allow this as a parameter to avoid conflicting settings?
+  {
+      if (value_ == 0.)
+      { // Zero integer case.
+        unctypes_ |= VALUE_ZERO;
+      }
+#ifdef UNC_CD_TRACE
+    {
+      cerr << "\n    ^^^ Constructed from int: value "
+        << ivalue << ", value_ " << value_ << ", unc " << uncertainty_ << ", df "
+        << dec << degFree_ << ", " << showUncTypes(unctypes_)
+        << endl;
+    }
+#endif
+  } // Constructor from integer value.
+
+  unc(const unc& ud) //!< Constructor copy from another unc.
+    : value_(ud.value_), uncertainty_(ud.uncertainty_),
+    degFree_(ud.degFree_), unctypes_(ud.unctypes_)
+  {  // Just copy all 4 member data.
+#ifdef UNC_CD_TRACE
+    {
+      cerr << "\n    ^^^ Constructed from unc: value_ "
+        << value_ << ", m_unc " << uncertainty_ << ", m_df "
+        << dec << degFree_ << ", " << showUncTypes(unctypes_)
+        << endl;
+    }
+#endif
+  } // Constructor from unc.
+
+  //! Destructors. Two versions defined in unc.ipp to provide diagnostic output.
+ // ~unc();  // Declaration, .
+
+   // Unary operators + and -.
+  // No change to degrees of freedom or unc_types.
+  // (unc<is_correlated> operator +(void) const; produces:
+  // C2535 member function already defined or declared).
+
+  unc<is_correlated> operator+ (void) const  // Unary +
+  {  // 'slope' d f(x)/dx = +1
+    return *this;  // All members remain unchanged.
+  }
+
+  unc<is_correlated> operator- (void) const // Unary -
+  {  // 'slope' d f(x)/dx = -1
+    if (is_correlated) // Negate BOTH value & uncertainty.
+      return unc<is_correlated>(-value_, -uncertainty_);
+    else // Don't negate sign of uncertainty if not correlated, only value.
+      return unc<is_correlated>(-value_, uncertainty_);
+  }
+
+  // Binary add & subtract operators.
+  // (Implemented using += and -= operators).
+  friend unc<is_correlated> operator+ (unc<is_correlated> a,
+    const unc<is_correlated>& b)
+  {
+    return a += b;
+  }
+
+  friend unc<is_correlated> operator+ (unc<is_correlated> a,
+    const double& b)
+  {
+    return a += b;
+  }
+
+  friend unc<is_correlated> operator+ (const double& b,
+    unc<is_correlated> a)
+  {
+    return a += b;
+  }
+
+  friend unc<is_correlated> operator- (unc<is_correlated> a,
+    const unc<is_correlated>& b)
+  {
+    return a -= b;
+  }
+
+  friend unc<is_correlated> operator- (unc<is_correlated> a,
+    const double& b)
+  {
+    return a -= b;
+  }
+
+  friend unc<is_correlated> operator- (const double& b,
+    unc<is_correlated> a)
+  {
+    a -= b; return -a;
+  }
+
+  // Pre-Increment & pre-decrement operators.
+  // (Implemented using += and -= operators).
+  // Since using integer unity, uncertainty & rationality is unchanged.
+  unc<is_correlated> operator++ (void)
+  { return (*this += 1.); }
+
+  unc<is_correlated> operator-- (void)
+  { return (*this -= 1.); }
+
+  unc<is_correlated> operator++ (int)
+  {
+    unc<is_correlated> retval(*this);
+    *this += 1.;
+    return retval;
+  }
+
+  unc<is_correlated> operator-- (int)
+  {
+    unc<is_correlated> retval(*this);
+    *this -= 1.;
+    return retval;
+  }
+
+  // Multiply & divide operators (using *= etc assignment operators).
+  friend unc<is_correlated> operator* (unc<is_correlated> a,
+    const unc<is_correlated>& b)
+  {
+    return a *= b;
+  }
+
+  // Uncertainty unchanged by all operations using a double.
+  friend unc<is_correlated> operator* (unc<is_correlated> a,
+    const double& b)
+  {
+    return a *= b;
+  }
+
+  friend unc<is_correlated> operator* (const double& b,
+    unc<is_correlated> a)
+  {
+    return a *= b;
+  }
+
+  friend unc<is_correlated> operator/ (unc<is_correlated> a,
+    const unc<is_correlated>& b)
+  {
+    return a /= b;
+  }
+
+  friend unc<is_correlated> operator/ (unc<is_correlated> a,
+    const double& b)
+  {
+    return a /= b;
+  }
+
+  friend unc<is_correlated> operator/ (const double& b,
+    unc<is_correlated> a)
+  {
+    unc<is_correlated> retval;
+    retval.uncertainty_ = -b * a.uncertainty_ / (a.value_ * a.value_);
+    retval.value_ = b / a.value_;
+    retval.unctypes_ &= ~(VALUE_RATIONAL | VALUE_INTEGER);
+    // Must assume double b is irrational and NOT integer.
+    // (Use a unc instead to divide by a rational).
+    return retval;
+  }
+
+  // Assignment operators +=, -=, *=, /=
+  // (Used by plain +, -, * and / operators).
+  // If VALUE_NEGATIVE_ONLY might check that value is still < 0?
+  // If VALUE_POSITIVE_ONLY might check that value is still > 0?
+
+  unc<is_correlated>& operator+= (const unc<is_correlated>& ud)
+  { // unc += unc
+    if (is_correlated)
+    {
+      uncertainty_ += ud.uncertainty_;  // If correlated then just add.
+      degFree_ = // Choose degrees of freedom of the max uncertainty.
+        (uncertainty_ > ud.uncertainty_) ? degFree_ : ud.degFree_;
+      // Exact method of estimating not known, but is a reasonable approximation
+      // provided really is highly correlated because less well predicted
+      // variance can be predicted well with the better predicted.
+      // See email from Steve LR Ellison, Lab of Government Chem, 24 Apr 98.
+    }
+    else
+    { // Uncorrelated so Propagation of Uncertainty rules apply.
+      // Barry N Taylor & Chris E Kuyatt, NIST Technical note 1297 (1994),
+      // Guidelines for Evaluating & Expressing the Uncertainty of Measurements.
+      // http:// physics.nist.gov/pubs/guidelines.appa.html
+      // 'Combined uncertainty' Appendix A formula A-3 = "sqrt(sum of squares)"
+      double comb_uncertainty = sqrtSumSqrs(uncertainty_, ud.uncertainty_);
+      degFree_ =  // Welch-Satterthwaite - see NIST Appendix A3 & Appendix B-1.
+        // Effective degrees of freedom <= - see Eq B-2, so use floor function.
+        static_cast<unsigned short>( // Degrees of freedom must be integer by definition.
+        floor(
+        pow4<double>(comb_uncertainty)/
+        (pow4<double>(uncertainty_)/degFree_ + pow4<double>(ud.uncertainty_) / ud.degFree_))
+        );
+      uncertainty_ = float(comb_uncertainty);
+    }
+    unctypes_ &= ~DEG_FREE_EXACT; // This warns of an approximation - no longer exact.
+    unctypes_ &= ud.unctypes_; // Imposes rules for all additions of uncs.
+    // zero + zero = zero, restrictions on pos & neg only only retained if both,
+    // int + int is int, rational + rational is rational, int + rational is rational.
+    // either or both plusminus same if BOTH.
+    // Quantisation retains only if both.
+    value_ += ud.value_;
+    return *this;
+  }
+
+  operator value_type() const 
+  {
+    return value_;
+  }
+
+  unc<is_correlated>& operator+= (const double& a)
+  { // unc += double
+    value_ += a;
+    // Uncertainty & Degrees of freedom both unchanged.
+    unctypes_ &= ~(VALUE_ZERO | VALUE_RATIONAL | VALUE_INTEGER | VALUE_NEGATIVE_ONLY | VALUE_POSITIVE_ONLY);
+    // All restrictions on value removed.
+    return *this;
+  }
+
+  unc<is_correlated>& operator-= (const unc<is_correlated>& ud)
+  { // unc -= double
+    if (is_correlated)
+    {  // Correlated.
+      uncertainty_ -= ud.uncertainty_;
+      degFree_ =  // Biggest - see +=
+        (uncertainty_ > ud.uncertainty_) ? degFree_ : ud.degFree_;
+    }
+    else
+    {  // Uncorrelated.
+      float comb_uncertainty = sqrtSumSqrs(uncertainty_, ud.uncertainty_);
+      degFree_ =  // Welch-Satterthwaite - see NIST Appendix A3 Appendix B-1.
+        (unsigned short)  // Must be integer by definition.
+        floor(   // Round or floor?
+        pow4(comb_uncertainty)/
+        (pow4(uncertainty_)/degFree_+pow4(ud.uncertainty_)/ud.degFree_)
+        );
+      uncertainty_ = float(comb_uncertainty);
+
+    }
+    unctypes_ &= ~DEG_FREE_EXACT;  // No longer exact.
+    unctypes_ &= ud.unctypes_; // See += operator.
+    value_ -= ud.value_;
+    return *this;
+  }
+
+  unc<is_correlated>& operator-= (const double& a)
+  {
+    value_ -= a;
+    // Uncertainty & Degrees of freedom both unchanged.
+    unctypes_ &= ~(VALUE_ZERO | VALUE_RATIONAL | VALUE_INTEGER | VALUE_NEGATIVE_ONLY | VALUE_POSITIVE_ONLY);
+    // All indicators & restrictions on value removed.
+    return *this;
+  }
+
+  unc<is_correlated>& operator*= (const unc<is_correlated>& ud)
+  {
+    if (is_correlated)
+    {
+      uncertainty_ = float(uncertainty_ * ud.value_ + ud.uncertainty_ * value_);
+      degFree_ = // Choose degrees of freedom of the max uncertainty.
+        (uncertainty_ > ud.uncertainty_) ? degFree_ : ud.degFree_;
+    }
+    else  // Uncorrelated.
+    {
+      double comb_uncertainty =
+        sqrtSumSqrs(uncertainty_ * ud.value_, ud.uncertainty_ * value_);
+      degFree_ =  // Welch-Satterthwaite - see NIST Appendix A3 Appendix B-1.
+        static_cast<unsigned short> ( // must be integer by definition.  Round or floor?
+        pow4(comb_uncertainty)/
+        (pow4(uncertainty_)/degFree_+pow4(ud.uncertainty_)/ud.degFree_) );
+      uncertainty_ = float(comb_uncertainty);
+    }
+    unctypes_ &= ~DEG_FREE_EXACT;  // No longer exact.
+    unctypes_ &= ud.unctypes_; //
+    value_ *= ud.value_;
+    return *this;
+  }
+
+  unc<is_correlated>& operator*= (const double& a)
+  {
+    value_ *= a;
+    uncertainty_ *= (float)a;  // Relative uncertainty unchanged.
+    // Multiplying by constant doesn't change degrees of freedom.
+    unctypes_ &= ~(VALUE_ZERO | VALUE_RATIONAL | VALUE_INTEGER | VALUE_NEGATIVE_ONLY | VALUE_POSITIVE_ONLY);
+    // All indicators & restrictions on value removed.
+    return *this;
+  }
+
+  unc<is_correlated>& operator/= (const unc<is_correlated>& ud)
+  { // unc /= unc
+    if (is_correlated)
+    {  // Correlated.
+      uncertainty_ = uncertainty_ / ud.value_
+        - (ud.uncertainty_ * value_) / (ud.value_ * ud.value_);
+      degFree_ = // Choose degrees of freedom of the max uncertainty.
+        (uncertainty_ > ud.uncertainty_) ? degFree_ : ud.degFree_;
+    }
+    else
+    { // Uncorrelated.
+      float comb_uncertainty = sqrtSumSqrs(uncertainty_ / ud.value_,
+        (ud.uncertainty_ * value_) / (ud.value_ * ud.value_));
+      degFree_ =  // Welch-Satterthwaite - see NIST Appendix A3 Appendix B-1.
+        (int)  // must be integer by definition.  Round or floor?
+        pow4(comb_uncertainty)/
+        (pow4(uncertainty_)/degFree_+pow4(ud.uncertainty_)/ud.degFree_);
+      uncertainty_ = float(comb_uncertainty);
+    }
+    unctypes_ &= ~DEG_FREE_EXACT;  // No longer exact.
+    if ((unctypes_ & VALUE_INTEGER) && (ud.unctypes_ & VALUE_INTEGER) )
+    { // int / int
+      unctypes_ |= VALUE_RATIONAL; // becomes rational,
+      unctypes_ &= ~VALUE_INTEGER; // but no longer int.
+    }
+    else
+    {// rational / rational is still rational.
+      unctypes_ &= ud.unctypes_;
+    }
+    if (ud.unctypes_ & VALUE_ZERO != 0)
+    { // Avoid divide by zero, unless both zero!
+      value_ = (value_ != 0.) ? INFINITY : 0.;
+    }
+    else
+    { // Probably safe to divide. Check value == 0 as well??
+      value_ /= ud.value_;
+    }
+    {  // Check if result is really an integer.
+      double i; // For integer part from modf.
+      double frac = modf(value_, &i);  // modf only works for doubles,
+      // so can't test frac = 0.0f and this is better anyway.
+      if (frac <= std::numeric_limits<double>::epsilon())  // nearly == 0
+        // numeric_limits<double>::epsilon() = 2.22045e-016 aka DBL_EPSILON
+      {
+        unctypes_ |= (VALUE_INTEGER | VALUE_RATIONAL);
+      }
+      // TODO Any perhaps check if value is (near) zero?
+    }
+    return *this;
+  }
+
+  /*! operator /=
+  \note Dividing by constant doesn't change degrees of freedom or uncertainty.
+     All indicators & restrictions on value removed.
+     Must assume double is irrational and not integer,
+     NOT int/int becomes rational as operator /= .
+  */
+  unc<is_correlated>& operator/= (const double& a)
+  {
+    value_ /= a;
+    uncertainty_ /= float(a);
+    unctypes_ &= ~(VALUE_ZERO | VALUE_RATIONAL | VALUE_INTEGER | VALUE_NEGATIVE_ONLY | VALUE_POSITIVE_ONLY);
+    return *this;
+  }
+
+  inline bool operator== (const unc<is_correlated>& x) const
+  { // Predicate compare equal.
+    return value_ == x.value_; // Compare values EXACTLY.
+    // Might also close_to compare within uncertainty - see equalU
+  } // operator==
+
+  inline bool operator!= (const unc<is_correlated>& x) const
+  { // Predicate compare not equal.
+    return value_ != x.value_; // Compare values EXACTLY.
+    // Might also close_to compare within uncertainty - see equalU
+  } // operator!=
+
+  inline bool operator< (const unc<is_correlated>& x) const
+  { // Predicate compare operator< for use by std::sort etc.
+    // (Note const needed to use with less!)
+    return value_ < x.value_;
+    // Use normal signed values (no allowance for uncertainties).
+    // Might also compare within uncertainty - see lessU
+  } // operator<
+
+  // Insert and extract operator>> and operator<< for unc.
+  friend std::ostream& operator<< (std::ostream& os, const unc<is_correlated>& val)
+  {
+    boost::io::ios_precision_saver precision_saver(os);
+    boost::io::ios_flags_saver flags_saver(os); 
+    // Changes are restored on destruction.
+    std::ostringstream oss; // Build up string.
+    oss.flags(os.flags()); // Copy flags to restore TODO not needed?).
+
+    double mean = val.mean();
+    float uncertainty = val.deviation();
+    unsigned short int degFree = val.degFree();
+    unsigned short int unc_flags = val.uncFlags();
+
+    // bools showing output requirements specified using unc additional ostream manipulators.
+    // Note that these bools are NOT initialised here,
+    // assuming compiler will warn if used before being initialised.
+    /*
+      \var bool isNoisyDigit
+      \brief Add an extra 'noisy' guard digit to reduce risk of information loss.
+    */
+    bool isNoisyDigit;  //!<  
+    bool isDegFree;  //!<  Append degrees of freedom.
+    bool isPlusMinus; //!< Uncertainty as +/- is required too (but ignore if value is exact or integer).
+    bool isUppercase; //!< Exponential format is, for example, 1E6 else 1e6.
+    bool isScientificFormat;  //!< Taken to mean that exponential format wanted (always possible).
+    bool isShowPoint;  //!< Means decimal point is always shown, for example 900. even if not needed.
+    bool isShowPos; //!< Show + sign always because ios flag was set with `<< showpo`s.
+    bool isFixed; //!< `os << fixed ...` ios decimal fixed d.dddd format (rather than scientific).
+    bool isWidthSet; //!< `os << setw(9)` has prescribed a width (rather than default width == 0).
+    bool isNoAdjust;  //!< std = default but unc usage not defined yet, center?
+    bool isRightJustify; //!< right justify, prepend leading pad before. `<< right << ...`
+    bool isLeftJustify; //!< left justify, append trailing pad after. `<< left ...`
+    bool isInternalJustify;  //!< Not defined yet, but use to center in field?
+    bool isCenter; //!< center if BOTH left and right specified.
+    bool isAlign; //!< Align on decimal point?
+    bool isConfidenceInterval; //!<  Append confidence interval, for example, "<1.23, 1.56>"
+    bool isSetSigDigits;  //!<  Use set sigdigits instead of calculate from uncertainty.
+    bool isSetUncSigDigits;  //!<  Use set sigdigits instead of calculate from uncertainty.
+    // Get print format requirements from std::ios flags. ****************************
+    const int iosFlags = os.flags();  // Save fmtflags in case need to restore.
+
+     // Width, precision, flags & fillChar data from stream os. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    std::streamsize iosWidth = os.width(); //!< \warning Width must be read BEFORE any use of os
+    // which would reset width back to zero!
+    // & prevent any ios formatting during os << ...
+    // because unc_output does all its own formatting.
+    isWidthSet = (iosWidth > 0); // For example by os << setw(99)
+
+    isUppercase = static_cast<bool>(iosFlags & std::ios_base::uppercase); // E not e.
+    // TODO No mechanism to change uppercase at present in round_* functions.
+    isScientificFormat = static_cast<bool>(iosFlags & std::ios_base::scientific); // exp format wanted.
+    isFixed = static_cast<bool>(iosFlags & std::ios_base::fixed); // `<< fixed` Fixed format wanted.
+    // means d.dddd format wanted, if possible, rather than scientific or exp format.
+    isNoAdjust = !static_cast<bool>(iosFlags & std::ios_base::adjustfield); // `<< noadjust`
+    // no adjustfield flags are set (default, and == << right - a waste!).
+    isLeftJustify = static_cast<bool>(iosFlags & std::ios_base::left);
+    // left justify, append trailing padding with fillchar after.
+    isRightJustify = static_cast<bool>(iosFlags & std::ios_base::right);
+    // right justify, prepend leading padding with fillchar before.
+    isInternalJustify = static_cast<bool>(iosFlags & std::ios_base::internal);
+    // IO streams use to output fill char between sign and 1st digit.
+    // And meaning of more than one bit is specially defined for unc_output:
+    isCenter = isLeftJustify && isRightJustify;
+    // center if BOTH left and right ios specified.
+    // Done with ` << ` center rather than `<< left << right ... `.
+    isAlign = isInternalJustify && isLeftJustify && isRightJustify;
+    // Align decimal point with previous value?
+
+    isShowPoint = static_cast<bool>(iosFlags & std::ios_base::showpoint);
+    // Means decimal point is always shown, for example 900. even if not needed.
+    isShowPos = static_cast<bool>(iosFlags & std::ios_base::showpos);
+    // Show + sign always.
+
+    // Get print format requirements from unc flags. 
+    long& uncFlags = os.iword(uncFlagsIndex); //  
+    isPlusMinus = static_cast<bool>(uncFlags & plusMinus); // `<< plusminus`
+    isNoisyDigit = static_cast<bool>(uncFlags & noisyDigit); // `<< addNoisyDigit`
+    isConfidenceInterval = static_cast<bool>(uncFlags & limits); // `<< addlimits`
+    isDegFree = static_cast<bool>(uncFlags & degfree); // `<< addDegrees`
+    isSetSigDigits = static_cast<bool>(uncFlags & useSetSigDigits); // `<< setsigdigits`
+    isSetUncSigDigits = static_cast<bool>(uncFlags & useSetUncSigDigits); // `<< setsigdigits`
+
+    // Pick up distribution type from unc_flags.
+    // UNC_UNIFORM = 1 << 11, //!< Uncertainty has rectangular or uniform probability distribution.
+    // UNC_TRIANGULAR = 1 << 12, //!< Uncertainty has triangular probability distribution.
+    distribution_type distrib;
+    if (unc_flags & UNC_UNIFORM)
+    {
+      distrib = uniform;
+    }
+    else if (unc_flags & UNC_TRIANGULAR)
+    {
+      distrib = triangular;
+    }
+    else
+    {
+      distrib = gaussian;
+    }
+
+    long& roundloss = os.iword(roundingLossIndex);
+    double epsilon;
+    if (roundloss == 0)
+    { // Not been set,
+      epsilon = 0.05; // so use a default.
+    }
+    else
+    { // Has been set by a call like `out << confidence(0.01);`.
+    // rounding loss is stored as a long, so scaled by 1000,
+      // so that 0.05 or 1% is stored as 50.
+      epsilon = roundloss / 1000.;  // `<< roundingloss(0.05)`
+    }
+    //! Confidence or alpha to compute confidence interval is similarly scaled.
+    //! Usage: `out << confidence(0.01) << ...` means 1 - confidence = 99% confidence.
+ //!   double confidence = os.iword(conf) / 1000.;  // `<< confidence(0.05)` aka 95% 
+
+    //int round_m(double epsilon = 0.01, double unc = 0., unsigned int uncsigdigits = 2, distribution_type distrib = gaussian);
+    //void out_confidence_interval(std::pair<double, double> ci, int m, std::ostream& os = std::cout);
+    //void out_value_limits(double mean, double unc, std::pair<double, double> ci, int m, std::ostream& os = std::cout);
+
+    long& conf = os.iword(confidenceIndex);
+    double confidence;
+    if (conf <= 0)
+    { // Has not been set, so use default.
+      confidence = 0.05;  // 95% confidence.
+    }
+    else
+    {
+      confidence = conf / 1.e6;
+    }
+    using boost::math::isfinite;
+    using boost::math::isnan;
+    using boost::math::isinf;
+
+    double intpart;
+    int max_digits10 = std::numeric_limits<double>::digits10 * 3010/10000;
+    // std::numeric_limits<double>::max_digits10))
+    if (boost::math::isfinite(mean))
+    { 
+      if(isSetSigDigits)
+      { // Use explicit number of digits of precision.
+        long& sigDigits = os.iword(setSigDigitsIndex);
+        if ((sigDigits <= 0) || (sigDigits > max_digits10) )
+        { // show all potentially significant digits.
+          sigDigits = max_digits10;
+        }
+        oss << std::showpoint << std::setprecision(sigDigits) << mean;
+      }
+      else
+      { // Use uncertainty to control digits of precision.
+        if (mean == 0)
+        { // isValueZero = true; 
+          if ((uncertainty == 0.F) )
+          { // Is exact integer zero, so not rounded, and no decimal point.
+            oss << "0";
+          }
+          else if (!isfinite(uncertainty))
+          { // Show all possibly significant digits for NaN and inf uncertainty.
+            oss << std::showpoint << std::setprecision(max_digits10) << mean;
+          }
+          else
+          { // Inexact zero.
+            int m = round_m(epsilon, uncertainty, 2, distrib); 
+            if (isNoisyDigit)
+            { // Move rounding digit to one less significant position.
+              m--;
+            }
+            oss << round_ms(0., m);
+          }
+        } // mean == 0
+        else if(unc_flags & VALUE_INTEGER)
+        { // Value is flagged as an integer (used integer constructor or set flag).
+          double fracpart = std::modf(mean, &intpart);
+          oss << static_cast<long>(intpart); // Integer, so not rounded, and no decimal point,
+          // even if decimal point is specified by showpoint!
+        }
+        else if (unc_flags & VALUE_EXACT)
+        { // Value flagged as exact because sd == 0 (but NOT integer)
+          // (used double constructor or set flag) so show decimal point.
+          oss.unsetf(std::ios_base::showpoint); // Ignore showpoint so NO trailing zeros.
+          // Kinda want a decimal point here, but causes trouble with setw :-(
+          oss << std::setprecision(std::numeric_limits<double>::digits10) << mean;
+          double fracpart = std::modf(mean, &intpart);
+          if (fracpart == 0.)
+          { // Avoid two decimal points!
+            oss << '.';
+          }
+        }
+        else
+        { // Non-zero uncertainty, sd != 0.
+          if (isfinite(uncertainty))
+          { // Rounding is appropriate.
+            int m = round_m(epsilon, uncertainty, 2, distrib); // m is rounding digit index.
+            if (isNoisyDigit)
+            { // Move rounding digit to one less significant position.
+              m--;
+            }
+            if (isShowPos)
+            {
+              oss << '+';
+            }
+            if (mean <= 1e15)
+            { // Will fit into 1000000000000 (digits10 = 15).
+              oss << round_ms(mean, m);
+            }
+            else
+            { // Won't fit into 1000000000000 (digits10 = 15), so switch to exponent format.
+              oss << mean;
+              //round_e(mean, m); // This value of m is wrong TODO !!!
+              // Need to round but and not display exp as "e+009"  TODO.
+            }
+          }
+          else
+          { // Uncertainty NAN or infinite, so show all possibly significant digits.
+            oss << std::showpoint << std::setprecision(max_digits10) << mean;
+          }
+        }
+      }
+    }
+    else
+    { // Mean is NaN or infinity.
+      if (isnan(mean))
+      {
+        oss << "NaN" ;
+      }
+      else if (isinf(mean))
+      {
+         oss << ((mean < 0) ? "-inf" : (isShowPos) ? "+inf" : "inf");
+      }
+      // Or could leave as native output, but MSVC format is ugly.
+    } // Mean
+
+    if (isPlusMinus && !(unc_flags & VALUE_INTEGER)) 
+    { // Want estimate of uncertainty.
+      if (isfinite(uncertainty))
+      { 
+        if (uncertainty == 0.F)
+        { // Special case short version.
+          oss << " +/-0";
+        }
+        else
+        { // Non-zero uncertainty.
+          int uncSigDigits = os.iword(setUncSigDigitsIndex);
+          // Default is round to 2 sig digit - ISO rule.
+          if (uncSigDigits <= 0)
+          { // Automatically choose uncSigDigits based on degrees of freedom.
+            // Passed negative values through to allow 
+            // an auto mode for w < 0 that chooses from degrees of freedom,
+            // From table H page 457 in Oliver & Goldsmith, confidence interval
+            // of standard deviation is about +/- 20% at 10 degrees of freedom,
+            // and only < +/- 10% above 100 observations (needing 2 stdDev sig Digits).
+            uncSigDigits = abs(uncSigDigits);
+            if (degFree > 100)
+            {
+              uncSigDigits = 3;
+            }
+            else if (degFree > 10)
+            {
+              uncSigDigits = 2;
+            }
+            else 
+            { // degFree in common range 1 to 10.
+              // Choose between 1 and 2 digits based on 1st digit of uncertainty.
+              // Would be too big a step if most significant digit was 1 or 2.
+              std::ostringstream oss;
+              oss << std::scientific << std::setprecision (1) << uncertainty; // Assume sd positive.
+              if(oss.str()[0] == '1') // Check 1st digit before decimal point.
+              { // Would be too big a step if most significant digit was 1 or 2.
+                uncSigDigits = 2;
+              }
+              else if (oss.str()[0] == '2')
+              {
+                uncSigDigits = 2;
+              }
+              else
+              { // 1st digit > 2 so can use just 1 digit.
+                 uncSigDigits = 1;
+              }
+            }
+          }
+        
+         if (unc_flags & UNC_NOPLUS)
+          {
+            oss << " +0/-";
+          }
+          else if (unc_flags & UNC_NOMINUS)
+          {
+            oss << " -0/+";
+          }
+          else
+          { // normal plus and minus.
+            oss << " +/-";
+          }
+          //oss.unsetf(std::ios_base::scientific);
+          oss << std::noshowpos  // Prefixed by " +/-" so never add +.
+            << std::fixed // << std::noscientific 
+            << std::showpoint
+            << std::setprecision(uncSigDigits); // switches to e format :-(
+          //double unc_rounded = round_sig(uncertainty, uncSigDigits);
+          //oss << unc_rounded;
+           //std::string round_f<FPT>(FPT v, int sigdigits);
+         std::string s = round_f<float>(uncertainty, uncSigDigits);
+          oss << s; 
+        }
+      }
+      else
+      { // Not finite uncertainty - NaN or inf.
+        if (isnan(uncertainty))
+        {
+          oss << " +/-?";
+        }
+        else if (isinf(uncertainty))
+        {
+          oss << " +/-inf";
+        }
+      }
+    } // uncertainty.
+
+    if(isConfidenceInterval)
+    { // Want to append confidence interval as <1.23, 2.34>.
+      if (boost::math::isfinite(mean) && boost::math::isfinite(uncertainty) && degFree >= 1)
+      { // Possible to compute confidence limits or interval in < > angle brackets.
+        std::streamsize osp = os.precision();
+        oss.precision(4); // 
+        //std::pair<double, double> conf_interval(double mean, double unc, double df = 1., double alpha = 0.05, distribution_type distrib = gaussian);
+        double alpha = os.iword(confidenceIndex) / 1.e6; // Pick up and unscale alpha.
+        double epsilon = os.iword(roundingLossIndex) / 1.e3; // Pick up and rounding loss and unscale.
+        int uncSigDigits = os.iword(setUncSigDigitsIndex);  // Pick up significant digits for uncertainty.
+        if(isNoisyDigit)
+        {
+          uncSigDigits++;
+        }
+        std::pair<double, double> ci  = conf_interval(mean, uncertainty, degFree, alpha, distrib);
+        int m = round_m(epsilon, uncertainty, uncSigDigits, distrib);
+        using boost::lexical_cast;
+        oss << " <" 
+            << lexical_cast<double>(round_ms(ci.first, m-1)) << ", "
+            << lexical_cast<double>(round_ms(ci.second, m-1))
+            << ">";
+      }
+      else
+      { // Not possible to compute confidence limits or interval.
+        oss << " < ? >" ;
+      }
+    } // Appended confidence interval.
+
+    if (isDegFree)
+    {
+      if (degFree == (std::numeric_limits<unsigned short int>::max)())
+      { // Is valid.
+         oss << " (?)";
+      }
+      else if (degFree == 0u)
+      {
+         oss << " (0?)";
+
+      }
+      else
+      {
+        oss << " (" << degFree << ")";
+      }
+
+    }
+    os << oss.str();
+    return os;
+  } // friend ostream& operator<< (ostream& os, const unc<is_correlated>& val)
+
+  friend std::istream& operator>> (std::istream& is, unc<is_correlated>& ud)
+  {
+    double mean;
+    double stdDev;
+    unsigned short int degreesOfFreedom;
+    unsigned short unctypes;
+    unc_input(mean, stdDev, degreesOfFreedom, unctypes, is);
+    // At present, uses a separate function for input (unlike output).
+    ud = unc<is_correlated>(mean, float(stdDev), degreesOfFreedom, unctypes);
+    // Inputs mean, SD & degrees of freedom & set unc types...
+    return is;
+  }
+
+  // Math functions for uncertain class.
+  friend unc<is_correlated> ceil(unc<is_correlated> arg)
+  {
+    arg.value_ = ceil(arg.value_);
+    arg.uncertainty_ = 0.;  // Becomes exact & rational integer.
+    arg.unctypes_ |= UNC_NOPLUS | UNC_NOMINUS | VALUE_INTEGER | VALUE_RATIONAL; // Exact.
+    arg.degFree_ = (std::numeric_limits<unsigned short>::max)(); //= USHRT_MAX; = 0xFFFF
+    return arg;
+  }
+
+  friend unc<is_correlated> floor(unc<is_correlated> arg)
+  {
+    arg.value_ = floor(arg.value_);
+    arg.uncertainty_ = 0.; // Becomes exact & rational integer.
+    arg.unctypes_ |= UNC_NOPLUS | UNC_NOMINUS| VALUE_INTEGER | VALUE_RATIONAL;  // Exact.
+    arg.degFree_ = (std::numeric_limits<unsigned short>::max)(); // USHRT_MAX; = 0xFFFF
+    return arg;
+  }
+
+  friend unc<is_correlated> fabs(unc<is_correlated> arg)
+  {
+    if (is_correlated && (arg.value_ < 0.))
+      arg.uncertainty_ *= -1.;
+    // Else uncorrelated so uncertainty unchanged?
+    arg.value_ = fabs(arg.value_);
+    unsigned short int plusMinus = arg.unctypes_ & (UNC_NOPLUS | UNC_NOMINUS);
+    if (( plusMinus != 0) // Neither, & not both
+      && (plusMinus != (UNC_NOPLUS | UNC_NOMINUS))
+      )
+    {  // Just one asymetric uncertainty.
+      plusMinus = ~plusMinus;  // Switch bits over.
+      arg.unctypes_ &= ~(UNC_NOPLUS | UNC_NOMINUS); // Clear both.
+      arg.unctypes_ |= plusMinus;  // Set switched.
+    }
+    return arg;
+  }
+
+  friend unc<is_correlated> abs(unc<is_correlated> arg)
+  { // Copy of fabs version above.
+    if (is_correlated && (arg.value_ < 0.))
+      arg.uncertainty_ *= -1.;
+    // Else uncorrelated so uncertainty unchanged?
+    arg.value_ = fabs(arg.value_);
+    unsigned short int plusMinus = arg.unctypes_ & (UNC_NOPLUS | UNC_NOMINUS);
+    if (( plusMinus != 0) // Neither, & not both
+      && (plusMinus != (UNC_NOPLUS | UNC_NOMINUS))
+      )
+    {  // Just one asymetric uncertainty.
+      plusMinus = ~plusMinus;  // Switch bits over.
+      arg.unctypes_ &= ~(UNC_NOPLUS | UNC_NOMINUS); // Clear both.
+      arg.unctypes_ |= plusMinus;  // Set switched.
+    }
+    return arg;
+  }
+
+
+  friend unc<is_correlated> ldexp(unc<is_correlated> arg,
+    int intarg)  // Real from significand or mantissa arg & exponent intarg.
+  {
+    if (is_correlated)
+      arg.uncertainty_ *= ldexp(1., intarg);
+    else
+      arg.uncertainty_ *= fabs(ldexp(1., intarg));
+    arg.value_ = ldexp(arg.value_, intarg);
+    arg.unctypes_ &= ~(UNC_KNOWN | UNC_NOPLUS | UNC_NOMINUS);  //
+    return arg;  // arg * 2**intarg
+  }
+
+  friend unc<is_correlated> modf(unc<is_correlated> arg, double* intpart)
+  { // Split unc into updated integer and return fraction parts.
+    arg.value_ = modf(arg.value_, intpart);  // value = fractional part.
+    // Must assume not rational fraction, so clear many bits.
+    arg.unctypes_ &= ~(VALUE_INTEGER | VALUE_RATIONAL | UNC_KNOWN | UNC_NOPLUS | UNC_NOMINUS | UNC_EXPLICIT | DEG_FREE_EXACT | DEG_FREE_KNOWN);
+    return arg; // Fractional part (mantissa or significant).
+  }
+
+  friend unc<is_correlated> frexp(unc<is_correlated> arg, int* intarg)
+  {  // Raise arg to integer power.
+    arg.uncertainty_ *= float(pow(2., double(-*intarg)));
+    arg.value_ = frexp(arg.value_, intarg);
+    // If zero, integer or rational remains so.
+    return arg;
+  }
+
+  friend unc<is_correlated> fmod(const unc<is_correlated>& arg,
+    const unc<is_correlated>& divisor)
+  { // Floating-point remainder of x / divisor such that
+    //   x = i * divisor + remainder,
+    // where i is an integer, remainder has the same sign as x, and
+    // absolute value of remainder is less than the absolute value of y.
+    unc<is_correlated> remainder(0.);  // For remainder.
+    if (divisor.value_ == 0.)
+    { // ANSI 4.5.6.4 if divisor == zero return zero.
+      remainder.value_ = 0.;
+      remainder.uncertainty_ = std::numeric_limits<float>::infinity();
+      remainder.unctypes_ = 0U;  //
+    }
+    else
+    {
+      double slope1 = 1. / divisor.value_; // If zero would cause divide by zero!
+      double slope2 = ((arg.value_ / divisor.value_) > 0.) ?
+        -floor(arg.value_ / divisor.value_) :
+      floor(-arg.value_ / divisor.value_);
+      if (is_correlated)
+        remainder.uncertainty_ = float(slope1 * arg.uncertainty_
+        + slope2 * divisor.uncertainty_);
+      else
+        remainder.uncertainty_ = float(sqrtSumSqrs(slope1 * arg.uncertainty_,
+        slope2 * divisor.uncertainty_));
+      remainder.value_ = fmod(arg.value_, divisor.value_);
+      remainder.unctypes_ = arg.unctypes_;  // Better choice than divisor?
+      remainder.unctypes_ &= ~(VALUE_INTEGER | VALUE_RATIONAL);
+      // Remainder can't be integer & unlikely to be rational, so clear these.
+    }
+    return remainder;  // remainder.
+  }
+
+  friend unc<is_correlated> sqrt(unc<is_correlated> arg)
+  { // sqrt(unc)
+    arg.value_ = sqrt(arg.value_);
+    if (is_correlated)
+      arg.uncertainty_ /= 2. * arg.value_;
+    else  // Uncorrelated.
+      arg.uncertainty_ /= fabs(2. * arg.value_);
+    arg.unctypes_ &= ~(VALUE_INTEGER); // Must assume not integer.
+    // sqrt of rational reamins rational?
+    return arg;
+  }
+
+  friend unc<is_correlated> sin(unc<is_correlated> arg)
+  {
+    if (is_correlated)
+      arg.uncertainty_ *= cos(arg.value_);
+    else
+      arg.uncertainty_ *= fabs(cos(arg.value_));
+    arg.value_ = sin(arg.value_);
+    arg.unctypes_ &= ~(VALUE_INTEGER | VALUE_RATIONAL); // Must assume not.
+    return arg;
+  }
+
+  friend unc<is_correlated> cos(unc<is_correlated> arg)
+  {
+    if (is_correlated)
+      arg.uncertainty_ *= -sin(arg.value_);
+    else
+      arg.uncertainty_ *= fabs(sin(arg.value_));
+    arg.value_ = cos(arg.value_);
+    return arg;
+  }
+
+  friend unc<is_correlated> tan(unc<is_correlated> arg)
+  {
+    double costemp = cos(arg.value_);
+    arg.uncertainty_ /= costemp * costemp;
+    arg.value_ = tan(arg.value_);
+    return arg;
+  }
+
+  friend unc<is_correlated> asin(unc<is_correlated> arg)
+  {
+    arg.uncertainty_ /= sqrt(1. - arg.value_ * arg.value_);
+    arg.value_ = asin(arg.value_);
+    return arg;
+  }
+
+  friend unc<is_correlated> acos(unc<is_correlated> arg)
+  {
+    if (is_correlated)
+      arg.uncertainty_ /= -sqrt(1. - arg.value_ * arg.value_);
+    else
+      arg.uncertainty_ /= sqrt(1. - arg.value_ * arg.value_);
+    arg.value_ = acos(arg.value_);
+    return arg;
+  }
+
+  friend unc<is_correlated> atan(unc<is_correlated> arg)
+  {
+    arg.uncertainty_ /= 1. + arg.value_ * arg.value_;
+    arg.value_ = atan(arg.value_);
+    return arg;
+  }
+
+  friend unc<is_correlated> atan2(const unc<is_correlated>& arg1,
+    const unc<is_correlated>& arg2)
+  {
+    unc<is_correlated> retval;
+    double slope1 = 1., slope2 = 1.; // slope = d f(x)/dx or f'(x).
+    double sum2 = arg2.value_ * arg2.value_ + arg1.value_ * arg1.value_;
+    if (sum2 != 0.)
+    {
+      slope1 = arg2.value_ / sum2;
+      slope2 = -arg1.value_ / sum2;
+    }
+    if (is_correlated)
+    {
+      retval.uncertainty_ = slope1 * arg1.uncertainty_
+        + slope2 * arg2.uncertainty_;
+    }
+    else
+    { // Uncorrelated.
+      retval.uncertainty_ = sqrtSumSqrs(slope1 * arg1.uncertainty_,
+        slope2 * arg2.uncertainty_);
+    }
+    retval.value_ = atan2(arg1.value_, arg2.value_);
+    return retval;
+  }
+
+  friend unc<is_correlated> exp(unc<is_correlated> arg)
+  {
+    arg.value_ = exp(arg.value_);
+    if (is_correlated)
+      arg.uncertainty_ *= arg.value_;
+    else
+      arg.uncertainty_ *= fabs(arg.value_);
+    return arg;
+  }
+
+  friend unc<is_correlated> log(unc<is_correlated> arg)
+  {
+    if (is_correlated)
+      arg.uncertainty_ /= arg.value_;
+    else
+      arg.uncertainty_ /= fabs(arg.value_);
+    arg.value_ = log(arg.value_);
+    return arg;
+  }
+
+  friend unc<is_correlated> log10(unc<is_correlated> arg)
+  {
+    const double oneDivLog10 = 0.434294481903251827651128918917;
+    // Use Boost.Math?
+    if (is_correlated)
+      arg.uncertainty_ *= oneDivLog10 / arg.value_;
+    else
+      arg.uncertainty_ *= oneDivLog10 / fabs(arg.value_);
+    arg.value_ = log10(arg.value_);
+    return arg;
+  }
+
+  friend unc<is_correlated> sinh(unc<is_correlated> arg)
+  {
+    arg.uncertainty_ *= cosh(arg.value_);
+    arg.value_ = sinh(arg.value_);
+    return arg;
+  }
+
+  friend unc<is_correlated> cosh(unc<is_correlated> arg)
+  {
+    if (is_correlated)
+      arg.uncertainty_ *= sinh(arg.value_);
+    else
+      arg.uncertainty_ *= fabs(sinh(arg.value_));
+    arg.value_ = cosh(arg.value_);
+    return arg;
+  }
+
+  friend unc<is_correlated> tanh(unc<is_correlated> arg)
+  {
+    double coshtemp = cosh(arg.value_);
+    arg.uncertainty_ /= coshtemp * coshtemp;
+    arg.value_ = tanh(arg.value_);
+    return arg;
+  }
+
+  // Power
+  friend unc<is_correlated> pow(const unc<is_correlated>& arg1,
+    const unc<is_correlated>& arg2)
+  {
+    unc<is_correlated> retval;
+    retval.value_ = pow(arg1.value_, arg2.value_);
+    double slope1, slope2;
+
+    if (0 == arg1.value_)
+    {
+      slope2 = 0.;  slope1 = 0.;
+      if (1. == arg2.value_)
+        slope1 = 1.;
+    }
+    else if (arg1.value_ < 0.)
+    { // pow(arg1, arg2) for arg1 < 0. is only defined for integer arg2.
+      slope1 = arg2.value_ * retval.value_ / arg1.value_;
+      slope2 = 0.;
+    }
+    else
+    {
+      slope1 = arg2.value_ * retval.value_ / arg1.value_;
+      slope2 = log(arg1.value_) * retval.value_;
+    }
+    if (is_correlated)
+      retval.uncertainty_ = slope1 * arg1.uncertainty_
+      + slope2 * arg2.uncertainty_;
+    else
+      retval.uncertainty_ = sqrtSumSqrs(slope1 * arg1.uncertainty_,
+      slope2 * arg2.uncertainty_);
+    return retval;
+  }
+
+  // Getter functions for read-only access to private data members:
+  // uncertainty_, value_, degrees of freedom and unc type.
+
+  // These are duplicates.
+  
+  double mean(void) const {return value_;}
+
+  float deviation(void) const {return uncertainty_;}  // 
+
+  unsigned short int degFree(void) const {return degFree_;}
+
+  unsigned short int uncFlags(void) const {return unctypes_;} // 16 flags.
+
+  // For testing single argument functions like sin,cos, tan, log, exp.
+  friend unc<is_correlated> PropagateUncertaintiesBySlope(
+    double (* certain_func)(double),  // For example sin
+    const unc<is_correlated>& arg)  // (angle)
+  {
+    unc<is_correlated> retval;
+    double std_deviation_up_value, std_deviation_down_value;
+    retval.value_ = certain_func(arg.value_);
+    std_deviation_up_value = certain_func(arg.value_ + arg.uncertainty_);
+    std_deviation_down_value = certain_func(arg.value_ - arg.uncertainty_);
+    retval.uncertainty_ = (std_deviation_up_value - std_deviation_down_value) * 0.5;
+    if (!is_correlated) retval.uncertainty_ = fabs(retval.uncertainty_);
+    return retval;
+  }
+
+  // For testing double argument functions like atan2, pow.
+  friend unc<is_correlated> PropagateUncertaintiesBySlope
+    (
+    double (*certain_func)(double, double),  // for example atan2 or pow
+    const unc<is_correlated>& arg1,  // For example arg1 is number to be raised to
+    const unc<is_correlated>& arg2)  // arg2 power.
+  {
+    unc<is_correlated> retval;
+
+    retval.value_ = certain_func(arg1.value_, arg2.value_);
+    if (is_correlated)
+    {
+      double up_val = certain_func(arg1.value_ + arg1.uncertainty_,
+        arg2.value_ + arg2.uncertainty_);
+      double down_val = certain_func(arg1.value_ - arg1.uncertainty_,
+        arg2.value_ - arg2.uncertainty_);
+      retval.uncertainty_ = 0.5 * (up_val - down_val);
+    }
+    else
+    {
+      double up_val1 = certain_func(arg1.value_ + arg1.uncertainty_,
+        arg2.value_);
+      double down_val1 = certain_func(arg1.value_ - arg1.uncertainty_,
+        arg2.value_);
+      double up_val2 = certain_func(arg1.value_,
+        arg2.value_ + arg2.uncertainty_);
+      double down_val2 = certain_func(arg1.value_,
+        arg2.value_ - arg2.uncertainty_);
+      retval.uncertainty_ = 0.5 * sqrtSumSqrs(up_val1 - down_val1,
+        up_val2 - down_val2);
+    }
+    return retval;
+  }
+  
+  // Predicate Comparison functions.
+  // Should be global to allow leftmost argument to use implicit type conversion
+  // according to Scott Meyers, Effective C++ Item 19 p 68 - 71.
+  // But these are member functions and seem to work OK.
+  // Note MUST be static bool.
+
+  static bool lessU(const unc<is_correlated>& l, const unc<is_correlated>& r) 
+  { // less using Comparison criterion including ONE standard deviation.
+    // (Comparison is possibly different for correlated case but not implemented yet).
+    double lhi = (l.value_ + l.uncertainty_);  // Upper confidence limit of left.
+    double rlo = (r.value_ - r.uncertainty_);	// Lower confidence limit of right.
+    double diff = (l.value_ + l.uncertainty_) - (r.value_ - r.uncertainty_);
+    // diff = lhi - rlo;
+    double tol = hypot(l.uncertainty_, r.uncertainty_); // 'Average' of two uncertainties.
+    bool isLess =  lhi < (rlo + hypot(l.uncertainty_, r.uncertainty_)); // == less
+    if (true)
+    { // Output diagnostic info.
+      std::cerr << "lessU " << l.value_ << space
+        << lhi // (l.value_ + l.uncertainty_)
+        << space << ((isLess) ? " < " : " >= ")
+        // << (r.value_ - r.uncertainty_) == rlo
+        << space << rlo << space << rlo + hypot(l.uncertainty_, r.uncertainty_) // tol
+        << space << r.value_ 
+        << space << tol 
+        << space << diff 
+        << std::endl;
+    }
+    return isLess;
+  } // bool lessU(const unc<is_correlated>& l, const unc<is_correlated>& r) 
+
+
+  static bool lessU2(const unc<is_correlated>& l, const unc<is_correlated>& r) 
+  { // less using Comparison criterion including TWO standard deviations.
+    // (Comparison is possibly different for correlated case but not implemented yet).
+    double lhi = (l.value_ + l.uncertainty_ + l.uncertainty_ );  // Upper confidence limit of left.
+    double rlo = (r.value_ - r.uncertainty_ - r.uncertainty_);	// Lower confidence limit of right.
+    // double diff = (l.value_ + l.uncertainty_) - (r.value_ - r.uncertainty_);
+    double diff = lhi - rlo;
+    double tol = hypot(l.uncertainty_ + l.uncertainty_, r.uncertainty_ + r.uncertainty_); // 'Average' of two uncertainties.
+    bool isLess =  lhi < (rlo + hypot(l.uncertainty_+ l.uncertainty_, r.uncertainty_ + r.uncertainty_)); // == less
+    if (true)
+    { // Output diagnostic info.
+      std::cerr << "lessU " << l.value_ << space
+        << lhi // (l.value_ + l.uncertainty_ * 2)
+        << space << ((isLess) ? " < " : " >= ")
+        // << (r.value_ - r.uncertainty_ * 2) == rlo
+        << space << rlo << space << rlo + tol
+        << space << r.value_ 
+        << space << tol 
+        << space << diff 
+        << std::endl;
+    }
+    return isLess;
+  } // bool lessU2(const unc<is_correlated>& l, const unc<is_correlated>& r)
+
+  static bool moreU(const unc<is_correlated>& l, const unc<is_correlated>& r) 
+  { // less using Comparison criterion within ONE standard deviation.
+    // Comparison is possibly different for correlated case but not implemented yet.
+    return l.value_ - l.uncertainty_ > r.value_ + r.uncertainty_; // Values with uncertainty. 
+  } // bool moreU
+
+  static bool equalU(const unc<is_correlated>& l, const unc<is_correlated>& r) 
+  { // less using Comparison criterion outside ONE standard deviation.
+    // Comparison is possibly different for correlated case but not implemented yet.
+    return !((l.value_ - l.uncertainty_ > r.value_ + r.uncertainty_) // > 
+     || (l.value_ + l.uncertainty_ < r.value_ - r.uncertainty_)); // <
+  } // bool equalU
+
+  static bool equalU2(const unc<is_correlated>& l, const unc<is_correlated>& r) 
+  { // less using Comparison criterion outside TWO standard deviations.
+    // Comparison is possibly different for correlated case but not implemented yet.
+    return !((l.value_ - l.uncertainty_ - l.uncertainty_> r.value_ + r.uncertainty_ + r.uncertainty_) // > 
+     || (l.value_ + l.uncertainty_ + l.uncertainty_ < r.value_ - r.uncertainty_ - r.uncertainty_)); // <
+  } // bool equalU2
+
+
+}; // class unc<is_correlated>
+
+template <bool correlated>
+std::ostream& operator<< (std::ostream& os, const std::pair< unc<correlated>, unc<correlated> >& u)
+{ /*! Output a pair (X and Y) of uncertain values with (if defined) uncertainty and degrees of freedom.
+     \details For example: "1.23 +/- 0.01 (13), 3.45 +/- 0.06 (78)".
+   */
+  os << u.first << ", " << u.second;
+  return os;
+} // std::ostream& operator<< (ostream& os, const pair<unc<correlated>, unc<correlated> >& u)
+
+
+//template std::ostream& operator<< (std::ostream& os, const std::pair< unc<false>, unc<false> >& u);
+
+//! Two helper functions to provide values and uncertainties as pairs.
+//! \note Names value_of and plural valueS_of.
+
+/*! Allow value part of variables of class unc to be assigned to, and compared with double.
+\tparam T Built-in floating-point type, float, double or long double, or uncertain type unc.
+*/
+template <class T>
+double value_of(T);
+
+/*! Allow uncertainty (standard deviation) part of variables of class unc to be assigned to, and compared with float.
+\tparam T Built-in floating-point type, float, double or long double, or uncertain type unc.
+*/
+template <class T>
+double unc_of(T);
+
+// Pairs
+template <class T> //! \tparam T Built-in floating-point type, float, double, long double or unc or Meas.
+std::pair<double, double> values_of(std::pair<T, T>);
+
+template <class T1, class T2> //! \tparam T Built-in floating-point type, float, double, long double or unc or Meas.
+std::pair<double, double> values_of(std::pair<T1, T2>);
+
+template <class T> //! \tparam T Built-in floating-point type, float, double, long double or unc or Meas.
+std::pair<double, double> uncs_of(std::pair<T, T>);
+
+template <class T1, class T2> //! \tparam T Built-in floating-point type, float, double, long double or unc or Meas.
+std::pair<double, double> uncs_of(std::pair<T1, T2>);
+
+/* already defined.
+template <class T> //! \tparam T Builtin-floating point type or unc.
+std::pair<double, double> values_of(std::pair<T, T> up)
+{ //! \return values (parts) as a pair of doubles.
+  //! \note so can write
+  //!   @c std::pair<const double, double> minmax = value_of(*result.first); // x min & max
+  //!   whether T is double or unc, or ...
+
+  double vp1 = up.first.value();
+  double vp2 = up.second.value();
+  std::pair<double, double> minmax = std::make_pair(up.first.value(), up.second.value());
+  return minmax;
+}
+*/// Global Predicates compare LessThan or operator< now static member functions.
+// was bool lessUnc(const unc<false>& a, const unc<false>& b);
+
+namespace std
+{ // Fudge until MSVC becomes compliant.
+  template<typename Type> inline
+    Type abs(const Type& a) 
+  { // Should be std::abs but is NOT in cstdlib - only provides global ::abs.
+    return Type((a < Type(0)) ? -a : a);
+  }
+} // namespace std
+
+// Predicate compare operators for use by sort etc.
+// Functors are _preferred_ to functions for STL algorithms.
+// Scott Meyers, ESTL, item 46, page 201..
+
+template<typename Type> // Predicate Functor modelled on STL less in functional.
+// Used below by min_element, etc.
+struct lessAbs : public std::binary_function<Type, Type, bool>
+{ // Usage: if (lessAbs<Meas>()(lm, hm)) ...
+  bool operator() (const Type& a, const Type& b) const
+  { // Note const to prevent modification - must be pure function.
+    // (Implies operator< for Type must also be const!)
+    return ((a < static_cast<Type>(0)) ? -a : a) < ((b < static_cast<Type>(0)) ? -b : b);
+    // Allows use with both POD like int and double,
+    // and other types for which both operator< and operator- are defined.
+    // Instead of:
+    // return fabs(a) < fabs(b); // fabs allows use with int and double,
+    // at price of conversion to double.
+    // But will fail for other types,
+    // so abs function written here using only operator< and operator-.
+  }
+
+}; // template <bool is_correlated> class unc
+
+// Specialization of autoprefix_norm for UDT boost::units::uncun
+// See /boost-trunk/libs/units/example/measurement.hpp
+// For autoprefix_norm see /boost-trunk/boost/units/io.hpp.
+// This specialization is required to get autoprefix to work with this class.
+
+using boost::units::autoprefix_norm_impl;
+
+autoprefix_norm_impl<unc<false>, true>::type
+autoprefix_norm(const unc<false> & arg)
+{
+  return autoprefix_norm_impl<double, true>::call(arg);
+}
+
+// Destructor Definitions need to go into unc.ipp, not unc.hpp
+// or will fail to link because two versions.
+
+#include <boost/quan/impl/unc.ipp>  // Definitions.
+#include <boost/quan/impl/unc_input.ipp>  // Definitions.
+// #include <boost/quan/impl/unc_output.ipp>  // Definitions.
+
+#endif // UNC_HPP
Added: sandbox/SOC/2007/quan/boost/quan/unc_init.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/unc_init.hpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,57 @@
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// Copyright Paul A. Bristow 1998, 2012.
+
+/*!
+  \file
+  \brief Initialisation of std::stream iword to store uncertainty information.
+   \details This sets the index values for data stored using the xalloc mechanism.
+   This is included from unc.hpp and accessed from unc.ipp for many functions.
+   Function setUncdefaults is used to set default values for these items for an iostream.
+*/
+
+#ifndef UNC_INIT
+#define UNC_INIT
+
+// unc_init.hpp called by unc.hpp
+
+#include <ios> // for ios_base.
+
+// This block of definitions MUST be positioned before main.
+// 14 indexes of long iwords allocated by calls of ios_base.xalloc();
+// 1st call of xalloc() returns 0 so ios_base.iword(0) used for magic id,
+// 2nd call of xalloc() returns 1 so ios_base.iword(1) used for uncFlags,
+// 3rd calls returns 2, so iosword(2) used for sigDigits ...
+// Order of assignment must ensure these match enum uncindex (if used).
+const long zeroIndex = std::ios_base::xalloc(); // 1st iword[0] to hold a 'magic' id.
+
+const long uncFlagsIndex = std::ios_base::xalloc(); // long& uncFlags = iword(1)
+const long oldUncFlagsIndex = std::ios_base::xalloc(); // long& olduncFlags = iword(2)
+const long sigDigitsIndex = std::ios_base::xalloc(); // sigDigits = iword(3)
+const long oldSigDigitsIndex = std::ios_base::xalloc(); // oldsigDigits = iword(4)
+const long setSigDigitsIndex = std::ios_base::xalloc(); // setsigDigits = iword(5)
+const long uncSigDigitsIndex = std::ios_base::xalloc(); // setUncSigDigitsIndex = iword(6)
+const long setUncSigDigitsIndex = std::ios_base::xalloc(); // setUncSigDigitsIndex = iword(7)
+const long oldUncSigDigitsIndex = std::ios_base::xalloc(); // oldUncSigDigitsIndex = iword(8)
+const long scaleIndex = std::ios_base::xalloc(); // scale = iword(9)
+const long oldScaleIndex = std::ios_base::xalloc(); // oldScale = iword(10)
+const long setScaleIndex = std::ios_base::xalloc(); // setScale = iword(11)
+const long uncWidthIndex = std::ios_base::xalloc(); // uncWidth = iword(12)
+const long oldUncWidthIndex = std::ios_base::xalloc(); // oldUncwidth = iword(13)
+const long oldUncSetWidthIndex = std::ios_base::xalloc(); // oldUncSetWidth = iword(14)
+const long usedIndex = std::ios_base::xalloc(); // used = iword(15)
+const long oldUncUsedIndex = std::ios_base::xalloc(); // oldUsed = iword(16)
+const long widthIndex = std::ios_base::xalloc(); // width = iword(17)
+const long oldWidthIndex = std::ios_base::xalloc(); // oldWidth = iword(18)
+const long roundingLossIndex = std::ios_base::xalloc(); // roundingLoss = iword(19)
+const long confidenceIndex = std::ios_base::xalloc(); // roundingLoss = iword(20)
+
+const long topIndex = std::ios_base::xalloc(); // long& topIndex = iword(21] == iword(0] check!
+
+extern const long indexID;  // 'Magic' value defined in unc_init.hpp.
+bool isIndexed = true; // Above indexes have been initialised.
+
+#endif
Added: sandbox/SOC/2007/quan/boost/quan/uncbools.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/uncbools.hpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,33 @@
+	long& uncWidth = os.iword(uncWidthIndex); //
+	long& oldUncWidth = os.iword(oldUncWidthIndex); //
+	long& uncFlags = os.iword(uncFlagsIndex);
+	long& Width = os.iword(widthIndex);
+	long& oldWidth = os.iword(oldWidthIndex);
+	long& setSigDigits = os.iword(setSigDigitsIndex);
+	long& setStdDevSigDigits = os.iword(stdDevSigDigitsIndex);
+
+	// bools showing output requirements.
+	bool isNoisyDigit; // Extra 'noisy' guard digit to reduce risk of information loss.
+	bool isPlusMinus;// Uncertainty as +/- is required too (but ignore if exact or integer).
+	bool isSetScale;		// Defined to mean scale to specified power of 10.
+	bool isAutoScale; // is to scale automatically to SI multple of 1000.
+	bool isUppercase; // Exponential format is, for example, 1E6 else 1e6.
+	bool isExpFormat;	// Taken to mean that exponential format wanted (always possible).
+	bool isShowPoint;  // Means decimal point is always shown, for example 900. even if not needed.
+	bool isShowPos; // Show + sign always.
+	bool isFixed;	// Taken to mean that d.dddd format wanted, if possible.
+	bool isLeftJustify; // left justify, trailing pad after.
+	bool isRightJustify; // right justify, leading pad before.
+	bool isInternalJustify;  // Not defined yet, but use to center in field?
+	// bools showing  state of arguments value, stdDev, df.
+	bool isExactValue; // value is exact (integer, rational, zero stdDev or noplus & nominus).
+	bool isIntegerValue; // value is an integer, or stdDev = 0.f.
+	bool isUncKnown; // StdDev or uncertainty is valid.
+	bool isValueNaN; // value is NaN
+	bool isStdDevNaN; // StdDev is NaN
+	bool isValueInfinite; // value is infinity.
+	bool isNegativeValue = false; // Value is negative.
+	bool isZeroValue; // Value is zero.
+	bool isCenter; // Both left and right, so center (on decimal point if possible).
+	bool isFirmFormat; // os << setw(9) has prescribed a width.
+
Added: sandbox/SOC/2007/quan/boost/quan/uncdata.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/uncdata.hpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,79 @@
+/*!
+\file
+\brief Summary of uncFlagsIndex, unc_types and uncertainflags.
+
+*/
+
+extern const long uncFlagsIndex; // uncertain flags for unc_output
+// by << flex << plusminus ...
+extern const long oldUncFlagsIndex; // Saved previous uncertain flags.
+extern const long sigDigitsIndex; // sigDigits auto calc in unc_output.
+extern const long setSigDigitsIndex; // sigfigs to use if setSigDigits flag set.
+extern const long oldSigDigitsIndex; // Previous value of sigDigitsIndex
+// by << setsigdigits ... Value assigned by << setSigDigits(4) ...
+extern const long stdDevSigDigitsIndex;  // Sigfigs to use for +|- output,
+// if setuncsigfigs flag bit set by << setuncsigfigs...// Value set by << setUncSigDigits(3) ...
+extern const long oldStdDevSigDigitsIndex;  // Previous value of stdDevSigDigitsIndex.
+extern const long ScaleIndex; // Auto scale factor calculated by unc_output.
+extern const long setScaleIndex; // Use if set scaled flag set by << setscale...
+// Scale value set by << setScale(6) ...
+extern const long oldScaleIndex; // Previous value of ScaleIndex.
+extern const long uncWidthIndex; // width to use by unc_output if
+// firm format uncFlags set by << flexform ...// Value assigned by << setUncWidth(9) ...
+extern const long oldUncWidthIndex; // Previous value of uncWidthIndex.
+extern const long oldUncSetWidthIndex; // Not used yet.
+extern const long usedIndex; // output chars actually used.
+extern const long oldUncUsedIndex;  //  Previous value of usedIndex.
+extern const long widthIndex;  // ios setwidth.
+extern const long oldWidthIndex;   // Previous value of ios setwidth.
+
+enum unc_types
+{   // 16 type bits used by unc uncTypes. Bit set = 1 means a positive attribute.
+  VALUE_ZERO = 1 << 0, // Too near zero to allow relsd = sd /mean
+  // A few times std::numeric_limits<float>::min() is a suitable limit?
+  VALUE_INTEGER = 1 << 1, // Exact integer 2,3,4 ... may not be possible to store.
+  VALUE_RATIONAL = 1 << 2, // Integers & Fractions 1/2, 1/3, 2/3, 5/4 ...
+  // so don't need irrational - must be if not rational.
+  // Irrational like pi, e ... representated as accurately as possible.
+  VALUE_NEGATIVE_ONLY = 1 << 3, // Value can ONLY be < 0.. ? or <=0?
+  VALUE_POSITIVE_ONLY = 1 << 4, // Value can ONLY be >=0..
+  UNC_KNOWN = 0x20,    // Uncertainty known (but if not value may known OK).
+  UNC_NOPLUS = 0x40, // Uncertainty can only be < value, + = zero.
+  UNC_NOMINUS = 0x80, // Uncertainty can only be > value - = zero.
+  // Integer, Rational or Exact by definition like 25.4 mm per inch,
+  // if unc = 0.0f or both UNC_NOPLUS & UNC_NOMINUS.
+  UNC_QUAN_DECIMAL = 0X100, // Quantised by least significant decimal digit.
+  UNC_QUAN_BINARY = 0X200, // Quantised by least significant binary digit.
+  UNC_EXPLICIT = 0x400, //If bit set = 1, uncertainty implicit from sig digits.
+  // or explicit if +/- or calculated (normal default case, bit = 0).
+  UNC_UNIFORM = 0x800, // Uncertainty has rectangular probability distribution.
+  UNC_TRIANGULAR = 0x1000, // Uncertainty has triangular probability distribution.
+  //  If not rectangular or triangular, then normal or Gaussian.
+  // But is triangular & gaussian different in real life?
+  DEG_FREE_EXACT = 0x2000, // Known number of observations -1,
+  // so default zero means 1 observation.
+  // else estimated, for example, using Welch-Satterthwaite.
+  DEG_FREE_KNOWN = 0x4000, // Degrees of freedom defined.
+  SPARE = 0x8000 // This unc_type is spare.
+};
+
+enum uncertainflags
+{  // For control of printing.
+  none, // Default.
+  firm = 1,  // bit 0: == 0 == false means flex, or firm == 1 == true.
+  setScaled = 2, // bit 1 Set scaled == 1 or not scaled == 0.
+  // by fixed factor SetScale and << scale ...
+  // power10 in range -max to +max.
+  autoScaled = 4,  // bit 2: auto = 1  with << autoscale ...
+  plusMinus = 8, // bit 3 = 1 means add +/- uncertainty << plusminus ...
+  addSISymbol = 0x10,  // bit 4 = 1, add suffix SI symbol G, M, k, m, u, n, p ...
+  // If one is applicable, else = 0 do nothing.
+  addSIPrefix = 0x20,  // bit 5 = 1, add suffix SI prefix Giga, Mega, kilo ...
+  noisyDigit = 0x40, // Add extra 'noisy' decimal digit to value & sd
+  // This means is suitable for input to other calculations because the
+  // random extra 2 to 3 bits will approximate a continuous function.
+  // Quantisation to fewer digits would distort statistical calculations.
+  // Default is to use minimum decimal digits for clearer display.
+  // Extra digit also added when degrees of freedom > 10.
+  setSigFig = 0x80, // if bit 7 = 1 use set sigfig else calculate from sd.
+  setUncSigFig = 0x100 // if bit 8 = 1 use set Unc sigfig else calculate from degrees of freedom.
\ No newline at end of file
Added: sandbox/SOC/2007/quan/boost/quan/uncs.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/uncs.hpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,122 @@
+// unc reference info from unc.hpp
+
+enum unc_types
+{   // 16 type bits used by UReal uncTypes. Bit set = 1 means a positive attribute.
+	VALUE_ZERO = 1 << 0, // Too near zero to allow relsd = sd /mean
+	// A few times std::numeric_limits<float>::min() is a suitable limit?
+	VALUE_INTEGER = 1 << 1, // Exact integer 2,3,4 ... may not be possible to store.
+	VALUE_RATIONAL = 1 << 2, // Integers & Fractions 1/2, 1/3, 2/3, 5/4 ...
+	// so don't need irrational - must be if not rational.
+	// Irrational like pi, e ... representated as accurately as possible.
+	VALUE_NEGATIVE_ONLY = 1 << 3, // Value can ONLY be < 0.. ? or <=0?
+	VALUE_POSITIVE_ONLY = 1 << 4, // Value can ONLY be >=0..
+	UNC_KNOWN = 0x20,    // Uncertainty known (but if not value may known OK).
+	UNC_NOPLUS = 0x40, // Uncertainty can only be < value, + = zero.
+	UNC_NOMINUS = 0x80, // Uncertainty can only be > value - = zero.
+	// Integer, Rational or Exact by definition like 25.4 mm per inch,
+	// if unc = 0.0f or both UNC_NOPLUS & UNC_NOMINUS.
+	UNC_QUAN_DECIMAL = 0X100, // Quantised by least significant decimal digit.
+	UNC_QUAN_BINARY = 0X200, // Quantised by least significant binary digit.
+	UNC_EXPLICIT = 0x400, //If bit set = 1, uncertainty implicit from sig digits.
+	// or explicit if +/- or calculated (normal default case, bit = 0).
+	UNC_RECTANGULAR = 0x800, // Uncertainty has rectangular probability distribution.
+	UNC_TRIANGULAR = 0x1000, // Uncertainty has triangular probability distribution.
+	//  If not rectangular or triangular, then normal or Gaussian.
+	// But is triangular & gaussian different in real life?
+	DEG_FREE_EXACT = 0x2000, // Known number of observations -1,
+	// so default zero means 1 observation.
+	// else estimated, for example, using Welch-Satterthwaite.
+	DEG_FREE_KNOWN = 0x4000, // Degrees of freedom defined.
+	SPARE = 0x8000 // This unc_type is spare.
+};
+
+const unsigned short int VALUE_EXACT = (UNC_NOMINUS | UNC_NOPLUS);  // Both set.
+const unsigned short int UNC_DEF = (UNC_KNOWN | UNC_NOMINUS | UNC_NOPLUS |
+																		UNC_QUAN_DECIMAL | UNC_QUAN_BINARY |
+																		UNC_EXPLICIT | UNC_RECTANGULAR | UNC_TRIANGULAR);  //
+const unsigned short int DEG_FREE_DEF = (DEG_FREE_EXACT | DEG_FREE_KNOWN);
+
+enum uncertainflags
+{  // For control of printing.
+	none, // Default.
+	firm = 1,  // bit 0: == 0 == false means flex, or firm == 1 == true.
+	setScaled = 2, // bit 1 Set scaled == 1 or not scaled == 0.
+	// by fixed factor SetScale and << scale ...
+	// power10 in range -max to +max.
+	autoScaled = 4,  // bit 2: auto = 1  with << autoscale ...
+	plusMinus = 8, // bit 3 = 1 means add +/- uncertainty << plusminus ...
+	addSISymbol = 0x10,  // bit 4 = 1, add suffix SI symbol G, M, k, m, u, n, p ...
+	// If one is applicable, else = 0 do nothing.
+	addSIPrefix = 0x20,  // bit 5 = 1, add suffix SI prefix Giga, Mega, kilo ...
+	noisyDigit = 0x40, // Add extra 'noisy' decimal digit to value & sd
+	// This means is suitable for input to other calculations because the
+	// random extra 2 to 3 bits will approximate a continuous function.
+	// Quantisation to fewer digits would distort statistical calculations.
+	// Default is to use minimum decimal digits for clearer display.
+	// Extra digit also added when degrees of freedom > 10.
+	setSigFig = 0x80, // if bit 7 = 1 use set sigfig else calculate from sd.
+	setUncSigFig = 0x100 // if bit 8 = 1 use set Unc sigfig
+	// else calculate from degrees of freedom.
+};
+
+void uncertainPrint(  // Declaration, defined below.
+										double, // Mean or most likely value.
+										float, // Standard deviation.
+										unsigned short int, // Degrees of freedom.
+										unsigned short int, // 16 Uncertain type flags.
+										ostream&);  // Output stream.
+
+
+void uncertainRead(double& mean,  // mean (central or most probable) value.
+		               double& stdDeviation,
+									 unsigned short int& degreesOfFreedom,  // 1 observation.
+									 unsigned short int& types,
+									 istream& is);
+
+// Parameterless Manipulators declarations.
+// Similar to ios_base flags but for uncertain printing.
+// Use uppercase convention for these,
+// but all lowercase for manipulators like hex, oct ...
+// Usage:  out << scale << noscale << autoscale << noautoscale
+// firmform << flexform << plusminus << noplusminus ....
+
+// All ios_base functions declared below are defined in unc.cpp
+// Note that all of these are entirely lower case, like ios manipulators.
+ios_base& scale(ios_base&); // To use value set with setUncScale(int)
+ios_base& noscale(ios_base&);  // or not scaled.
+ios_base& autoscale(ios_base&); //  Scale to suitable symbol like M, k, m...
+ios_base& noautoscale(ios_base&);  // or not.
+ios_base& firmform(ios_base&);  // Firm fixed layout using setUncWidth.
+ios_base& flexform(ios_base&); // Flexible free format.
+ios_base& plusminus(ios_base&);  // Add +/- uncertainty.
+ios_base& noplusminus(ios_base&);  // No +/- uncertainty
+ios_base& addSIprefix(ios_base&); // Add SI prefix like kilo, micro ..
+ios_base& noSIprefix(ios_base&);	// (Takes precedence over SI symbol if both set).
+ios_base& addSIsymbol(ios_base&); // Add SI symbol like M, k, m.
+ios_base& noSIsymbol(ios_base&);  // No SI symbol like M, k, m
+ios_base& addNoisyDigit(ios_base&);  // Add an extra 'noisy' digit for computer.
+ios_base& noNoisyDigit(ios_base&);  // No noisy for human reading.
+ios_base& setsigdigits(ios_base&);    // Use sigDigits set with << setSigDigits(4) ...
+ios_base& autouncsigfigs(ios_base&);  // Calculate sigfigs from uncertainty.
+ios_base& setuncsigfigs(ios_base&); // Use sigDigits set with << setUncSigDigits(2) ...
+ios_base& autosigfigs(ios_base&);  // Calculate sigfigs from uncertainty.
+
+// Functions to change uncertain flags on specified ios_base.
+// Usage: f = uFlags(out); f = uFlags(out, 0xFF);
+// f = setuFlags(out, 0xFF); f = resetuFlags(out, 0xFF);
+long uFlags(ios_base&);  // Returns current uncertain flags.
+long uFlags(ios_base&, long); // Assigns all uncertain flags & returns previous.
+long setuFlags(ios_base&, long);  // Set specific flags = 1
+long resetuFlags(ios_base&, long);  // Reset/clear specific flags = 0
+
+// Forward declarations, defined in unc.cpp.
+class showUncFlags;  // Output uncertain flags to ostream << showUncFlags ...
+class setAllUncFlags;  // Assign value to set (aand/or clear) all unc flags.
+class setUncFlags;  // Set specific unc flags bits.
+class setMaskedUncFlags;  // Clear mask & then set unc flag bits.
+class resetUncFlags;  //
+class resetMaskedUncFlags;
+class setUncWidth;
+class setUncScale; //
+class setSigDigits;  // sigfigs to use for value if << setsigdigits
+class setUncSigDigits;  // sigfigs to use for uncertainty if << setuncsigfigs
\ No newline at end of file
Added: sandbox/SOC/2007/quan/boost/quan/xiostream.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/boost/quan/xiostream.hpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,120 @@
+/*! \file xiostream.hpp
+  \brief Extra iostream manipulators
+  \details Definitions in xiostream.cpp
+
+  \author Paul A. Bristow
+  \date Sep 2009
+*/
+
+// Copyright Paul A. Bristow 2009
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef XIOSTREAM_HPP
+#define XIOSTREAM_HPP
+
+#include <iostream>
+#include <cfloat>  // for <float.h> for _isnan, _finite, _fpclass & values.
+
+//using std::ios_base;
+//using std::ostream;
+//using std::istream;
+//using std::cout;
+//using std::cerr;
+//using std::endl;
+//using std::hex;
+//using std::dec;
+//using std::showbase;
+//using std::ios_base::fmtflags;
+//using std::ios_base::iostate;
+
+// Parameterless ostream manipulators space, newline, bell, etc.
+// Usage: out << bell << newline << tab << space << twobackslash ...
+// Now done more simply using:
+const char nl = '\n';
+const char tab = '\t';
+const char space = ' ';
+const char sp = ' ';
+const char bell = '\a';
+
+// Single int parameter manipulators.
+// Usage: out << spaces(12) << stars(8) << tabs(2) ...
+// spaces & stars done with simple way, NOT using template,
+// See S Teale p 181-3, said to be longer but faster.
+
+// TODO these should be declared here, and *defined* elsewhere?
+
+class spaces;
+class tabs;
+class stars;
+class chars;
+
+class spaces  // Definition for this file.
+{ // Usage: out << spaces(12) ...
+  friend std::ostream& operator<< (std::ostream&, const spaces&);
+public:
+  spaces(int); // Constructor defined in xiostream.cpp.
+private:
+  int num;
+};
+
+class tabs  // Definition for this file.
+{ // Usage: out << tabs(2) ...
+  friend std::ostream& operator<< (std::ostream&, const tabs&);
+public:
+  tabs(int); // Constructor defined in xiostream.cpp.
+private:
+  int num;
+};
+
+class stars  // Definition for this file.
+{   // Usage:  out << stars(10) ...
+  friend std::ostream& operator<< (std::ostream&, const stars&);
+public:
+  stars(int);  // Constructor defined in xiostream.cpp.
+  // private:
+  int num;
+};
+
+// Manipulator class with int repeat count & character chars.
+class chars  // Definition for this file.
+{ // Usage:  out << chars(10, '_') ....
+  friend std::ostream& operator<< (std::ostream&, const chars&);
+public:
+  chars(int, char);  // Constructor defined in xiostream.cpp.
+private:
+  int num;
+  char character;
+};
+
+class setupperbase
+{
+  friend std::ostream& operator<< (std::ostream&, const setupperbase&);
+  friend std::istream& operator>> (std::istream&, const setupperbase&);
+public:
+  setupperbase(int);  // Constructor defined in xiostream.cpp.
+private:
+  int base;
+}; // class setupperbase
+
+void outIosFlags(long flags, std::ostream& os); // Show std iostream flags.
+void outFpClass(double value, std::ostream& os);  // Show Floating-point type.
+
+void outIOstates(std::ios_base::iostate rdstate = std::cout.rdstate(), std::ostream& os = std::cerr, const char* term = ". ");
+// Outputs rdstate as words "good", "eof", "fail" and/or "bad".
+void outFmtFlags(std::ios_base::fmtflags fmtFlags = std::cout.flags(), std::ostream& os = std::cerr, const char* term = ". ");
+// Outputs ios_base fmtflags as words like "skipws", "scientific", "left"...
+// Note that the default values must be in the header file, NOT in the .cpp or .ipp file.
+
+// Ostream manipulators to show state of stream.
+std::ostream& showiostate(std::ostream& os);  // Show IO stream state in words for this stream.
+// Usage: cout << showiostate ...
+
+std::ostream& showformat(std::ostream& os); // Show IO stream format flags in words for this stream.
+// Usage:	cout << showformat ...
+
+#include <boost/quan/impl/xiostream.ipp>
+
+#endif // XIOSTREAM_HPP
Added: sandbox/SOC/2007/quan/libs/quan/doc/doxygen/draft.png
==============================================================================
Binary file. No diff available.
Added: sandbox/SOC/2007/quan/libs/quan/doc/doxygen/draft.svg
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/libs/quan/doc/doxygen/draft.svg	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   version="1.1"
+   width="652"
+   height="694"
+   id="svg2">
+  <metadata
+     id="metadata8">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs6" />
+  <image
+     xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAowAAAK2CAIAAABLsFpKAAAAA3NCSVQICAjb4U/gAAAgAElEQVR4 nO3d23bbuJaFYQA8y066R7//M/boim1RPKIv1g63to+SCIAg+H9XrlRCMXLMqQUsANpaqwAAiM80 TVmWbX0XWzJb3wAAAJ/ouq5t277vt76RLeVb3wAAAO91XXe5XKZpmudZKVWW5dZ3tA0qaQBAXJaE VkqN43i5XA5bT1NJAwAicp3QYhgG+eKA9bSmcQwAEImPCb3I87yqqqqqwt/VhqikAQBR+CahlVLj OCqltNaHqqcJaQDA9r5PaCHj3tba49TThDQAYGO3JLRSSmst9bRS6iA5TUgDALZ0Y0IvDpXThDQA YDP3JrQ4Tk4T0gCAbfR9/0BCi4PkNCENANjAYzX0tSPkNCENAAhtTQ19bdnnJNWcJqQBAEH1fd+2 7fqEVgfo92bvbgBAOA4TejEMwzAMS1qnhJAGAITjPKGVUnmeG2OSPHmakAYABPLPP/84T+gsy4qi aJpGa+32yjEgpAEAIZDQDyCkAQDekdCPIaQBAH6R0A8jpAEAHpHQaxDSAABfSOiVCGkAgBc+EtoY c5yEVuw4BgDwgRraCUIaAODY//3f/83z7PaaB0xoxXA3AMCtf/75h4R2hZAGADjDPLRbDHcDANxg Hto5KmkAgAMktA+ENABgLRLaE0IaALAKCe0PIQ0AeBydYl7ROAYAeBA1tG9U0gCAR5DQARDSAIC7 kdBhENIAgPswDx0Mc9IAgDv4q6Hruiah3yGkAQC3YpQ7MIa7AQA3oYYOj5AGAPzMa0IbQxh9jvcF APADf51iJPT3eGsAAN/xlNBlWZLQP+LdAQB8iYTeFm8QAOBzJPTmeI8AAJ8goWPA2wQAeI+EjgTv FADgP5DQ8eDNAgD8GwkdFd4vAMC//Pnzh4SOCnt3AwCUooaOEu8aAIAaOlK
8cQBwdH/+/BnH0e01 SWgneO8A4NBI6JgxJw0Ax8U8dOR4BwHgoEjo+PEmAsAR0Sm2C7yPAHA4PuahlVLTNBVFQUI7xFsJ AMfyzz//+EhopZTW+vX11dPFj4mQBoAD8TEPfc1a+/LyQk67QkgDwFH4mIf+iJx2iJAGgEPwNA/9 KXLaFUIaANIXMqEFOe2EttZufQ8AAI98z0N/Q2v969evPGfjrAdRSQNAysLMQ3+FenolKmkASNaG NfQ16umHUUkDQJq2raGvUU8/jJAGgASF7xT7Hjn9GEIaAFITW0ILcvoBzEkDQFIimYf+CvPTd6GS BoB0RJ7Qinr6ToQ0ACQink6x70lOD8Ow9Y3sACENACnwd7aVD9Zazsu6BSENALu3lxr6GvX0LWgc A4B989HLbYwpikIpNY6j1/jXWj8/P8tr4SNCGgB2zF9CN02jtb5cLn3f+y7Tf/36RU5/iuFuANgr rwltjNFa13VdlmWWZW5f5Z3X11fGvT9FSAPALvlOaPmVMDktfWTk9EeENADsj4+E1lq/S+jl18np rRDSALAznhK6LMuPCb3837qui6IgpwOjcQwA9iR8Qi+stQH6yOj3vkZIA8BuhJmH/kaYnFb0e//F cDcA7EPIeehvfn+AcW+lFPucCCppANiBzWvoa4x7B0MlDQCxiyqhFX1kARHSABC1GEa5P71C0zRF UTx8hVuQ0wx3A0C8NuzlvgV9ZL4R0gAQqdhGuT9FTnvFcDcAxGgXCa1C7UemjtrvTSUNANH5559/ nBemPhJ6QT3tCZU0AMRldwmtruppr31k6nj1NCENABH58+fP7hJaSE5XVcW4t0OENADEYi/z0F9h fto5QhoAorD3hBbktFuENABsL42EFuS0Q4Q0AGwspYQW5LQrhDQAbCm9hBbBcvrPnz8J5zTrpAFg M6km9IL10ytt/y0EgGOK8+QMtzh/eiUqaQDYQPI19DWpp7uum+fZ6wulV0/H9Y0EgCN4eXk5TkKr gPuc
pDc/Hd33EgDSNs+z8+0zY05oEaaPTGud2Lh3pN9OAEiVMSbP86ZptNauLhh5QgvWZT2AOWkA 2MA0TeM4tm27cpp2Lwm9oN/7Lvv4pgJAYrIsy/O8rus14bq7hFbU03eikgaAzaypp/eY0Avq6Rvt 71sLAMl4uJ6ObT30vainb0QlDQAbu7eelhq6rmvfCecb9fSPdvkRDABSIvX0jWXxMsq994RW7O99 A0IaALa35PT367J2PQ/9qSWnvf6N9rt+muFuAIjFNE3DMFwul0/HvdNL6Gtt2/oe97bW/v79e1/j 3oQ0AETkq/npZOahvxEgp9Xe5qcT/DgGABtauTnJp/3eR0hopVTTNPR7v0MlDQDOvL6+yiTryqS5 rqcPktAL6ulrhDQAuCGnT7rKVMnpruuyLDtOQgtyekFIA4AD1+dDu8rpeZ6nacqyLMlOse+R04KQ BoC1rhNauMppa62rw7J2h5xWhDQArPQxocXR5pJ9IKcPN4QCAA59ldBKqXmeZdGz74xJGP3ehDQA POibhBbk9HqS075n5aPNaUIaAB7xY0ILcnq9pmmqqjrm/t7MSQPA3W5M6AXz0+uFmZ9+fn4uy9Lr S9yFShoA7vPy8nJXQivqaRfCzE+/vr72fe/1Je5CSAPAHR6evCSn1wszPx1VThPSAHCrle1F5PR6 Mj8doI8skpxmThoAbuKqAVhrXZYl89NrHGd+mkoaAH7msPXXWks9vdJx5qcJaQD4wQOdYt+b53kc x3EcGct82EFympAGgO/42OZCa53neZ7nh92X24kj9JExJw0AX/KR0KyZdqtt267r5nn2+ipbzU9T SQPA50joXQizH9lW/d6ENAB8goTekQDz01rrTXKa4W4AeI+E3qMk12VRSQPAfyChdyrJfm8qaQD4 t3tPzrgFCR1SYvU0lTQA/Ivz9dCKhA4usXVZVNIAoBSj3GlJpp6mkgYAXzuWkNBbSaaeppIGcHTU 0KlKoJ6mkgZwaJ4SOs9zEnpzCf
R7U0kDOC5q6CPYdT1NJQ3goEjog9j1/DSVNIAjYj300ey0nqaS BnA4rIc+oJ3OTxPSAI6FUe7D2mNOE9IADoSEPrjd5TQhDeAoSGioveU0IQ3gEFgPjUXTNFVV7SKn CWkA6fO062ee503TkNB7VNf1LnKakAaQOH+j3CT0rtV1Hf+4NyENIGX+RrlJ6ATEPz9NSANIFqPc +FHk89OENIA0+Tt9koROTMzz02wLCiBBnnb9pIZO2OVy6boutn1DqaQBpMbTrp8kdNrirKcJaQBJ oVMMD4swpwlpAOmgUwwrxZbThDSARLAeGk5EtX6axjEAKWCUG25F0kdGJQ1g90hoOBfJuDchDWDf SGh4EkNOE9IAdoyEhlebz08T0gD2ioRGANvu703jGIBdYk8xhLRVHxmVNID98bGnGOuh8Y2t5qcJ aQA7w8kZ2MQmOU1IA9gTEhobCp/ThDSA3WBPMWwuWE7LP3VCGsA+sC83IhEgp/M8t9Zaa3N/rwEA rrDaClGp61op5anfuyiKqqqKotBaU0kDiB0JjQh5qqevE1ox3A0gciQ0ouV8P7J3Ca3YzARAzEho xM/VPicfE1pRSQOIFgmNXXAy7v1pQitCGkCcSGjsyMqc/iqhFSENIEIk9BrTNDl/9/Cjh3P6m4RW SrEEC0BcSOg1xnEchmEYhnEcm6bZ+naO5YF1Wd8ntCKkAUSFhF5DErptW6XUPM9KKXI6sLty+seE Vgx3A4gHCb3GdUIrpeZ57rpu+U8Ec+O49y0JraikAUSChF7jXUILyWlFPR2c1NN93391oOqNCa0I aQAxIKHX+DShxTzPcp4SOR2Y5LRS6mNO357QipAGsDkSeo1vElpM00ROb+LTnL4roRUhDWBb/hK6 rmsSWkzTxLj3Jt7l9L0JrQhpABuihl7jxoQWjHtvZclprfW9Ca3YuxvAVkjoNe5K6EWWZWVZktPh 9X0vh5ffldCKkAawCa+j3Hme+BjhYwktyOmtWGvvTWjFOmkA
4ZHQa0hCn8/nx/649JGxfjq8BxJa UUkDCMxHQmuti6I4TkKvj1hjTFVV1NPxo5IGEA4JvcY4jn3fP1xDX5M+Murp+BHSAAIhodeQGvpy uTw2avoR4967QEgDCIGEXsPVKPc70zRN0/TV1pWIASENwDtPCX2oTjEfJW+e50VRJP8G7hohDcAv fzV00zTJB8zKXu5v5HleVVVVVc6vDIfo7gbgEaPca3itoUnoXaCSBuALo9xrUENDEdIAPHl9fXWe 0Eop2fXzOAntqpdbWGtJ6H0hpAG49/r6Ksc5ODfPszGJP7iWUW4SGsxJA3DMX0KLLMt+/fqValR7 moe21so5iST0vqT5rxzAVuZ51lp7TdBpml5eXuZ59vcSW/HXKUZC7xQhDcAlY0xd10VRkNP3opcb HxHSABzLsoycvhcJjU8R0gDcI6fvQkLjK4Q0AC+WnHbbovxOAjktZ1uR0PgUIQ3AF8npsizJ6a8s Z1u5vaystirLkoTeO5ZgAfBrmqbL5TIMg9cc3eO6LEa58aM9/YMGsEfMT3/K33poEjolhDQA78jp d6ZpYscS3ILhbgCBMO4tpmmiUww3ivffMYDEUE8rEhp3IqQBhHPwnCahcS9CGkBQh81pSWjnq60U CZ005qQBbOBo89PU0HjM9v92ARzQoeppamg8jEoawGaOUE/727FEPuiQ0GmjkgawmeT395b10D5q aBL6IKikAWws1Xp6GeV2/phllPs4qKQBbCzJ+WkSGk4Q0gC2l1hOk9BwhZAGEIVkcpqEhkPMSQOI yDzPbdvud36ahIZbhDSAuOw3p2W1FQkNhxjuBhAXY0zTNLsb915OnySh4RAhDSA6u8tpT7t+WmtJ 6IMjpAHEaMnp+Pc58bfrZ1EUJPTBMScNIF7xz0/TKQavCGkAUQuT08aY379/35vTJDR8Y7gbQNTC zE/P83zvuDcJjQAIaQCxi7CPbOkUc57QWZaR0FgQ0gB2wBgTz3lZXs+H5mwrXGNOGsBuBO
sje35+ zrLs0//rdZS7LMu6rt1eFrtGJQ1gN4KNe7++vn76OcBTQltrZZSbhMY7VNIAdkbq6b7vvT6+PtbT nnYsUXSK4WtU0gB2RurpsiwD1NPTNC3/6Smh6RTDN6ikAexSyPlppRQ1NDZBSAPYqzA5rbWuqqrr OjrFEB4hDWDHwsxP+0BC4xbMSQPYsWV+2uv6aedIaNwo3/oGAGAVyWmllO9xb1dIaNyOShrA7oVZ P+0ECY27xP4PGgBusYucJqFxr3j/NQPAXSLPaRIaD4jxnzIAPCbanCah8Zi4/h0DwEoR5jQJjYfF 8o8YAFyJKqdJaKyx/b9gAHBuyelt10+T0FiJddIA0rT5+mkSGutRSQNI1ob1NAkNJwhpACnbZN9Q EhquENIAEhc4p0loOMScNID0hZyfzvOchIYrVNIADiHYuqy+76dp8voSOA5CGsBRhMnpeZ5fXl7I aThBSAM4kDD93uQ0XNHW2q3vAQCCmue5bVvf89PGmF+/fmVZ5u8lkDwqaQCHw7g39oKQBnBE5DR2 geFuAMc1z/Plcun7nnFvxIlKGsBxGWPqui7LknoacSKkARzaktP0eyNCDHcDAOPeiBSVNAAw7o1I EdIAoBQ5jSgR0kBcxnH0fQIEvkJOIzbMSQMReX197fu+LEs57lAp5fs0CHwUZn5aa/3792/mp/E9 QhqIhST08p95nmdZVlWVMYaoDow+MkSCkAai8C6hr1VVlee5nAnhdZkQrpHTiAEhDWzvm4RWSllr tdZFUeR5XlUVUR0M497YHCENbOz7hBaS00JmrH0ftghBPY1tEdLAlm5J6E/RXBYMOY0NEdLAZh5O aKG1NsaUZVkURZZlFNb+MO6NrRDSwDZWJvQ1a23TNFmWSWFNWvtATmMThDSwAYcJvTDGyKotOSuC MXDnGPdGeIQ0EJqPhF5IGV3XdZZlRVEoCmunyGkERkgDQb29vXVdF+a1ZIE1Y+BukdMIiZAGwgmZ 0LJqyxijtZbCmuY
yV8hpBENIA4GETOhPSVRTWDtBTiMMQhoIYfOEXgrrPM9lLxQpsje8pb2j3xsB ENKAd5sn9Duyc5kU1nmeKwrrR1FPwzdCGvArtoQWS2EtO5flec6W4I8hp+EVIQ14FGdCv/OusCaq 7xUsp5+fn2XkA8dBSAO+7CKhr0lb2dJchtuR0/CEkAa8GMfx7e1tmqatb+Ruxpgsy6qqyrKM5rLb kdPwgZAGvLDWys5iOw05rbVEtTSEK5rLbkBOwzlCGvBlHMeXl5e9/4jJLijSX0Zz2Y/IabhFSAO+ TNPUtm3XdQkEm4x7N00jg+EJ/I38IafhECENeNR13dvb22N/VmtdFEU8GW+tlYSWvVDoA/8GOQ1X CGnAo2mazufzMAwP/FlrbV3XeZ5fLhdrrdfH/b2kp6yua2MMzWWfIqfhBCEN+NW2raTsvX/QWpvn +el0MsYMw9D3/TRN8fzAWmtl3FuiWo7FxDVyGusR0oBf1to/f/48thZLIrCqKq21tbbrumEYxnGU /cKc3+rDZAxcWsFpLrsmOT0Mg9fFeFrrX79+kdNJIqQBv6y1Ukw/fIVfv34tdaqE9GOluVdS90tz mdaawFhQT2MNQhrwbhzHP3/+PPzH8zx/enq63rdZorrrummaIixbl4O2aC4TYeppcjpJhDTgnRTT bds+llhSnpZlaYxZflHKsrZtp2mKbQBcbkYWWMsYOCdDkNN4DCENhND3/dvb28M/bh+LaWGtnaZp GIau66Jq/17I0LdsCX7w8GB+Gg8gpIEQrLVvb2993z98haqqnp6evvq/8ujvui62xVrqb2EtY+DS BHfY5jJyGvcipIEQrLV935/P54d/4owxTdNUVfXNS8zzPPz16J36dX16xzHHwGXug5zGjQhpIJB5 nl9eXsZxfLiILMuyaZrvs81aKx8IZGl1hAWrPHNkAFwK6+u59iOQnPbd701Op4GQBgKR7Hx4l1Bx Op3qur7ld47jOE1ThLuVCXnyFEWxRPWhCmvqa
dyIkAbCWX/ItNb6+fn5xu29JJ5lHlQ6wKNqAl/I LuWyaus4m4xST+MWhDQQlKzFeviPL3uQ3TtELIuq1+yp4tUyBi5T70qpI4yBk9P4ESENBDUMw/l8 XlNMZ1n2/Pz8QMVprZWeMkmFaAtWY8yyaiv5MfAwOa2U+v37Nzm9R4Q0EJS19nw+d1235gplWT4/ Pz+WsssA+DzP4zg+fBteyXNJmsCloT3hwjrM/LQip/eJkAaCknnil5eXNZWT1vp0OpVl+XA1LLch TeDRRrXI8zz55jLqaXyFkAZCk0OmV66PKstSTrF8+ArSRDaO4zzP5/NZ/d1qNE7SXCb9ZUk2l9Hv jU8R0sAG+r5/eXlZmTS3L8f60TRNsmGZNIE7uaYP1zuXqeTGwMlpfERIAxuQYnrlvmBFUTRN4+pp K4W1NIHLlHnMDwdjzHVhvfXtOMP8NN4hpIFtrFyLpZTSWj89PZVl6eqWhLV2HMdxHPu+9x0VK2mt pQlc3oQ00pqcxjVCGtjGPM+vr68rm7aMMb9///YRTrJGS3ZBiXYn8EWWZVJYZ1mWQFSHyek8z2Ut n7+XwHp8jAI2k+f5MAwrZ6b7vpfOZ1d3JeTZXde1rNSSPnC3L+GQzKlfLpe6riWwd33QlpwgLl97 yuksy1w1NMArKmlgM+M4vry8rPwZLIri6enJdyZN0zTPs8xYS/UfcwQWf+26D9zfuqwsy6SbgTI6 foQ0sBmJvfP5vDJImqZZCi9/ZOvvaZr6vpdJ68jzzxhT17W0mKm4P1V8xce4Nwm9Lwx3A5uRw5XX h8cwDHI6hZO7+or+qygKiQ05YivaD/qy/ns5vUNWbe0rqpdxb1dHmZHQu0MlDWzs7e1tzS6hSilr 7fPzs4RQMFJVL03gkT9JZLcyaQXP83xfUe2qniah94iQBrYkh16cz+eVdZKcuhF+10xZXX25XGR1 dZxHYS7k3pYtwSO/22vrc9oYczqdSOjdYbgb2JIMxmZZtjKkZXFz+D4peTl
pAi+KQprAo/3oLzd2 uVy01n3fy1lbWuv4c2tlvzc19H5RSQMbk2L69fV15XXyPP/9+7eTW3rYPM/WWjliS9I65lJV4rks S5nRj/xu1aP1NAm9a4Q0sL1xHF9fX6dp2kWb94+km0x2Au/7XsXdrmWtvY7qyBdY35vTJPTeEdJA FC6XixxFtcb6o7HckiO22rZ11ZzslTTbS3OZk657T27PadmxRNaLh7k3OMecNBAFOTV5Zftu13VF UQRu8/6GbA0tM+5SWMcc1fM8yyj9UliXZRnhGPiN67JI6DRQSQOxcLIWS4rp8G3e35PnjBR/6zdv CUOOxZTtUCLcuez7epqETgaVNBAFa21VVcMwrKk1tdZxHggtCSdnVeV5LtuWRb66Whr6pGdeVm1F 1Vz2Tb+3bLVGQqeBShqIheyQJZ1Wa8Q2M/3R9RFb8XeWKaWstRLSVVVJVR3JDX+sp40xTdOQ0Mmg kgZiIRXb+pCWI6FifkYvR2zJ+PwwDDKEEEnyfaS1liNGZMa6rmtZ4L71fb2vpxnlTg+VNBCRaZra tu26bmVc1XV9Op1c3ZVvMu4t25Z5PUHZIekDz/NcmuO2/Xgh9fQ0TWVZktCJIaSBuDhZi2WMeXp6 iqHUu500V/d933VdzFW1kMlpWawlhfW2zXqylbr0uG14G3CO4W4gLmVZLjO1D5PAi6fL6RYy1yt7 i259Lz+TN1ZKfxkDl+nqrVZtSS964BdFAHxTgbhITab1qlEua+35fJa11w7vzbdxHOX4yx19tlB/ N04fx1EO8ZTtUKho4QQhDcRFa12WpZwoteYiSimp8PYSeMMwyMTqHufg5E2WqF6ay4wxeZ7v7jMH osKcNBAd6QO6XC4rr1MUxfPz8y4SYtcJ/SlrbfGXjGfs4huB2FBJA9FZ5hdXFmHjOHZdV9e1u1vz YhgGWTO99Y24JBvLSHuBHF8te4NvfV/YGSppIEauiumyLJ+enmKu4dKroT8lrQayRCrLMsbAcSMq aSBG
TtrHlFJ935dlKftxRkhq6OQTWv3dZHQYBglpWbVFcxl+RCUNRMpa+/Lysn4QuKqqpmkizIOD 1NCfkqFv2RKcwhrfoJIG4lVV1foMG4Yhwmlp5zW07OOxl4nteZ7llBFZr1VVFYU1PkUlDcRrmqbX 19eVO2XK+VpRzUwvnWIOE7osy7qup2mSXi3Zy8XJxQOIZ+cyxIaQBuJlre37/vX1dWW+Zln2/Pwc ydNfEnoYBlcXXBJaKlE567PrOlmy7OpVfLPWGmOKosjzvCzLeA7awrYIaSBqwzCcz+dxHFc+spum WY5L2pDvhF5Ya+XQKonq+DcDvybndsgpYZF8tMJWCGkgdm9vb13XrbxInuen02nb7Z19JHRRFN+3 xck25m3byjSwq5cOQDYsq+uaTbmPjO89EDtpH1vZEiXHIbu6pQcEq6E//jY5E0yO2JINRlzdg1fy qUJOid7RMADcIqSB2DnZf1t2R8nzfJMW4mW1lasL3pjQ179fa306ncZxlEO7rbWRjyNKK1me5yT0 kRHSQOyMMU3TrO+FlsOaiqII/NB3vh763oQW8rfO/5IVUFKqOrkrt+SIjqIoWJd1cHz7gR2Q3bxX hpyM94ZPaOfroR9I6HeyLJPTR+q6rqpKRXb6RZZlTdOQ0FA0jgF70XXd+rVYWuunp6dgu4RGUkN/ TwYYpmnqui6GqloGTkhoCEIa2Id5nt/e3tY3XtV13TRNgMLR344lPtJLpqil6N9wdbXMQ5PQWBDS wD5IhLRtu/I6Wuvn5+eiKJzc1Vf2ldALiWqZq5Zty0IOg5PQ+IiQBnZjnuc/f/6sXEmltZaJWH9J sNOEviZD9FJYhxkDJ6HxKf41AHsiG0auuYJUiv4KROcJrbUOnNBKqSzLZPuXp6enANuJkND4CpU0 sCfjOL68vKxfi3U6neQ4B1c3JhKood+RQyRlCxQZBnc+Bk5C4xuskwb2xBhTVdXlcllzEUmdeZ7d 7gudRg398R6UUnmey6qteZ5lDN
zV9m0kNL5HSAN7Yoxxkqx93xdF4TCk06uh35FDJI0xz8/PS2fZ ym3LSGj8iJAGdqaqqr7v1y8TGobBVU5vtS93eFJYy0LzoiiWHUYfuNSy62dsf0dEhZAGdsZaK0du rBlx1VrLAY7rNwZfaug1F7kWbUIv5B2Ts5+LohiGQc7EvD2tl4TmJEp8L9KfAQBfkXFXJ71Ll8tl 5eh08qPc35PvRVVVT09Pp9OpLMtb3odlX24SGj+iuxvYH1lG9fb2tvI6WZbJIdOPRf7BE/ojWVQt VfU4jp++q+z6ibsw3A3sj9ZajkmepmlNSS3dT4/tPkZCf5RlmSywVkrJpuXvZgFIaNyLShrYq7Zt 1+8Saox5enq6N6dJ6Fss53bM8yzT/03TMA+Nu1BJA7tkrS2KQtYCrbmOVHt3jXiT0Ddazq6W1dVV VUmpvfV9YU8IaWCXpGUpy7L1O0u3bSuNyrf8ZhL6XssYuLU21b8j/OFfDLBXWuv1h07KH78xdH3s KVYURcIJvZA2gq3vAvvDPxpg35wcOtl13Y+/x9Oun03TkF7AV/jZQNTsf9r6dqKTZZnsfrWSTJp+ 8xtIaGATzEkjIhIAsqzIWjvPs5xBJFtrLR038oXWWn6bv1MXd0EOfli5Jae829KB/PH/+piHLoqC hAZ+REhjS0sGT9MkG3QopZbTACU55At1NatnjJHe5qV5Sl1F+NFIU9L6fbO7rsvzvKqqd79OQgMb Yp00tiEBrJTquk621HisLJZ6WoJKakr1txnqOKy1Ly8vK3fPttbWdV3X9fXHHRIa2BaVNIKSGB6G QTZ5WKJaYvWBcJW56nmeh2GQTbhkZeqhFqRaa/M8l9GIhy+ite77/rqSJqGBzVFJIxyZ9ey6TkLa a71bluUyeHuEwnocx5eXl5U/ztbasiyfnp6MMSQ0EANCGiFIsSsPfRvkC+AAACAASURBVCn4wgRn 8VfyVbW19nK5nM/nlW9slmVPT09yNRIa2BwhDe8kmNu23WQZ
lUxaN02znHyQqr7vX19f138Aknl9 EhqIASENv7qu67puZU/TetJcJttPbnsn/lhrz+fzLduShERCA2ukXFhgQ9ZaOVhXCujNZ4WttXLK r6zdyrJs81vyQdZiSS9eDGTXTxIaeBiVNNyTFc99369fvOuDzFJXVZVeTs/z/Pr6uvm4haCGBtaj koZj1tq2bfu+j6eee0d6y6dpSi8/jDFVVcUQ0iQ04AQ/P3BG+sJeX1/llPutb+c78zxLm5XsPLr1 7bgUwwJxEhpwheFuuCHbicTQI3aXLMtOp5MxZvNgc6ht27Ztt3p1EhpwiJ8iOCA9YrKydut7uc80 TTKJO03T1vfijGy4tslLk9CAW/wgYa1xHM/nc9u2O805mURPKaeLosjzPPwgGQkNOMfPElYZx1EK 6Mgnob83z3NiOV1VVeCdW0howAd+nPC4YRjO5/MwDAl0NiSW07LPWrCXI6EBT/iJwoP6vpfjERNI aJFSTmdZVtd1mG8NO5YA/vBDhUfI+qWt78K9eZ7P53Ma67KyLKuqyvdfxBhTliUJDXjCzxXulmpC C2vt29tbGiHtu8ebUW7AN360cJ+2bRNOaDHP88vLy65b4URVVXKklQ8kNBAAP124gyy12vouQpD5 6b3X01prTz3ezEMDYfADhludz+fL5bL1XQQip2Z1XbfrnNZa+zhHRGvNPDQQBj9juEnghJZtwK+/ CE/29957+7rktMML0ikGhMQpWPhZmISWLDTGyNNfa22MsdbO82yMmed5miat9TzPwVYAj+M4DIO/ ad0AjDF5nmvtZpd+5qGBwAhp/MBrQltrJYyzLJMAkP+83otDfo8si5JRaDloUvLbd2C3bWuMqeva 66t4led5WZZd162/lNaahAZCIqTxHa8JLUlc13We57LX9KdPf4nhZTVRURRSVUuZK2nt6Q7FMAxZ lu23npZiuu/79W+Utbbv+11/ZAH2haMq8SV/Ca21lq02six7uP1Y/unK4Zh93zu9wfcv9P
T0tOtk knO++75fP/BQVdXpdAq55yhwZIQ0PucvoeWMJuk6Xv+slzHwvu/7vh+GwV94/Nd//dd+z5yWt+h8 Pjv5ef/169d+xxWAfWG4G5+Q9dBuA89am2VZWZZlWWZZ5uriy5i5TGw7GdT99FVkmHenFaQMXbhq H+v7XnoI1l8KwPf4McN7UkM7T6O6rk+n0+l0cpjQ18qyrOva06C0NKz5uHIwcuSGk0uN4+jkOgB+ REjjP3jaU+x0OlVVVZal+tsI5oPMc//+/dtHkTeOo5MG6a1IMe1kxH6aJlcj5wC+R0jj33zU0Frr X79+lWXpaX/Kd6ST+fn52cdHgQCd5F5JN4CTv4I02K+/DoDvEdL4F+edYrK9szQZBZ6/zPP8169f bl/UWtt13a6TyVorHfXrLyXr39ZfB8D3CGko5WGUW7Z3Pp1OYQroj6SedpjTUprvOqSXfWPWX0o+ spDTgG+ENNyPcsvccF3X265ZyrKsaRqHF5SFTLse8TbGOHlPZA842QZu/dUAfIWQPjrnNXSe503T bJ7Q6u9BjQ77vSWZdl1Mq7/TEE4udblcEjh1G4gZIX1ozmtoCcU8zyNZRCsrsx3uvCHlo6urbcLh FqcJDC0AkYviSYpNOO8Uiy2hhRwv4epqywGari64iaIonOT0PM/DMOz93QBiFtHDFCE5T2jZKyO2 hBZlWTo8U9nrPuFhuGofU0pN05TAGwJEK7rnKQLwNA8dZ0ILh8vA5OhMJ5faipw46arNW04OXX8p AB9F+kiFP8735Y5zlPuatEplWeZkYFZOyVx/nW1Za8uydPLP4HK5ENKAJ5E+VeFJ8p1iX3FYO6ax 7ki2ZnN1tb1v8wJEK+oHK9w6SKfYV5ycjLlcJ4GcluXs66+jtZYNUxN4T4DY7ODZCicOntBKKWOM k0ySpdJ7n5ZWrtvHnJ9tCkAR0gdBQqu/m2Kuv+GUoqiqKidrsaSYps0bcG43T1g8jIReOLlnCek0 hnblyA0nHzvmeR7
HMY23BYjHzh6yuBcJ/c766WRrbQLd3UIOmXY1NtD3fTLvDBCJXT5ncSMS+h3Z zdvJdZIZ9JZdaJxUwPLxZe/bpgJR2eWjFrc41J5iN3IyLZ3AZibvZFnm5LOLtfZyuTDiDTi016ct vuejho58T7Ebrc9XaYpOKYqKonC4vXnXdSm9OcC29v3AxacY5f6GMWZlTstmJikV09Za2ZHNyaVk zfT6SwFQhHR6SOgfrYkQieeUElr9bR9zNTwwDEPXdeuvA0AR0okhoW+xJmLd5lk8tNZ1Xbva22QY Btq8ASfSefKChL7RynzVf7m6n0i4an1XStHjDbiS1MP3yEjoG83zvCY/ZLg7sTJaZFnmZPcxpZS1 tm1bjtwA1kvq+XtYrLa63TzPa/5SMtyd3tsi8jx3tUsoG5ABTqT5rDkUVlvdTnqP11fS6Y11C4fT 7dbarutSfaOAYFJ7Ch8No9x3keMU1yRHlmUOlxRHSL77Ti41jiNt3sBKCT6Ij6NtWxL6LnLK5Jor HGH81uGnEDrIgJXSfBYfQdu2bds6vGDyCS1l9JqQljOjUn1/hDGmKApXn0W6rmMtFrBGyo+bhJHQ j1k/+rp+w7L4Sdugq6v1fU+bN/CwlJ/IqTqfzyT0A6y1K4de3e5xHS1ZMO3qH8MwDMl/rAH8Sfmh nCTmoR+28rRja23yb9GiLEtX7WOyZvoIc/mAD0d56KSBUe6HrW8Z01pXVXWcorAoCld/2WmaWDMN PCbxR3NKSOg1pmlaMyFtrc2yLOEV0u9orYuiMMa4OnKDQW/gMek/ndNAQq8xTdP6EVeHI8C7ICMH Dmemh2FwcingUNJ/QCeAhF5j2WVsTSVXFIWrfa33wmH7mNZ6HEfOmQYekP4zeu/o5V5Ja9113cq+ bmOMq2Mcd8ThkRta67Zt2dgEuNchHtP7xa6f653P55X7aRhjmqZxdT87IjPTDj+dDMNAMQ3c5ShP 6j1ilHu9vu/XB4NMRR+z78lh+5i1tu/79dcBD
uUoD+vdadv2fD47DIYDJvQ0TcMwrN/uqizLA451 C2tt0zSu/vore+yBAzrK83pfpIZ2mNAJnw/9jWEY1kdCXddHaxm7JqvOHJ5f6eRjE3AcB3pk74WP Ue5Uz4f+Rtd15/N55UXyPHe4p8dOZVnmcBeXYRg4cgO43YGe2rsgo9wOL3jAUW6l1DAMThruHLY3 75ocjeXqahy5AdzuQA/u+Dkf5T5sQjtZ7SMjEE5uae/yPHe4kYssW3d1NSBtB3p2R44a2omlWWzl HKox5lA7df+oqipXOT3P8+VyYS0WcIsDPb5jRg3thBzk0Pf9+gCQ2pGQXkj7mKtLFUVBSAO3ONAT PFrOa2ittWw0faiEnud5HMfz+bx+KFW2rT7ssqtPaa3rul7/qUVr3TSNLL92cmNA2vg52Zjs+um2 YrPWzvN8qEpF/squzi0+nU6HOkvjRvLZZeUVJKH5AATciCfRltq2dbvr56LrOqlUDvI0tNa+vb2t r6GttVJDf/qxyVorvy7HdVx/IJD/XH5xOdRy+SPLF/tljJEpgMc+CZHQwAMI6c10Xed2PfQ1a+1y 8eSfifM8v76+rl/VY63N8/zjkZTLyMQ8z9KStryWtdZaKxtnyhdyP1mWyS9qrY0x1xO68oX8r93F tiwcf2B3TxIaeAwhvQ15oOd57m9jh4PktCS0q7exLMuyLNXfYFZK9X0v2Sw5vRSR7+rm5dfl64+f GCSPrzNbvinygUB+Mf5qW86vvHc7dBIaeNiDI1dYz1o7juPlchmGwd+rpP18dJvQVVU1TSPfl2WX 6ZUHUX9Ffu4km5VS0uW3jCfHnNnW2j9//tw1bnE6nVL9Fwj4RkhvKUxOq0Sfkm4TWilV1/U4jp/W wb4tFbnEs0S11PRLkEcS2HKY1fl8vuXRIT3hRz6hBFiJ4e4tyeO4rmullNecTm/c23lCK6Wct9nf bnldGWOXTwlSysvm4bIx5/VZFxve6u3/ihIexQHCoJLentTTbdt6PXggpXF
vHwkdrWVgfOljkN3Q 5D+3KrIvl8v3i/tT+vcGbIiQjgLz07c7VEK/s3SryXdQesjzPJc1Y1JkhwnsYRjO5/M38wJJzrAA 4THcHYUw494J9HvP8/zy8nLYM5SWullGxZf+c6WUtIsvrWcS2/4yuyiKPM8//Uak8VkQiASVdESo p7935Br6R+8mqsuylNYzWY0tC7gdBra0172+vr7bQGa//7qAOFFJR4R6+hsk9PeuA1gasNXfIvt6 fZcxxknrmQS/MWaapuU6JDTgHJV0dILV0ztaG3PwUe6VriNZTqCS7/6yIZp6NLCHYXh5eZGvSWjA B0I6Rox7X7PWvry8UEM7scxSyzC4TF1L69kDRfY0TW3b9n2/l39LwO4Q0pFinxNBQochJbVEdVEU 6m/r+I+tZ3JIDAkNeEJIx4t6moQOaVnfJaksRz7L2PiygcnHwJZjvJetyAG4RUhH7cg5TUJv6HpU XCl1XWTL8Pi7k0Ui2bIUSA8hHbtj5vQDpzjAn3dJLEW2dB1K3xkAT1iCFbsDrsuSGpqEjse79V3D MFyftgnAH0J6Bw6V04xyR06mqGXchTIa8I2Q3oeD5DQJHb/YZkaAtPFBeDeWnJYVMp5Ya8/n8zAM m5ypTEJHTnZBIaGBYKik9yTh86c3SWhZHDzPswzbXrdHLVtSyxd0LytqaGALhPTOJDnuHaaXW5YV ySFRMp9qrZXVRNfrg5f/nOfZ/iX3No6j/KfX+4wWNTQQHiG9P4nltO9ebkliGadVSsnX6ubieIlk iW05UmKaJkluCfJxHL2eC7m5fe30DqSEddJ7lcb6ad+j3LIrdV3X+q/111xKbfnZkbSWhUlKKfk6 sYK7aRoSGtgEIb1jez8vy19CyyresizzPM/zQMNF8qMkc9jzPA/DIN8gKcHD3INz1NDAtgjpfdtv TvtL6CzLqqqSGnqr8efriW2t9TAM8zxLciulZGw//rFxEhrYHCG9e3vMaX8Jnef58/Ozq5Ftt2QM XE6k
kOHxpSUtwh2wSWggBoR0CvaV054SOsuyPM9Pp1NUUfcVCWxjjCxJH8dR0jqSzVBJaCAShHQi 9pLTnlZbyQy0NIi5vXIYy0y2dIy/K7ID/6VIaCAehHQ64s9pTzV0URRFUVRVtdOEfmfpDF9az2Q+ e5qmAH9BEhqICiGdFHmmd13X973XF3pgTY6nhC7LUtrE0kjodySwtdYyHr60ni0brbj9W5PQQGwI 6dTEWU+T0E5c74Bmre37Xorspfhe8z6Q0ECECOkEhamnb3+mk9A+XLeeyWD4sib7gR9qEhqIE9uC Jkj2DZWv/eW0tfZyuSilvn+yk9CeLMvM5FS0pci+Xt+11Nnq2yKbhAaiRSWdrBjqaRJ6E+9msoUE tvrQLk5CAzEjpFO2bU6T0JGQn/ElqqVdfNkNjYQGYkZIJ26rPjISOk7XrWfq7xFhJDQQLUI6feHr aRJ6FyLcixTAOzSOpS9wH1lRFOfzmYSOH+8kED8q6aMIVk9rrZ2fzEhCAzgmKumjCFZPO//YR0ID OCxC+kDC5LRbJDSAIyOkj2VfOU1CAzg4Qvpw9pLTJDQAENJHFH9Ok9AAoAjpw4o5p0loABCE9HHF mdMkNAAsCOlDiy2nSWgAuEZIH92S03K+4YZ3QkIDwDtm6xvA9iSn67qWk4k3QUIDwEdsC4p/CbNv 6KdIaAD4FMPd+Jet5qdJaAD4CiGNfws/P01CA8A3mJP+3HJQxPUXy+FOH/9vMpb56bIsfb+WMSbP cxIaAL5CJa2WuJX/nKbJWqu1nqZp+RX1N4+NMVrrLMvk9xtjjDFKKa21MUb+4N4jJ9i49zRN8zxP 07S8HADg2qEfjvM8S7fUPM+SFpLE745Dlui9/uKaviKloaT4kt97FCantdaXy0XeUnIaAD463JNx nmdjTNd10zQNwyAFsdTKX1XAy69/+huuR7yttV3XLfFcFEWWZXmeL9W2h7+QL8Hq6bZt5eWyLPP3 KgCwR4dYgiUV8DiO1tq+76dpWo
pmf8Epb+xSVZdlaYyRr72+rlth1mVprWUWnJwGgGuJh7QksRTN 4zhKTm8SkPKiRVEYY6qqWkbIw9/JvYKtn26ahpwGgGsph7SUy23bzvM8jqOKZsA5yzKpHWUOe+vb +Rk5DQCbSDOkpXSW6jnav6C1Ns/zoihk6jrywpqcBoDwEgzpruuGYei6TkVTOn9P6um6riNvngqZ 00VR7GKMAQC8SiekZd3U+XyWJVVb387dtNZFUZRlWRRFtJ8tyGkACCmRh+AwDH3fj+O47ECyO9J5 PgxDWZZ5nldVFWETeOB1WYr10wCObfdPQGkKe3t7S2NIQFZaj+M4DEPTNLJBytY39R/IaQAIZt/D 3eM49n2/7Iax9e04lmWZDIBHmFJhxr2ttafTiXFvAIe145CWhAhzWNOGtNan0ynP89h6yshpAPBt fw8+mak9n8/DMOx3Bvp28zy/vb3JeY5VVW19O/8WbH9vxr0BHNbOnnqyfdjlcvHdXRwPGcaXgnWa ptPpFE9DWcj5aRnyIacBHMqeHnnW2mEYLpeLbB92NPM8Xy6XaZpkmVYkDWXBcprzsgAc0G6ed/M8 yy4lx0xo9bekHoZBGtrruo5klpp+bwDwZB8Pu3me27aVfNr6XrYne5LP83w6nYwxMQx9Lzktox3+ Xuh8PjdNo8hpAMewg+5uEvorxpimaeJp/JZ+78vl4rvlnv3IABxE7CE9TVPbtjvd6TMArXXTNLKi eut7UYqcBgCnog7paZpeXl6I5+/JUHNVVWVZbn0vSgVcPy3nZZHTABIW7wOOhL6RTANba621MSyk DjM/rbWm3xtA8iJ9usWT0MtIw8f+rHjWKyulxnGUSQHpq9qW5LQcvkm/NwA8LMZH2zAMb29vwRJa YljiVg600H8ta5G11tJTLV/In5rnOaqcVn83/aiqavOub9ZlAcB60T3XLpfLsr1UABLGZVlKqGRZ Zq2VhLsOb/W3bpZRZa31PM8S2+M4yj5o8zwvf2pDl8tlnmfZ
RvQ4Oc1+ZACSFNdDLUxCy/Wl3JRg XlL5OtXeJdxSai//mee5lK1aaxlqnqZJpoeXstvrX+QrSyIeJ6cvl4t8QU4DSElET7S2bS+Xi++E 1lpXVVUURZZl75YX35Vn7zJ7aZWq61qmh5fAdnfvd5BEtNYWRUFOA8BObT88K7zW0FLUSio3TXM9 2eyPFNNd10laqy1OvM6yrCxLaeAK/NLvsC4LAB4QxbMsQELLMuKQw79Spsskt0R113WBw3Kapr7v JbqOUE+zLgtAYrZ/kPlO6KIoyrKUBcThg0oa05qmkdOr5BirkKMXy5HbB8lpRR8ZgIRs/BTz3Skm m0fGsGWmDLYbY2TUd8nOAA6Y09TTANKw5SPMd0L//v3bGBPJuctCmsmrqjqfz9M0BTt284A5zfpp AAnYrHHMX0IbY6RBLPKn8zAMfd93XRfsFeUcjs1zWtFHBgC32ebh5TWh8zyXg6GcX9wtWQaW53nX dWFK6qPV01rrtm0Z9wawXxs8ufwltBTQHxdAR8sYI3uqSE4H2An1mDktX5PTAHYn9GPrcrl42rFE TnTI8zyqSehbFEUhDWVt24bJaXn/D5LTivlpALsV9JklCe0jh4qiOJ1OYXYp8UEav4uieHl5CdD4 Pc+z7K9CTgNAzMI9sPwldFmWz8/PsR1IdS9ZUf3r16/L5TIMg++oluvneX6cfUPJaQC7E+hp5Tuh 1RYblfhgjFkOhA6Q033fS0YeJKfP5/PpdFLkNICdCPGo8pTQWuuiKCShUyI7lBVF4XuFkjreeVn0 kQHYF+/PKU+93HJ0xFJ0JmZJLGutTB77c7ScVox7A9gPv5uZeKqhZdOuuq7dXjY28q2RTzm+X6uu axkH3lywfU5Op1NRFOQ0gJh5fEL5q6GPkNDq7yy7jBb4zmk5jDmGnA427s38NID4+Xo8eVoPvRyQ 7PaykQuW0zId7vVVbhEyp+XvS04DiJOXZxOj3M41TbNsTObpJay1l8tFNkHz9BK3C3n+tH
xNTgOI kPsHEwntSVVVEiqeclprPc9z13Va67IsfbzEvfcT7FxL+YKcBhAbx08lEtoryU6vOT0Mg2x/FkNi 0e8N4OBcPpJI6AAC5HTXdcYYrXUM55Qw7g3gyJw9j0joYHzntFw8z/MYQlr93bVGvmbcG8ChuDmO goQOTFrc/WWJtfb19TXMKdc3Koqiqirfk+Vt2/Z9H9VfHMCROXjKk9CbWOrpYRh87BQmzd5yPrfz iz8mQD3NuDeAqKx9DJHQGyrLUlaie6r8pImsqqp4DgBl3BvAoax6BpHQm/O6Lsta2/e9fBSI55Ax chrAcTxeIZHQkZD56SzLfGzDPk3T+XyOJ6EF89MADuLBKoGEjkpZlvM8+xv0bts2hu1CrzE/DeAI HqmkSegI1XXtL0eHYfB9svUDpJ72vYmpbEHv9bA4APjK3fUBZ1tF63Q6aa19nMMxjuMwDHmex9NB JpZ6uus6H9e31jZNo7WObcAfwEHc98z1d7YVCe1E0zSe3kavZ3usURRFWZae6ummacqyZKwbwFbu ePp4GuWWY5dIaFfqup7n2cfotJyRFWFieaqn67omoQFs69YHEPPQe6G1lrLSeU5P0zRNkzEmtkFv 5TqnZZSbhAawuZueQf4SWpYPub3swS0nUjjv95Y9yGI4xfJTDnOahAYQiZ9LIq8JHdvCnjRITvs4 IUOWTUfb6uxkfppRbgDx+OFJ5K+Xm4T2Smstb+88z26/fdM0jeO4lK2xWVlPk9AAovJdJe2vl5uE DkBy2nkxLcux3F7TrYfraRIaQGy+DGl/vdwkdDBa61+/fjnP6b7vE8tpay0JDSBCn4e0115uEjqw uq7d9mPP8zxNU7Qz0+KunKZTDECcPnl2yzw0nWJpkCaysizd7pnl4zOcc7fkNDU0gJi9D2nmodOT ZVlRFG4Hved57rou8mJa3ZDT1NAAYvYfIc08dKqKonC+Hn0cx/iLafVtTlNDA4jcv0Oaeei0Oc/p aZoibx9bfJrTJDS
A+P0rpLuuo4ZOm9a6LEuH+4VZa4dhmKbJ1QW9epfTJDSAXciVUl3X+egUk02k Seh4ON+DbBiGeZ6dL/HyZNnnRD6vkNAA4pd3Xedpo0e5prWWs3jj0TTNNE0Oz97o+z7LsgiP3PhU URRyq3v5YAHg4IyPXT8Xfd/76BXHw2TFkcNMjfOQ6W9kWUZCA9gL89///d/+ri5FGzkdD621MaYo ClfDG27rcgDANaOU+p//+R9/L0BOx8YYU1WVw2/HXtZiAcDu/GvYk5w+lCzLTqeTq2/Hjnq8AWBf /j03GSCnvc5/43Za6yzLHLY3Oz8QEwCg3u045junh2EgpyMh64adXEoWTDu5FADg2vsuX+rp43C4 bJpKGgB8+GQpjtecnueZejoSDkN6GAZ6vAHAuc/XyzLufQSyJZyrtVh8NwHAuS83tSCnj8AYk+e5 k+9C3/csxAIAt77beYr56eS52thEa22t5VsJAG79sD0k89Np01rnee5kLRY93gDg3M97OFNPpy3P c2PM+vff/uXkrgAA6paQVtTTqSvL0smRG9M08U0EAIdufTTTR5YwSej1b/48zxxLCgAO3VE/kdOp kvax9deZ55liGgAcum+Qk5xOkjEmy7KVRbC1dp5nimkAcOjumUhyOj3W2qIoVk5Lyyosxa4mAODO I89lcjoxWmtjjKvV0k5uCQCgHgtpxbqsFGVZtv4Nn6aJ4W4AcOXxEU7WZaVETphefx2+XwDg0Kpp SMa9k6G1lkHvldfhzEoAcGjtQ5mcTsb6SpodxwDALQf7TJHTaVjf9iWz0XynAMAVByGtyOlUrCym Zam0q5sBALgJaUVO758xxskO3nyPAMAVZyGtyOn9W7mpp6v11gAA4TKkFTm9Z+u7u2kcAwC3HIe0 Iqd3y1orC7HWXIQlWADgkPuQVuxHtlsrS2GGuwHALS8hrdiPbJ/Wv58kNAA45CukFfX0Dq2vgwlp AHDIY0gr6uldkdOg17yZTma1AQALvyGt6CPbD
2vtyjOs5JQOQhoAXPEe0oqc3gmpg1dexBjDNwIA XAkR0ipUTrMn5RrjOK5/A52cdwkAEIFCWgXpI7tcLpRxj5HZ6PWVtJOLAABEuJBW9JFFTN69lRfJ 89zJ7t8AABH6kcq4d4RcfaxZv7EoAODaBo/UADnNuPe9+r6fpmnNFbTWeZ67uh8AgNokpBX93pFZ v/hKLpLnORPSAODQZoOTjHvHo+/7lRPS1lr6ugHAuS1nEMP0e5PT35vneeVAt/o71l0UhZNbAgCI jdt8AvR7k9Pfm+e57/uVF5G9xphfAAC3tu/FpZ7ekCT0+jdHa12WJRPSAODW9iGt/NfT5PSnpPAd x3F9yxgD3QDgQxQhrcjpLWitu64bx3H9pdjGBAB8iOjBSk4H1vf9+tlopVRRFLR2A4APEYW0IqcD krXR6/u6lVJ5nrONCQD4EFdIK3I6lHEc27Zdfx1jTFVV668DAPgoupBW5LR/4zheLhcnl2KXMQDw J8aQVuS0T7J83Em/mFKqqipaxgDAk3gfr+S0D9Zaa23XdU42HqnrmpYxAPAn3pBW5LQHWuvz+ezk rywHU1JGA4A/sT9hyWm3zufzyrM0FkVR1HXt5FIAgE/FHtKKnHanbVtXCZ1lWV3XbNYNAF7tIKQV Oe3CMAzDMDhZGC3HaRhj6OsGAK/2EdKKnF5nGIa+7111dGutm6ZhNhoAfNvTc5acfoz81bquc3XB pmlo6gaAAPYU0oqcfojbhC7LkoQGgDB2FtKKnL7T5XI5n8+u23p6IwAAA81JREFUrqa1LoqCnboB IIz9hbQip2/mNqGVUlVVsVM3AASzy5BW5PQN+r53m9BlWZLQABDSXkNakdPfGobB4Ty0UsoYUxQF Hd0AENK+n7nk9KeGYbhcLq4WXCmljDFlWZZlycJoAAhp3yGtyOkPloR2uB2YMaZpGhIaAALbfUgr /znddd1ectpTQj8/P5PQABBeCiGtPOe0tXYX9bSnhD6dTiQ0AGwikZBWhx/
3loQehsFhQmut5cRo QhoANpFOSKsD57TzTjGR53lRFOwvBgBbSSqk1SFz2scot/p7XDQJDQAbSi2k1cFyehiGtm3dJrS1 Vga6i6JwdU0AwAMSDGl1mJyWGnqaJrc1tNb6dDqR0ACwuTRDWh0gpz2Nciulnp6e2P4TAGKgnT/i o/K///u//i6uta6qqq7r8JtlktAAcATJVtIiyfXT/hK6aZqyLN1eEwDwsMRDWgUZ927bNlhO+0vo qqrYnRsAopJ+SCv/OS0t1gFy2ndCs+AKAKJyiJBWSeS0v4SWE65o5waA2CTeOPaO1z4yOXG5aRof fWS+a2gSGgAidJRKWuy0niahAeCYjhXSaoc5TUIDwGEdLqTVrnKahAaAIzvWnPS1+Oenl9MnHd6Y IKEBYBeOWEmLyOtpT6dPKhIaAPbjuCGtIs5pRrkBAOrIw92L2Ma9GeUGAIhDV9IiqnqahAYALAhp paLJaeahAQDXCOl/2TynmYcGALzDnPR/2Gp+WiJ8miYSGgCwoJL+D5vU01JDk9AAgHcI6fcC5zSj 3ACArzDc/bkw497TNJHQAICvENJf8p3TWZZZa+nlBgB8hZD+jteclndea+32siQ0ACSDkP6B15x2 joQGgJTQOPYDr31kbpHQAJAYQvpnu8hpEhoA0kNI3yTynCahASBJhPStos1pEhoAUkVI3yHCnCah ASBhhPR9osppEhoA0kZI3y2SnCahASB5hPQjNs9pEhoAjoCQftCGOU1CA8BBENKP2ySnSWgAOA5C epXAOU1CA8ChENJrBcvpsixJaAA4FELagQA5XZZlVVUkNAAcCqdgOePvvCxGuQHgmKiknfFUT5PQ AHBYhLRLznOahAaAIyOkHXOY03SKAcDBEdLuOclpOsUAAIS0FytzmoQGAChC2p+Hc5qEBgAIQtqj B3KahAYALAhpv+7KaRIaAHCNkPbuxpwmoQEA7xDSIfyY0yQ0AOAjQjqQb3JaEjrP85D3AwCIHyEd zqc5
vSS01jr8LQEAYkZIB/Uup0loAMA3COnQlpwmoQEA3+Ooym28vr6S0ACA7/0/YBJ1/NDwq84A AAAASUVORK5CYII= "
+     x="0"
+     y="0"
+     width="652"
+     height="694"
+     id="image10" />
+</svg>
Added: sandbox/SOC/2007/quan/libs/quan/doc/doxygen/important.png
==============================================================================
Binary file. No diff available.
Added: sandbox/SOC/2007/quan/libs/quan/doc/doxygen/proposed_for_boost.png
==============================================================================
Binary file. No diff available.
Added: sandbox/SOC/2007/quan/libs/quan/doc/doxygen/quan_doxyfile.txt
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/libs/quan/doc/doxygen/quan_doxyfile.txt	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,1810 @@
+# Doxyfile 1.8.0
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should 
+# identify the project. Note that if you do not use Doxywizard you need 
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME           = Boost.Quan
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description 
+# for a project that appears at the top of each page and should give viewer 
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = "Boost.Quan library of uncertain functions"
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is 
+# included in the documentation. The maximum height of the logo should not 
+# exceed 55 pixels and the maximum width should not exceed 200 pixels. 
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO           = Proposed_for_Boost.png
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = 
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, 
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, 
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful if your file system 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 12
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only). 
+# A mapping has the form "name=value". For example adding 
+# "class=itcl::class" will allow you to use the command class in the 
+# itcl::class meaning.
+
+TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it 
+# parses. With this tag you can assign which parser to use for a given extension. 
+# Doxygen has a built-in mapping, but you can override or extend it using this 
+# tag. The format is ext=language, where ext is a file extension, and language 
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, 
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make 
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C 
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions 
+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all 
+# comments according to the Markdown format, which allows for more readable 
+# documentation. See http://daringfireball.net/projects/markdown/ for details. 
+# The output of markdown processing is further processed by doxygen, so you 
+# can mix doxygen, HTML, and XML commands with Markdown formatting. 
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also makes the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to 
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and 
+# unions are shown inside the group in which they are included (e.g. using 
+# @ingroup) instead of on a separate page (for HTML and Man pages) or 
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and 
+# unions with only public data fields will be shown inline in the documentation 
+# of the scope in which they are defined (i.e. file, namespace, or group 
+# documentation), provided this scope is documented. If set to NO (the default), 
+# structs, classes, and unions are shown on a separate page (for HTML and Man 
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk. 
+# When the cache is full, less often used symbols will be written to disk. 
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penalty. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will roughly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+SYMBOL_CACHE_SIZE      = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be 
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given 
+# their name and scope. Since this can be an expensive process and often the 
+# same symbol appear multiple times in the code, doxygen keeps a cache of 
+# pre-resolved symbols. If the cache is too small doxygen will become slower. 
+# If the cache is too large, memory is wasted. The cache size is given by this 
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen 
+# will list include files with double quotes in the documentation 
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = NO
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen 
+# will sort the (brief and detailed) documentation of class members so that 
+# constructors and destructors are listed first. If set to NO (the default) 
+# the constructors will appear in the respective orders defined by 
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. 
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO 
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to 
+# do proper type resolution of all parameters of a function it will reject a 
+# match between the prototype and the implementation of a member function even 
+# if there is only one candidate or it is obvious which candidate to choose 
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen 
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = NO
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = NO
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= NO
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or macro consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and macros in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index 
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed 
+# by doxygen. The layout file controls the global structure of the generated 
+# output files in an output format independent way. The create the layout file 
+# that represents doxygen's defaults, run doxygen with the -l option. 
+# You can optionally specify a file name after the option, if omitted 
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files 
+# containing the references data. This must be a list of .bib files. The 
+# .bib extension is automatically appended if omitted. Using this command 
+# requires the bibtex tool to be installed. See also 
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style 
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this 
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = doxywarn.log
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = ../../../../boost/quan \
+                         ../../src
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh 
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py 
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS          = *.cpp \
+                         *.ipp \
+                         *.hpp
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag. 
+# Note that relative paths are relative to the directory from which doxygen is 
+# run.
+
+EXCLUDE                = "../../../../boost/quan/meas - all const.hpp" \
+                         ../../../../boost/quan/meas2.hpp \
+                         "../../../../boost/quan/unc - all const.hpp" \
+                         ../../../../boost/quan/uncbools.hpp \
+                         ../../../../boost/quan/uncdata.hpp \
+                         ../../../../boost/quan/uncs.hpp \
+                         "../../src/Boost CHECK expanded macros.cpp"
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or 
+# directories that are symbolic links (a Unix file system feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty or if 
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file 
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) 
+# and it is also possible to disable source filtering for a specific pattern 
+# using *.ext= (so without naming a filter). This option only has effect when 
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS = 
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
+# link to the source code.  Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header. Note that when using a custom header you are responsible  
+# for the proper inclusion of any scripts and style sheets that doxygen 
+# needs, which is dependent on the configuration options used. 
+# It is advised to generate a default header using "doxygen -w html 
+# header.html footer.html stylesheet.css YourConfigFile" and then modify 
+# that header. Note that the header is subject to change so you typically 
+# have to redo this when upgrading to a newer version of doxygen or when 
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER            = quan_doxygen_header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = quan_doxygen_footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# style sheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = quan_doxygen.css
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or 
+# other source files which should be copied to the HTML output directory. Note 
+# that these files will be copied to the base HTML output directory. Use the 
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these 
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that 
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. 
+# Doxygen will adjust the colors in the style sheet and background images 
+# according to this color. Hue is specified as an angle on a colorwheel, 
+# see http://en.wikipedia.org/wiki/Hue for more information. 
+# For instance the value 0 represents red, 60 is yellow, 120 is green, 
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. 
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of 
+# the colors in the HTML output. For a value of 0 the output will use 
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT    = 104
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to 
+# the luminance component of the colors in the HTML output. Values below 
+# 100 gradually make the output lighter, whereas values above 100 make 
+# the output darker. The value divided by 100 is the actual gamma applied, 
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, 
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA  = 82
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML 
+# page will contain the date and time when the page was generated. Setting 
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html 
+# for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify 
+# the documentation publisher. This should be a reverse domain-name style 
+# string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and 
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated 
+# that can be used as input for Qt's qhelpgenerator to generate a 
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to 
+# add. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the 
+# custom filter to add. For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> 
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this 
+# project's 
+# filter section matches. 
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> 
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files  
+# will be generated, which together with the HTML files, form an Eclipse help 
+# plugin. To install this plugin and make it available under the help contents 
+# menu in Eclipse, the contents of the directory containing the HTML and XML 
+# files needs to be copied into the plugins directory of eclipse. The name of 
+# the directory within the plugins directory should be the same as 
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before 
+# the help appears.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin 
+# the directory name containing the HTML and XML files should also have 
+# this name.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) 
+# at top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it. Since the tabs have the same information as the 
+# navigation tree you can set this option to NO if you already set 
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
+# structure should be generated to display hierarchical information. 
+# If the tag value is set to YES, a side panel will be generated 
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 
+# Windows users are probably better off using the HTML help feature. 
+# Since the tree basically has the same information as the tab index you 
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values 
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML 
+# documentation. Note that a value of 0 will completely suppress the enum 
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, 
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES       = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open 
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images 
+# generated for formulas are transparent PNGs. Transparent PNGs are 
+# not supported properly for IE 6.0, but are supported on all modern browsers. 
+# Note that when changing this option you need to delete any form_*.png files 
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax 
+# (see http://www.mathjax.org) which uses client side Javascript for the 
+# rendering instead of using prerendered bitmaps. Use this if you do not 
+# have LaTeX installed or if you want to formulas look prettier in the HTML 
+# output. When enabled you may also need to install MathJax separately and 
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you need to specify the location relative to the 
+# HTML output directory using the MATHJAX_RELPATH option. The destination 
+# directory should contain the MathJax.js script. For instance, if the mathjax 
+# directory is located at the same level as the HTML output directory, then 
+# MATHJAX_RELPATH should be ../mathjax. The default value points to 
+# the MathJax Content Delivery Network so you can quickly see the result without 
+# installing MathJax.  However, it is strongly recommended to install a local 
+# copy of MathJax from http://www.mathjax.org before deployment.
+
+MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension 
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS     = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box 
+# for the HTML output. The underlying search engine uses javascript 
+# and DHTML and should work on any modern browser. Note that when using 
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets 
+# (GENERATE_DOCSET) there is already a search function so this one should 
+# typically be disabled. For large projects the javascript based search engine 
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE           = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be 
+# implemented using a PHP enabled web server instead of at the web client 
+# using Javascript. Doxygen will generate the search PHP script and index 
+# file to put on the web server. The advantage of the server 
+# based approach is that it scales better to large projects and allows 
+# full text search. The disadvantages are that it is more difficult to setup 
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name. 
+# Note that when enabling USE_PDFLATEX this option is only used for 
+# generating bitmaps for formulas in the HTML output, but not in the 
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for 
+# the generated latex document. The footer should contain everything after 
+# the last chapter. If it is left blank doxygen will generate a 
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include 
+# source code with syntax highlighting in the LaTeX output. 
+# Note that which sources are shown also depends on other settings 
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the 
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See 
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = __declspec(x)=
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition that 
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all references to function-like macros 
+# that are alone on a line, have an all uppercase name, and do not end with a 
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. For each 
+# tag file the location of the external documentation should be added. The 
+# format of a tag file without this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths 
+# or URLs. Note that each tag file must have a unique name (where the name does 
+# NOT include the path). If a tag file is not located in the directory in which 
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option also works with HAVE_DOT disabled, but it is recommended to 
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is 
+# allowed to run in parallel. When set to 0 (the default) doxygen will 
+# base this on the number of processors available in the system. You can set it 
+# explicitly to a value larger than 0 to get control over the balance 
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS        = 0
+
+# By default doxygen will use the Helvetica font for all dot files that 
+# doxygen generates. When you want a differently looking font you can specify 
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find 
+# the font, which can be done by putting it in a standard location or by setting 
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the 
+# directory containing the font.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the Helvetica font. 
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to 
+# set the path where dot can find it.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside 
+# the class node. If there are many fields or methods and many nodes the 
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS 
+# threshold limits the number of items for each type to make the size more 
+# managable. Set this to 0 for no limit. Note that the threshold may be 
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include 
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are svg, png, jpg, or gif. 
+# If left blank png will be used. If you choose svg you need to set 
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files 
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to 
+# enable generation of interactive SVG images that allow zooming and panning. 
+# Note that this requires a modern browser other than Internet Explorer. 
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you 
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files 
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG        = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that 
+# contain msc files that are included in the documentation (see the 
+# \mscfile command).
+
+MSCFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. Warning: Depending on the platform used, 
+# enabling this option may lead to badly anti-aliased labels on the edges of 
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
Added: sandbox/SOC/2007/quan/libs/quan/doc/doxygen/quan_doxygen.css
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/libs/quan/doc/doxygen/quan_doxygen.css	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,504 @@
+/*
+  The standard CSS for Doxygen but
+  with changed C++ code (syntax) colorization checks_doxygen.css */
+/*
+  Copyright Paul A. Bristow 2011
+  Use, modification and distribution are subject to the
+  Boost Software License, Version 1.0.
+  (See accompanying file LICENSE_1_0.txt
+  or copy at http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+body, table, div, p, dl
+{
+  font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
+  font-size: 12px;
+}
+
+/* @group Heading Levels */
+
+h1 {
+  text-align: center;
+  font-size: 150%;
+}
+
+h2 {
+  font-size: 120%;
+}
+
+h3 {
+  font-size: 100%;
+}
+
+dt {
+  font-weight: bold;
+}
+
+div.multicol {
+  -moz-column-gap: 1em;
+  -webkit-column-gap: 1em;
+  -moz-column-count: 3;
+  -webkit-column-count: 3;
+}
+
+p.startli, p.startdd {
+  margin-top: 2px;
+}
+
+p.endli {
+  margin-bottom: 0px;
+}
+
+p.enddd {
+  margin-bottom: 4px;
+}
+
+/* @end */
+
+caption {
+  font-weight: bold;
+}
+
+span.legend {
+        font-size: 70%;
+        text-align: center;
+}
+
+div.qindex, div.navtab{
+  background-color: #e8eef2;
+  border: 1px solid #84b0c7;
+  text-align: center;
+  margin: 2px;
+  padding: 2px;
+}
+
+div.qindex, div.navpath {
+  width: 100%;
+  line-height: 140%;
+}
+
+div.navtab {
+  margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+  color: #153788;
+  font-weight: normal;
+  text-decoration: none;
+}
+
+.contents a:visited {
+  color: #1b77c5;
+}
+
+a:hover {
+  text-decoration: underline;
+}
+
+a.qindex {
+  font-weight: bold;
+}
+
+a.qindexHL {
+  font-weight: bold;
+  background-color: #6666cc;
+  color: #ffffff;
+  border: 1px double #9295C2;
+}
+
+.contents a.qindexHL:visited {
+        color: #ffffff;
+}
+
+a.el {
+  font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code {
+}
+
+a.codeRef {
+}
+
+/* @end */
+
+dl.el {
+  margin-left: -1cm;
+}
+
+.fragment {
+  font-family: monospace, fixed;
+  font-size: 105%;
+}
+
+pre.fragment {
+  border: 1px solid #CCCCCC;
+  background-color: #f5f5f5;
+  padding: 4px 6px;
+  margin: 4px 8px 4px 2px;
+}
+
+div.ah {
+  background-color: black;
+  font-weight: bold;
+  color: #ffffff;
+  margin-bottom: 3px;
+  margin-top: 3px
+}
+
+div.groupHeader {
+  margin-left: 16px;
+  margin-top: 12px;
+  margin-bottom: 6px;
+  font-weight: bold;
+}
+
+div.groupText {
+  margin-left: 16px;
+  font-style: italic;
+}
+
+td.indexkey {
+  background-color: #e8eef2;
+  font-weight: bold;
+  border: 1px solid #CCCCCC;
+  margin: 2px 0px 2px 0;
+  padding: 2px 10px;
+}
+
+td.indexvalue {
+  background-color: #e8eef2;
+  border: 1px solid #CCCCCC;
+  padding: 2px 10px;
+  margin: 2px 0px;
+}
+
+tr.memlist {
+  background-color: #f0f0f0;
+}
+
+p.formulaDsp {
+  text-align: center;
+}
+
+img.formulaDsp {
+
+}
+
+img.formulaInl {
+  vertical-align: middle;
+}
+
+div.center {
+  text-align: center;
+        margin-top: 0px;
+        margin-bottom: 0px;
+        padding: 0px;
+}
+
+div.center img {
+  border: 0px;
+}
+
+img.footer {
+  border: 0px;
+  vertical-align: middle;
+}
+
+/* @group Code (syntax) Colorization */
+
+span.keyword {
+  color: blue
+}
+
+span.keywordtype {
+  color: blue
+}
+
+span.keywordflow {
+  color: blue
+}
+
+span.comment {
+  color: green
+}
+
+span.preprocessor {
+  color: darkblue
+}
+
+span.stringliteral {
+  color: brown
+}
+
+span.charliteral {
+  color: brown
+}
+
+span.operator {
+  color: red
+}
+span.vhdldigit {
+  color: red
+}
+
+span.vhdlchar {
+  color: brown
+}
+
+span.vhdlkeyword {
+  color: blue
+}
+
+span.vhdllogic {
+  color: magenta
+}
+
+/* @end */
+
+.search {
+  color: #003399;
+  font-weight: bold;
+}
+
+form.search {
+  margin-bottom: 0px;
+  margin-top: 0px;
+}
+
+input.search {
+  font-size: 75%;
+  color: #000080;
+  font-weight: normal;
+  background-color: #e8eef2;
+}
+
+td.tiny {
+  font-size: 75%;
+}
+
+.dirtab {
+  padding: 4px;
+  border-collapse: collapse;
+  border: 1px solid #84b0c7;
+}
+
+th.dirtab {
+  background: #e8eef2;
+  font-weight: bold;
+}
+
+hr {
+  height: 0;
+  border: none;
+  border-top: 1px solid #666;
+}
+
+/* @group Member Descriptions */
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+  background-color: #FAFAFA;
+  border: none;
+  margin: 4px;
+  padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+  padding: 0px 8px 4px 8px;
+  color: #555;
+}
+
+.memItemLeft, .memItemRight, .memTemplParams {
+  border-top: 1px solid #ccc;
+}
+
+.memItemLeft, .memTemplItemLeft {
+        white-space: nowrap;
+}
+
+.memTemplParams {
+  color: #606060;
+        white-space: nowrap;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation. */
+
+.memtemplate {
+  font-size: 80%;
+  color: #606060;
+  font-weight: normal;
+  margin-left: 3px;
+}
+
+.memnav {
+  background-color: #e8eef2;
+  border: 1px solid #84b0c7;
+  text-align: center;
+  margin: 2px;
+  margin-right: 15px;
+  padding: 2px;
+}
+
+.memitem {
+  padding: 0;
+  margin-bottom: 10px;
+}
+
+.memname {
+  white-space: nowrap;
+  font-weight: bold;
+}
+
+.memproto, .memdoc {
+  border: 1px solid #84b0c7;
+}
+
+.memproto {
+  padding: 0;
+  background-color: #d5e1e8;
+  font-weight: bold;
+  -webkit-border-top-left-radius: 8px;
+  -webkit-border-top-right-radius: 8px;
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+  -moz-border-radius-topleft: 8px;
+  -moz-border-radius-topright: 8px;
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+
+}
+
+.memdoc {
+  padding: 2px 5px;
+  background-color: #eef3f5;
+  border-top-width: 0;
+  -webkit-border-bottom-left-radius: 8px;
+  -webkit-border-bottom-right-radius: 8px;
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+  -moz-border-radius-bottomleft: 8px;
+  -moz-border-radius-bottomright: 8px;
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+}
+
+.paramkey {
+  text-align: right;
+}
+
+.paramtype {
+  white-space: nowrap;
+}
+
+.paramname {
+  color: #602020;
+  white-space: nowrap;
+}
+.paramname em {
+  font-style: normal;
+}
+
+/* @end */
+
+/* @group Directory (tree) */
+
+/* for the tree view. */
+
+.ftvtree {
+  font-family: sans-serif;
+  margin: 0.5em;
+}
+
+/* These are for tree view when used as main index. */
+
+.directory {
+  font-size: 9pt;
+  font-weight: bold;
+}
+
+.directory h3 {
+  margin: 0px;
+  margin-top: 1em;
+  font-size: 11pt;
+}
+
+/*
+The following two styles can be used to replace the root node title
+with an image of your choice.  Simply uncomment the next two styles,
+specify the name of your image and be sure to set 'height' to the
+proper pixel height of your image.
+*/
+
+.directory h3.swap {
+  height: 61px;
+  background-repeat: no-repeat;
+  background-image: url("draft.png");
+}
+.directory h3.swap span {
+  display: none;
+}
+/*
+*/
+
+.directory > h3 {
+  margin-top: 0;
+}
+
+.directory p {
+  margin: 0px;
+  white-space: nowrap;
+}
+
+.directory div {
+  display: none;
+  margin: 0px;
+}
+
+.directory img {
+  vertical-align: -30%;
+}
+
+/* These are for tree view when not used as main index. */
+
+.directory-alt {
+  font-size: 100%;
+  font-weight: bold;
+}
+
+.directory-alt h3 {
+  margin: 0px;
+  margin-top: 1em;
+  font-size: 11pt;
+}
+
+.directory-alt > h3 {
+  margin-top: 0;
+}
+
+.directory-alt p {
+  margin: 0px;
+  white-space: nowrap;
+}
+
+.directory-alt div {
+  display: none;
+  margin: 0px;
+}
+
+.directory-alt img {
+  vertical-align: -30%;
+}
+
+/* @end */
+
+address {
+  font-style: normal;
+  color: #333;
+}
Added: sandbox/SOC/2007/quan/libs/quan/doc/doxygen/quan_doxygen_footer.html
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/libs/quan/doc/doxygen/quan_doxygen_footer.html	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,29 @@
+<!-- custom Doxygen footer quan_doxygen_footer.html  -->-
+
+<!-- Copyright 2012 Paul A. Bristow -->
+<!-- Distributed under the Boost Software License, Version 1.0. -->
+<!-- (See accompanying file LICENSE_1_0.txt or copy at          -->
+<!-- http://www.boost.org/LICENSE_1_0.txt)                      -->
+
+<hr size="1"/>
+<table width="100%">
+<tbody>
+  <tr>
+   <address style="text-align: left;">
+     <p>Use, modification and distribution are subject to the Boost Software License, Version 1.0.<br/>
+     (See accompanying file LICENSE_1_0.txt or copy at 
+      http://www.boost.org/LICENSE_1_0.txt )</p>
+      <!-- Change copyright to YOUR name (and affiliation, if any) below:  -->
+     <p>Copyright © $year Paul A. Bristow</p>
+      <!-- $year becomes the current year, for example 2010, so claims copyright for a range of years, 2009 - 2010. -->
+     <p>Doxygen Documentation generated by  
 $doxygenversion, Revised at $datetime</p>
+  </address>
+  </tr>
+</tbody>
+</table>
+  <!-- You can also add a footer logo, taking care that the location of the footer.png is correct. -->
+  <!-- <img src="../images/my_footer.png" alt="Boost Doxygen documentation footer.png" -->
+  </body> <!-- <body> is in doxygen_header.html -->
+</html><!-- <html>  is in doxygen_header.html -->
+
+
Added: sandbox/SOC/2007/quan/libs/quan/doc/doxygen/quan_doxygen_header.html
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/libs/quan/doc/doxygen/quan_doxygen_header.html	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,47 @@
+
+<!-- quan_doxygen_header.html -->
+
+<!-- From Sample custom Doxygen header from my_doxygen_header.html  -->-
+
+<!-- Copyright 1998 - 2012 Paul A. Bristow. -->
+
+<!-- Distributed under the Boost Software License, Version 1.0. -->
+<!-- (See accompanying file LICENSE_1_0.txt or copy at          -->
+<!-- http://www.boost.org/LICENSE_1_0.txt)                      -->
+
+<html> <!-- </html> is in footer. -->
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+
+  <!-- Add your title here ! -->
+  <title>Boost.quan $datetime $projectname $projectnumber</title>
+
+  <!-- Add your custom stylesheet here ! -->
+  <link href="../quan_doxygen.css" rel="stylesheet" type="text/css"/>
+  <!-- Note that this overrides any stylesheet specified in doxyfile setting HTML_STYLESHEET="mystylesheet.css" ! -->
+  <link href="tabs.css" rel="stylesheet" type="text/css"/>
+</head>
+
+<!-- Add draft background here if, for example, not yet accepted or otherwise not finalised. -->
+<body style="background-image: url(../../images/draft.png);">
+</body>
+
+<!-- You could also flag status by using a color? -->
+<!--<body style="background-image: url(../../images/draft.png) ; color : darkblue"> -->
+
+<!-- </body> is in footer. -->
+
+<!-- Add your logo here or -->
+<!-- Boost logo here if accepted after review, else some "Proposed for Boost" logo, for example the one below, or "proposed for Boost" ! -->
+<table cellpadding="5" width="100%">
+  <tbody>
+    <tr>
+      <td valign="top"><img alt="Proposed for Boost." src="../proposed_for_boost.png" height="80" width="250"/></td>
+    </tr>
+  </tbody>
+</table>
+<p>
+  <br/>  <!-- Some space below logo, if needed. -->
+</p>
+
Added: sandbox/SOC/2007/quan/libs/quan/example/quan_simple/quan_simple.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/libs/quan/example/quan_simple/quan_simple.cpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,59 @@
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// Copyright Paul A. Bristow 1998, 2012.
+
+
+#include <boost/version.hpp>
+#include <boost/quan/unc.hpp>
+#include <boost/quan/unc_init.hpp>
+
+#include <iostream>
+
+std::string versions()
+{
+  std::stringstream mess;
+  mess << "Program: " __FILE__  << "\n";
+#ifdef __TIMESTAMP__
+  mess << __TIMESTAMP__;
+#endif
+  mess << "\nBuildInfo:\n" "  Platform " << BOOST_PLATFORM;
+  mess << "\n  Compiler " BOOST_COMPILER;
+#ifdef _MSC_FULL_VER
+  mess << "\n  MSVC version "<< BOOST_STRINGIZE(_MSC_FULL_VER) << ".";
+#endif
+  mess << "\n  STL " BOOST_STDLIB;
+  mess << "\n  Boost version " << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100 << endl;
+  return mess.str();
+} // std::string versions()
+
+int main()
+{
+   std::cout << std::endl;
+
+   std::cout << versions() << std::endl;
+  setUncDefaults(std::cout);
+  uncun u(1.23, 0.45F);
+  std::cout << "URealCorr u(1.23, 0.45); = " << u << plusminus << std::endl;
+
+
+} // int main()
+
+/*
+  Description: Autorun J:\Cpp\quan\MSVC\Debug\quan_simple.exe
+  
+  Program: ..\..\libs\quan\example\quan_simple\quan_simple.cpp
+  Thu Jul 19 16:06:56 2012
+  BuildInfo:
+    Platform Win32
+    Compiler Microsoft Visual C++ version 10.0
+    MSVC version 160040219.
+    STL Dinkumware standard library version 520
+    Boost version 1.50.0
+  
+  URealCorr u(1.23, 0.45); = 1.2
+
+
+*/
\ No newline at end of file
Added: sandbox/SOC/2007/quan/libs/quan/test/Quan1In.txt
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/libs/quan/test/Quan1In.txt	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,3 @@
+0.05 (9)
+1.1 +/-0.1 1.2 1.0 1.1+/-0.001
+1.25 0.97
Added: sandbox/SOC/2007/quan/libs/quan/test/TestQuan1.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/libs/quan/test/TestQuan1.cpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,1047 @@
+// TestQuan1.cpp
+// Test unc fully first.
+// Compiles and run 8 Aug but results wrong in unc
+// Using atime seems to work but is messy - use Boost posixTime?
+
+// Test of Quan1 - univariate using uncertainty and statistical tests.
+
+// see QuanOne word document for description.
+#ifdef _MSC_VER
+#  pragma warning(disable : 4189) // 'argument' : conversion from 'time_t' to 'unsigned short', possible loss of data
+#  pragma warning(disable : 4996) //  _CRT_SECURE_NO_WARNINGS.
+#  pragma warning(disable : 4702) // Unreachable code.
+#endif
+
+#include <cmath>   // for sqrt, exp ...
+#include <iostream> // 
+#include <iomanip>  // for  setw, setprecision ...
+#include <fstream>  // for filing.
+#include <string>  // for C++ Std strings.
+#include <sstream> // for stringstreams.
+#include <vector>  // for vectors.
+#include <functional>  // for less...
+#include <algorithm>  // for sort, copy, swap ...
+#include <numeric> // for accumulate... 
+#include <locale> 
+#include <ctime>  // C time.h defines time_t time(time_t* timer);
+#include <cassert> // for testing only.
+
+#include "unc.hpp" // Declaration of Uncertain Classes.
+#include "meas.hpp" // uncertain plus order.
+#include "to_string.hpp" // 
+
+using std::ofstream;
+using std::ifstream;
+using std::istringstream;
+using std::getline;
+using std::ios;
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::flush;
+using std::hex;
+using std::ws;
+using std::skipws;
+using std::noskipws;
+using std::string;
+using std::istringstream;
+using std::ostringstream;
+using std::boolalpha;
+using std::uppercase;
+using std::scientific;
+using std::setprecision;
+using std::resetiosflags;
+using std::fixed;
+using std::vector;
+using std::iterator;
+using std::allocator;
+using std::abs;
+using std::copy;
+using std::sort;
+using std::accumulate;
+using std::transform;
+using std::less;
+using std::swap;
+using std::locale;
+using std::use_facet;
+using std::ctype;
+using std::numpunct;
+
+time_t timeNow(); // return C time(0);
+std::ostream& operator<< (std::ostream& os, time_t t); 
+
+char const outFilename[] = "Quan1Out.txt";
+char const logFilename[] = "Quan1Log.txt";
+char const testInputFilename[] = "Quan1In.txt";
+
+// This block of definitions MUST be positioned before main.
+// 14 indexes of long iwords allocated by calls of ios_base.xalloc();
+// 1st call of xalloc() returns 0 so ios_base.iword(0) used for magic id,
+// 2nd call of xalloc() returns 1 so ios_base.iword(1) used for uncFlags,
+// 3rd calls returns 2, so iosword(2) used for sigDigits ...
+// Order of assignment must ensure these match enum uncindex (if used).
+const long zeroIndex = ios_base::xalloc(); // 1st iword[0] to hold a 'magic' id.
+
+const long uncFlagsIndex = ios_base::xalloc(); // long& uncFlags = iword(1)
+const long oldUncFlagsIndex = ios_base::xalloc(); // long& olduncFlags = iword(2)
+const long sigDigitsIndex = ios_base::xalloc(); // sigDigits = iword(3)
+const long oldSigDigitsIndex = ios_base::xalloc(); // oldsigDigits = iword(4)
+const long setSigDigitsIndex = ios_base::xalloc(); // setsigDigits = iword(5)
+const long stdDevSigDigitsIndex = ios_base::xalloc(); // stdDevSigDigits = iword(6)
+const long oldStdDevSigDigitsIndex = ios_base::xalloc(); // oldStdDevSigDigits = iword(7)
+const long ScaleIndex = ios_base::xalloc(); // scale = iword(8)
+const long oldScaleIndex = ios_base::xalloc(); // oldScale = iword(9)
+const long setScaleIndex = ios_base::xalloc(); // setScale = iword(10)
+const long uncWidthIndex = ios_base::xalloc(); // uncWidth = iword(11)
+const long oldUncWidthIndex = ios_base::xalloc(); // oldUncwidth = iword(12)
+const long oldUncSetWidthIndex = ios_base::xalloc(); // oldUncSetWidth = iword(13)
+const long usedIndex = ios_base::xalloc(); // used = iword(14)
+const long oldUncUsedIndex = ios_base::xalloc(); // oldUsed = iword(15)
+const long widthIndex = ios_base::xalloc(); // width = iword(16)
+const long oldWidthIndex = ios_base::xalloc(); // oldWidth = iword(17)
+
+const long topIndex = ios_base::xalloc(); // long& topIndex = iword(18] == iword(0] check!
+
+extern const long indexID;  // 'Magic' value defined in unc.cpp.
+
+bool isIndexed = true; // Above indexes have been initialised.
+
+char const* Ctime(time_t* t); // Timestamp as string "Tue Apr 24 16:57:31 2001""\n"
+
+// #include <boost/test/minimal.hpp> // Boost minimal test
+#define BOOST_TEST_MAIN // Required for int test_main() (must come FIRST).
+#define BOOST_LIB_DIAGNOSTIC "on"// Show library file details.
+// Linking to lib file: libboost_unit_test_framework-vc100-mt-s-1_49.lib
+
+#include <boost/config.hpp>
+#include <boost/cstdlib.hpp> // needed for boost::exit_failure;
+
+#include <boost/test/unit_test.hpp> // Enhanced for unit_test framework autolink,
+#include <boost/test/floating_point_comparison.hpp> // Extra test tool for FP comparison.
+  using boost::unit_test::test_suite;
+  using boost::unit_test::unit_test_log;
+
+    // Direct use of std predicate function less using
+  // TEMPLATE STRUCT less in <functional>
+  // Used below for URealUncorr and Meas which both have operator< defined.
+  // if (std::less<double>()(l, h))
+  // if (std::less<URealUncorr>()(l, h))
+  // if (std::less<Meas>()(lm, hm))
+
+  //template<typename Type>
+  //struct less
+  //  : public binaryfunction<Type, Type, bool>
+  //{	// functor for operator<
+  //  bool operator()(const Type& Left, const Type& Right) const
+  //  {	// apply operator< to operands
+  //    return (Left < Right);
+  //  } // operator<
+  //};
+
+
+BOOST_AUTO_TEST_CASE(quan1_test_0)
+{ 
+  string message("Quan1 test: " __FILE__ );
+#ifdef __TIMESTAMP__
+  message += " at " BOOST_STRINGIZE(__TIMESTAMP__);
+#endif
+#ifdef _MSC_FULL_VER
+  message +=  ", MSVC version " BOOST_STRINGIZE(_MSC_FULL_VER) ".";
+#else
+  message += "."
+#endif
+  BOOST_MESSAGE(message);
+  BOOST_CHECK(std::numeric_limits<double>::is_iec559 == true);
+  // IEE745 is assumed by code.
+
+  setUncDefaults(cout); 
+  BOOST_CHECK(isIndexed); // Should pass.
+  BOOST_CHECK(cout.iword(zeroIndex) == indexID); // Should pass.
+  BOOST_CHECK(cout.iword(topIndex) == indexID); // Should pass.
+  cout.iword(0) = indexID; // 1st iword[0] to hold a 'magic' id.
+
+  // Integrity check on iword begin and end no longer needed in CHECK.
+  {
+    ostringstream oss;
+    setUncDefaults(oss);
+    BOOST_CHECK(oss.iword(zeroIndex)== indexID);
+    BOOST_CHECK(oss.iword(0) == indexID);
+    BOOST_CHECK(oss.iword(topIndex)== indexID);
+    BOOST_CHECK(oss.iword(0) == indexID);
+  }
+} // BOOST_AUTO_TEST_CASE(quan1_test_0)
+
+// Macros to test output strings and inputusing unc and meas classes.
+  // Note uses setUncDefaults(oss); to initialise unc iostream data.
+  // Example: CHECK(plusminus << u123, "1.234 +/-0.02");
+#define CHECK(manips, result)\
+{\
+  ostringstream oss;\
+  setUncDefaults(oss);\
+  oss << manips;\
+  BOOST_CHECK_EQUAL(oss.str(), result);\
+}// #define	CHECK(manips, result)
+
+BOOST_AUTO_TEST_CASE(quan1_test_1)
+  {	// Some examples of testing uncertaint class without using macro CHECK.
+  {
+    ostringstream oss;
+    setUncDefaults(oss);
+    URealUncorr u0(0., 0.F);
+    oss << u0;
+    BOOST_CHECK_EQUAL(oss.str(),"0");
+  }
+  {
+    ostringstream oss;
+    setUncDefaults(oss);
+    URealUncorr u2(2., 0.F);
+    oss << u2;
+    BOOST_CHECK_EQUAL(oss.str(), "2.");
+    //cout << "URealUncorr u2(2., 0.F) == " << u2 << endl;
+  }
+  {
+    ostringstream oss;
+    setUncDefaults(oss);
+    URealUncorr u123(1.23, 0.01F);
+    oss << plusminus << u123;
+    BOOST_CHECK_EQUAL(oss.str(),"1.230 +/-0.02");
+    // cout << "URealUncorr u123(1.23., 0.01F) == " << plusminus << u123 << endl;
+  }
+} // BOOST_AUTO_TEST_CASE(quan1_test_1)
+
+
+BOOST_AUTO_TEST_CASE(quan1_test_2)
+{ // Tests on display of uncertain flags and uncertain types. 
+
+    unsigned short int uncFlags = plusMinus | noisyDigit;
+    //cout << showUncFlags(uncFlags) << endl;
+    CHECK(showUncFlags(uncFlags), "uncFlags (48) add_+/- add_noisy."); 
+    unsigned short int uncTypes = UNC_QUAN_DECIMAL | UNC_KNOWN;
+    //cout << showUncTypes(uncTypes) << endl; // uncTypes: (120) uncKnown quantize10
+    CHECK(showUncTypes(uncTypes), "uncTypes (0x120) uncKnown quantize10.");
+    unsigned short defType = UNC_KNOWN | UNC_EXPLICIT | DEG_FREE_EXACT | DEG_FREE_KNOWN; //  0x6420
+    //cout << showUncTypes(defType) << endl; 
+    CHECK(showUncTypes(defType), "uncTypes (0x6420) uncKnown explicit df_exact df_known.");
+} // BOOST_AUTO_TEST_CASE(quan1_test_2)
+
+
+BOOST_AUTO_TEST_CASE(quan1_test_3)
+{
+
+  // +/- symbol = dec 177, hex F1  messy!! fout is different to cout!
+  ofstream fout(outFilename, ios::out); // use default overwrite/ iso::replace.
+  BOOST_CHECK(fout);
+  //if (!fout)
+  //{  // failed to open OK.
+  //  cerr << "File " << outFilename << " failed to open!" << endl;
+  //  return notOK;
+  //}
+   cout << "Quan1 Test output to "	<< outFilename << space <<  __TIMESTAMP__ << endl;
+
+  ifstream fin(testInputFilename, ios::in);
+  BOOST_CHECK(fin.is_open());
+  //if (!fin.is_open())
+  //{
+  //  cerr << "File " << testInputFilename << " failed to open!" << endl;
+  //  return notOK;
+  //}
+  cout << "Quan1 input from " <<  testInputFilename << space << __TIMESTAMP__  << endl;
+  
+
+  if (false)
+  {// Test of comparison operators and predicates for UReals now in unc.h. 
+    // Rely on unc tests.
+    URealUncorr u0(0.,0.F); // Exact integral zero gave problems before, now OK - all zero.
+    cout << noplusminus << endl; 
+    cout << "URealUncorr u0(0.,0.F) == " << u0 << endl;  // plain 0
+    cout << plusminus << flush;
+    cout << "URealUncorr u0(0.,0.F) == " << u0 << endl; // still plain 0 as expected.
+    cout << noplusminus << u0 << endl; // still plain 0 as expected.
+    cout << plusminus  << u0 << endl; // 9.89 < 9.99 < 10.1
+    cout << addlimits << plusminus << u0 << endl; // 9.89 < 9.99 +/-0.10 < 10.1
+    cout << uppercase << boolalpha << endl;
+    cout << showformat << endl; // FormatFlags (0x4205)  skipws, uppercase, dec, boolalpha.
+    // 	ostream& showuncflags(ostream& os);
+    cout << showuncflags << endl; // uncFlags (0x808)  add +/-, add limits.
+    // void outUncFlags(unsigned short int uncFlags = std::cout.iword(uncFlagsIndex), ostream& os = std::cerr);
+    //outUncFlags(unsigned short(cout.iword(uncFlagsIndex)), cout); // Using defaults above.
+    cout << endl;
+  }
+
+
+  /* to_string doesn't appear to work - causes bad_alloc - come back to this?
+  if(false)// Test to_string, and some specializations.
+  {
+    double dd = 3.333333333333333333333333333333;
+    std::string xx;
+    xx = to_string<double>(dd);
+    cout << xx << endl; // to_string default is precision(10) not std default 6.
+    CHECK(xx, "3.333333333"); // Expect precision 10 digits.
+    xx = to_string<bool>(true); 
+    cout << xx << endl; // to_string default is boolalpha.
+    CHECK(xx, "true"); // Expect boolalpha so "true" not "1".
+
+    URealUncorr uu(1.6, 0.1f);
+    setUncDefaults(cout);
+    xx = to_string<URealUncorr>(uu);
+    cout << xx << endl;
+    CHECK(xx, "1.5 < 1.6 +/-0.10 < 1.7"); // Expect addlimits & plusminus.
+
+    //const char* cs = "test";
+    //xx = to_string("test");
+    //CHECK(xx, "test");
+    //URealUncorr hhh(1.6, 0.1f); // even at 2 standard deviations.
+    //string hs = "to_string<URealUncorr>(hhh)  " + to_string<URealUncorr>(hhh) +" is cool!";
+    //cout << hs << endl;
+  } // tostring
+  */
+  
+  // Check operators which only use value taking no account of uncertainty.
+  URealUncorr l(1.1, 0.1f); // Two test values l and h whose confidence intervals DO overlap.
+  URealUncorr h(1.1, 0.1f);
+  URealUncorr ll(1.1, 0.1f); // Test values ll and hh whose confidence intervals DON'T overlap at one sd.
+  URealUncorr hh(1.4, 0.1f);
+  URealUncorr lll(1.1, 0.1f); // Test values lll and hhh whose confidence intervals DON'T overlap,
+  URealUncorr hhh(1.6, 0.1f); // even at 2 standard deviations.
+
+  cout 	<< "top of lower " << l.getValue() << " = " << l.getValue() + l.getStdDeviation() << endl
+    << "bottom of higher " << h.getValue() << " = " << h.getValue() - h.getStdDeviation() << endl;
+  // If linearly combining SDs adding or subtracting two values, use sqrt sum squares or hypot.
+  BOOST_CHECK_GE((l.getValue() + l.getStdDeviation()), (h.getValue() - h.getStdDeviation()));
+
+  cout << "sqrt_sumsquares sds = " << hypot(h.getStdDeviation(), l.getStdDeviation()) << nl;
+  // But that isn't relevant when comparing means - see below NR in C .
+
+  cout << "Difference of values in max sds between " << plusminus << h << " and " << l << " == "
+   << (h.getValue() - l.getValue())/ std::max(l.getStdDeviation(), h.getStdDeviation()) << endl; // max
+
+  cout << "Difference in sds between " << h << " and " << l << " == "
+   << (h.getValue() - l.getValue())/ hypot(h.getStdDeviation(), l.getStdDeviation())  << endl; // hypot
+
+  cout << "Difference in sds between " << hh << " and " << ll << " == "
+   << (hh.getValue() - ll.getValue())/ hypot(hh.getStdDeviation(), ll.getStdDeviation())  << endl; // hypot
+
+  cout << "Difference in sds between " << hhh << " and " << lll << " == "
+   << (hhh.getValue() - lll.getValue())/ hypot(hhh.getStdDeviation(), lll.getStdDeviation())  << endl; // hypot
+
+  // NR in C 13.4.3 p 512 comparing means with unequal variance, degrees of freedom and uncertainty.
+  double meandiff = hh.getValue() - ll.getValue();
+  URealUncorr meandiffu;
+  meandiffu = ( hh - ll);
+  cout << "Means "  << plusminus << ll << tab << hh << ", Difference of means is " << meandiffu << endl;
+  cout << "SDs " << ll.getStdDeviation() << tab << hh.getStdDeviation() << endl;
+  double cdf = hypot(hh.getStdDeviation(), ll.getStdDeviation());
+  cout << "hypot sds " << cdf << nl; // Cruder combined uncertainty - wrong?
+  double dfll = ll.getDegFree() +1; // N1
+  double dfhh = hh.getDegFree() +1; // N2
+  cout << "Degrees of freedom " << dfll << tab << dfhh << nl;
+  double sell = (ll.getStdDeviation() * ll.getStdDeviation() )/ (ll.getDegFree() +1);
+  double sehh = (hh.getStdDeviation() * hh.getStdDeviation() )/ (hh.getDegFree() +1);
+  double se = sqrt(sell + sehh);
+  cout << "Standard errors " << sell << tab << sehh << ", mean se " << (sell + sehh) * 0.5 << " sqrt() " << se << nl;
+
+  double varll = ll.getStdDeviation() * ll.getStdDeviation();
+  double varhh = hh.getStdDeviation() * hh.getStdDeviation();
+  cout << "Variances " << varll << tab << varhh << nl;
+  double varlln = varll / dfll ; // variances/N
+  double varhhn = varhh / dfhh;
+  cout << "variance/df " << varlln << tab << varhhn << nl;
+  double dftop = (varlln + varhhn) * (varlln + varhhn); // top of 13.4.4
+  cout << "df top " << dftop << endl;
+  double dfbot = (varlln * varlln)/ dfll + (varhhn * varhhn) / dfhh; // bottom of 13.4.4
+  cout << "df bot " << dfbot << endl;
+  double df = dftop/dfbot;
+  cout << "df " << df << nl; // Final 13.4.4 degrees of freedom (not integer).
+
+  cout << "sqrt(varlln + varhhn) " << sqrt(varlln + varhhn) << endl;
+
+  double st = meandiff/ sqrt(varlln + varhhn); // Student's t 13.4.3
+  cout << "Student's t " << st << ", df " << df << nl;
+
+//	double prob = betai(0.5 * df, 0.5, df/(df + st * st));
+//	cout << "Probability that are different is " << prob << endl;
+
+
+  if (l < h)
+  { // Uses URealUncorr::operator<  - only uses central value, no uncertainty.
+    cout << noplusminus << l << " is  < " << h  << endl; // 0.90 < 1.1 < 1.3  is < 1.0 < 1.2 < 1.4
+  }
+  if (l == h)
+  { // Uses URealUncorr::operator==  - only uses central value, no uncertainty.
+    cout << " l == h " << endl;
+  }
+  if (l != h)
+  { // Uses URealUncorr::operator!=  - only uses central value, no uncertainty.
+    cout << " l != h " << endl;
+  }
+
+
+ 
+  double ld = 1.2;
+  double hd = 3.4;
+  if (std::less<double>()(ld, hd))
+  {
+    cout << "(less<double>(" << ld << ", " << hd << " )) " << endl;
+  }
+  if (std::less<URealUncorr>()(l, h))
+  {
+    cout << "(std::less(l, h)) " << " l < h " << endl;
+  }
+  if (lessAbs<URealUncorr>()(l, h))
+  {
+    cout << "(lessAbs(l, h)) " << " l < h " << endl;
+  }
+  cout << "Test member predicate function " << plusminus << l << " < " << h  << endl;
+  cout << plusminus << "(lessUnc(l, h)) ";
+  if (URealUncorr::lessU(l, h))
+  { // 
+    cout << " l < h " << endl;
+  }	
+  else
+  { // Not less so check if 
+    if (URealUncorr::moreU(l, h))
+    { // greater
+      cout << " l > h " << endl;
+    }
+    else
+    { // or approximate equal.
+      cout << " l ~= h " << endl;
+    }
+  }
+  cout << " l " << l << ((URealUncorr::equalU(l, h) ? " ~= " : " != ")) << " h " << h << endl;
+  cout << " ll " << ll << ((URealUncorr::equalU(ll, hh) ? " ~= " : " != ")) << " hh " << hh << endl;
+  cout << " l " << l << ((URealUncorr::equalU2(l, h) ? " ~= " : " != ")) << " h " << h << endl;
+  cout << " ll " << ll << ((URealUncorr::equalU2(ll, hh) ? " ~= " : " != ")) << " hh " << hh << endl;
+
+  cout << "Testing static memberfunction predicate lessU<isCorrelated>" << nl;
+  //	bool lessU(const UReal<isCorrelated>& l, const UReal<isCorrelated>& r) 
+
+  if (UReal<false>::lessU(ll, hh) )
+  { // Not using typedef for UReal<false>::
+    cout << ll << " is < " << hh << endl;
+  }	
+  else
+  {
+    cout << ll << " is >= " << hh << endl;
+  }
+  // if (UReal<true>::lessU(ll, hh) ) // fails because ll and hh are correlated.
+  // and anyway is not really implemented yet for correlated,
+  // but would use the same code silently.
+   UReal<true> lc(1.); 	UReal<true> hc(2.);
+  // Two correlated reals.
+
+  if (UReal<true>::lessU(lc, hc) )
+  { // Full UReal<true>::
+    cout << " lc < hc " << endl;
+  }	
+  // global bool lessUnc not longer implemented for UReal<false> or <true>
+  // and will fail to compile if  "if (lessUnc(lc, hc) ... " is used.	
+  //
+
+  if (URealUncorr::lessU(ll, hh) )
+  { // Full URealUncorr:: qualification is essential - uses typedef for URealUncorr.
+    cout << ll << " is < " << hh << endl;
+  }	
+  else
+  {
+    cout << ll << " is >= " << hh << endl;
+  }
+  if (URealUncorr::lessU2(ll, hh) )
+  { // Two sd version.
+    cout << ll << " is << " << hh << endl;
+  }	
+  else
+  {
+    cout << ll << " is >= " << hh << endl;
+  }
+  
+  if (URealUncorr::lessU2(lll, hhh) )
+  { // Two sd version.
+    cout << lll << " is << " << hhh << endl;
+  }	
+  else
+  {
+    cout << lll << " is >= " << hhh << endl;
+  }
+
+  if (URealUncorr::lessU(0., hh) )
+  { // Left most argument needs conversion from double.
+    cout << " 0. < " << hh << endl;
+  }	
+  else
+  {
+    cout << " 0. >= " << hh << nl;
+  }
+
+  const URealUncorr vh(99.);
+  if (URealUncorr::lessU(ll, vh) )
+  { // right most argument needs conversion from double.
+    cout <<  ll << " is < " << vh << endl;
+  }	
+  else
+  {
+    cout <<  ll << " is >= " << vh << endl;
+  }
+
+//	typedef UReal<false>::lessU UlessU;  doesn't work
+  // Check moreU
+  if (URealUncorr::moreU(ll, vh) )
+  { // right most argument needs conversion from double.
+    cout <<  ll << " is > " << vh << endl;
+  }	
+  else
+  {
+    cout <<  ll << " is <= " << vh << endl;
+  }
+
+  if (URealUncorr::equalU(l, h) )
+  { // right most argument needs conversion from double.
+    cout << l << " is ~= " << h << endl;
+  }	
+  else
+  {
+    cout << l << " is !~= " << h << endl;
+  }
+
+
+//	time_t* nowp = &now;
+//	cout << " now = "  << localtime(&now) << endl; //  Outputs 004BCDD0 address of struct* tm?
+//	cout << Ctime(nowp) << endl; // outputs: "Fri Jul 21 15:31:41 2000" = asctime(localtime(now))
+//	cout << asctime(localtime(&now)) << endl; // outputs: "Fri Jul 21 15:31:41 2000""\n" = asctime(localtime(now))
+
+ 
+    URealUncorr u0(0., 0.F);
+
+    Meas zz; // Default constructor.
+    //cout << "Meas zz; = " << zz << endl;
+    CHECK(zz, "0"); 
+
+    zz = 1.;
+    //cout << "zz = 1; == " << zz << endl;
+    CHECK(zz, "1"); 
+
+    Meas z0(0.); // Construct from double zero.
+    //cout << "Meas z0(0.) == " << z0 << endl;
+    CHECK(z0, "0"); 
+
+    Meas z0i(0); // Construct from int zero.
+    //cout << "Meas z0i(0) == " << z0i << endl;
+    CHECK(z0i, "0"); 
+
+    Meas one(1.);
+
+    ptime now =  ptime(day_clock::local_day());
+    Meas m0(u0, "m0", now); // Using now defaults.
+    // CHECK(m0, "m0 0 @ 15:42:45"); // Doesn't work because time now keeps changing!
+    Meas m01(u0, "m01", 2); // Using unity value defaults.
+    //cout << m01 << endl;
+    CHECK(m01, "m01 0 # 2");
+
+
+    //Meas(URealUncorr u, string id, time_t ti);  // <<<<<<<<<<<<<<<<< test these 
+    //Meas(URealUncorr u, string id, unsigned short int);// <<<<<<<<<<<<<<<<< test these 
+
+    Meas zm1(-1.); // negative double value to allow check of abs function below. 
+    Meas z1m(-1.); // negative double value to check ==
+    BOOST_CHECK(zm1 == z1m);
+    BOOST_CHECK(zm1 != z0);
+
+    //bool c = (zz < z0); // Check operator<
+    BOOST_CHECK(z0 < zz); // Check operator<
+    BOOST_CHECK(zz > z0); // Check operator>
+    //cout << zz <<  " < " << z0 << " is " << boolalpha << c << endl;
+    //c = (zm1 < 0 );
+    BOOST_CHECK(zm1 < 0 );
+    // BOOST_CHECK(0 > zm1); // No operator >
+
+    //cout << zm1 <<  " < " << z0 << " is " << boolalpha << c << endl;
+    //bool c = (zm1 < Meas(0) );
+    BOOST_CHECK(zm1 < Meas(0) );
+    // cout << zm1 <<  " < " << Meas(0) << " is " << boolalpha << c << endl;
+    BOOST_CHECK(Meas(0) > zm1 );
+
+    Meas mone = -one;
+    //cout << "-one == " << mone << endl;
+    CHECK(mone, "-1");
+    //cout << "Meas zm1(-1.) == " << zm1 << endl;
+    CHECK(zm1, "-1");
+  
+    Meas z1 = fabs(zm1); // double to check abs function.
+    BOOST_CHECK(z1 == 1 );
+    Meas z11 = abs(zm1); // double to check abs function.
+    BOOST_CHECK(z11 == 1 );
+    //cout << "abs(zm1) = std::abs(zm1) = " << abs(zm1) << endl; // Should lookup type Meas, and does!
+    //cout << "abs<Meas>(zm1) == " << abs<Meas>(zm1) << endl; // explicit Type Meas fails!
+    //cout << "abs(zm1).m_value == " << abs(zm1.m_value) << endl;		
+
+  //Meas lmNow(l, "low", now);
+  //cout << "Meas lmNow(l, \"low\", now) == " << lmNow << endl; 
+  //Meas hmNow(h, "hi", 2);
+  //cout << "Meas hmNow(h, \"hi\", 2); == " << hmNow << endl; 
+  //time_t nnow =   now + 90; // Add 90 seconds to time for Meas hi.
+  //Meas nmNow(h, "hi", nnow); // Show time has advanced.
+  //cout << "Meas nmNow(h, \"hi\", nnow); == " << nmNow << endl; // Meas nmNow(h, "hi", nnow); == hi 1.2 @ 22:59:49
+  // Some comparisons.
+
+
+  Meas lm(l, "low", 1);
+  Meas hm(h, "high", 2);
+
+
+  if (lm < hm)
+  { // Using bool operator< (Meas&)
+    cout << "(lm < hm)  "<< lm << " < " << hm << endl;
+  }				
+  if (std::less<Meas>()(lm, hm))
+  { // Using std functor less which uses operator<
+    cout << "less(lm, hm) " << lm << " < " << hm << endl;
+  }
+  if (lessAbs<Meas>()(lm, hm))
+  { // Using Meas functor lessAbs
+    cout << "lessAbs<Meas>()(lm, hm) " << lm << " < " << hm << endl;
+  }
+  if (lessAbs<Meas>()(lm, hm))
+  { // Using Meas functor lessAbs again 
+    cout << "lessAbs<Meas>()(lm, hm) " << lm << " < " << hm << endl;
+  }
+  if (Meas::lessAbsM(lm, hm))
+  { // Compare absolute value within uncertainty using Meas::lessAbsM function.
+    cout << "lessAbsM(lm, hm) " << lm << " < " << hm << endl;
+  }
+    
+
+  int vCount = 0;
+  vector<URealUncorr> vs;
+  vector<Meas> vms;
+  vs.reserve(20); // More efficient than repeated push_backs.
+  cout << "Space reserved for " << vs.capacity() << " values." << endl;
+  
+  string line; // = "  123.45 +/- 0.1 mA (99) ! description";
+  int lineCount = 0;
+  int valueCount = 0;
+  while(!fin.fail())
+  {
+    URealUncorr v;
+    Meas vm;
+    if (fin)
+    { // More to get.
+      getline(fin, line); // 1.1 1.2 1.0 1.1 ...
+    }
+    if (line.size() == 0) break;  // Blank line (key return) to quit.
+    if (line.size() > 0)
+    { // Not a blank line.
+      ++lineCount;
+      fout << "Input line: " << line << endl;  // Echo input line to file.
+      istringstream is(line);
+      do
+      {
+        is >> v; // Read uncertain "1.2" or "1.2 +/-0.05".
+        //cout << v << endl;  // Echo input URealUncorr & 
+        Meas vm(v, "", valueCount); // Assign order of measurements.
+        // No ID so far? time is default not_a_date_time.
+        valueCount++;
+        vs.push_back(v);  // push onto the back of the UReal vector vs.
+        vms.push_back(vm); // push vm onto the back of the Meas vector vms.
+              
+        if (is.eof() == true)
+        {  // Tried to read more but no units given.
+          cout << "is.eof() == true" << " after " << v << "(no unit)." << endl;
+          break;
+        } // if
+        if (is.fail() == true)
+        { // Always seems to be fail == true when eof
+          cout << "is.fail == true!" << endl;
+          cout << v << "(no unit)." << endl;
+          break;
+        }
+        // int avail = is.rdbuf()->in_avail();
+      } // do
+      while (is.good() && (is.rdbuf()->in_avail() != 0));
+    } // Not blank line.
+  } // while
+  // cout << "vs.front() == " << vs.front() << ", vs.back() == " << vs.back() << endl;
+  // cout << "*vs.begin() == " << *vs.begin() << ", *vs.end() -1 == " << *(vs.end() -1) << endl;
+  // vector<URealUncorr>::ostream_iterator vi = vs.begin();
+  // ostream_iterator<URealUncorr> voi(cout, " ");
+  // ostream_iterator<URealUncorr> vi1(cout);  // default delimiter.
+  
+
+  vCount = vs.size()-1; // -1 becos 1st is expected uncertainty
+  double expectUncValue = vs[0].getValue();  // Expected +/- uncertainty.
+  float expectUncUnc = vs[0].getStdDeviation();
+  vs[0].setStdDeviation(float(vs[0].getValue() /10.));
+  vs[0].setDegFree(6);
+  URealUncorr expectUnc = vs[0];
+  cout  << vCount << " values, with expected uncertainty "
+    << plusminus
+    //<< adddegfree
+    << addreplicates  // Only show degrees of freedom > 1.
+    << expectUnc
+    << ", on " << lineCount << " lines." << endl;
+
+
+
+
+  // Output to file using copy.
+
+  setUncDefaults(fout);
+
+  fout << nl << vCount << " uncertain Values with expected uncertainty "
+    << plusminus
+    << addreplicates // show degrees of freedom if > 1.
+    << expectUnc
+    << "\n""Input from file:"  << testInputFilename << endl;
+
+
+  copy(vs.begin() + 1, vs.end(), std::ostream_iterator<URealUncorr>(fout, "\n"));
+  // vs.begin() is vs[0] which is expected uncertainty.
+  fout << endl;  // vs[1] = 1.10 1.20 1.00 ... 
+
+  fout << vms.size() << "  measurements " << endl;
+  copy(vms.begin() + 1, vms.end(), std::ostream_iterator<Meas>(fout, "\n"));
+  // vms.begin() is vs[0] which is expected uncertainty.
+  fout << endl;  // vs[1] = 1.10 1.20 1.00 ... 
+
+  if(true)
+  { 
+    std::vector<URealUncorr>::iterator vuBegin = vs.begin() + 1; // 0th is expected unc.
+    std::vector<URealUncorr>::iterator vuEnd = vs.end();
+    URealUncorr total(0.);
+    total = accumulate(vuBegin, vuEnd, total);
+    setUncDefaults(cout);
+    cout << total << endl;
+    sort(vuBegin, vuEnd);
+    sort(vuBegin, vuEnd, lessAbs<URealUncorr>() ); // Functor using binary_function in <functional>
+    sort(vuBegin, vuEnd, URealUncorr::lessU ); // static member function
+    sort(vuBegin, vuEnd, URealUncorr::moreU );
+    //sort(vuBegin, vuEnd, URealUncorr::equalU );  // asserts invalid operator<
+  }
+
+    // Now calculate mean and check for outliers etc.
+  { // Sum uncertain values using while loop.
+    cout << vCount << " Uncertain Values:" << plusminus << addlimits << endl;
+    std::vector<URealUncorr>::iterator vi = vs.begin() + 1;
+    // +1 because 0th value is expected uncertainty.
+    unsigned int i = 0;
+    URealUncorr sum(0.);
+    while(vi != vs.end())
+    {
+      sum += *vi;
+      ++i; // # number from 1 to n
+      cout << "Value #" << i << space << *vi 
+      // << ", sum " << sum
+      << nl; // Value 1 1.10, ...
+      ++vi;
+    }  // while, leaving vi == vs.end();
+    if ( i != (vs.size() - 1) ) // Check i is correct.
+      cout << i << space << vs.size() << endl;
+    cout << "mean = " << sum / i << endl; 
+    }
+    
+    std::ostream_iterator<Meas> osmit(cout, ", ");  // Set up iterator and comma separator.
+    cout.iword(uncFlagsIndex) &= ~plusMinus;  // clear bit 3 = 0 to mean Do NOT add +/-.
+    cout << showuncflags << endl;
+    cout << nl << "plusMinus " << noplusminus << nolimits << showuncflags << endl;
+
+  // Examples of sorting by various criteria.
+    sort(vms.begin() +1, vms.end());  // begin and (past the) end.
+    cout << "Sorted Meas vector using default operator<." << nl;
+    copy(vms.begin() +1, vms.end(), osmit);  // using std::ostream_iterator osmit for 1-based.
+    cout << endl;
+
+    //sort(vms.begin() +1, vms.end(), less);  // begin at [1] and (past the) end.
+    // cannot deduce template arguments.  Should be Meas::less
+
+
+    // Using other member functors precedes and lessU
+    //bool Meas::precedes(const Meas& l, const Meas& r); // Needs to be static member function.
+    sort(vms.begin() +1, vms.end(), Meas::precedes);  // Sort by m_order.
+    cout << "Sorted by order using static member functor Meas::precedes." << nl;
+    copy(vms.begin() +1, vms.end(), osmit);  cout << endl;
+
+    cout << nl << "plusMinus " << plusminus << showuncflags << endl;
+    cout << vs.at(1) << endl;
+
+    // Demo use of:
+//		bool Meas::precedes(const Meas& l, const Meas& r); // Needs to be static member function.
+//		bool Meas::lessU(const Meas& l, const Meas& r); // Needs to be static member function.
+//		bool Meas::lessU2(const Meas& l, const Meas& r); // Needs to be static member function.
+
+    sort(vms.begin() +1, vms.end(), Meas::precedes);  // Sort by m_order.
+
+    sort(vms.begin() +1, vms.end());  // begin at [1] and (past the) end.
+    cout << "Sorted by value using static member functor Meas::less." << nl;
+    copy(vms.begin() +1, vms.end(), osmit);	cout << nl << endl;
+    sort(vms.begin() +1, vms.end(), Meas::precedes);  // Sort by m_order.
+    cout << "Sorted by order using static member functor Meas::precedes." << nl;
+    copy(vms.begin() +1, vms.end(), osmit);	cout << nl << endl;
+
+    sort(vms.begin() +1, vms.end(), Meas::lessU);  // Sort by uncertain value within 1 sd.
+    cout << "Sorted by uncertain value using static member functor Meas::lessU." << nl;
+    copy(vms.begin() +1, vms.end(), osmit); cout << nl << endl;
+
+    sort(vms.begin() +1, vms.end(), Meas::lessU2);  // Sort by uncertain value within 2 sd.
+    cout << "Sorted by uncertain value using static member functor Meas::lessU2." << nl;
+    copy(vms.begin() +1, vms.end(), osmit); cout << nl<< endl;
+
+    sort(vms.begin() +1, vms.end(), Meas::lessAbsM);  // begin at [1] and (past the) end.
+    cout << "Sorted using functor lessAbsM." << nl;
+    copy(vms.begin() +1, vms.end(), osmit); cout<< nl << endl;
+
+
+
+  // Now consider use of Wilcoxon test.
+    fin.close(); // Input file.
+    fout.close();  // Output file.
+    cout << '\n' << __FILE__ << " ended " <<  __TIMESTAMP__ << endl;
+} // BOOST_AUTO_TEST_CASE(quan1_test_3)
+
+    //return 0;
+
+
+/*
+
+
+*/
+  /*
+  { // Output to console using while loop.
+    cout << vCount << " Uncertain Values input from file:" << plusminus << adddegfree << endl;
+    std::vector<URealUncorr>::iterator vi = vs.begin() + 1; // 0th value is expected uncertainty.
+    int i = 1;
+    while(vi != vs.end())
+    {
+      // cout << "Value " << i << space << *vi << endl; // Value 1 1.10, ...
+      ++i;
+      ++vi;
+    }  // while, leaving vi == vs.end();
+  }
+  // Copy to two C arrays containing separate values and uncertainties.
+  // Use vector or valarray instead?
+  double* vvs = new double[vCount+1]; // Values.
+  float* vus = new float[vCount+1];	// Uncertainties.
+  {	// Output using for loop.
+    int count = 1;
+    for (std::vector<URealUncorr>::iterator vi = vs.begin()+1; vi != vs.end(); ++vi, ++count)
+    {
+      cout << "Value #" << count << space << *vi << space; // "Value# 1 1.10 implicit"
+      cout << (((*vi).getUncTypes() & UNC_IMPLICIT) ? "implicit" : "explicit") << endl;
+      vvs[count] = (*vi).getValue();
+      vus[count] = (*vi).getStdDeviation();
+    }	// for
+    cout << endl; // Value 2 1.20  Value 3 1.00
+  }
+  
+  cout << setprecision(16) << endl;  // full precision, including noisy digit.
+  
+  {	// Check against expected uncertainty using a for loop.
+    int count = 1;
+    for (std::vector<URealUncorr>::iterator vi = vs.begin()+1; vi != vs.end(); ++vi, ++count)
+    {
+      if ((vus[count] - expectUncValue) > expectUncUnc ) // absolute uncertainty.
+      {
+        bool im = ((*vi).getUncTypes() & UNC_IMPLICIT);
+        cout << "Value " << count << space << *vi << ", "
+          << (((*vi).getUncTypes() & UNC_IMPLICIT)  ? "implicit" : "explicit")
+          << " uncertainty "
+          << vus[count]
+          << " is greater than expected "<< vs[0] << '!' << endl;
+      }
+    }	// for
+  }
+  
+  delete[] vvs;  // Need explicit destruction.
+  delete[] vus;
+    */	// Change in global locale, and thus that imbued to input and output,
+  // used to check that uncertainRead and uncertainPrint
+  // do fail (as expected) for input 1.23.
+
+  //locale krautLocale(std::locale::classic(), locale("German_Germany"), locale::numeric | locale::monetary); // category
+  //locale::global(krautLocale);
+  //// making decimal point a comma not a period.
+  ////locale krautLocale("German_Germany");
+  //locale aussieLocale ("English_Australia");
+  //locale frogLocale("French");
+  //BOOST_CHECK(use_facet<ctype<char> >(aussieLocale).is(std::ctype_base::alpha, 'a') == true);
+
+  //const numpunct <char>& npunctK = use_facet <numpunct <char> >(krautLocale);
+  //cout << krautLocale.name( ) << " truename "<< npunctK.truename() << endl;
+  //cout << aussieLocale.name( ) << " falsename "<< npunctK.falsename() << endl;
+  //BOOST_CHECK(npunctK.decimal_point() == ',');
+
+  //BOOST_CHECK(use_facet <numpunct <char> >(frogLocale).truename() == "true");
+  //BOOST_CHECK(use_facet <numpunct <char> >(aussieLocale).decimal_point() == '.');
+
+  //cout.imbue(locale("German_Germany")); //  X Open == De_DE
+  //URealUncorr v(1.234, 0.002F, 20);
+  //cout << " v(1.234, 0.002, 20) == "<< v << endl; // v(1.234, 0.002, 20) == 1,2340 Note , !
+                
+/*								
+
+other code to handle file input?
+
+{
+  std::vector<URealUncorr> vs(4);
+  cout << "Space for " << vs.size() << " values." << endl;
+  int vNumber = 0;
+  for (std::vector<URealUncorr>::iterator it = vs.begin();
+  it != vs.end(); ++it, ++vNumber)
+  {  // do all tests.
+    vs[vNumber] = *it;
+    cout << "vs " << vNumber << ": " << *it << ' ';
+    istringstream myIstream(line); // "  1.2 +/- 0.1 ";
+    // Read value and deduce if int or real, and implied uncertainty.
+    // 1, 10, 100, 1000 imply exact integer.
+    // 100. implies 100.0 +/- 0.5
+    // 100.0 +/- 5.0 , 100 +/- 50 can only be input with explicit +/-
+    // 100.0 implies 100.00 +/- 0.05
+    // 1.0 & 1.1  implies +/- 0.05
+    // 1.10 & 1.23 implies +/- 0.005
+    // Can't fractional part as int because leading zero is significant.
+    // Can read first part before . as an int cos leading zeros carry no info.
+    
+    int avail = myIstream.rdbuf()->in_avail();
+    // cout << " (" << avail << ")   ";
+    if (avail == 0)
+    {
+      cerr << "No input!" << endl;
+    }
+  }
+}
+
+//	bool operator<(const MyInt& x) const { return _value < x._value; }
+//	bool operator==(const MyInt& x) const { return _value == x._value; }
+
+
+------ Build started: Project: Quan1, Configuration: Debug Win32 ------
+  Running 4 test cases...
+  Platform: Win32
+  Compiler: Microsoft Visual C++ version 10.0
+  STL     : Dinkumware standard library version 520
+  Boost   : 1.49.0
+  Quan1 test: TestQuan1.cpp at "Wed Jan 18 12:44:01 2012", MSVC version 160040219.
+  Quan1 Test output to Quan1Out.txt Wed Jan 18 12:44:01 2012
+  Quan1 input from Quan1In.txt Wed Jan 18 12:44:01 2012
+  top of lower 1.1 = 1.2
+  bottom of higher 1.1 = 1
+  sqrt_sumsquares sds = 0.141421
+  Difference of values in max sds between 1.10 +/-0.2 and 1.10 +/-0.2 == 0
+  Difference in sds between 1.10 +/-0.2 and 1.10 +/-0.2 == 0
+  Difference in sds between 1.40 +/-0.2 and 1.10 +/-0.2 == 2.12132
+  Difference in sds between 1.60 +/-0.2 and 1.10 +/-0.2 == 3.53553
+  Means 1.10 +/-0.2	1.40 +/-0.2, Difference of means is 0.30 +/-0.3
+  SDs 0.1	0.1
+  hypot sds 0.141421
+  Degrees of freedom 1	1
+  Standard errors 0.01	0.01, mean se 0.01 sqrt() 0.141421
+  Variances 0.01	0.01
+  variance/df 0.01	0.01
+  df top 0.0004
+  df bot 0.0002
+  df 2
+  sqrt(varlln + varhhn) 0.141421
+  Student's t 2.12132, df 2
+   l == h 
+  (less<double>(1.2, 3.4 )) 
+  Test member predicate function 1.10 +/-0.2 < 1.10 +/-0.2
+  (lessUnc(l, h))  l ~= h 
+   l 1.10 +/-0.2 ~=  h 1.10 +/-0.2
+   ll 1.10 +/-0.2 !=  hh 1.40 +/-0.2
+   l 1.10 +/-0.2 ~=  h 1.10 +/-0.2
+   ll 1.10 +/-0.2 ~=  hh 1.40 +/-0.2
+  Testing static memberfunction predicate lessU<isCorrelated>
+  1.10 +/-0.2 is < 1.40 +/-0.2
+   lc < hc 
+  1.10 +/-0.2 is < 1.40 +/-0.2
+  lessU 1.1 1.2  >=  1 1.14142 1.1 0.141421 0.2
+  lessU 1.1 1.2  <  1.3 1.44142 1.4 0.141421 -0.1
+  lessU 1 1  <  2 2 2 0 -1
+  lessU 1.1 1.2  <  1.3 1.44142 1.4 0.141421 -0.1
+  lessU 1.1 1.3  <  1.2 1.48284 1.4 0.282843 0.1
+  lessU 1.1 1.3  <  1.4 1.68284 1.6 0.282843 -0.1
+  lessU 0 0  <  1.3 1.4 1.4 0.1 -1.3
+  lessU 1.1 1.2  <  99 99.1 99 0.1 -97.8
+  1.10 +/-0.2 is << 1.40 +/-0.2
+  1.10 +/-0.2 is << 1.60 +/-0.2
+   0. < 1.40 +/-0.2
+  1.10 +/-0.2 is < 99. +/-0
+  1.10 +/-0.2 is <= 99. +/-0
+  1.10 +/-0.2 is ~= 1.10 +/-0.2
+  Space reserved for 20 values.
+  is.eof() == true after 1.1000 +/-0.001(no unit).
+  is.eof() == true after 0.9700 +/-0.005(no unit).
+  6 values, with expected uncertainty 0.0500 +/-0.01, on 3 lines.
+  6.620
+  6 Uncertain Values:
+  Value #1 1.2500 +/-0.003
+  Value #2 1.20 +/-0.03
+  Value #3 1.10 +/-0.03
+  Value #4 1.1000 +/-0.001
+  Value #5 1.00 +/-0.03
+  Value #6 0.9700 +/-0.005
+  mean = 1.103 +/-0.007
+  
+  
+  plusMinus 
+  Sorted Meas vector using default operator<.
+  0.97 # 6, 1 # 3, 1.1 # 1, 1.1 # 4, 1.2 # 2, 1.25 # 5, 
+  Sorted by order using static member functor Meas::precedes.
+  1.1 # 1, 1.2 # 2, 1 # 3, 1.1 # 4, 1.25 # 5, 0.97 # 6, 
+  
+  plusMinus 
+  1.2500 +/-0.003
+  Sorted by value using static member functor Meas::less.
+  0.97 # 6, 1 # 3, 1.1 # 1, 1.1 # 4, 1.2 # 2, 1.25 # 5, 
+  
+  Sorted by order using static member functor Meas::precedes.
+  1.1 # 1, 1.2 # 2, 1 # 3, 1.1 # 4, 1.25 # 5, 0.97 # 6, 
+  
+  Sorted by uncertain value using static member functor Meas::lessU.
+  0.97 # 6, 1 # 3, 1.1 # 1, 1.1 # 4, 1.2 # 2, 1.25 # 5, 
+  
+  Sorted by uncertain value using static member functor Meas::lessU2.
+  0.97 # 6, 1 # 3, 1.1 # 1, 1.1 # 4, 1.2 # 2, 1.25 # 5, 
+  
+  Sorted using functor lessAbsM.
+  0.97 # 6, 1 # 3, 1.1 # 1, 1.1 # 4, 1.2 # 2, 1.25 # 5, 
+  
+  
+  TestQuan1.cpp ended Wed Jan 18 12:44:01 2012
+  lessU 1 1.0125  >=  0.9675 0.980248 0.97 0.0127475 0.045
+  lessU 1 1.0125  >=  0.9675 0.980248 0.97 0.0127475 0.045
+  lessU 1.1 1.1125  >=  0.9675 0.980248 0.97 0.0127475 0.145
+  lessU 1.1 1.1125  >=  0.9875 1.00518 1 0.0176777 0.125
+  lessU 1.1 1.1005  >=  0.9675 0.97005 0.97 0.00254951 0.133
+  lessU 1.1 1.1005  >=  1.0875 1.10001 1.1 0.01251 0.013
+  lessU 1.2 1.2125  >=  0.9675 0.980248 0.97 0.0127475 0.245
+  lessU 1.2 1.2125  >=  1.0995 1.11201 1.1 0.01251 0.113
+  lessU 1.25 1.25125  >=  0.9675 0.970295 0.97 0.00279509 0.28375
+  lessU 1.25 1.25125  >=  1.1875 1.20006 1.2 0.0125623 0.06375
+  MU #2 1.2 1.2  >=  1.1 1.1 #1 1.1
+  MU #2 1.2 1.2  >=  1.1 1.1 #1 1.1
+  MU #3 1 1  <  1.1 1.1 #1 1.1
+  MU #1 1.1 1.1  >=  1 1 #3 1
+  MU #4 1.1 1.1  >=  1 1 #3 1
+  MU #4 1.1 1.1  <  1.2 1.2 #2 1.2
+  MU #2 1.2 1.2  >=  1.1 1.1 #4 1.1
+  MU #4 1.1 1.1  >=  1.1 1.1 #1 1.1
+  MU #5 1.25 1.25  >=  1 1 #3 1
+  MU #5 1.25 1.25  >=  1.2 1.2 #2 1.2
+  MU #6 0.97 0.97  <  1 1 #3 1
+  MU #3 1 1  >=  0.97 0.97 #6 0.97
+  U2 #3 1 1  >= 0.97 0.97 #6 0.97
+  U2 #3 1 1  >= 0.97 0.97 #6 0.97
+  U2 #1 1.1 1.1  >= 0.97 0.97 #6 0.97
+  U2 #1 1.1 1.1  >= 1 1 #3 1
+  U2 #4 1.1 1.1  >= 0.97 0.97 #6 0.97
+  U2 #4 1.1 1.1  >= 1.1 1.1 #1 1.1
+  U2 #2 1.2 1.2  >= 0.97 0.97 #6 0.97
+  U2 #2 1.2 1.2  >= 1.1 1.1 #4 1.1
+  U2 #5 1.25 1.25  >= 0.97 0.97 #6 0.97
+  U2 #5 1.25 1.25  >= 1.2 1.2 #2 1.2
+  
+  *** No errors detected
+========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
+
+
+
+*/
\ No newline at end of file
Added: sandbox/SOC/2007/quan/libs/quan/test/test_rounding.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/libs/quan/test/test_rounding.cpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,1432 @@
+/*!
+  \file
+  \brief Tests of Common rounding.
+  \details 
+    http://www.diycalculator.com/popup-m-round.shtml#A3
+    all rounding types, including round-to-half and asymmetric and symmetric versions.\n
+    http://www.chem1.com/acad/webtext/pre/mm3.html
+     "The purpose in rounding off is to avoid expressing a value to a greater degree of precision
+     than is consistent with the uncertainty in the measurement."\n
+     "Observed values should be rounded off to the number of digits
+     that most accurately conveys the uncertainty in the measurement."
+  \date Oct 09, May 12
+  \author Paul A. Bristow
+*/
+
+//   \file test_rounding_cout.hpp
+
+// Copyright Paul A. Bristow 2009, 2012.
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)  // Boost.Test
+  
+#define BOOST_TEST_MAIN
+// #define BOOST_LIB_DIAGNOSTIC "on" // Report Boost.Test library file details.
+
+#include <boost/static_assert.hpp>
+
+#include <boost/test/unit_test.hpp>
+  using boost::unit_test::test_suite;
+  using boost::unit_test::unit_test_log;
+
+using boost::unit_test_framework::unit_test_log;
+using boost::unit_test_framework::log_level;
+
+#include <boost/quan/rounding.hpp>
+
+#include <iostream>
+  using std::cout;
+  using std::cerr;
+  using std::cin;
+  using std::endl;
+  using std::ends;
+  using std::dec;
+  using std::hex;
+  using std::fixed;
+  using std::left;
+  using std::right;
+  using std::showpoint;
+  using std::defaultfloat;
+  using std::scientific;
+  using std::boolalpha;
+  using std::showpos;
+  using std::noshowpos;
+
+#include <iomanip>
+  using std::setprecision;
+  using std::setw;
+#include <string>
+  using std::string;
+
+#include <fstream>  // for fstream
+  using std::fstream;
+  using std::ofstream;
+
+#include <sstream> // stream
+  using std::ostringstream;
+  using std::string;
+  using std::basic_string;
+  using std::ios_base;
+
+#include <limits>
+  using std::numeric_limits;
+
+BOOST_STATIC_ASSERT (std::numeric_limits<double>::is_iec559); // Assume IEEE 754 ONLY.
+// _STATIC_ASSERT (numeric_limits<double>::is_iec559); // and MS STATIC assert.
+
+ // const unsigned int maxdigits10 = 2 + std::numeric_limits<double>::digits * 3010/10000;
+  const double eps = std::numeric_limits<double>::epsilon();
+  const int digits10 = std::numeric_limits<double>::digits10;
+
+  const double tol = 0.001; // Fractional tolerance for  BOOST_CHECK_CLOSE_FRACTION.
+
+BOOST_AUTO_TEST_CASE(round_test_0)
+{ 
+  //BOOST_CHECK_EQUAL(round_ms(12345, 1), "12345."); // 3 significant digits, so rounder digit is '8', and m is +1
+}
+
+BOOST_AUTO_TEST_CASE(round_test_1)
+{ // Round to cout tests.
+
+  string message("Round test: " __FILE__ );
+#ifdef __TIMESTAMP__
+  message += " at " BOOST_STRINGIZE(__TIMESTAMP__);
+#endif
+#ifdef _MSC_FULL_VER
+  message +=  ", MSVC version " BOOST_STRINGIZE(_MSC_FULL_VER) ".";
+#else
+  message += "."
+#endif
+
+  BOOST_MESSAGE(message);
+  BOOST_MESSAGE("double maxdigits10 is " << maxdigits10);
+    cout << "std::numeric_limits<double>::max_exponent = " << std::numeric_limits<double>::max_exponent 
+    << ", \nstd::numeric_limits<double>::max_exponent10 = " << std::numeric_limits<double>::max_exponent10 
+    << ",\nstd::numeric_limits<double>::max_exponent10 -1 = "<< std::numeric_limits<double>::max_exponent10 -1 << ". " << endl;
+    //  std::numeric_limits<double>::max_exponent = 1024, 
+    //  std::numeric_limits<double>::max_exponent10 = 308,
+    //  std::numeric_limits<double>::max_exponent10 -1 = 307. 
+#ifdef _MSC_VER
+    BOOST_CHECK_EQUAL(maxdigits10, 17U);
+#endif
+
+  // Experiments to see if a special meaning can be assigned to BOTH fixed and scientific.
+  // BUT the std::hex display option added with TR1
+  // means CANNOT use this mechanism.
+  // #define _IOShexfloat	0x3000	// added with TR1.
+  // Last top Bit 15 also appears used, so MUST use uncflags for controlling scaling etc.
+
+  //std::ios_base::fmtflags fs = cout.flags();
+  //cout << hex << "cout.flags() " << (cout.flags() & std::ios_base::floatfield) << endl;
+  //cout << "std::ios::fixed "<< std::ios::fixed  << fixed << endl;
+  //cout << hex << "cout.flags() " << (cout.flags() & std::ios_base::floatfield) << endl;
+  //cout << "std::ios::scientific "<< std::ios::scientific << scientific << endl;
+  //cout << hex << "cout.flags() " << (cout.flags() & std::ios_base::floatfield) << endl;
+ 
+  //cout.setf(std::ios::fixed | std::ios::scientific, std::ios_base::floatfield);
+  //cout.setf(std::ios::fixed | std::ios::scientific);
+  //cout << hex << "cout.flags() = " << (cout.flags() & std::ios_base::floatfield) << endl;
+  // so need a extra 'special' manipulator to set BOTH scientific AND fixed.
+} //  BOOST_AUTO_TEST_CASE(round_test_1)
+
+
+
+BOOST_AUTO_TEST_CASE(round_f_test)
+{
+  // Removed as assume can do scaling with Boost,Units autoscaling.
+  //{ // Test unc scaling to scientific and engineering powers.
+  //    scaled = true;
+  //    BOOST_CHECK_EQUAL(round_f(123.4567, 3), "123."); // No trailing space.
+  //    BOOST_CHECK_EQUAL(round_f(1234.567, 3), "1.23 k");
+  //    BOOST_CHECK_EQUAL(round_f(12345678.9, 3), "12.3 M");
+  //    BOOST_CHECK_EQUAL(round_f(123456789., 4), "123.5 M");
+  //    BOOST_CHECK_EQUAL(round_f(1234567890., 6), "1.23457 G");
+  //    scaled = false;
+  //}
+  { // Test round_f.
+    // round_f is fixed format.
+    double v = 1.23456; // Value to test rounded output.
+    BOOST_CHECK_EQUAL(round_f(v, 0), ""); // With message "Trying to output zero significant digits!".
+    BOOST_CHECK_EQUAL(round_f(v, -1), ""); // With message "Trying to output -1 significant digits!".
+    BOOST_CHECK_EQUAL(round_f(v, 1), "1."); // 
+    BOOST_CHECK_EQUAL(round_f(v, 2), "1.2"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 3), "1.23"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 4), "1.235"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 5), "1.2346"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 6), "1.23456"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 7), "1.234560"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 8), "1.2345600"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 9), "1.23456000"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 10), "1.234560000"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 11), "1.2345600000"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 12), "1.23456000000"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 13), "1.234560000000"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 14), "1.2345600000000"); // Maximum significant digits -1
+    BOOST_CHECK_EQUAL(round_f(v, 15), "1.23456000000000"); // 
+    // Message is  "Maximum significant digits is 15" - and several repeats.
+    BOOST_CHECK_EQUAL(round_f(v, 16), "1.23456000000000"); //  Maximum significant digits is 15
+    BOOST_CHECK_EQUAL(round_f(v, 17), "1.23456000000000"); // Maximum significant digits is 15
+    BOOST_CHECK_EQUAL(round_f(v, std::numeric_limits<double>::digits10), "1.23456000000000"); // 
+    BOOST_CHECK_EQUAL(round_f(v, maxdigits10), "1.23456000000000"); // Maximum significant digits is 15 (should be std::numeric_limits<double>::maxdigits10).
+
+    v = 1.23456789012345678901234567890; // Check that all the digits are used, and rounded at digit 15
+    BOOST_CHECK_EQUAL(round_f(v, maxdigits10), "1.23456789012346"); // Maximum significant digits is 15 (should be std::numeric_limits<double>::maxdigits10).
+
+    v = 0.12345678901234567890; // Value < unity.
+    BOOST_CHECK_EQUAL(round_f(v, 1), "0.1"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 2), "0.12"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 3), "0.123"); // 
+    BOOST_CHECK_EQUAL(round_f(v, digits10-10), "0.12346"); // 5
+    BOOST_CHECK_EQUAL(round_f(v, 13), "0.1234567890123"); // 13
+    BOOST_CHECK_EQUAL(round_f(v, digits10 -2), "0.1234567890123"); // 13
+    BOOST_CHECK_EQUAL(round_f(v, 14), "0.12345678901235"); // 14
+    BOOST_CHECK_EQUAL(round_f(v, digits10 -1), "0.12345678901235"); // 14
+    BOOST_CHECK_EQUAL(round_f(v, maxdigits10), "0.123456789012346"); // Maximum significant digits is 15 (should be std::numeric_limits<double>::maxdigits10).
+  
+    v = 0.0012345678901234567890; // Value much less than unity.
+    BOOST_CHECK_EQUAL(round_f(v, 1), "0.001"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 2), "0.0012"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 3), "0.00123"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 4), "0.001235"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 10), "0.001234567890"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 11), "0.0012345678901"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 12), "0.00123456789012"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 13), "0.001234567890123"); // 
+    BOOST_CHECK_EQUAL(round_f(v, 14), "0.0012345678901235"); // 
+    BOOST_CHECK_EQUAL(round_f(v, digits10), "0.00123456789012346"); // 
+    BOOST_CHECK_EQUAL(round_f(v, maxdigits10), "0.00123456789012346"); // 
+
+    v = 12345678901234567890.0; // Value > max_digits10 digits.
+    BOOST_CHECK_EQUAL(round_f(v, 4),           "12350000000000000000.");
+    BOOST_CHECK_EQUAL(round_f(v, 10),          "12345678900000000000.");
+    BOOST_CHECK_EQUAL(round_f(v, maxdigits10), "12345678901234600000."); 
+
+    v = 0.0000000012345678901234567890; // Value < max_digits10 digits.
+    BOOST_CHECK_EQUAL(round_f(v, 4), "0.000000001235"); // 
+
+    // Value max and min.
+    v = (std::numeric_limits<double>::max)(); // 1.797693134862316e+308
+    BOOST_CHECK_EQUAL(round_f(v, 4), "179800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000."); // 
+    v = (std::numeric_limits<double>::min)();// 2.2250738585072014e-308
+    BOOST_CHECK_EQUAL(round_f(v, 4), "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002225"); // 
+  }
+} //BOOST_AUTO_TEST_CASE(round_f_test)
+
+
+BOOST_AUTO_TEST_CASE(round_e_test)  // Test round_e.
+{ // round_e is scientific or exponential format.
+  {
+    double d = 1.1234012340123401234; // No carry examples.
+
+    BOOST_CHECK_EQUAL(round_e(d, 1), "1.");
+    BOOST_CHECK_EQUAL(round_e(d, 2), "1.1");
+    BOOST_CHECK_EQUAL(round_e(d, 3), "1.12"); 
+    BOOST_CHECK_EQUAL(round_e(d, 4), "1.123"); // 4 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 5), "1.1234"); // 5 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 6), "1.12340"); //6 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, digits10-1), "1.1234012340123"); // 14 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, digits10),   "1.12340123401234"); // 15 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, maxdigits10), "1.12340123401234"); // 15 sigdigits, because reached digits10.
+    BOOST_CHECK_EQUAL(round_e(d, maxdigits10+1), "1.12340123401234");  // 15 sigdigits, because reached digits10.
+    BOOST_CHECK_EQUAL(round_e(d, maxdigits10+2), "1.12340123401234");  // 15 sigdigits, because reached digits10.
+  }
+
+  {
+    double d = 1.12345678901234567890; // 
+
+  //cout << "round_e(d, 1); " << round_e(d, 1);  // 1.
+  //cout << "round_e(d, 2); " << round_e(d, 2); // 1.1
+  //cout << "round_e(d, 3); " << round_e(d, 3); // 1.12
+  //cout << "round_e(d, 4); "<< round_e(d, 4); // 1.123
+  //cout << "round_e(d, 5); "<< round_e(d, 5); // 1.1234
+  //cout << "round_e(d, 6); "<< round_e(d, 6); // 1.12340
+  //cout << "round_e(d, digits10); "<< round_e(d, digits10); // 
+  //cout << "round_e(d, digits10); "<< round_e(d, maxdigits10); //
+
+  BOOST_CHECK_EQUAL(round_e(d, 1), "1."); // 1 digits.
+  BOOST_CHECK_EQUAL(round_e(d, 2), "1.1"); // 2 digits.
+  BOOST_CHECK_EQUAL(round_e(d, 3), "1.12"); // 3 digits.
+  BOOST_CHECK_EQUAL(round_e(d, 4), "1.123"); // 4 digits.
+  BOOST_CHECK_EQUAL(round_e(d, 5), "1.1235"); // 5 digits.
+  BOOST_CHECK_EQUAL(round_e(d, 6), "1.12346"); // 6 digits.
+
+  BOOST_CHECK_EQUAL(round_e(d, 11), "1.1234567890"); // 11 digits.
+  BOOST_CHECK_EQUAL(round_e(d, 12), "1.12345678901"); // 12 digits.
+  BOOST_CHECK_EQUAL(round_e(d, 13), "1.123456789012"); // 13 digits.
+  BOOST_CHECK_EQUAL(round_e(d, 14), "1.1234567890123"); // 14 digits.
+  BOOST_CHECK_EQUAL(round_e(d, 15), "1.12345678901235"); // 15 digits.
+  BOOST_CHECK_EQUAL(round_e(d, 16), "1.12345678901235"); // 15 digits, because reached digits10.
+  BOOST_CHECK_EQUAL(round_e(d, 17), "1.12345678901235");  // 15 digits, because reached digits10.
+  BOOST_CHECK_EQUAL(round_e(d, 18), "1.12345678901235");  // 15 digits, because reached digits10.
+  }
+  {
+    double d = 0.99999999999999999; // Round to before decimal point.
+    // cout << setprecision(4) << showpoint << d << endl; // 1.000
+    BOOST_CHECK_EQUAL(round_e(d, 1), "1."); // 1 digit.
+    BOOST_CHECK_EQUAL(round_e(d, 2), "1.0"); // 2 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 3), "1.00"); // 3 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 4), "1.000"); // 4 digits.
+    // ... 
+    BOOST_CHECK_EQUAL(round_e(d, 15), "1.00000000000000"); // 15 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 16), "1.00000000000000"); // 15 digits, because reached digits10.
+    BOOST_CHECK_EQUAL(round_e(d, 17), "1.00000000000000");  // 15 digits, because reached digits10.
+    BOOST_CHECK_EQUAL(round_e(d, 18), "1.00000000000000");  // 15 digits, because reached digits10.
+  }
+
+  {
+    double d = 19.999999999999999; // Actually 2.00000000000000
+    BOOST_CHECK_EQUAL(round_e(d, 1), "2.e1"); // 1 digit.
+    BOOST_CHECK_EQUAL(round_e(d, 2), "2.0e1"); // 2 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 3), "2.00e1"); // 3 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 4), "2.000e1"); // 4 digits.
+    //... 
+    BOOST_CHECK_EQUAL(round_e(d, 15), "2.00000000000000e1"); // 15 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 16), "2.00000000000000e1"); // 15 digits, because reached digits10.
+    BOOST_CHECK_EQUAL(round_e(d, 17), "2.00000000000000e1");  // 15 digits, because reached digits10.
+    BOOST_CHECK_EQUAL(round_e(d, 18), "2.00000000000000e1");  // 15 digits, because reached digits10.
+  }
+  { 
+    double d = 19.99; // Roundable.
+    BOOST_CHECK_EQUAL(round_e(d, 1), "2.e1"); // 1 digit.
+    BOOST_CHECK_EQUAL(round_e(d, 2), "2.0e1"); // 2 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 3), "2.00e1"); // 3 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 4), "1.999e1"); // 4 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 5), "1.9990e1"); // 5 digits, last is trailing significant zero.
+    //... 
+    BOOST_CHECK_EQUAL(round_e(d, 15), "1.99900000000000e1"); // 15 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 16), "1.99900000000000e1"); // 15 digits, because reached digits10.
+    BOOST_CHECK_EQUAL(round_e(d, 17), "1.99900000000000e1");  // 15 digits, because reached digits10.
+    BOOST_CHECK_EQUAL(round_e(d, 18), "1.99900000000000e1");  // 15 digits, because reached digits10.
+  }
+    { // Positive exponent.
+    double d = 9.9e+2; // 990
+    //cout << setprecision(1) << fixed << d << endl; //  990.0
+    //cout << setprecision(1) << scientific << d << endl; // 9.9e+002
+    //cout << setprecision(0) << scientific << d << endl; // 9.9e+002
+    BOOST_CHECK_EQUAL(round_e(d, 1), "1.e3"); // 1 digit, rounded.
+    BOOST_CHECK_EQUAL(round_e(d, 2), "9.9e2"); // 2 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 3), "9.90e2"); // 3 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 4), "9.900e2"); // 4 digits.
+  }
+
+  { // Big positive exponent.
+    double d = 9.9e+20; // 990
+    //cout << setprecision(1) << fixed << d << endl; //  990000000000000000000.0
+    //cout << setprecision(1) << scientific << d << endl; // 9.9e+020
+    //cout << setprecision(0) << scientific << d << endl; // 9.9e+020
+    BOOST_CHECK_EQUAL(round_e(d, 1), "1.e21"); // 1 digit, rounded.
+    BOOST_CHECK_EQUAL(round_e(d, 2), "9.9e20"); // 2 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 3), "9.90e20"); // 3 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 4), "9.900e20"); // 4 digits.
+  }
+
+    { // Very big positive exponent.
+    double d = 9.9e+123; // 
+    //cout << setprecision(1) << fixed << d << endl; //  990000000000000000000.0
+    //cout << setprecision(1) << scientific << d << endl; // 9.9e+020
+    //cout << setprecision(0) << scientific << d << endl; // 9.9e+020
+    BOOST_CHECK_EQUAL(round_e(d, 1), "1.e124"); // 1 digit, rounded.
+    BOOST_CHECK_EQUAL(round_e(d, 2), "9.9e123"); // 2 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 3), "9.90e123"); // 3 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 4), "9.900e123"); // 4 digits.
+  }
+
+  { // Negative exponent.
+    double d = 9.9e-2;
+    //cout << setprecision(1) << fixed << d << endl; // 0.1
+    //cout << setprecision(1) << scientific << d << endl; // 9.9e-002
+    BOOST_CHECK_EQUAL(round_e(d, 1), "1.e-1"); // 1 digit, rounded.
+    BOOST_CHECK_EQUAL(round_e(d, 2), "9.9e-2"); // 2 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 3), "9.90e-2"); // 3 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 4), "9.900e-2"); // 4 digits.
+  }
+
+  { // Big negative exponent.
+    double d = 9.9e-20;
+    //cout << setprecision(1) << fixed << d << endl; // 0.1
+    //cout << setprecision(1) << scientific << d << endl; // 9.9e-002
+    BOOST_CHECK_EQUAL(round_e(d, 1), "1.e-19"); // 1 digit, rounded.
+    BOOST_CHECK_EQUAL(round_e(d, 2), "9.9e-20"); // 2 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 3), "9.90e-20"); // 3 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 4), "9.900e-20"); // 4 digits.
+  }
+  { // Very big negative exponent.
+    double d = 9.9e-234;
+    //cout << setprecision(1) << fixed << d << endl; // 0.1
+    //cout << setprecision(1) << scientific << d << endl; // 9.9e-002
+    BOOST_CHECK_EQUAL(round_e(d, 1), "1.e-233"); // 1 digit, rounded.
+    BOOST_CHECK_EQUAL(round_e(d, 2), "9.9e-234"); // 2 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 3), "9.90e-234"); // 3 digits.
+    BOOST_CHECK_EQUAL(round_e(d, 4), "9.900e-234"); // 4 digits.
+  }
+  { // Negative values.
+    double d = -1.;
+    BOOST_CHECK_EQUAL(round_e(d, 1), "-1."); // 1 digit, not rounded.
+    BOOST_CHECK_EQUAL(round_e(d, 2), "-1.0"); // 2 digit, not rounded.
+    BOOST_CHECK_EQUAL(round_e(d, 3), "-1.00"); // 2 digit, not rounded.
+  }
+
+  { // Problematic rounding.
+    // 1.5 is stored as 1.49999999999999, but should round up to 1.5, not down to 1.4.
+    double d = 1.5;
+    BOOST_CHECK_EQUAL(round_e(d, 1), "2."); // 1 digit, not rounded.
+    BOOST_CHECK_EQUAL(round_e(d, 2), "1.5"); // 2 digit, not rounded.
+    BOOST_CHECK_EQUAL(round_e(d, 3), "1.50"); // 2 digit, not rounded.
+  }
+
+  { // Misc
+    double d = 1.2945678901234567890e6;
+    BOOST_CHECK_EQUAL(round_e(d, 1), "1.e6");
+    BOOST_CHECK_EQUAL(round_e(d, 2), "1.3e6");
+    BOOST_CHECK_EQUAL(round_e(d, 3), "1.29e6");
+    BOOST_CHECK_EQUAL(round_e(d, 4), "1.295e6"); 
+    BOOST_CHECK_EQUAL(round_e(d, 11), "1.2945678901e6"); // 11 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 12), "1.29456789012e6"); // 12 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 13), "1.294567890123e6"); // 13 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 14), "1.2945678901235e6"); // 14 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 15), "1.29456789012346e6"); // 15 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 16), "1.29456789012346e6"); // 15 sigdigits, because reached digits10.
+    BOOST_CHECK_EQUAL(round_e(d, 17), "1.29456789012346e6");  // 15 sigdigits, because reached digits10.
+    BOOST_CHECK_EQUAL(round_e(d, 18), "1.29456789012346e6");  // 15 sigdigits, because reached digits10.
+
+    d = 987.654; // 9.87654e2
+
+    BOOST_CHECK_EQUAL(round_e(d, 1), "1.e3");
+    BOOST_CHECK_EQUAL(round_e(d, 2), "9.9e2");
+    BOOST_CHECK_EQUAL(round_e(d, 3), "9.88e2");
+    BOOST_CHECK_EQUAL(round_e(d, 4), "9.877e2"); 
+    BOOST_CHECK_EQUAL(round_e(d, 5), "9.8765e2"); 
+    BOOST_CHECK_EQUAL(round_e(d, 6), "9.87654e2"); 
+    BOOST_CHECK_EQUAL(round_e(d, 7), "9.876540e2"); // 11 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 11), "9.8765400000e2"); // 11 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 12), "9.87654000000e2"); // 12 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 13), "9.876540000000e2"); // 13 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 14), "9.8765400000000e2"); // 14 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 15), "9.87654000000000e2"); // 15 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 16), "9.87654000000000e2"); // 15 sigdigits, because reached digits10.
+    BOOST_CHECK_EQUAL(round_e(d, 17), "9.87654000000000e2");  // 15 sigdigits, because reached digits10.
+    BOOST_CHECK_EQUAL(round_e(d, 18), "9.87654000000000e2");  // 15 sigdigits, because reached digits10.
+
+
+     d = 0.0987654; // 9.87654e-2
+
+    BOOST_CHECK_EQUAL(round_e(d, 1), "1.e-1");
+    BOOST_CHECK_EQUAL(round_e(d, 2), "9.9e-2");
+    BOOST_CHECK_EQUAL(round_e(d, 3), "9.88e-2");
+    BOOST_CHECK_EQUAL(round_e(d, 4), "9.877e-2"); 
+    BOOST_CHECK_EQUAL(round_e(d, 5), "9.8765e-2"); 
+    BOOST_CHECK_EQUAL(round_e(d, 6), "9.87654e-2"); 
+    BOOST_CHECK_EQUAL(round_e(d, 7), "9.876540e-2"); // 7 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 11), "9.8765400000e-2"); // 11 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 12), "9.87654000000e-2"); // 12 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 13), "9.876540000000e-2"); // 13 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 14), "9.8765400000000e-2"); // 14 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 15), "9.87654000000000e-2"); // 15 sigdigits.
+    BOOST_CHECK_EQUAL(round_e(d, 16), "9.87654000000000e-2"); // 15 sigdigits, because reached digits10.
+    BOOST_CHECK_EQUAL(round_e(d, 17), "9.87654000000000e-2");  // 15 sigdigits, because reached digits10.
+    BOOST_CHECK_EQUAL(round_e(d, 18), "9.87654000000000e-2");  // 15 sigdigits, because reached digits10.
+  }
+
+  { // Non-finites.
+    double d = std::numeric_limits<double>::quiet_NaN();
+    BOOST_CHECK_EQUAL(round_e(d, 1), "NaN");
+    BOOST_CHECK_EQUAL(round_e(-d, 1), "-NaN");
+
+    d = std::numeric_limits<double>::infinity();
+    BOOST_CHECK_EQUAL(round_e(d, 1), "Inf");
+    BOOST_CHECK_EQUAL(round_e(-d, 1), "-Inf");
+  }
+} // BOOST_AUTO_TEST_CASE(round_e_test) 
+
+BOOST_AUTO_TEST_CASE(cdf_quantile_test)
+  { // Test the calculation of CDF and quantiles for triangular and uniform distributions.
+    static const double sqrt_6 = 2.4494897427831780981972840747058913919659474804966; // sqrt(6)
+
+    boost::math::triangular tdist(-sqrt_6, 0., +sqrt_6); // Wimmer page 23, below eq 6.
+    double alpha = 0.005;
+    double qlo = quantile(complement(tdist, alpha));
+    double qhi = quantile(tdist, alpha);
+    //cout << "quantile(complement(tdist, alpha));  " << qlo << ", quantile(tdist, alpha) " << qhi << endl;
+    //  quantile(complement(tdist, alpha));  2.20454, quantile(tdist, alpha) -2.20454
+    //cout << "cdf( quantile(complement(tdist, alpha)) = "<< cdf_tri(qlo) << ", cdf(quantile(tdist, alpha) = " << cdf_tri(qhi) << endl;
+    //   cdf( quantile(complement(tdist, alpha)) = 0.995, cdf(quantile(tdist, alpha) = 0.005
+    BOOST_CHECK_CLOSE_FRACTION(cdf_tri(qhi), alpha, 0.001); 
+    BOOST_CHECK_CLOSE_FRACTION(cdf_tri(qlo), 1. - alpha, 0.001); 
+
+    double q01l = quantile_tri(1. - alpha);
+    double q01h = quantile_tri(alpha);
+
+    //cout << "quantile_tri(1. - alpha) " << q01l << ", quantile_tri(alpha); " << q01h << endl;
+    //   quantile_tri(1. - alpha) 2.20454, quantile_tri(alpha); -2.20454
+
+    double c01h = cdf_tri(q01h);
+    BOOST_CHECK_CLOSE_FRACTION(c01h, alpha, 0.02); // Fails with 0.01, OK with 0.02
+    // difference{0.292893} between c01h{0.0070710678118655057} and alpha{0.01} exceeds 0.01
+
+    double c01l = cdf_tri(q01l);
+    BOOST_CHECK_CLOSE_FRACTION(c01l, 1. - alpha, 0.005);  // OK at 0.005
+    //cout << "cdf_tri(quantile_tri(alpha)) " << c01l << ",cdf_tri(quantile_tri(1. - alpha)) " << c01h << endl;
+    //  cdf_tri(quantile_tri(alpha)) 0.995,cdf_tri(quantile_tri(1. - alpha)) 0.005
+    BOOST_CHECK_EQUAL(cdf_tri(-3.), 0); // check > sqrt_6 limits.
+    BOOST_CHECK_EQUAL(cdf_tri(+3.), 1.);
+
+    boost::math::uniform udist(-sqrt_3, +sqrt_3); // Wimmer page 3, below eq 5.
+  // Loop back tests.
+  //cout << "loopback boost::math cdf(z) "<< endl;
+    for (double d = -2.4; d < +2.4; d += 0.2)
+    {
+     // cout << d << ' '<< cdf(tdist, d) << ' ' << quantile(tdist, cdf(tdist, d)) << ' '<< d - quantile(tdist, cdf(tdist, d)) << endl;
+      //BOOST_CHECK_CLOSE_FRACTION(d, quantile(tdist, cdf(tdist, d)), 0.01); fails for d near zero
+      BOOST_CHECK_SMALL(d - quantile(tdist, cdf(tdist, d)), 100 * eps);
+    }
+
+    //cout << "loopback boost::math quantile(alpha))" << endl;
+    for (double a = 0.; a <= 1.; a += 0.1)
+    {
+      //cout << a << ' ' << quantile(tdist, a) << ' ' << cdf(tdist, quantile(tdist, a)) << ' ' << a - cdf(tdist, quantile(tdist, a)) << endl;
+      BOOST_CHECK_CLOSE_FRACTION(a, cdf(tdist, quantile(tdist, a)), 0.01);
+    }
+
+    //cout << "loopback triangular cdf(z)" << endl;
+    for (double d = -2.4; d < +2.4; d += 0.2)
+    {
+      //cout << d << ' '<< cdf_tri(d) << ' ' << quantile_tri(cdf_tri(tdist, d)) << ' '<< d - quantile_tri(cdf_tri(tdist, d)) << endl;
+      //BOOST_CHECK_CLOSE_FRACTION(d, quantile_tri(cdf(tdist, d)), 0.01); // fails d near zero
+      BOOST_CHECK_SMALL(d - quantile_tri(cdf(tdist, d)), 100 * eps);
+    }
+
+    //cout << "loopback triangular quantile" << endl;
+    for (double a = 0.; a <= 1.; a += 0.1)
+    {
+      //cout << a << ' ' << quantile_tri(a) << ' ' << cdf_tri(quantile_tri(a)) << ' ' << a - cdf_tri(quantile_tri(a)) << endl;
+      BOOST_CHECK_CLOSE_FRACTION(a, cdf_tri(quantile_tri(a)), 0.01);
+    }
+    //cout << "loopback uniform quantile" << endl;
+    for (double a = 0.; a <= 1.; a += 0.1)
+    {
+      //cout << a << ' ' << quantile_uni(a) << ' ' << cdf_uni(quantile_uni(a)) << ' ' << a - cdf_uni(quantile_uni(a)) << endl;
+      BOOST_CHECK_CLOSE_FRACTION(a, cdf_uni(quantile_uni(a)), 0.01);
+    }
+    //cout << "loopback uniform cdf_uni(z)" << endl;
+    for (double d = -sqrt_3; d < +sqrt_3; d += 0.2)
+    {
+      //cout << d << ' '<< cdf(d) << ' ' << quantile_tri(cdf(tdist, d)) << ' '<< d - quantile_tri(cdf(tdist, d)) << endl;
+      //BOOST_CHECK_CLOSE_FRACTION(d, quantile_tri(cdf(tdist, d)), 0.01); // fails d near zero
+      BOOST_CHECK_SMALL(d - quantile_uni(cdf(udist, d)), 100 * eps);
+    }    
+    //  Compare Wimmer and Boost::math uniform cdf
+    for (double d = -sqrt_3; d < +sqrt_3; d += 0.2)
+    {
+      BOOST_CHECK_SMALL((cdf_uni(d) - cdf(udist, d)), 100 * eps);
+    }    
+    //  Compare Wimmer and Boost::math uniform quant
+    for (double a = 0.; a <= 1.; a += 0.1)
+    {
+      BOOST_CHECK_SMALL((quantile_uni(a) - quantile(udist, a)), 100 * eps);
+    }    
+  } // BOOST_AUTO_TEST_CASE(cdf_quantile_test)
+
+BOOST_AUTO_TEST_CASE(round_ms_test)
+{  // Test round_ms function.
+  //template<typename = FPT> std::string round_ms(FPT v, signed int m); // Round v to digit m.
+
+  double v = (std::numeric_limits<double>::max)();
+  BOOST_CHECK_EQUAL(round_ms(v, std::numeric_limits<double>::max_exponent10), "0."); // 1.797693134862316 and 308
+  BOOST_CHECK_EQUAL(round_ms(-v, std::numeric_limits<double>::max_exponent10), "0."); // -1.797693134862316 and 308
+  BOOST_CHECK_EQUAL(round_ms(v, std::numeric_limits<double>::max_exponent10 -1), "200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000."); // -1.797693134862316 and 307
+  BOOST_CHECK_EQUAL(round_ms(-v, std::numeric_limits<double>::max_exponent10 -1), "-200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000."); // -1.797693134862316 and 307
+
+  BOOST_CHECK_EQUAL(round_ms(v, 308), "0."); // 1.797693134862316 and 308
+  BOOST_CHECK_EQUAL(round_ms(-v, 308), "0."); // -1.797693134862316 and 308
+  BOOST_CHECK_EQUAL(round_ms(v, 307), "200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000."); // -1.797693134862316 and 308
+  BOOST_CHECK_EQUAL(round_ms(-v, 307), "-200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000."); // -1.797693134862316 and 308
+
+  v = (std::numeric_limits<double>::min)();
+  // cout <<setprecision (17) << v << endl; // 2.2250738585072014e-308 
+  BOOST_CHECK_EQUAL(round_ms(v, std::numeric_limits<double>::min_exponent10), "0."); //  2.22507385850720 and -308
+  BOOST_CHECK_EQUAL(round_ms(v, std::numeric_limits<double>::min_exponent10+1), "0."); //  2.22507385850720 and -307 ?? is 0. expected?
+  BOOST_CHECK_EQUAL(round_ms(v, std::numeric_limits<double>::min_exponent10+2), "0."); //  2.22507385850720 and -306 ?? is 0. expected?
+
+  // Zero (positive).
+  BOOST_CHECK_EQUAL(round_ms(0., 0), "0."); // 
+  BOOST_CHECK_EQUAL(round_ms(0., +1), "0."); // 
+  BOOST_CHECK_EQUAL(round_ms(0., -1), "0."); // 
+  BOOST_CHECK_EQUAL(round_ms(0., +2), "0."); // 
+  BOOST_CHECK_EQUAL(round_ms(0., -2), "0.0"); // 
+  BOOST_CHECK_EQUAL(round_ms(0., -3), "0.00"); // 
+  // Zero (negative).
+  BOOST_CHECK_EQUAL(round_ms(-0., +2), "0."); // 
+  BOOST_CHECK_EQUAL(round_ms(-0., +1), "0."); // 
+  BOOST_CHECK_EQUAL(round_ms(-0., 0), "0."); // 
+  BOOST_CHECK_EQUAL(round_ms(-0., -1), "-0."); // 
+  BOOST_CHECK_EQUAL(round_ms(-0., -3), "-0.00"); // 
+  BOOST_CHECK_EQUAL(round_ms(-3278.35876, -3), "-3278.36"); // 
+
+  // Infinity plus and minus.
+  BOOST_CHECK_EQUAL(round_ms(+std::numeric_limits<double>::infinity(), +2), "inf");
+  BOOST_CHECK_EQUAL(round_ms(-std::numeric_limits<double>::infinity(), +1), "-inf");
+  // NaN, note sign bit of NaN is recognized.
+  BOOST_CHECK_EQUAL(round_ms(+std::numeric_limits<double>::quiet_NaN(), +2), "NaN");
+  BOOST_CHECK_EQUAL(round_ms(-std::numeric_limits<double>::quiet_NaN(), +1), "-NaN");
+
+  BOOST_CHECK_EQUAL(round_ms(123.45678901234567890, -2),"123.5") ; //
+  // Wimmer example 2 page 1660
+  BOOST_CHECK_EQUAL(round_ms(3278.35876, -3), "3278.36"); // 
+  BOOST_CHECK_EQUAL(round_ms(159.21, +1), "200."); //
+  BOOST_CHECK_EQUAL(round_ms(1121.85, +3), "0."); //
+  // Some more examples.
+  BOOST_CHECK_EQUAL(round_ms(1111.1111, +3), "0."); //
+  BOOST_CHECK_EQUAL(round_ms(1111.1111, +2), "1000."); //
+  BOOST_CHECK_EQUAL(round_ms(1111.1111, +1), "1100."); //
+  BOOST_CHECK_EQUAL(round_ms(1111.1111, +0), "1110."); //
+  BOOST_CHECK_EQUAL(round_ms(1111.1111, -1), "1111."); //
+  BOOST_CHECK_EQUAL(round_ms(1111.1111, -2), "1111.1"); //
+  BOOST_CHECK_EQUAL(round_ms(1111.1111, -3), "1111.11"); //
+
+  BOOST_CHECK_EQUAL(round_ms(9999.9999, +4), "0."); //
+  BOOST_CHECK_EQUAL(round_ms(9999.9999, +3), "0."); //
+  BOOST_CHECK_EQUAL(round_ms(9999.9999, +2), "10000."); //
+  BOOST_CHECK_EQUAL(round_ms(9999.9999, +1), "10000."); //
+  BOOST_CHECK_EQUAL(round_ms(9999.9999, +0), "10000."); //
+  BOOST_CHECK_EQUAL(round_ms(9999.9999, -1), "10000."); //
+  BOOST_CHECK_EQUAL(round_ms(9999.9999, -2), "10000.0"); //
+  BOOST_CHECK_EQUAL(round_ms(9999.9999, -3), "10000.00"); //
+  BOOST_CHECK_EQUAL(round_ms(9999.9999, -4), "10000.000"); //
+  BOOST_CHECK_EQUAL(round_ms(9999.9999, -5), "9999.9999"); //
+
+  BOOST_CHECK_EQUAL(round_ms(1703.12345679, -7), "1703.123457"); // David A. Pimentel 6 digits after decimal point example 2 (so m = -7).
+
+  BOOST_CHECK_EQUAL(round_ms(0.152, -3), "0.15");
+  BOOST_CHECK_EQUAL(round_ms(0.155, -3), "0.16");
+  BOOST_CHECK_EQUAL(round_ms(0.159, -3), "0.16");
+  // With option to use shorter form with no zero preceeding decimal point.
+  //BOOST_CHECK_EQUAL(round_ms(0.152, -3), ".15");
+  //BOOST_CHECK_EQUAL(round_ms(0.155, -3), ".16");
+  //BOOST_CHECK_EQUAL(round_ms(0.159, -3), ".16");
+
+  BOOST_CHECK_EQUAL(round_ms(0.159, 0), "0.");
+  BOOST_CHECK_EQUAL(round_ms(0.159, -1), "0.");
+  BOOST_CHECK_EQUAL(round_ms(0.159, -2), "0.2");
+  BOOST_CHECK_EQUAL(round_ms(0.159, -3), "0.16");
+  BOOST_CHECK_EQUAL(round_ms(0.159, -4), "0.159");
+
+  BOOST_CHECK_EQUAL(round_ms(0.01234567, -2), "0.");
+  BOOST_CHECK_EQUAL(round_ms(0.01234567, -3), "0.01");
+  BOOST_CHECK_EQUAL(round_ms(0.01234567, -4), "0.012");
+  BOOST_CHECK_EQUAL(round_ms(0.0001234567, -6), "0.00012");
+
+  // Examples from http://www.chem1.com/acad/webtext/pre/mm3.html
+  BOOST_CHECK_EQUAL(round_ms(34.216, -2), "34.2"); // 3 significant digits, so rounder digit is '1', and m is -2
+  BOOST_CHECK_EQUAL(round_ms(6.252, -2), "6.3"); // 2 significant digits, so rounder digit is '5', and m is -2
+  BOOST_CHECK_EQUAL(round_ms(39.99, -2), "40.0"); // 3 significant digits, so rounder digit is '9', and m is -2
+  BOOST_CHECK_EQUAL(round_ms(85381., 1), "85400."); // 3 significant digits, so rounder digit is '8', and m is +1
+  BOOST_CHECK_EQUAL(round_ms(0.04597, -5), "0.0460"); // 3 significant digits, so rounder digit is '7', and m is -5
+
+  BOOST_CHECK_EQUAL(round_ms(1.23, -2),"1.2"); // round to -1, so m = -2 round down, no carry
+  BOOST_CHECK_EQUAL(round_ms(1.25, -2),"1.3"); // round -1, so m = -2, round up no carry.
+  BOOST_CHECK_EQUAL(round_ms(1.95, -2),"2.0"); // round -1, so m = -2, round up, and carry.
+
+  // Some very large values.
+  BOOST_CHECK_EQUAL(round_ms(1.95e+6, +2),"1950000."); // 
+  BOOST_CHECK_EQUAL(round_ms(1.95e+9, +2),"1950000000."); // 
+  BOOST_CHECK_EQUAL(round_ms(1.95e+12, +2),"1950000000000."); // 
+  BOOST_CHECK_EQUAL(round_ms(1.95e+15, +2),"1950000000000000."); // 
+  BOOST_CHECK_EQUAL(round_ms(1.95e+18, +2),"1950000000000000000."); // 
+  BOOST_CHECK_EQUAL(round_ms(1.95e+24, +2),"1950000000000000000000000."); // 
+  // numeric_limits<double>::max() = 1.797693134862316 E 308
+  BOOST_CHECK_EQUAL(round_ms(numeric_limits<double>::max(), 305),"180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000."); // 
+  BOOST_CHECK_EQUAL(round_ms(numeric_limits<double>::min(), -307),"0."); 
+
+  // Some small values.
+  BOOST_CHECK_EQUAL(round_ms(1.95e-6, -8),"0.0000020");
+  BOOST_CHECK_EQUAL(round_ms(-1.95e-6, -8),"-0.0000020");
+  BOOST_CHECK_EQUAL(round_ms(-1.95e-12, -14),"-0.0000000000020");
+} // BOOST_AUTO_TEST_CASE(round_ms_test)
+
+BOOST_AUTO_TEST_CASE(Wimmer_3)
+{ // Test by comparion with Wimmer example 3, page 1660.
+  // Calculate confidence interval.
+  //std::pair<double, double> conf_interval(double value, double unc, double df, double alpha);
+  std::pair<double, double> p(97.8725, 157.7975);
+  // cout << p << endl; // <97.8725, 157.798>
+  p = conf_interval(127.835, 15.287);  // Default to 1 degree of freedom, alpha 0.05, 95% confidence & gaussian.
+  BOOST_CHECK_CLOSE_FRACTION(p.first, 97.8725, tol);
+  BOOST_CHECK_CLOSE_FRACTION(p.second, 157.798, tol); // 
+  // 2nd example for 99%, alpha = 0.01:
+  p = conf_interval(127.835, 15.287, 1.,  0.01);  // 99% confidence.
+  BOOST_CHECK_CLOSE_FRACTION(p.first, 88.4583, tol);
+  BOOST_CHECK_CLOSE_FRACTION(p.second, 167.2117, tol); // 
+  // End Test by comparion with Wimmer example 3, page 1660.
+} // BOOST_AUTO_TEST_CASE(Wimmer_3)
+
+BOOST_AUTO_TEST_CASE(Wimmer_4)
+{ // Wimmer example 4  - more than one measurement.
+  // std::pair<double, double> conf_interval(double mean, double unc, double df = 1., double alpha = 0.05, distribution_type distrib = gaussian)
+  // Uncertainty 1.215349 given is now sigma/sqrt(N or df),
+  // so need to multiply by sqrt(2).
+  std::pair<double, double> p;
+  p = conf_interval(13.8049, 1.215349 * sqrt(2.), 2, 0.05, gaussian); // 95% confidence, and default gaussian.
+  BOOST_CHECK_CLOSE_FRACTION(p.first, 11.42281596, tol);
+  BOOST_CHECK_CLOSE_FRACTION(p.second, 16.18698404, tol);
+  p = conf_interval(13.8049, 1.215349 * sqrt(2.), 2);  // 95% confidence, and default gaussian.
+  BOOST_CHECK_CLOSE_FRACTION(p.first, 11.42281596, tol);
+  BOOST_CHECK_CLOSE_FRACTION(p.second, 16.18698404, tol);
+// Similarly for 
+  p = conf_interval(13.8049, 1.215349 * sqrt(2.), 2, 0.01);  // df =2, 99% confidence, and default gaussian.
+  BOOST_CHECK_CLOSE_FRACTION(p.first, 10.67416098, tol);
+  BOOST_CHECK_CLOSE_FRACTION(p.second, 16.93563902, tol); // 
+  // End Wimmer example 4
+} // BOOST_AUTO_TEST_CASE(Wimmer_4)
+
+BOOST_AUTO_TEST_CASE(Wimmer_5_1)
+{ // Wimmer example 5(i) e = 0.01
+  //int round_m(double epsilon, double unc, unsigned int sigdigits, distribution_type t);
+
+  // Mean is 127.835, and standard deviation sigma is 15.287.
+  double sigma = 15.287;
+  // Round sigma to 2 significant decimal digits.
+  double sigma_star = round_sig(sigma, 2); // 2 for ISO rule.
+  BOOST_CHECK_CLOSE_FRACTION(sigma_star, 15., tol); // Sigma rounded.
+
+  double epsilon = 0.01; // Allow 1% loss from rounding.
+  int m = round_m(epsilon, sigma, 2U, gaussian); // Calculate rounding digit, using sigma.
+  BOOST_CHECK_EQUAL(m, -1); // Rounding digit is 1st after decimal point, 0.d.
+  // Repeat using defaults.
+  m = round_m(epsilon, sigma); // Calculate rounding digit, using sigma.
+  BOOST_CHECK_EQUAL(m, -1); // Rounding digit is 1st after decimal point, 0.d.
+
+  double g = gamma(sigma_star, sigma);
+  BOOST_CHECK_CLOSE_FRACTION(g, 0.98123, tol); // Check gamma = 0.98123 given.
+
+  double d = delta(epsilon, g, gaussian); 
+  BOOST_CHECK_CLOSE_FRACTION(d, 0.0537, tol); // Wimmer only quotes 0.05.
+  d = 0.05 * sigma_star / (5 * g); // Round as Wimmer to 0.05
+  double md = log10(d);
+  BOOST_CHECK_CLOSE_FRACTION(md, -0.815, tol);
+  BOOST_CHECK_CLOSE_FRACTION(floor(md), -1, tol); // m = -1, so rounding digit is 0.d.
+  // Using full accuracy 0.0537 also gives m = -1 as calculated by round_m above.
+  
+  double x = 127.835; // Value to be rounded using m = -1.
+  BOOST_CHECK_EQUAL(round_ms(x, m),"128."); // Round mean to a string.
+  BOOST_CHECK_EQUAL(round_ms(x, round_m(0.01, 15.287, 2U, gaussian)),"128.");
+
+// void out_value_df_limits(double mean, double unc, int degfree = 1, std::ostream& os = cout)
+  ostringstream oss;
+  out_value_df_limits(127.835, 15.287, 1, oss);
+  // out_value_df_limits(123.835, 15.287); 128. +/- 15 <97.9, 157.8>
+  // cout << oss.str() << endl;
+  BOOST_CHECK_EQUAL(oss.str(), "128. +/- 15 <97.9, 157.8>");
+} // BOOST_AUTO_TEST_CASE(Wimmer_5_1)
+  
+ BOOST_AUTO_TEST_CASE(Wimmer_5_2) 
+ { // Wimmer example 5(ii)
+
+   double sigma = 0.0232;
+   double sigma_star = round_sig(sigma, 1); // Why only one significant digit for rounding?
+   BOOST_CHECK_CLOSE_FRACTION(sigma_star, 0.02, tol);
+
+   double g = gamma(sigma_star, sigma);
+   BOOST_CHECK_CLOSE_FRACTION(g, 0.86207, tol); // Check gamma =  0.86207 given.
+
+   // Wimmer says epsilon = 0.04 will fails from table 1.
+   // Epsilon 0.05 (95%) gamma_0.05 is 0.90175 which is > 0.86207,
+   // Epsilon 0.1 (90%) gamma_0.1 is 0.81271 which is < 0.86207 so OK.
+   double epsilon = 0.001; // Expect to fail if only use one digit for rounding sigma.
+   int m = round_m(epsilon, sigma); // Calculate rounding digit, using sigma.
+   BOOST_CHECK_EQUAL(m, -9999);
+   // Message: Cannot return a rounding m because epsilon 0.001 is too small!
+   epsilon = 0.1;  // Should be OK.
+   m = round_m(epsilon, sigma); // Calculate rounding digit, using sigma.
+   BOOST_CHECK_EQUAL(m, -3);
+
+   double x = 1.23875;  // Final part of example.
+   epsilon = 0.1;  // Should be OK.
+   string s = round_ms(x, m);
+   BOOST_CHECK_EQUAL(s, "1.24");
+   std::pair<double, double> ci =
+     conf_interval(x, sigma_star, 1., 0.05);
+   //cout << "conf_interval(x, sigma, 1., 0.05);" << ci << endl;
+   BOOST_CHECK_CLOSE_FRACTION(ci.first, 1.2008, tol * 2); // 1.1995
+   BOOST_CHECK_CLOSE_FRACTION(ci.second, 1.2792, tol); // 1.27795
+   // Not sure why this isn't exactly same as Wimmer.
+ }
+
+BOOST_AUTO_TEST_CASE(round_ue_test)
+{ // Test using round_ue 
+  // Round using value and uncertainty (and controlling sigdigits of uncertainty).
+  // std::string round_ue(double v, double unc, double epsilon = 0.01, unsigned int sigdigits = 2U)
+  BOOST_CHECK_EQUAL(round_ue(127.835, 15.287, 0.01, 2U),"128.");  // explicit 2 uncertain digits.
+  BOOST_CHECK_EQUAL(round_ue(127.835, 15.287, 0.01),"128."); // Default unc sigdigit (2)s.
+  BOOST_CHECK_EQUAL(round_ue(127.835, 15.287),"128."); // Default unc sigdigits and default epsilon.
+
+  // Wimmer example 5(i b) e = 0.04
+  BOOST_CHECK_EQUAL(round_ue(127.835, 15.287, 0.04),"130."); // Increase e to 0.04 to allow more rounding loss.
+  // Wimmer example 5(ii a) e = 0.05 fails.
+  //BOOST_CHECK_NE(round_ue(1.23875, 0.0232, 0.05, 1U),"1.24"); // Fails correctly with message:
+  // Epsilon 0.05 is too small for gamma rounded/unrounded ratio 0.862069
+  // Cannot return a rounding m because epsilon is too small!
+  // Wimmer example 5(ii b) e = 0.1
+  BOOST_CHECK_EQUAL(round_ue(1.23875, 0.0232, 0.1, 1U),"1.24"); // 
+
+  { // Wimmer example 6 - case (ii) known confidence interval estimate for sigma.
+
+    // P{lo_sigma < sigma < hi_sigma} = 1 - phi
+  
+    // So we know 0.98 confidence interval for unc (sigma) is <5.67, 5.82>.
+    // phi = 1- 0.98 = 0.02
+    // unc conf phi = 0.02, round conf eps = 0.05, combined eta = eps - phi = 0.05 - 0.02 = 0.03.
+    double nu = 0.03;
+
+    std::pair<double, double> u(5.67, 5.82); // Known sigma 0.98 confidence interval estimate.
+    // and gamma = 5.67/5.82 = 0.97423
+    //cout << "uncs ratio " << gamma(5.67, 5.82) << endl; //  uncs ratio 0.974227
+    BOOST_CHECK_CLOSE_FRACTION(gamma(5.67, 5.82), 0.97423, tol); // unc ratio.
+    // cout << "delta " << delta(nu, gamma(5.67, 5.82)) << endl; //  delta 0.261833
+    BOOST_CHECK_CLOSE_FRACTION(delta(nu, gamma(5.67, 5.82)), 0.26, tol*10); // delta = 0.26
+    // cout << log10(0.26 * 5.82 /5) << endl; // expect -0.519074
+    BOOST_CHECK_CLOSE_FRACTION(log10(0.26 * 5.82 / 5), -0.519, tol); 
+    // m < -0.519 so rounding x.
+    int m = static_cast<int>(floor(-0.519));
+    //cout << "floor(-0.519) " << m << endl; // floor(-0.519) -1
+    BOOST_CHECK_EQUAL(m, -1);
+    double x = 56.387; // Measured value.
+    BOOST_CHECK_EQUAL(round_ms(x, m), "56."); // Rounded measured value.
+    double x_star = 56.; // Rounded mean x.
+
+    double alpha = 0.05; // 95% confidence, for 0.05_proper (1-alpha) = 0.95 confidence interval.
+    using boost::math::normal;
+    normal dist; // Normal distribution with zero mean and unit standard deviation.
+    //double t1 = quantile(dist, alpha / 2);
+    //cout << t1 << endl; // = -1.95996 so can use 
+    double t = quantile(complement(dist, alpha /2 ));
+    // cout << t << endl; // 1.95996 for 0.05
+    BOOST_CHECK_CLOSE_FRACTION(t, 1.95996, tol);
+    // Wimmer rounds to t = 1.96; but tests pass OK with either value.
+
+    std::pair<double, double> p; // Confidence interval.
+    p.first = x_star - 5.67 * t; // lower.
+    p.second = x_star + 5.67 * t; // higher.
+    // cout << p << endl; //  <44.887, 67.113>
+    BOOST_CHECK_CLOSE_FRACTION(p.first, 44.8868, tol); // Wimmer values.
+    BOOST_CHECK_CLOSE_FRACTION(p.second, 67.1132, tol);
+    
+    // Wimmer second example using tighter alpha.
+    x_star = 56.; // Rounded mean.
+    alpha = 0.01; // 99% confidence for 0.05 proper 0.99 confidence interval estimate.
+    normal dist01; // Normal distribution with zero mean and unit standard deviation.
+    t = quantile(complement(dist01, alpha / 2));
+    // cout << t << endl; // 1.95996
+    // Confidence interval.
+    p.first = x_star - 5.67 * t;
+    p.second = x_star + 5.67 * t;
+    // cout << "Alpha 0.01 " << p << endl; //  Alpha 0.01 <41.395, 70.605>
+    BOOST_CHECK_CLOSE_FRACTION(p.first, 41.391, tol); 
+    BOOST_CHECK_CLOSE_FRACTION(p.second, 70.6059, tol); 
+    // Note this 0.995 confidence requirement means that the interval is wider.
+  }//End Wimmer example 6 - case (ii) known confidence interval estimate for sigma.
+    
+  { // Wimmer p 1662, example 7 - Repeated measurements with known variance.
+    using namespace boost::math;
+    int n = 10; // number of measurements is 10.
+    double x = 87.93911210729208; //  Mean of 10 measurements.
+    double variance = 0.5; // known variance sigma^2 is 0.5.
+    double sigma = sqrt(variance); // and known variance sigma^2 is 0.5.
+    double sigma_star = sigma / sqrt(static_cast<double>(n)); // Why divide by sqrt(10)?
+    BOOST_CHECK_CLOSE_FRACTION(sigma_star, 0.223606797, tol/10.); 
+    double sigma_rounded = round_sig(sigma_star, 1); // Round to 1 sig digit to get 0.2.
+    // cout << "unc_rounded " << unc_rounded << endl; // unc_rounded 0.2
+    BOOST_CHECK_CLOSE_FRACTION(sigma_rounded, 0.2, tol); // 
+    BOOST_CHECK_EQUAL(sigma_rounded, 0.2); // unc 0.1 properly rounded.
+    ostringstream oss;
+    oss << setprecision(3) << sigma_rounded; // expect 0.2 whatever precision (< digits10)
+    BOOST_CHECK_EQUAL(oss.str(), "0.2"); // sigma 0.1_properly rounded.
+
+    double gam = sigma_rounded / sigma_star; // 0.2 / 0.223606797 = 0.89442
+    BOOST_CHECK_CLOSE_FRACTION(gam, 0.89442, tol);  
+    // Using eq 24 gives delta(0.1, 0.89442, max) = 0.43
+    double del = delta(0.1, gam); // eps = 0.1 for mere 90% confidence.
+    BOOST_CHECK_CLOSE_FRACTION(del, 0.43, 0.05); 
+    // According to eq 12, m < -1.716, 
+    // so we ought to round x mean to order m = -2, (rounding digit is 0.0d)
+    // to get the 0.1 properly-rounded result of format dd.d, 
+    // and the 0.1-proper (1-alpha) confidence interval estimate for mean,
+    // for alpha = 0.01,
+    // confidence interval is 87.9 +/- 0.2 and (87.3848, 88.4152).
+
+    double r = log10(del * sigma_rounded / (5 * gam));
+    //cout << "r = " << r << endl; //   r = -1.71409
+    BOOST_CHECK_CLOSE_FRACTION(r, -1.716, tol *5 );
+    int m = static_cast<int>(floor(log10(del * sigma_rounded / (5 * gam)))); // Wimmer eq 12 p 1661.
+    BOOST_CHECK_EQUAL(m, -2);
+    // Expect mean 87.9 +/- 0.2
+    BOOST_CHECK_EQUAL(round_ms(x, m), "87.9"); // 0.1 properly rounded.
+    // Have already got unc_rounded so display "+/- 0.2".
+    double rounded_x = 87.9;
+
+    // Estimate confidence interval.
+    double alpha = 0.01;
+    //boost::math::normal dist(rounded_x, variance/(n-1));
+    //double t = quantile(complement(dist, alpha/2));
+    //cout << "quantile(complement(dist, alpha/2)); = " << t << endl; // for 0.1 = 1.64485, 0.01 2.57583
+    // This should be the upper limit.
+    // quantile(complement(dist, alpha/2)); = 88.1213  
+    // dist(x, variance/n); gives quantile(complement(dist, alpha/2)); = 88.0679
+    // dist(rounded_x, variance/n); gives quantile(complement(dist, alpha/2)); = 88.0288
+    // dist(rounded_x, variance/(n-1)); gives quantile(complement(dist, alpha/2)); = 88.0431
+    // So none of these are quite right - expect upper = 88.4152
+
+    normal dist01;
+    double t = quantile(complement(dist01, alpha/2));
+    std::pair<double, double> p; // Confidence interval.
+    // Note use of rounded values to get exactly the same result as Wimmer.
+    p.first = rounded_x - sigma_rounded * t;
+    p.second = rounded_x + sigma_rounded * t;
+    // cout << "lower " << p.first << ", upper " << p.second << endl; //   lower 87.3848, upper 88.4152
+    BOOST_CHECK_CLOSE_FRACTION(p.first, 87.3848, tol);  // These confidence intervals are given.
+    BOOST_CHECK_CLOSE_FRACTION(p.second, 88.4152, tol); 
+
+    // So in summary:
+    // void out_value_limits(double mean, double unc, std::pair<double, double> ci, int m, std::ostream& os = cout);
+    // std::cout << "out_value_limits(x, sigma_star, p, m, std::cout); ";
+    // out_value_limits(x, sigma_star, p, m, std::cout); 
+    // std::cout << std::endl;
+    //  out_value_limits(x, sigma_star, p, m, std::cout); 87.9 +/- 0.22 <87.38, 88.42> 
+
+    alpha = 0.1;  // 90% confidence for mean.
+    t = quantile(complement(dist01, alpha / 2));
+    //cout << t << endl; // 1.64485
+    p.first = rounded_x - sigma_star * t;
+    p.second = rounded_x + sigma_star * t;
+    // cout << "Alpha 0.1 " << p << endl; // Alpha 0.1 <87.5322, 88.2678>
+    BOOST_CHECK_CLOSE_FRACTION(p.first, 87.573, tol);  // These confidence intervals not given,
+    BOOST_CHECK_CLOSE_FRACTION(p.second, 88.27, tol);  // but they look plausible.
+
+    alpha = 0.05;  // 95% confidence for mean (not given by Wimmer).
+    t = quantile(complement(dist01, alpha / 2));
+    // cout << t << endl; // 1.95996
+    p.first = rounded_x - sigma_star * t;
+    p.second = rounded_x + sigma_star * t;
+    //cout << "Alpha 0.05 " << p << endl; // 87.5009 == 87.5 // 88.3774 == 88.3 rounded.
+    // Alpha 0.05 <87.4617, 88.3383>
+    BOOST_CHECK_CLOSE_FRACTION(p.first, 87.3848, tol); 
+    BOOST_CHECK_CLOSE_FRACTION(p.second, 88.4152, tol); 
+    BOOST_CHECK_EQUAL(round_ms(p.first, m), "87.5"); // 0.1 properly rounded.
+    BOOST_CHECK_EQUAL(round_ms(p.second, m), "88.3"); // 0.1 properly rounded.
+
+    alpha = 0.01;  // 99% confidence for mean (Wimmer).
+    t = quantile(complement(dist01, alpha / 2));
+    // cout << t << endl; // 2.57583
+    p.first = rounded_x - sigma_star * t;
+    p.second = rounded_x + sigma_star * t;
+    // cout << "Alpha 0.01 " << p << endl;// 87.3631 == 87.3,  88.5151 == 88.5
+    // Alpha 0.01 <87.324, 88.476>
+    BOOST_CHECK_CLOSE_FRACTION(p.first, 87.3848, tol); // but Wimmer gives 87.3848 not 88.5151.
+    BOOST_CHECK_CLOSE_FRACTION(p.second, 88.4152, tol); // but Wimmer gives 88.4152 not 88.5151.
+    BOOST_CHECK_EQUAL(round_ms(p.first, m), "87.3"); // 0.1_properly rounded.
+    BOOST_CHECK_EQUAL(round_ms(p.second, m), "88.5"); // 0.1_properly rounded.
+    //cout << "Mean " << x << " == " << round_ms(x, m) << " +/- " << sigma_rounded
+    //  << " <" << round_ms(p.first, m) << ", " << round_ms(p.second, m) << ">" << endl;
+    //Mean 87.9391 == 87.9 +/- 0.2 <87.3, 88.5>
+
+  }// End Wimmer p 1662, example 7 - Repeated measurements with known variance.
+} // BOOST_AUTO_TEST_CASE(round_m_test)
+
+BOOST_AUTO_TEST_CASE(Wimmer_triangular_test)
+{  // Wimmer Triangular distribution example 3, page 27.
+  double x = 127.835;
+  double unc = 15.287;
+  double unc_rounded = round_sig(unc, 2); // round to 2 sig digit - ISO rule.
+  // cout << "unc_rounded " << unc_rounded << endl; // unc_rounded 15
+  BOOST_CHECK_CLOSE_FRACTION(unc_rounded, 15., 0.01);
+  ostringstream oss;
+  oss << setprecision(3) << unc_rounded; // expect 0.2 whatever precision (< digits10)
+  BOOST_CHECK_EQUAL(oss.str(), "15"); // unc 15. properly rounded.
+  double gam = unc_rounded / unc;
+  BOOST_CHECK_CLOSE_FRACTION(gam, 0.98123, 0.01); 
+  // double delta(double epsilon, double gamma, distribution_type distrib = normal);
+  double del = delta(0.01, gam, triangular); // eps = 0.01 for high 99% confidence.
+  BOOST_CHECK_CLOSE_FRACTION(del, 0.0561, 0.01);
+
+  int m = round_m(0.01, unc, 2, triangular);
+  BOOST_CHECK_EQUAL(m, -1);
+  BOOST_CHECK_EQUAL(round_ms(x, m), "128.");
+  // ostringstream oss2; // Maybe quicker to construct a new string than erase old one?
+  oss.clear(); // Clears only clear stream fail or error bits!
+  oss.str(""); // Erases the previous str (oss.str().erase() does NOT change std::string - because it only acts on a copy C string?)
+  oss << setprecision(3) << unc_rounded; // expect 15 whatever precision (< digits10)
+  BOOST_CHECK_EQUAL(oss.str(), "15"); // unc 15. properly rounded.
+  std::pair<double, double> ci;
+  //std::pair<double, double> conf_interval(double value, double unc, double df = 1., double alpha = 0.05, distribution_type distrib);
+  // value should be the rounded value 130, not the 'exact' double value 127.835.
+  // unc should also be the rounded value, 15, not the 'exact' double value 15.287.
+  // I don't understand the logic of calculating the confidence intervals with rounded data?
+  using boost::lexical_cast;
+  double vr = lexical_cast<double>(round_ms(x, m)); // = 128.
+  ci = conf_interval(vr, unc_rounded, 1, 0.05, triangular); // alpha = 0.05, example 3 1st 0.01-proper 0.95 confidence interval <99.5, 156.5>. 
+  // cout << "conf_interval(vr, unc, 1, 0.05, triangular); " << ci << endl;
+  //  conf_interval(vr, unc, 1, 0.05, triangular); <99.4735, 156.527>
+  BOOST_CHECK_CLOSE_FRACTION(ci.first, 99.5, tol); // 98.9 
+  BOOST_CHECK_CLOSE_FRACTION(ci.second, 156.5, tol); // 157.1
+
+  // Round confidence intervals to 1 decimal digit 
+  //double cilo =  lexical_cast<double>(round_ms(ci.first, m-1)); // = 98.9
+  //cout << "ci lo " << cilo << endl; //   ci lo 99.5
+  //double cihi =  lexical_cast<double>(round_ms(ci.second, m-1)); // = 156.5
+  //cout << "ci hi " << cihi << endl; //  ci hi 156.5
+
+  //out_confidence_interval(ci, m, cout); // <99.5, 157>
+  //cout << endl;
+
+  oss.clear(); // Clears only clear stream fail or error bits!
+  oss.str(""); // Erases the previous str (oss.str().erase() does NOT change std::string - because it only acts on a copy C string?)
+  out_confidence_interval(ci, m, oss); // <99.5, 157>
+  BOOST_CHECK_EQUAL(oss.str(), "<99.5, 157>");
+
+  //out_value_limits(x, unc, ci, m); //  128. +/- 15 <99.5, 156.5>
+  //cout << endl;
+  oss.clear(); // Clears only clear stream fail or error bits!
+  oss.str(""); // Erases the previous str (oss.str().erase() does NOT change std::string - because it only acts on a copy C string?)
+  out_value_limits(x, unc, ci, m, oss); //  128. +/- 15 <99.5, 156.5>
+  BOOST_CHECK_EQUAL(oss.str(), "128. +/- 15 <99.5, 156.5>");
+
+  // Now for 2nd example, consider eps = 0.05 - only 95% rather than 99% confidence of rounding loss.
+  del = delta(0.05, gam, triangular); // eps = 0.05 for lower 95% confidence.
+  BOOST_CHECK_CLOSE_FRACTION(del, 0.4931, tol);
+  m = round_m(0.05, unc, 2, triangular);
+  BOOST_CHECK_EQUAL(m, 0); // round to order m == 0
+  BOOST_CHECK_EQUAL(round_ms(x, m), "130.");
+  // Show confidence intervals for various alpha, 0.01 to 0.1:
+  ci = conf_interval(x, unc, 1, 0.01, triangular);
+  //cout << "conf_interval(x, unc, 1, 0.01, triangular); " << ci << endl;
+  oss.clear(); // Clears only clear stream fail or error bits!
+  oss.str(""); // Erases the previous str (oss.str().erase() does NOT change std::string - because it only acts on a copy C string?)
+  oss << setprecision(6) << ci;
+  BOOST_CHECK_EQUAL(oss.str(), "<94.1342, 161.536>");
+
+  ci = conf_interval(x, unc, 1, 0.02, triangular);
+  //cout << "conf_interval(x, unc, 1, 0.02, triangular); " << ci << endl;
+  oss.clear(); // Clears only clear stream fail or error bits!
+  oss.str(""); // Erases the previous str (oss.str().erase() does NOT change std::string - because it only acts on a copy C string?)
+  oss << setprecision(6) << ci;
+  BOOST_CHECK_EQUAL(oss.str(), "<95.6852, 159.985>");
+
+  ci = conf_interval(x, unc, 1, 0.05, triangular);
+  //cout << "conf_interval(x, unc, 1, 0.05, triangular); " << ci << endl;
+  oss.clear(); // Clears only clear stream fail or error bits!
+  oss.str(""); // Erases the previous str (oss.str().erase() does NOT change std::string - because it only acts on a copy C string?)
+  oss << setprecision(6) << ci;
+  BOOST_CHECK_EQUAL(oss.str(), "<98.7627, 156.907>");
+
+  ci = conf_interval(x, unc, 1, 0.1, triangular);
+  //cout << "conf_interval(x, unc, 1, 0.1, triangular); " << ci << endl;
+  oss.clear(); // Clears only clear stream fail or error bits!
+  oss.str(""); // Erases the previous str (oss.str().erase() does NOT change std::string - because it only acts on a copy C string?)
+  oss << setprecision(6) << ci;
+  BOOST_CHECK_EQUAL(oss.str(), "<102.231, 153.439>");
+
+  //conf_interval(x, unc, 1, 0.01, triangular); <94.1342, 161.536>
+  //conf_interval(x, unc, 1, 0.02, triangular); <95.6852, 159.985>
+  //conf_interval(x, unc, 1, 0.05, triangular); <98.7627, 156.907>
+  //conf_interval(x, unc, 1, 0.1, triangular); <102.231, 153.439>
+  // Showing significantly wider interval as require less confidence (1-alpha) from 99% down to 90%.
+
+  // Check with Wimmer 0.05 proper 0.95 confidence interval is <101.5, 158.5>
+  vr = lexical_cast<double>(round_ms(x, m));
+  ci = conf_interval(vr, unc_rounded, 1, 0.05, triangular);
+  BOOST_CHECK_CLOSE_FRACTION(ci.first, 101.5, tol);
+  BOOST_CHECK_CLOSE_FRACTION(ci.second, 158.5, tol);
+} // BOOST_AUTO_TEST_CASE(Wimmer_triangular_test)
+
+BOOST_AUTO_TEST_CASE(Wimmer_uniform_test)
+{ // Wimmer Uniform distribution - no example but use same data as triangular.
+  //cout << "Uniform distribution " << endl;
+  double x = 127.835;
+  double unc = 15.287;
+  double unc_rounded = round_sig(unc, 2); // round to 2 sig digit - why?
+  // cout << "unc_rounded " << unc_rounded << endl; // 15
+  BOOST_CHECK_CLOSE_FRACTION(unc_rounded, 15., tol);
+  ostringstream oss;
+  oss << setprecision(3) << unc_rounded; // expect 0.2 whatever precision (< digits10)
+  BOOST_CHECK_EQUAL(oss.str(), "15"); // unc 15. properly rounded.
+  double gam = unc_rounded / unc;
+  BOOST_CHECK_CLOSE_FRACTION(gam, 0.98123, 0.01); 
+  // double delta(double epsilon, double gamma, distribution_type distrib = normal);
+  // Compare all deltas for the three distributions.
+  BOOST_CHECK_CLOSE_FRACTION(delta(0.01, gam),  0.053705908361491229, 0.01);
+  BOOST_CHECK_CLOSE_FRACTION(delta(0.01, gam, triangular), 0.056070697653393911, 0.01);
+  BOOST_CHECK_CLOSE_FRACTION(delta(0.01, gam, uniform), -1, 0.01);
+  // cout << "delta(0.01, gam, gaussian) = " << delta(0.01, gam) << ' ' << delta(0.01, gam, triangular) << ' ' << delta(0.01, gam, uniform) << endl;
+  // "Epsilon 0.01 is too small for gamma rounded/unrounded ratio 0.98122587819716089, threshold is 0.98999999999999999for uniform distribution."
+  double del = delta(0.01, gam, uniform); // eps = 0.01 for high 99% confidence.
+  BOOST_CHECK_CLOSE_FRACTION(del, -1., 0.01); // but is too high, so return -1 
+  // "Epsilon 0.01 is too small for gamma rounded/unrounded ratio 0.981226, threshold is 0.99."
+  del = delta(0.04, gam, uniform); // eps = 0.01 for not so high 96% confidence.
+  BOOST_CHECK_CLOSE_FRACTION(del, 0.106046331775506, tol);
+  int m = round_m(0.04, unc, 2, uniform);
+  BOOST_CHECK_EQUAL(m, -1);
+  BOOST_CHECK_EQUAL(round_ms(x, m), "128.");
+  // ostringstream oss2; // Maybe quicker to construct a new string than erase old one?
+  oss.clear(); // Clears only clear stream fail or error bits!
+  oss.str(""); // Erases the previous str (oss.str().erase() does NOT change std::string - because it only acts on a copy C string?)
+  oss << setprecision(3) << unc_rounded; // expect 15 whatever precision (< digits10)
+  BOOST_CHECK_EQUAL(oss.str(), "15"); // unc 15. properly rounded.
+  //std::pair<double, double> conf_interval(double value, double unc, double df = 1., double alpha = 0.05, distribution_type distrib);
+  // value should be the rounded value 130, not the 'exact' double value 127.835.
+  // unc should also be the rounded value, 15, not the 'exact' double value 15.287.
+  // I don't understand the logic of calculating the confidence intervals with rounded data?
+  using boost::lexical_cast;
+  double vr = lexical_cast<double>(round_ms(x, m)); // = 128.
+  std::pair<double, double> ci = conf_interval(vr, unc_rounded, 1, 0.05, uniform); // alpha = 0.05, example 3b 1st 0.04-proper 0.95 confidence interval <99.5, 156.5>. 
+  //cout << "conf_interval(vr, unc, 1, 0.05, uniform); " << ci << endl;
+  //  conf_interval(vr, unc, 1, 0.05, uniform); <103.318, 152.682>
+  {
+    std::ostringstream os;
+    os << ci;
+    BOOST_CHECK_EQUAL(os.str(), "<103.318, 152.682>");
+  }
+  BOOST_CHECK_CLOSE_FRACTION(ci.first, 103.32, tol); //
+  BOOST_CHECK_CLOSE_FRACTION(ci.second, 152.68, tol); // 
+  //cout << "out_value_limits(x, unc, ci, m) = " ;
+  //out_value_limits(x, unc, ci, m);
+  //cout << endl; // 
+  // out_value_limits(x, unc, ci, m) = 128. +/- 15 <103.3, 152.7>
+  {
+    std::ostringstream os;
+    out_value_limits(x, unc, ci, m, os); // Output value, uncertainty and confidence limits.
+    BOOST_CHECK_EQUAL(os.str(), "128. +/- 15 <103.3, 152.7>");
+    // Need also degrees of freedom.
+
+  }
+} // BOOST_AUTO_TEST_CASE(Wimmer_uniform_test)
+
+BOOST_AUTO_TEST_CASE(Sephton_C_rounding_test)
+{  // Sephton's example of counter-intuitive C/C++ rounding.
+    double d = 0.15; 
+    //cout << setprecision(17) << "0.15 precision 17 is " << d << endl; // Double is 0.14999999999999999
+    //cout << setprecision(1) << "0.15 precision 1 is " << d << endl; // 0.15 precision 1 is 0.1
+    // so internally stored value is nearer to 1., so rounds down to 0.1, perhaps to viewers' surprise!
+    BOOST_CHECK_EQUAL(round_e(d, 0),""); // No significant digits! might decide to throw an exception?
+    BOOST_CHECK_EQUAL(round_e(d, 1),"2.e-1"); // 1 significant digit.
+    BOOST_CHECK_EQUAL(round_e(d, 2),"1.5e-1"); 
+    BOOST_CHECK_EQUAL(round_e(d, 3),"1.50e-1");
+    BOOST_CHECK_EQUAL(round_e(d, 4),"1.500e-1");
+
+    d = 1.25; //
+    //cout << setprecision(17) << "1.25 precision 17 is " << d << endl; // Double is 
+    //cout << setprecision(2) << "1.25 precision 2 is " << d << endl; // 1.25 precision 2 is 1.3
+    //cout << "printf(""%.1f"", 1.25); = "; printf("%.1f\n", 1.25); cout << endl; // printf(%.1f, 1.25); = 1.3
+    d = 0.15; // Sephton's pathological example showing that
+    // output digit string is 'correct' (0.15) for precision(numeric_limits<double>::digits10)
+    // and this rounds to 0.2, as expected.
+    // Imprecision 0.14999999999999999 only appears at numeric_limits<double>::maxdigits10.
+    // So by starting with the digit10 precision string, we should never get the unexpected
+    // and unwanted rounding down to 0.1.
+    for (int i = 1; i <= maxdigits10; i++)
+    {
+      //cout << i << ' ' << showpoint << setprecision(i) << d << ' ' << round_e(d, i) << endl;
+      //1 0.1 2.e-001
+      //2 0.15 1.5e-001
+      //3 0.150 1.50e-001
+      //4 0.1500 1.500e-001
+      //5 0.15000 1.5000e-001
+      //6 0.150000 1.50000e-001
+      //7 0.1500000 1.500000e-001
+      //8 0.15000000 1.5000000e-001
+      //9 0.150000000 1.50000000e-001
+      //10 0.1500000000 1.500000000e-001
+      //11 0.15000000000 1.5000000000e-001
+      //12 0.150000000000 1.50000000000e-001
+      //13 0.1500000000000 1.500000000000e-001
+      //14 0.15000000000000 1.5000000000000e-001
+      //15 0.150000000000000 1.50000000000000e-001
+      //16 0.1500000000000000 1.50000000000000e-001
+      //17 0.14999999999999999 1.50000000000000e-001
+    }
+} // BOOST_AUTO_TEST_CASE(Sephton_C_rounding_test) Sephton's example of counter-intuitive C/C++ rounding.
+
+ BOOST_AUTO_TEST_CASE(round_n_test) // Round number v *at* d th decimal place.
+ {
+  // Test round_1.
+  BOOST_CHECK_CLOSE_FRACTION(round_1(0.52), 0.5, 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_1(0.55), 0.6, 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_1(0.59), 0.6, 2 * eps);
+
+    // Test round_2.
+  BOOST_CHECK_CLOSE_FRACTION(round_2(0.152), 0.15, 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_2(0.155), 0.16, 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_2(0.159), 0.16, 2 * eps);
+
+  // Test round_3.
+  BOOST_CHECK_CLOSE_FRACTION(round_3(0.1552), 0.155, 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_3(0.1555), 0.156, 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_3(0.1559), 0.156, 2 * eps);
+
+  // Test round_n.
+  BOOST_CHECK_CLOSE_FRACTION(round_to_n(0.159, 1), 0.2, 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_to_n(0.159, 2), 0.16, 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_to_n(0.159, 3), 0.159, 2 * eps);
+
+  // Test round_sig. v rounded to n significant decimal digits.
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(1703.12345679, 6), 1703.12, 2 * eps); //  David A. Pimentel 6 significant digits example 1.
+  BOOST_CHECK_CLOSE_FRACTION(round_nth(1703.12345679, 6), 1703.123457, 2 * eps); //  David A. Pimentel 6 digits after decimal point example 2.
+
+  // Value 15.284.
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(15.284, 0), 0., 2 * eps); //  By definition, zero significant digits returns zero.
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(15.284, 1), 20., 2 * eps); // Expect rounded up to 20.
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(15.284, 2), 15., 2 * eps); // Expect rounded to 15.
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(15.284, 3), 15.3, 2 * eps);  // Round up .28 to .3.
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(15.284, 4), 15.28, 2 * eps); // Round .284 to .28.
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(15.284, 5), 15.284, 2 * eps); // Unchanged.
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(15.284, 5), 15.2840, 2 * eps); // Unchanged but with one trailing zero.
+
+  // Quite big values, but not more than digits10. 
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(123456.789, 0), 0., 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(123456.789, 1), 100000., 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(123456.789, 2), 120000., 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(123456.789, 3), 123000, 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(123456.789, 4), 123500., 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(123456.789, 5), 123460.0, 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(123456.789, 6), 123457.0, 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(123456.789, 7), 123456.8, 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(123456.789, 8), 123456.79, 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(123456.789, 9), 123456.789, 2 * eps);
+
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(15.287, 2), 15., 2 * eps);
+  // Wimmer rounding examples, p 1659, 1 significant digit rounding.
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(127.37, 1), 100., 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(0.0983, 1), 0.1, 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(52.83, 1), 50., 2 * eps);
+  // Wimmer rounding examples, p 1660, 3 significant digit rounding.
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(1582.738, 3), 1580., 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(985.438, 3), 985., 2 * eps);
+  BOOST_CHECK_CLOSE_FRACTION(round_sig(0.00987624, 3), 0.00988, 2 * eps);
+
+  //cout << round(15.287) << ' ' << round(15.287)/15.287 << endl; // 0.981226
+  //cout << round(15.587) << endl;
+  //cout << round(15.1f) << endl;
+ } //  BOOST_AUTO_TEST_CASE(round_n_test)
+
+
+ BOOST_AUTO_TEST_CASE(Wimmer_delta)
+ {
+  //double d0 = delta(0.01, 15./15.287);
+  //double d1 = delta(0.01, 0.98123);
+  //double d2 = delta(0.04, 0.98123);
+  //double d3 = delta(0.005, 0.99736);
+  //double d4 = delta(0.1, 0.89442);
+  //cout << d1 << endl; // 0.053779
+  //cout << d2 << endl; // 0.352144
+  //cout << d3 << endl; // 0.12
+  //cout << d4 << endl; // 0.431895
+
+  //double d5 = delta(0.05, 0.86207);
+  // Epsilon 0.05 is too small for gamma rounded/unrounded ratio 0.86207
+
+  //cout << d5 << endl; // -1.#IND
+
+  // Values in Table 1 Threshold value of gamma rounded for epsilon.
+  // If gamma rounded ratio > threshold, cannot get epsilon-properly rounded result.
+  //double d005 = delta(0.005, 0.98972); // fails.
+  //double d005p = delta(0.005, 0.99871);  // is OK
+  //double d01 = delta(0.01, 0.97954);
+  //double d02 = delta(0.02, 0.95951);
+  //double d03 = delta(0.03, 0.93987);
+  //double d04 = delta(0.04, 0.92063);
+  //double d05 = delta(0.05, 0.90175);
+  //double d1 = delta(0.1, 0.81271);
+  //Epsilon 0.05 is too small for gamma rounded/unrounded ratio 0.86207
+  //Epsilon 0.005 is too small for gamma rounded/unrounded ratio 0.98972
+  //Epsilon 0.01 is too small for gamma rounded/unrounded ratio 0.97954
+  //Epsilon 0.02 is too small for gamma rounded/unrounded ratio 0.95951
+  //Epsilon 0.03 is too small for gamma rounded/unrounded ratio 0.93987
+  //Epsilon 0.04 is too small for gamma rounded/unrounded ratio 0.92063
+  //Epsilon 0.05 is too small for gamma rounded/unrounded ratio 0.90175
+  //Epsilon 0.1 is too small for gamma rounded/unrounded ratio 0.81271
+
+
+  //cout << d005p << endl;
+  //cout << d005 << endl;
+  //cout << d01 << endl;
+  //cout << d02 << endl;
+  //cout << d03 << endl;
+  //cout << d04 << endl;
+  //cout << d05 << endl;
+  //cout << d1 << endl;
+
+  // Wimmer et al claim "equation 24 approximation error is less than 0.0123 for epsilon 0.005 to 0.1".
+  // Check that this is true for these examples from the text.
+  // Perhaps should be abs (difference) < 0.0123 ?
+   BOOST_CHECK((delta(0.01, 0.98123) - 0.05) < 0.0123);  
+   BOOST_CHECK((delta(0.04, 0.98123) - 0.35) < 0.0123);  
+   BOOST_CHECK((delta(0.005, 0.99736) - 0.12) < 0.0123);  
+   BOOST_CHECK((delta(0.1, 0.89442) - 0.43) < 0.0123);  
+}    // BOOST_AUTO_TEST_CASE(Wimmer_delta)
+
+BOOST_AUTO_TEST_CASE(Wimmer_gamma_test)   // Test Wimmer gamma = rounded /unrounded
+{
+  BOOST_CHECK_CLOSE_FRACTION(gamma(1.8, 1.8457), 0.97524, 0.01); 
+} // BOOST_AUTO_TEST_CASE(Wimmer_gamma_test) 
+
+BOOST_AUTO_TEST_CASE(round_m_test2)
+{
+    ostringstream oss;
+    double u = 15.287;
+    //cout << round_1(u) << ' ' << round_2(u) << ' ' << round_3(u) << ' ' << round_nth(u, 4) << endl;
+    // 15.3 15.29 15.287 15.287
+    oss << round_1(u);
+    BOOST_CHECK_EQUAL(oss.str(), "15.3");
+    oss.str(""); oss.clear();
+
+    double t = 0.15; // printf unwanted round down case.
+   // cout << round_1(t) << ' ' << round_2(t) << ' ' << round_3(t) << ' ' << round_nth(t, 4) << endl;
+    // 0.2 0.15 0.15 0.15
+    // Note the desired 0.2! Using this rounding algorithm, unlike printf 0.1.
+    //   0.2 0.15 0.15 0.15
+    oss << round_1(t);
+    BOOST_CHECK_EQUAL(oss.str(), "0.2");
+    oss.str(""); oss.clear();
+    oss << round_2(t);
+    BOOST_CHECK_EQUAL(oss.str(), "0.15");
+    oss.str(""); oss.clear();
+    oss << round_nth(t, 1);
+    BOOST_CHECK_EQUAL(oss.str(), "0.2");
+
+    BOOST_CHECK_EQUAL(round_m(0.01, 15.287, 2U), -1); // Example 5 (i a), page 1662.
+    BOOST_CHECK_EQUAL(round_m(0.04, 15.287, 2U), 0); // Example 5 (i b)
+    BOOST_CHECK_NE(round_m(0.05, 0.0232, 1U), -3); // Example 5 (ii a) epsilon <= 0.05 should fail, and does.   
+   // Cannot return a rounding m because epsilon 0.05 is too small!
+    BOOST_CHECK_EQUAL(round_m(0.1, 0.0232, 1U), -3); // Example 5 (ii b), should pass.
+  
+  // 0.053779018871944452 and 0.05
+  BOOST_CHECK_EQUAL(round_e(0.0000000012345678901234567, 1),"1.e-9"); // round 1 sig digit.
+  //BOOST_CHECK_EQUAL(round(0.12345678901234567, 0),"1."); // round 0 - at decimal
+  //BOOST_CHECK_EQUAL(round(1.2345678901234567, 0),"1."); // round 0 - at decimal
+  //BOOST_CHECK_EQUAL(round(123456789.01234567, 0),"1."); // round 0 - at decimal
+  //BOOST_CHECK_EQUAL(round(12345678901234567., 0),"1."); // round 0 - at decimal
+  //BOOST_CHECK_EQUAL(round(12345678901234567890123456789., 0),"1."); // round 0 - at decimal
+
+  //double d = 1.2945678901234567890;
+  //cout << scientific << setprecision(0) << d << endl; //default 6
+  //cout << scientific << setprecision(1) << d << endl; // 1.2
+  //cout << scientific << setprecision(2) << d << endl; // 1.23
+  //cout << scientific << setprecision(3) << d << endl; // 1.235
+  //cout << scientific << setprecision(15) << d << endl; // 1.294567890123457e+000 
+  //cout << scientific << setprecision(16) << d << endl; // 1.2945678901234567e+000
+  //cout << scientific << setprecision(17) << d << endl; // 1.29456789012345670e+000
+  //cout << scientific << setprecision(18) << d << endl; // 1.294567890123456700e+000
+} // BOOST_AUTO_TEST_CASE(round_m_test) 
+
+//  cout << endl;
+
+/*
+
+------ Build started: Project: test_rounding, Configuration: Debug Win32 ------
+Build started 04-May-2012 18:12:45.
+InitializeBuildStatus:
+  Creating "Debug\test_rounding.unsuccessfulbuild" because "AlwaysCreate" was specified.
+ClCompile:
+  test_rounding.cpp
+ManifestResourceCompile:
+  All outputs are up-to-date.
+Manifest:
+  All outputs are up-to-date.
+LinkEmbedManifest:
+  All outputs are up-to-date.
+  test_rounding.vcxproj -> J:\Cpp\quan\MSVC\Debug\test_rounding.exe
+CustomBuildStep:
+  Description: Autorun "J:\Cpp\quan\MSVC\Debug\\test_rounding.exe"
+  Running 17 test cases...
+  Platform: Win32
+  Compiler: Microsoft Visual C++ version 10.0
+  STL     : Dinkumware standard library version 520
+  Boost   : 1.50.0
+  Round test: ..\libs\quan\test\test_rounding.cpp at "Fri May  4 18:12:45 2012", MSVC version 160040219.
+  double maxdigits10 is 17
+  std::numeric_limits<double>::max_exponent = 1024, 
+  std::numeric_limits<double>::max_exponent10 = 308,
+  std::numeric_limits<double>::max_exponent10 -1 = 307. 
+  Trying to output zero significant digits!
+  Trying to output -1 significant digits!
+  Maximum significant digits is 15
+  Maximum significant digits is 15
+  Maximum significant digits is 15
+  Maximum significant digits is 15
+  Maximum significant digits is 15
+  Maximum significant digits is 15
+  Maximum significant digits is 15
+  Epsilon 0.001 is too small for gamma rounded/unrounded ratio 0.991379, threshold is -0.00666462 for gaussian distribution.
+  Cannot compute a rounding m because epsilon 0.001 is too small!
+  Epsilon 0.01 is too small for gamma rounded/unrounded ratio 0.981226, threshold is 0.99 for uniform distribution.
+  Epsilon 0.01 is too small for gamma rounded/unrounded ratio 0.981226, threshold is 0.99 for uniform distribution.
+  Trying to display 0 significant decimal digits!
+  Cannot return a rounding m because epsilon 0.05 is too small!
+  
+  Test suite "Master Test Suite" passed with:
+    544 assertions out of 544 passed
+    17 test cases out of 17 passed
+  
+    Test case "round_test_1" passed with:
+      1 assertion out of 1 passed
+  
+    Test case "round_f_test" passed with:
+      48 assertions out of 48 passed
+  
+    Test case "round_e_test" passed with:
+      126 assertions out of 126 passed
+  
+    Test case "cdf_quantile_test" passed with:
+      134 assertions out of 134 passed
+  
+    Test case "round_ms_test" passed with:
+      80 assertions out of 80 passed
+  
+    Test case "Wimmer_3" passed with:
+      4 assertions out of 4 passed
+  
+    Test case "Wimmer_4" passed with:
+      6 assertions out of 6 passed
+  
+    Test case "Wimmer_5_1" passed with:
+      10 assertions out of 10 passed
+  
+    Test case "Wimmer_5_2" passed with:
+      7 assertions out of 7 passed
+  
+    Test case "round_ue_test" passed with:
+      36 assertions out of 36 passed
+  
+    Test case "Wimmer_triangular_test" passed with:
+      20 assertions out of 20 passed
+  
+    Test case "Wimmer_uniform_test" passed with:
+      15 assertions out of 15 passed
+  
+    Test case "Sephton_C_rounding_test" passed with:
+      5 assertions out of 5 passed
+  
+    Test case "round_n_test" passed with:
+      38 assertions out of 38 passed
+  
+    Test case "Wimmer_delta" passed with:
+      4 assertions out of 4 passed
+  
+    Test case "Wimmer_gamma_test" passed with:
+      1 assertion out of 1 passed
+  
+    Test case "round_m_test2" passed with:
+      9 assertions out of 9 passed
+  
+FinalizeBuildStatus:
+  Deleting file "Debug\test_rounding.unsuccessfulbuild".
+  Touching "Debug\test_rounding.lastbuildstate".
+
+Build succeeded.
+
+Time Elapsed 00:00:04.20
+========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
+
+
+*/
+
Added: sandbox/SOC/2007/quan/libs/quan/test/unc_tests.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/quan/libs/quan/test/unc_tests.cpp	2012-10-05 10:48:15 EDT (Fri, 05 Oct 2012)
@@ -0,0 +1,1766 @@
+/*!
+  \file 
+  \brief Testing uncertain classes using Boost Test Tool.
+  \details Class for simple Propagation of Uncertainties
+     according to a pure Gaussian model.
+*/
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+// Copyright Paul A. Bristow 1998, 2012.
+
+// unc_tests.cpp 
+
+#ifdef _MSC_VER
+#  pragma warning(disable: 4702) // unreachable code
+#  pragma warning(disable: 4511) // copy constructor could not be generated.
+#  pragma warning(disable: 4512) // assignment operator could not be generated.
+#  pragma warning(disable: 4521) // alignment of a member was sensitive to packing.
+#  pragma warning(disable: 4100) // unreferenced formal parameter.
+#  pragma warning(disable: 4701) // local variable may be used without having been initialized.
+#  pragma warning(disable: 4121) // alignment of a member was sensitive to packing.
+#  pragma warning(disable: 4127) // conditional expression is constant.
+#endif
+
+// #define UNC_TRACE // Diagnostic output.
+
+#define BOOST_TEST_MAIN // Required for int test_main() (must come FIRST).
+//#define BOOST_LIB_DIAGNOSTIC "on"// Show library file details.
+// Linking to lib file: libboost_unit_test_framework-vc100-mt-s-1_49.lib
+
+#include <boost/config.hpp>
+#include <boost/cstdlib.hpp> // needed for boost::exit_failure;
+
+#include <boost/test/unit_test.hpp> // Enhanced for unit_test framework autolink,
+#include <boost/test/floating_point_comparison.hpp> // Extra test tool for FP comparison.
+  using boost::unit_test::test_suite;
+  using boost::unit_test::unit_test_log;
+
+// Classes for simple propagation of Uncertainties according to a pure Gaussian model.
+
+#include <cmath>   // for <math.h>
+#include <iostream>
+  using std::ostream;
+  using std::cout;
+  using std::ios_base;
+  using std::ends;
+  using std::endl;
+  using std::ios_base;
+  using std::hex;
+  using std::oct;
+  using std::dec;
+  using std::boolalpha;
+  using std::getline;
+  using std::skipws;
+  using std::noskipws;
+  using std::uppercase;
+  using std::showbase;
+  using std::showpos;
+  using std::left;
+  using std::right;
+  using std::internal; // Initial default - neither left, right nor internal.
+#include <iomanip>  // for <iomanip.h> for setw, setprecision ...
+  using std::setfill;
+#include <fstream>  // for <fstream.h> for filing.
+  using std::ofstream;
+  using std::ifstream;
+#include <string>  // for C++ Std strings
+  using std::basic_string;
+  using std::string;
+#include <sstream> // for o & istringstream
+  using std::istringstream;
+  using std::ostringstream;
+  using std::stringstream;
+#include <limits>
+  using std::numeric_limits;
+
+#include <boost/quan/xiostream.hpp> // extra iostream manipulators like noshowbase
+  using std::lowercase;
+  using std::defaultfloat; // Initial default - neither scientific nor fixed.
+  using std::nofixed;
+  using std::noscientific;
+  using std::noadjust;
+  using std::hexbase;
+
+#include <boost/quan/unc.hpp> // Declaration of Uncertain Classes.
+
+// Files made global to avoid nasty memory leak, and loop to end of memory.
+const char testInputFilename[] = "unc_test_input.txt"; // Input for tests (fin).
+ifstream fin(testInputFilename, ios_base::in);
+const char outFilename[] = "unc_test_output.txt"; // output from tests (fout).
+ofstream fout(outFilename, ios_base::out); // Use default ios_base::overwrite/replace.
+// const char logFilename[] = "unc_log.txt"; // // Boost test log (usual to send to cout).
+// ofstream lout(logFilename, ios_base::out); // Use default overwrite/ iso::replace.
+const char diagFilename[] = "unc_diag.txt"; // diagnostic log diverted from cerr (dout).
+  ofstream dout(diagFilename, ios_base::out); // Use default overwrite/ iso::replace.
+//const char testLogFilename[] = "unc_test.log"; // Not used yet.
+
+// typedef basic_string <char>::size_type size_type;
+// using basic_string <char>::size_type;
+
+// toString concept works for some purposes,
+// but is flawed to combine several manipulators and it needs setUncDefaults.
+// Check using manips output expected string result, for example:
+// CHECK(hex << showbase << setw(10) << i, "       0xf")
+// CHECK(scientific << setw(20) << d, "       1.234568e+001");
+// Note: sets uncertain defaults (& oss has ios defaults too).
+// BUT CHECK cannot check the number of chars output using unc_print "used",
+// so use CHECK_USED for this.
+
+#define CHECK(manips, result)\
+{\
+  ostringstream oss;\
+  setUncDefaults(oss);\
+  oss << manips;\
+  BOOST_CHECK_EQUAL(oss.str(), result);\
+}// #define	CHECK(manips, result)
+//	BOOST_CHECK_EQUAL(oss.str().length(), strlen(result));\
+// Temporarily removed because causes too much clutter in log.
+// Anyway. if strings are same, then length check is superfluous.
+
+// Also check that the unc used count was correct.
+#define	CHECK_USED(manips, result)\
+{\
+  typedef basic_string <char>::size_type size_type;\
+  ostringstream oss;\
+  setUncDefaults(oss);\
+  oss << manips;\
+  BOOST_CHECK_EQUAL(oss.str(), result);\
+}
+//	BOOST_CHECK_EQUAL(oss.str().length(), static_cast<size_type>(oss.iword(usedIndex)));\
+// Was temporarily removed because causes too much clutter in log.
+
+// Compare results of reading string into a uncun, for example 1.2 +/-0.01 (8)
+// with all elements of uncun type.
+#define	CHECK_IN(in_string, mean, sd, df, ty)\
+{\
+  uncun r;\
+  std::istringstream iss(in_string);\
+  setUncDefaults(iss);\
+  iss >> r;\
+  BOOST_CHECK_CLOSE_FRACTION(r.value(), mean, numeric_limits<double>::epsilon());\
+  BOOST_CHECK_CLOSE_FRACTION(r.std_dev(), sd, numeric_limits<float>::epsilon());\
+  BOOST_CHECK_EQUAL(r.deg_free(), df);\
+  BOOST_CHECK_EQUAL(r.types(), ty);\
+  showUncTypes(r.types());\
+} // #define	CHECK_IN(in, value, sd, df, types)
+
+// CHECK_OUT_IN Output via manips, and read back in, check is same.
+#define	 CHECK_OUT_IN(manips, result, value, sd, df, types)\
+{\
+  typedef basic_string <char>::size_type size_type;\
+  stringstream ss;\
+  setUncDefaults(ss);\
+  ss << manips;\
+  BOOST_CHECK_EQUAL(ss.str(), result);\
+  BOOST_CHECK_EQUAL(ss.str().length(), static_cast<size_type>(ss.iword(usedIndex)));\
+  uncun r;\
+  ss >> r;\
+  BOOST_CHECK_CLOSE_FRACTION(r.value(), value, numeric_limits<double>::epsilon());\
+  BOOST_CHECK_CLOSE_FRACTION(r.std_dev(), sd, numeric_limits<float>::epsilon());\
+  BOOST_CHECK_EQUAL(r.deg_free(), df);\
+  BOOST_CHECK_EQUAL(r.types(), types);\
+}// #define	CHECK_OUT_IN(manips, result)
+
+// Integrity check on iword begin and end no longer needed in CHECK.
+// BOOST_CHECK_EQUAL(oss.iword(topIndex), indexID);\
+// BOOST_CHECK_EQUAL(oss.iword(0), indexID);\
+// BOOST_CHECK_EQUAL(oss.iword(topIndex), indexID);\
+// BOOST_CHECK_EQUAL(oss.iword(0), indexID);\
+
+// This test case is automatically registered by using BOOST_AUTO_TEST_CASE.
+  using std::istream;
+  using std::ostream;
+  using std::ios_base;
+  using std::char_traits;
+  using std::cout;
+  using std::cerr;
+  using std::cin;
+  using std::endl;
+  using std::flush;
+  using std::ws;
+  using std::streamsize;
+  using std::boolalpha;
+  using std::dec;
+  using std::hex;
+  using std::showbase;
+  using std::fixed;
+  using std::scientific;
+  using std::right;
+  using std::showpos;
+  using std::noshowpos;
+  using std::noshowbase;
+  using std::noshowpoint;
+  using std::showpoint;
+
+  using std::setprecision;
+  using std::setw;
+  using std::resetiosflags;
+
+
+BOOST_AUTO_TEST_CASE(unc_test_basic)
+{ // Uncertain Class tests.
+  boost::unit_test::unit_test_log.set_threshold_level( boost::unit_test::log_messages);
+
+  string message("Round to cout test: " __FILE__ );
+#ifdef __TIMESTAMP__
+  message += " at " BOOST_STRINGIZE(__TIMESTAMP__);
+#endif
+#ifdef _MSC_FULL_VER
+  message +=  ", MSVC version " BOOST_STRINGIZE(_MSC_FULL_VER) ".";
+#else
+  message += "."
+#endif
+  BOOST_MESSAGE(message);
+
+ //   BOOST_CHECK(zeroIndex == indexID); // Should pass?
+
+
+  // BOOST_CHECK(lout.is_open());
+  //   unc_tests.cpp(235): info: check lout.is_open() passed
+  // unit_test_log.set_stream(lout); // Switch to log file.
+  // BOOST_TEST_MESSAGE(message); 
+
+  BOOST_CHECK(numeric_limits<double>::is_iec559 == true);	// IEC559/IEEE754 floating point.
+
+  // Change log level to record warnings & errors.
+  // unit_test_log.set_log_threshold(boost::unit_test::log_successful_tests);
+  unit_test_log.set_threshold_level(boost::unit_test::log_all_errors);
+  //unit_test_log::instance().set_threshold_level(test_suite);
+  //unit_test_log::instance().set_threshold_level(messages); // user messages
+  // Prepare to send log to a file instead of cout.
+
+  cout << "\x0F1 Uncertain Class Test output to " << outFilename << ' '
+    << __FILE__ << ' ' <<  __TIMESTAMP__ << endl;
+  // +- symbol on screen cout = dec 177, hex F1 but shows ~n in files?
+  // BUT is messy because in file codeset +- symbol \x0B1 176!
+
+  BOOST_CHECK(fout.is_open());
+  // Test output to file ...
+  fout << "Test Output from " << __FILE__ << " " << __TIMESTAMP__"\n" << endl;
+
+  // Test diagnostic output to file ...
+  //BOOST_CHECK(lout.is_open());
+  //lout << "Unc " << logFilename << " opened." << endl;
+  BOOST_CHECK(dout.is_open());
+  dout << "Unc Diagnostics logged to " << diagFilename << " from " << __FILE__ << " " << __TIMESTAMP__"\n"<< endl;
+  cout << "Unc Diagnostics logged to " << diagFilename  << endl; // \x0F1 on screen but ~n in files.
+  cerr.rdbuf(dout.rdbuf());	// cerr = dout;  // Switch cerr to diagnostic log.
+  // dout << "Diagnostic cerr from " << __FILE__ << " " << __TIMESTAMP__"\n" << endl;
+  cerr << "\x0B1 \x0B5 Diagnostic cerr from " << __FILE__ << " " << __TIMESTAMP__"\n" << endl;
+  // Greek mu is \x0B5 for files, degree symbol is \x0B0
+  // BOOST_CHECK(fin.is_open());  // No input yet?
+
+  BOOST_MESSAGE("Uncertain Class tests log. " << "                                     Expected   Was    Expected");
+
+  // cout.fill('0'); // to get trailing zeros.
+  // cout << fixed << setprecision(17) << 12.34 << automatic << endl; // 12.34000000000000000
+  // gives 17 digits (2 digits plus 15 trailing zeros AFTER decimal point).
+
+  //________________________________________________________________________________________________________________________________
+  {
+    // Some floating point comparison examples, with two tolerances, just wide enough, and too tight.
+  double fp1 = 1.;
+  double fp2 = 1.00001;
+  BOOST_CHECK_CLOSE(fp1, fp2, 0.00100001); // Wide tolerance info: test fp1 ~= fp2 passed.
+  // difference between fp1{1} and fp2{1.00001} exceeds 0.001% (0.00001 * 100 = 0.001%)
+  // Note that BOOST_CHECK_CLOSE(fp1, fp2, 0.001); // just fails, but 0.001000001 passes.
+
+  // BOOST_CHECK_CLOSE(fp1, fp2, 0.0000000001); // Tight tolerance so should fail [1 !~= 1.00001 (+/-1e-010)].
+  // error in "call_test_main": difference between fp1{1} and fp2{1.00001} exceeds 1e-010%
+  }
+
+  setUncDefaults(fout); // Should set the indexID values too.
+  long& zeroid = fout.iword(zeroIndex);
+  long& topid = fout.iword(topIndex);
+  BOOST_CHECK_EQUAL(zeroid, indexID); // Check iword init at bottom OK,
+  BOOST_CHECK_EQUAL(topid, indexID); // Check iword init at bottom OK,
+  BOOST_CHECK_EQUAL(fout.iword(zeroIndex), indexID); // Check iword init at bottom OK,
+  BOOST_CHECK_EQUAL(fout.iword(topIndex), indexID);// and at top too.
+  long& uncFlags = fout.iword(uncFlagsIndex);
+
+  setUncDefaults(dout); // Should set the indexID values too.
+  zeroid = dout.iword(zeroIndex);
+  topid = dout.iword(topIndex);
+  BOOST_CHECK_EQUAL(zeroid, indexID); // Check iword init at bottom OK,
+  BOOST_CHECK_EQUAL(topid, indexID);// & at top too.
+
+  setUncDefaults(std::cout);
+
+  // Check initial ios flags, precision, fill, width.
+  // Expect IOS flags: skipwhite dec, precision 6, fill ' '
+  std::streamsize originalWidth = fout.width(); // Not useful to restore.
+  BOOST_CHECK_EQUAL(fout.width(), 0);  // std default precision.
+  std::streamsize originalPrecision = fout.precision();  // Default precision is 6.
+  BOOST_CHECK_EQUAL(fout.precision(), 6);  // std default precision is 6.
+  long originalFlags = fout.flags();  // hex 201 == skipwhite dec.
+  BOOST_CHECK_EQUAL(fout.flags(), 0x201); 
+  BOOST_CHECK_EQUAL(fout.flags(), std::ios_base::skipws | std::ios_base::dec);
+  BOOST_CHECK_EQUAL(fout.fill(), ' '); // fill char is space.
+  BOOST_CHECK_EQUAL(fout.flags() & ios_base::floatfield, 0);
+  BOOST_CHECK_EQUAL(fout.flags() & ios_base::adjustfield, 0);
+  BOOST_CHECK_EQUAL(fout.flags() & ios_base::adjustfield, (int)!(ios_base::left | ios_base::right | ios_base::internal));
+  BOOST_CHECK_EQUAL(fout.flags() & ios_base::showbase, 0); // no showbase.
+  BOOST_CHECK_EQUAL(fout.flags() & ios_base::boolalpha, 0); // no boolapha.
+
+  // Basic checks on re-initialisation of ios and unc using.
+  void setiosDefaults(ostream&); // &
+  void setUncDefaults(ios_base&);
+
+  ostringstream oss;
+  std::ios_base::fmtflags init_flags = oss.flags();
+  //outFmtFlags(init_flags); // Default flags after initializing stream: skipws & dec.
+  setUncDefaults(oss);
+  long init_uflags = uFlags(oss); 
+  oss.flags(~init_flags); // Alter all the flags.
+  //outFmtFlags(oss.flags()); // Show altered flags.
+  //outFmtFlags(0xFFFFFF); // Show all flags.
+  oss.precision(99);
+  BOOST_CHECK_EQUAL(oss.precision(), 99);
+  oss.fill('*');
+  BOOST_CHECK_EQUAL(oss.fill(), '*');
+
+  //setuFlags(oss,0xFFFFFFFF);
+  //showUncFlags(oss);
+  // Restore as initialised.
+  setiosDefaults(oss);
+  setUncDefaults(oss);	
+  //outFmtFlags(oss.flags());
+  //outUncFlags(oss);
+  BOOST_CHECK_EQUAL(oss.rdstate(), ios_base::goodbit);
+  BOOST_CHECK_EQUAL(init_flags, oss.flags()); // Check now same as when initialised = skipws & dec.
+  BOOST_CHECK_EQUAL(oss.precision(), 6);
+  BOOST_CHECK_EQUAL(oss.fill(), ' ');
+  BOOST_CHECK_EQUAL(oss.width(), 0);
+  BOOST_CHECK_EQUAL(uFlags(oss), init_uflags);
+  BOOST_CHECK_EQUAL(oss.iword(uncFlagsIndex), 0);
+  BOOST_CHECK_EQUAL(oss.iword(sigDigitsIndex), 3);
+  BOOST_CHECK_EQUAL(oss.iword(uncWidthIndex), 10);
+  BOOST_CHECK_EQUAL(oss.iword(scaleIndex), 0);
+  BOOST_CHECK_EQUAL(oss.iword(setUncSigDigitsIndex), 2);// Default 2 sig digits.
+
+  extern const long indexID;  // random id to check init OK.
+  BOOST_CHECK_EQUAL(oss.iword(zeroIndex), indexID);
+  BOOST_CHECK_EQUAL(oss.iword(topIndex), indexID);
+
+  std::streamsize w = cerr.width(6); // Set a width of 6.
+  BOOST_CHECK_EQUAL(cerr.width(), 6);  // Confirm has been set to 6.
+  cerr << endl; // Does NOT 'Use' width.
+  BOOST_CHECK_EQUAL(cerr.width(), 6);  // Confirm is STILL 6.
+  cerr << '\t' << endl; // (\a shows as small square) Does 'Use' width, like << "use" or << 99 
+  BOOST_CHECK_EQUAL(cerr.width(), 0);// Check width has been reset to zero.
+  } // BOOST_AUTO_TEST_CASE(unc_test_basic)
+
+//#define CPP_TESTS
+#ifdef CPP_TESTS
+BOOST_AUTO_TEST_CASE(unc_test_stdio)
+{  // Examples of C++ std integer output.
+  int i1 = 1;
+  CHECK(i1, "1");
+  CHECK(noshowpoint << i1, "1"); // Explicit NOshowpoint
+  CHECK(showpoint << i1, "1"); // Never show point if value is integer!
+
+  int i1234 = 1234;
+  CHECK(i1234, "1234");
+  CHECK(noshowpoint << i1234, "1234"); // Normal 
+  CHECK(showpoint << i1234, "1234"); // NOT "1234." Doesn't show point if integer!
+  CHECK(showpos << i1234, "+1234"); // Shows +
+
+  int m1 = -1; // negative variable.
+  CHECK(m1, "-1"); //  negative constant. 
+  CHECK(hex << m1, "ffffffff"); // 
+  int m1234 = -1234;
+  CHECK(m1234, "-1234"); // plain negative
+  CHECK(noshowpoint << m1234, "-1234"); // Normal 
+  CHECK(showpoint << m1234, "-1234"); // NOT "-1234." Doesn't show point if integer!
+  CHECK(showpos << m1234, "-1234"); // Makes no difference - always show - sign.
+  CHECK(noshowpos << m1234, "-1234"); // Makes no difference - always show - sign.
+
+  int i = 15;
+  CHECK(hex << showbase << setw(5) << i, "  0xf"); // 2 spaces + 3 digit chars.
+  CHECK(hex << noshowbase << setw(5) << i, "    f"); // 4 spaces + 1 digit char .
+  CHECK(hex << left << noshowbase << setw(5) << i, "f    "); // 1 digit char + 4 fill spaces.
+  CHECK(right << dec << noshowbase << setw(5) << i, "   15"); // 1 digit char + 3 fill spaces.
+  CHECK(setfill('~') << left << dec << noshowbase << setw(5) << i, "15~~~"); //  3 ~ & 1 digit char.
+  CHECK(setfill('~') << right << dec << noshowbase << setw(5) << i, "~~~15"); // 1 digit char + 3 ~.
+
+  // Check some examples of built-in double output.
+
+  double zero = 0.;
+  double one = 1.;
+  double minus1 = -1.;
+  double point1 = 0.1;
+
+  CHECK(zero, "0"); // normal defaults, width = 1
+  CHECK(showpos << zero, "+0"); // normal defaults, width = 1
+  CHECK(setprecision(0) << zero, "0"); // NO decimal point.
+  // Check use of showpos and showpoint.
+  CHECK(fixed << showpos << showpoint << zero, "+0.000000"); // 1+6 zeros - no precision set, so defaults to 6.
+  CHECK(showpoint << setprecision(1) << zero, "0.0"); // normal defaults, width = 7
+  CHECK(showpoint << showpos << setprecision(0) << zero, "+0.000000"); // 6 zeros
+  CHECK(showpoint << showpos << setprecision(1) << zero, "+0.0"); // normal defaults, width = 1
+  CHECK(showpoint << showpos << setprecision(-1) << zero, "+0.000000"); // 6 zeros
+  CHECK(showpoint << showpos << setprecision(6) << zero, "+0.000000"); // 6 zeros
+  // So setprecision(0) means precision(6) if normal unless fixed when
+  CHECK(fixed << showpoint << setfill('~') << setprecision(0) << zero, "0."); // width = 2
+  CHECK(fixed << showpos << showpoint << setfill('~') << setprecision(0) << zero, "+0."); // width = 2
+  CHECK(fixed << showpos << showpoint << setprecision(0) << zero, "+0."); // width = 3
+  CHECK(fixed << showpos << showpoint << setprecision(1) << zero, "+0.0"); // width = 4
+  CHECK(fixed << showpos << showpoint << setprecision(2) << zero, "+0.00"); // width = 5
+  CHECK(fixed << showpos << showpoint << setprecision(3) << zero, "+0.000"); // width = 6
+
+  CHECK(fixed << setprecision(0) << zero, "0"); // width = 1 
+  CHECK(fixed << showpoint << setprecision(0) << zero, "0."); // width = 2
+  CHECK(fixed << showpoint << setprecision(1) << zero, "0.0"); // width = 3
+  CHECK(fixed << showpoint << setprecision(2) << zero, "0.00"); // width = 4
+  CHECK(fixed << showpoint << setprecision(3) << zero, "0.000"); // width = 5
+
+  CHECK(one, "1"); // normal defaults, width = 1
+  CHECK(showpoint << one, "1.00000"); // Same as above, using default precision(6)
+  // << showpoint means that precision is used.
+  CHECK(left << showpoint << setfill('~') << setprecision(6) << one, "1.00000"); // width = 7
+  CHECK(left << showpoint << setfill('~') << setprecision(1) << one, "1."); // width = 7
+  CHECK(left << showpoint << setfill('~') << setprecision(0) << one, "1.00000"); // NOT "1."
+  // So conclude that precision(0) means default is used.
+  // Show how precision controls if width is not set & show that no fill char ~ are used):
+  CHECK(left << fixed << showpoint << setprecision(4) << one, "1.0000"); // width = 6
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(6) << one, "1.000000"); // width = 8
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(5) << one, "1.00000"); // width = 7
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(4) << one, "1.0000"); // width = 6
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(3) << one, "1.000"); // width = 5
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(2) << one, "1.00"); // width = 4
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(1) << one, "1.0"); // width = 3
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(0) << one, "1."); // width = 2
+  CHECK(left << showpoint << setfill('~') << setprecision(0) << one, "1.00000"); // width = 6 + 1 .
+
+  CHECK(fixed << showpoint << setprecision(0) << minus1, "-1."); // width = 3 if value >= 1, precision(0) then 1 digit.
+  CHECK(fixed << showpoint << setprecision(1) << minus1, "-1.0"); // width = 4
+  CHECK(fixed << showpoint << setprecision(2) << minus1, "-1.00"); // width = 5
+  CHECK(fixed << showpoint << setprecision(3) << minus1, "-1.000"); // width = 6
+
+  CHECK(fixed << showpoint << setprecision(0) << point1, "0."); // width = 2 - else if value < 1. then NO precision!
+  CHECK(fixed << showpoint << setprecision(1) << point1, "0.1"); // width = 3 
+  CHECK(fixed << showpoint << setprecision(2) << point1, "0.10"); // width = 4
+  CHECK(fixed << showpoint << setprecision(3) << point1, "0.100"); // width = 5
+
+  double big = 123456.;
+  CHECK(big, "123456"); // default 'normal' is not fixed, nor showpoint, nor scientific.
+  // Nicholai M Josuttis, The C++ Standard Library, ISBN 0 201 37926 0, page 624
+  CHECK(showpoint                    << big, "123456."); // Add single . point.
+  CHECK(showpoint << setprecision(0) << big, "123456."); // Same as no setprecision
+  CHECK(showpoint << setprecision(1) << big, "1.e+005"); // Cuts down to 1 decimal place and goes exp.
+  CHECK(showpoint << setprecision(2) << big, "1.2e+005"); // Cuts down to 1+1 decimal place and goes exp.
+  CHECK(showpoint << setprecision(3) << big, "1.23e+005"); // Cuts down to 1+2 decimal place and goes exp.
+  CHECK(showpoint << setprecision(4) << big, "1.235e+005"); // Rounds to 1+3 decimal place and goes exp.
+  CHECK(showpoint << setprecision(5) << big, "1.2346e+005"); // Rounds to 1+4 decimal place and goes exp.
+  CHECK(showpoint << setprecision(6) << big, "123456."); // Using default 6 for setprecision(6).
+  CHECK(showpoint                    << big, "123456."); // Same as using default setprecision(6).
+  CHECK(showpoint << setprecision(7) << big, "123456.0"); // Precision digits (7) in integral & fractional part.
+  CHECK(showpoint << setprecision(17) << big, "123456.00000000000"); // Max 64-bit double setprecision, 18 digits
+
+  // If fixed then precision sets the number of digits in the FRACTIONAL part.
+  CHECK(fixed << showpoint << setprecision(0) << big, "123456."); // 
+  CHECK(fixed << showpoint << setprecision(1) << big, "123456.0"); //
+  CHECK(fixed << showpoint << setprecision(2) << big, "123456.00"); //
+  CHECK(fixed << showpoint << setprecision(3) << big, "123456.000"); //
+
+  double fourDigits = 1234.;
+  CHECK(fourDigits, "1234"); // default 'normal' aka 'automatic' is not fixed, nor scientific, nor showpoint, nor showpos.
+  // Nicholai M Josuttis, The C++ Standard Library, ISBN 0 201 37926 0, page 624
+  CHECK(showpoint                    << fourDigits, "1234.00"); // Add single . point.
+  CHECK(showpoint << setprecision(0) << fourDigits, "1234.00"); // Same as no setprecision
+  CHECK(showpoint << setprecision(1) << fourDigits, "1.e+003"); // Cuts down to 1 decimal place and goes exp.
+  CHECK(showpoint << setprecision(2) << fourDigits, "1.2e+003"); // Cuts down to 1+1 decimal place and goes exp.
+  CHECK(showpoint << setprecision(3) << fourDigits, "1.23e+003"); // Cuts down to 1+2 decimal place and goes exp.
+  CHECK(showpoint << setprecision(4) << fourDigits, "1234."); // Rounds to 1+3 decimal place.
+  CHECK(showpoint << setprecision(5) << fourDigits, "1234.0"); // Rounds to 1+4 decimal place.
+  CHECK(showpoint << setprecision(6) << fourDigits, "1234.00"); // Using default 6 for setprecision(6).
+  CHECK(showpoint                    << fourDigits, "1234.00"); // Same as using default setprecision(6).
+  CHECK(showpoint << setprecision(7) << fourDigits, "1234.000"); // Precision digits (7) in integral & fractional part.
+  CHECK(showpoint << setprecision(17) << fourDigits, "1234.0000000000000"); // Max 64-bit double setprecision, 18 digits
+                                                  
+  // If fixed then precision sets the number of digits in the FRACTIONAL part.
+  CHECK(fixed << showpoint << setprecision(0) << fourDigits, "1234."); // 
+  CHECK(fixed << showpoint << setprecision(1) << fourDigits, "1234.0"); //
+  CHECK(fixed << showpoint << setprecision(2) << fourDigits, "1234.00"); //
+  CHECK(fixed << showpoint << setprecision(3) << fourDigits, "1234.000"); //
+
+  // Using fixed, showpoint and setprecision to show significant digits, including decimal point and trailing zeros.
+  double twelve34 = 12.34;
+  CHECK(twelve34, "12.34");
+  CHECK(fixed << showpoint << setprecision(0) << twelve34, "12.");
+  CHECK(fixed << showpoint << setprecision(1) << twelve34, "12.3");
+  CHECK(fixed << showpoint << setprecision(2) << twelve34, "12.34");
+  CHECK(fixed << showpoint << setprecision(3) << twelve34, "12.340"); // Adds trailing zero(s)
+  CHECK(fixed << showpoint << setprecision(4) << twelve34, "12.3400");
+  CHECK(fixed << showpoint << setprecision(5) << twelve34, "12.34000");
+
+  // fill NOT used unless width is set.
+  // Forcing + sign with showpos 
+  CHECK(left << fixed << showpos << showpoint << setfill('0') << setprecision(0) << one, "+1."); // width = 3
+  CHECK(left << fixed << showpoint << setfill('0') << setprecision(0) << minus1, "-1."); // width = 3
+
+  // fill NOT used unless width is set using setw().
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(4) << one, "1.0000"); // no set width, 4 zeros after.
+  // Using setfill and showpoint (and setw) to show trailing zeros.
+  CHECK(left << fixed << showpoint << setfill('0') << setprecision(4) << setw(8) << one, "1.000000"); // 2 extra fill zeros.
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(4) << setw(8) << one, "1.0000~~"); // 2 extra fill ~.
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(4) << setw(7) << one, "1.0000~"); // 1 extra fill ~
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(4) << setw(6) << one, "1.0000"); // width has no effect.
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(4) << setw(5) << one, "1.0000"); // NO fill.
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(3) << setw(4) << one, "1.000");
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(2) << setw(3) << one, "1.00");
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(1) << setw(3) << one, "1.0");
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(1) << setw(1) << one, "1.0"); // want 1.
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(1) << setw(2)  << zero , "0.0"); // want 0.
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(1) << setw(1)  << zero , "0.0"); // 0.0
+  CHECK(left << fixed << noshowpoint << setfill('~') << setprecision(1) << setw(1)  << zero , "0.0");
+  CHECK(left << fixed << noshowpoint << setfill('~') << setprecision(0) << setw(1)  << zero , "0");
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(0)  << setw(1)  << zero , "0.");
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(0)  << setw(0)  << zero , "0."); // setw(0) undefined?
+  CHECK(left << fixed << showpoint << setfill('~') << setprecision(-1) << one, "1.000000"); // precision < 0 means default = 6
+
+  double d = 1.234567890;
+  CHECK(setw(20) << d, "             1.23457"); // precision 6, width 20  is 13 spaces + 7 chars.
+  CHECK(fixed << setw(20) << d, "            1.234568"); // width 20  is 12 spaces + 8 chars.
+  CHECK(fixed << setw(20) << d, "            1.234568"); // width 20  is 13 spaces + 8 chars.
+  CHECK(scientific << setw(20) << d, "       1.234568e+000"); // width 20  is 7 spaces + 13 chars.
+  CHECK(scientific << d, "1.234568e+000"); // width reverts automatically to 0.
+  CHECK(scientific << setw(20) << right << d, "       1.234568e+000"); // width 20  is 7 spaces + 13 chars.
+  CHECK(scientific << setw(20) << left << d, "1.234568e+000       "); // width 20  is 7 spaces + 13 chars.
+  CHECK(scientific << setw(20) << internal << d, "       1.234568e+000"); // width 20  is 7 spaces + 13 chars.
+  CHECK(scientific << setw(20) << showpos << internal << d, "+      1.234568e+000"); // width 20  is 7 spaces + 13 chars.
+  CHECK(scientific << setw(20) << showpos << internal << setfill('0') << d, "+0000001.234568e+000"); // width 20 is 6 zero fills, 0 spaces + 14 chars.
+  CHECK(scientific << setw(20) << showpos << internal << setfill('*') << d, "+******1.234568e+000"); // width 20 is 6 * fills, 0 spaces + 14 chars.
+  CHECK(scientific << setw(20) << showpos << d, "      +1.234568e+000"); // width 20  is 6 spaces + 14 chars.
+  CHECK(scientific << setw(20) << showpos << left << d, "+1.234568e+000      "); // width 20  is 14 chars + 6 spaces.
+  CHECK(scientific << setw(20) << noshowpos << setfill('~') << d, "~~~~~~~1.234568e+000"); // Combine scientific with fill
+  CHECK(scientific << setw(20) << noshowpos << right << setfill('~') << d,    "~~~~~~~1.234568e+000"); // Combine scientific with fill
+  CHECK(scientific << setw(20) << noshowpos << internal << setfill('~') << d, "~~~~~~~1.234568e+000"); // Combine scientific with fill
+  CHECK(scientific << setw(20) << noshowpos << left << setfill('~') << d, "1.234568e+000~~~~~~~"); // Combine scientific with fill
+
+  // Padding with fill char.
+  CHECK(setw(0) << setfill('~') << i, "15"); // width(0) so no fill.
+  CHECK(setw(1) << setfill('~') << i, "15"); // width(1) so no room for fill.
+  CHECK(setw(2) << setfill('~') << i, "15"); // width(1) so no room for fill.
+  CHECK(setw(3) << setfill('~') << i, "~15"); // width(1) so 1 fill.
+  CHECK(setw(5) << setfill('~') << i, "~~~15"); // width 5 is 3 fill + 2 digits.
+  CHECK(setw(5) << setfill('~') << right << i, "~~~15"); // width 5 is 3 fill + 2 digits.
+  CHECK(setw(5) << setfill('~') << internal << i, "~~~15"); // width 5 is 3 fill + 2 digits.
+  CHECK(setw(5) << setfill('~') << left << i, "15~~~"); // width 5 is 2 digits + 3 fill.
+  CHECK(setw(5) << setfill('~') << noadjust << i, "~~~15"); // width 5 is 3 fill + 2 digits.
+  CHECK(setw(5) << setfill('~') << left << i, "15~~~"); // width 5 is 2 digits + 3 fill.
+  CHECK(setfill(' ') << i, "15"); // width goes back to 0 each time.
+
+  // Extra multiple manipulators: spaces, tabs and chars.
+  CHECK(spaces(5), "     ");
+  CHECK(tabs(5), "\t""\t""\t""\t""\t");
+  CHECK(stars(5), "*****");
+  CHECK(chars(5, '~'), "~~~~~");
+  CHECK(chars(5, ' '), "     ");
+} // BOOST_AUTO_TEST_CASE(unc_test_stdio)
+#endif // CPP_TESTS
+  
+BOOST_AUTO_TEST_CASE(unc_test_std_rounding)
+{ // Show 'C++ Standard' rounding of 9.95 and precision(6) is NOT "10."
+  {
+    // Repeated with unc types later.
+    double nine95 = 9.95;
+    double nine94 = 9.94;
+    double nine96 = 9.96;
+    CHECK(nine95, "9.95");  // Should NOT round up to 10 - default precision is 6. 
+    CHECK(nine94, "9.94");  // Should NOT down up to 9.9 
+    CHECK(nine96, "9.96");  // Should NOT round up to 10. 
+
+    CHECK(setprecision(2) << nine95, "9.9");  // Should round up to 10.  
+    CHECK(setprecision(2) << nine94, "9.9");  // Should down up to 9.9 .
+    CHECK(setprecision(2) << nine96, "10");  // Should round up to 10 . 
+    CHECK(showpoint << setprecision(2) << nine96, "10.");  // Should round up to 10. 
+    CHECK(fixed << noshowpoint << setprecision(2) << nine95, "9.95");
+    CHECK(fixed << showpoint << setprecision(2) << nine95, "9.95");
+  }
+  { // Similar checks for unc type.
+    uncun nine94(9.94, 0.1f); // 
+    uncun nine95B(_nextafter(9.95, numeric_limits<double>::min()), 0.1f); // Just below 9.95.
+    uncun nine95(9.95, 0.1f); // Nearest representable to 9.95.
+    uncun nine95A(_nextafter(9.95, numeric_limits<double>::max()), 0.1f); // Just after 9.95.
+    uncun nine96(9.96, 0.1f); // 
+    CHECK(nine94, "9.94");  // Should round down up to 9.94. 
+    CHECK(nine95B, "9.95");  // Should NOT round up to 10. 
+    CHECK(nine95, "9.95");  // Should NOT round up to 10.  
+    CHECK(nine95A, "9.95");  // Should NOT round up to 10. 
+    CHECK(nine96, "9.96");  // Should NOT round up to 10.
+  }
+}// BOOST_AUTO_TEST_CASE(unc_test_std_rounding)
+
+
+ BOOST_AUTO_TEST_CASE(unc_test_zeros)
+ { // Uncertain reals - constructor and get/set functions.
+   { // (Start a new scope for all uncs to allow reuse of names like one23...)
+    uncun zd(0);  // Integer Zero, using constructor from int zero.
+    unsigned short f = zd.uncFlags();
+    BOOST_CHECK(zd.types() & VALUE_ZERO); // Should be flagged as zero.
+    BOOST_CHECK(zd.types() & VALUE_EXACT); // Should be flagged as exact because sd == 0.
+    BOOST_CHECK(zd.types() & VALUE_INTEGER); // and integer.
+    CHECK(zd, "0"); // Expect just 0 because is exact integer zero.
+
+    uncun u0(0.); // Construct from double zero (default unc, df, & flags)
+    BOOST_CHECK_EQUAL(u0.value(), 0.);
+    BOOST_CHECK_EQUAL(u0.std_dev(), 0.f);
+    BOOST_CHECK_EQUAL(u0.deg_free(), 1);
+    BOOST_CHECK(u0.types() & VALUE_ZERO); // Should still be flagged as zero.
+    CHECK(u0, "0"); // Expect 0 because is exact and isInteger zero because zero uncertainty.
+ 
+   }
+   {
+   uncun u0(0, 0);  // Exact Zero, using constructor from int zero.
+    //BOOST_CHECK(u0.types() & VALUE_ZERO);
+    //BOOST_CHECK((u0.types() & VALUE_INTEGER)); // 
+
+    u0.std_dev(0.01f); // Zero, but add known uncertainty.
+    BOOST_CHECK_EQUAL(u0.std_dev(), 0.01f);
+    BOOST_CHECK(u0.types() & VALUE_ZERO);
+    BOOST_CHECK(!(u0.types() & VALUE_INTEGER)); // No longer exact,
+    BOOST_CHECK((u0.types() & UNC_KNOWN)); // but unc is known.
+    CHECK_USED(plusminus << u0, "0.000 +/-0.010");  // So now show added uncertainty.
+
+    u0.std_dev(0.1f); // Increase std deviation.
+    BOOST_CHECK(u0.types() & VALUE_ZERO); // Should still be flagged as zero.
+    BOOST_CHECK(!(u0.types() & VALUE_INTEGER)); // Made uncertain, so no longer exact.
+    CHECK_USED(u0, "0.00"); // So now add decimal point.
+    CHECK_USED(plusminus << u0, "0.00 +/-0.10"); // So now show increased uncertainty.
+
+    u0.std_dev(1.f); // Increase std deviation more.
+    BOOST_CHECK(u0.types() & VALUE_ZERO); // Should still be flagged as zero.
+    BOOST_CHECK(!(u0.types() & VALUE_INTEGER)); // Made uncertain so no longer exact.
+    CHECK_USED(u0, "0.0"); // Add decimal point.
+    CHECK_USED(plusminus << u0, "0.0 +/-1.0"); // Add uncertainty.
+
+    uncun z(0);  // Exact Zero, using constructor from integer.
+    BOOST_CHECK_EQUAL(z.value(), 0.); // value
+    BOOST_CHECK_EQUAL(z.std_dev(), 0.f);// std_dev
+    BOOST_CHECK_EQUAL(z.deg_free(), 1); // deg_free
+    BOOST_CHECK(z.types() & VALUE_ZERO); // Is zero.
+    BOOST_CHECK(z.types() & VALUE_INTEGER); // Is integer.
+    CHECK_USED(z, "0"); // Exact zero.
+    CHECK_USED(setw(0) << z, "0"); // Exact zero, default width.
+    CHECK_USED(setw(1) << z, "0"); // Tight fit.
+    CHECK_USED(setw(2) << z, " 0"); // no adjust == right justify
+    CHECK_USED(left << setw(2) << z, "0 "); // Just 1 pad.
+    CHECK_USED(left << setw(3) << z, "0  "); // 2 pads.
+    CHECK_USED(left << setw(4) << z, "0   "); // 1 digit plus 3 pad.
+    CHECK_USED(left << setw(4) << z, "0   "); // 1 digit plus 3 pad, left == default.
+    CHECK_USED(right << setw(4) << z, "   0"); // right so 3 pad plus 1 digit.
+   }
+  } //  BOOST_AUTO_TEST_CASE(unc_test_zeros)
+
+ BOOST_AUTO_TEST_CASE(unc_test_unity)
+ {
+    uncun unity(1); // Exact unity constructed from integer.
+    BOOST_CHECK(unity.types() & VALUE_INTEGER); // Check IS recognised as integer.
+    CHECK_USED(unity, "1");  // No decimal point for integer.
+// CHECK_USED(showpoint << unity, "1."); // DO show decimal point for integer value but only if showpoint.
+// But this would imply all the setprecision (6) trailing zeros!  showpoint is MAD!
+    BOOST_CHECK(unity.types() & VALUE_EXACT); // And is exact (sd == 0).
+    CHECK_USED(plusminus << unity, "1"); // Do NOT show +/-0 for integer value.
+
+    unity.types(VALUE_INTEGER); // Clear integer flag.
+    BOOST_CHECK((unity.types() & VALUE_INTEGER) == false); // Check integer flag has been cleared.
+    BOOST_CHECK(unity.types() & VALUE_EXACT); // Check is still exact (sd == 0).
+
+    CHECK_USED(unity, "1."); // Should have decimal point because sd == 0,
+    // so exact (but no longer integer).
+    CHECK_USED(showpoint << unity, "1."); // Regardless of showpoint or not.
+
+    CHECK_USED(plusminus << unity, "1. +/-0"); // Do show +/-0 for exact value (no longer integer).
+    // Show "+/-0" if requested for real exact, for example: "2.54 +/-0".
+    // But NOT for integer, so, for example, just "1" and never "1 +/-0".
+
+    uncun ud(1., 0.f);  // Exact Unity from double.
+    BOOST_CHECK(!(ud.types() & VALUE_ZERO)); // Should NOT be flagged as zero.
+    BOOST_CHECK(ud.types() & VALUE_EXACT); // Should be flagged as zero.
+    BOOST_CHECK(!(ud.types() & VALUE_INTEGER)); // but NOT integer.
+    
+    uncun negud(-1., 0.f);  // Exact Minus negative Unity from double.
+    BOOST_CHECK(!(negud.types() & VALUE_ZERO)); // Should NOT be flagged as zero.
+    BOOST_CHECK(negud.types() & VALUE_EXACT); // Should be flagged as zero.
+    uncun u0(0.);
+    u0.std_dev(0.001f);
+    CHECK_USED(u0, "0.0000");
+    u0.std_dev(0.0001f);
+    CHECK_USED(u0, "0.00000"); // 
+    u0.std_dev(0.00001f);
+    CHECK_USED(u0, "0.000000"); // 
+    u0.std_dev(0.000001f);
+    CHECK_USED(u0, "0.0000000"); // 
+    u0.std_dev(0.000000000000001f);
+    CHECK_USED(u0,"0.00000000000000"); // All 15 guaranteed decimal digits.
+    u0.std_dev(0.0000000000000001f);
+    CHECK_USED(u0, "0.00000000000000"); // All 17 significant decimal digits.
+    uncun exact(1., 1.f, 2, VALUE_EXACT);  // Exact Unity from double with sd and df.
+    // This should signal a conflict in the constructor!
+    BOOST_CHECK(exact.types() & VALUE_EXACT); // Should still be flagged as exact.
+    BOOST_CHECK_EQUAL(exact.value(), 1.); // value
+    BOOST_CHECK_EQUAL(exact.std_dev(), 0.f);//  StdDeviation should be over-ridden by VALUE_EXACT.
+    // "Value 1 flagged as exact, but uncertainty 1 is not zero!"
+    BOOST_CHECK_EQUAL(exact.deg_free(), 0); // deg_free should be overwritten by VALUE_EXACT.
+    // "Value 1 flagged as exact, but degfree 2 is not zero!"
+
+    uncun iminus1(-1); // Exact minus 1 from integer -1 value.
+    BOOST_CHECK(iminus1.types() & VALUE_INTEGER); // Check IS recognised as integer.
+    BOOST_CHECK(iminus1.types() & VALUE_EXACT); // Check IS recognised as integer.
+    BOOST_CHECK(iminus1.types() & UNC_NOPLUS); // Check IS recognised as no > 0.
+    uncun iminus10(-10); // Exact minus 10 from integer -1 value.
+    BOOST_CHECK(iminus10.types() & VALUE_INTEGER); // Check IS recognised as integer.
+    BOOST_CHECK(iminus10.types() & UNC_NOPLUS); // Check IS recognised as not > 0.
+    BOOST_CHECK(iminus10.types() & UNC_NOMINUS); // Check IS recognised as not < 0.
+    CHECK_USED(iminus10, "-10");  // Must be negative integer. 
+
+    uncun uminus1(-1.); // NOT Exact minus 1 from double -1. value.
+    BOOST_CHECK(!(uminus1.types() & VALUE_INTEGER)); // Check IS recognised as integer.
+    CHECK_USED(uminus1, "-1.");  // Must be negative double, not integer.  
+    // These fail separating 1 and .
+    //CHECK_USED(left << setw(10)  << uminus1, "-1.       ");  //
+    //CHECK_USED(right << setw(10) << uminus1, "       -1.");  //
+
+ }   // BOOST_AUTO_TEST_CASE(unc_test_unity)
+
+ BOOST_AUTO_TEST_CASE(unc_test_1234)
+ {
+    int t = 12;
+    uncun twelveI(t); // Exact 12 from integer variable.
+    BOOST_CHECK(twelveI.types() & VALUE_INTEGER); // Check IS integer from variable.
+    CHECK_USED(twelveI, "12"); // no . because integer.
+//    CHECK_USED(noplusminus << showpoint << twelveI, "12."); // Show decimal point for integer value only if showpoint.
+    CHECK_USED(plusminus << twelveI, "12"); // Do NOT show +/-0 for integer value.
+    twelveI.types(VALUE_INTEGER); // Clear integer flag.
+    BOOST_CHECK(!(twelveI.types() & VALUE_INTEGER)); // Check integer flag has cleared.
+    CHECK_USED(twelveI, "12."); // Should have decimal point because sd = 0 so should be exact like 2.54.
+
+    uncun twelve3(12.3, 0.026f); // Explicit sd. 
+    CHECK_USED(noplusminus << twelve3, "12.30"); // OK
+    CHECK_USED(plusminus << twelve3, "12.30 +/-0.026"); 
+    //CHECK_OUT_IN(plusminus << twelve3, "12.30 +/-0.05", 12.3, 0.025f, 0,  (UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT) ));
+
+    uncun imax(numeric_limits<int>::max()); // Exact int max 2147483647.
+    BOOST_CHECK(imax.types() & VALUE_INTEGER); // Check IS integer from argument.
+    CHECK_USED(imax, "2147483647"); // no . because integer.
+
+    uncun imin(numeric_limits<int>::min()); // Exact int min -2147483648.
+    BOOST_CHECK(imin.types() & VALUE_INTEGER); // Check IS integer from argument.
+    CHECK_USED(imin, "-2147483648"); // no . because integer.
+    uncun twelvede(1234.); // double from double variable, default stddev, so implicitly exact.
+    BOOST_CHECK(!(twelvede.types() & VALUE_INTEGER)); // Check is NOT integer from variable.
+    BOOST_CHECK((twelvede.types() & VALUE_EXACT)); // Check IS flagged as exact.
+    CHECK_USED(twelvede, "1234."); // . because from double, even though exact.  // 1.234 no trailing zeros.
+ } // BOOST_AUTO_TEST_CASE(unc_test_1234)
+
+ BOOST_AUTO_TEST_CASE(unc_test_exact)
+ { // Exact values
+   // 1. inch Autoscaled SI 25. +/- 13. millimeter or 25. mm
+    // 1.0 inch Autoscaled SI 25.4 +/- 1.3 millimeter or 25.4 mm
+    // 1.00 Autoscaled SI 25.4 +/- 0.13 millimeter or 25.4 mm
+    // 1.000 Autoscaled SI 25.400 +/- 0.013 millimeter or 25.400 mm
+   
+    uncun inch_in_cm(2.54); // Exact, with decimal fraction part, implicitly created from double.
+    BOOST_CHECK((inch_in_cm.types() & VALUE_EXACT)); // Check is known to be exact.
+
+    CHECK_USED(inch_in_cm, "2.54"); // No trailing zeros, because exact.
+    // Trailing zeros would imply an uncertainty.
+
+    inch_in_cm.setUncTypes(inch_in_cm.types() & ~VALUE_EXACT); // Flag as NOT exact.
+    BOOST_CHECK(!(inch_in_cm.types() & VALUE_EXACT)); // Check exact flag has cleared.
+    CHECK_USED(inch_in_cm, "2.54000000000000"); // Max trailing zeros, because sd still == 0.F.
+
+    inch_in_cm.std_dev(0.0012f); // Add some uncertainty.
+    BOOST_CHECK(!(inch_in_cm.types() & VALUE_EXACT)); // Check still NOT exact.
+    CHECK_USED(inch_in_cm, "2.540"); // One trailing zeros because std dev specified 0.012f.
+    inch_in_cm.types(VALUE_EXACT); // Make Exact - Explicitly. - Doesn't work
+    inch_in_cm.std_dev(0.f); // No uncertainty.
+    BOOST_CHECK((inch_in_cm.types() & VALUE_EXACT)); // Check is now known to be exact.
+    CHECK_USED(inch_in_cm, "2.54"); // Explicitly exact, so no trailing zeros.
+} //  BOOST_AUTO_TEST_CASE(unc_test_exact)
+
+
+  BOOST_AUTO_TEST_CASE(unc_test_12345)
+  {
+    uncun one234(1234.321, 1000.f); // double from double variable, but NOT exact.
+    BOOST_CHECK(!(one234.types() & VALUE_INTEGER)); // Check NOT integer from variable.
+    BOOST_CHECK(!(one234.types() & VALUE_EXACT)); // Check is NOT flagged as exact.
+    CHECK_USED(one234, "1200."); // Rounded to zero before decimal point shows uncertainty.) 
+    one234.std_dev(100.f);
+    CHECK_USED(one234, "1230."); // No trailing zeros show implicit uncertainty.
+    one234.std_dev(10.f);
+    CHECK_USED(one234, "1234."); // because from double and not exact, fractional decimals show uncertainty.
+    one234.std_dev(1.f);
+    CHECK_USED(one234, "1234.3"); // because from double and not exact, fractional decimals show uncertainty.
+    one234.std_dev(0.1f);
+    CHECK_USED(one234, "1234.32"); // because from double and not exact, fractional decimals show uncertainty.
+    one234.std_dev(0.01f);
+    CHECK_USED(one234, "1234.321"); // because from double and not exact, trailing zero shows uncertainty.
+    
+    uncun twelve34(12.34, 0.10f); // double from double variable, but NOT exact.
+    BOOST_CHECK(!(twelve34.types() & VALUE_INTEGER)); // Check NOT integer from variable.
+    BOOST_CHECK(!(twelve34.types() & VALUE_EXACT)); // Check is flagged NOT exact.
+    CHECK_USED(twelve34, "12.34"); // because from double and not exact, trailing zeros show uncertainty.
+    twelve34.std_dev(0.01f);
+    CHECK_USED(twelve34, "12.340"); // trailing zeros show uncertainty.
+    twelve34.std_dev(0.001f);
+    CHECK_USED(twelve34, "12.3400"); // trailing zeros show uncertainty.
+    twelve34.std_dev(0.0001f);
+    CHECK_USED(twelve34, "12.34000"); // trailing zeros show uncertainty.
+    twelve34.std_dev(0.00001f);
+    CHECK_USED(twelve34, "12.340000"); // trailing zeros show uncertainty.
+    // Now increase std above the step 1.9999
+
+    twelve34.std_dev(1.f);
+    CHECK_USED(twelve34, "12.3"); // 
+    CHECK_USED(addnoisyDigit << twelve34, "12.34"); // 1 more sig digit because requested.
+
+    twelve34.std_dev(2.f);
+    CHECK_USED(twelve34, "12."); // 1 less sig digit because over the 1.9999 stdDev step.
+    CHECK_USED(addnoisyDigit << twelve34, "12.3"); // 1 more sig digit because requested.
+
+    uncun twelve(12., 0.25f); // Implicit from input of 12. is +|- 0.5
+    // so for 0.95 probability, to get std deviation halve 0.5 to 0.25.
+    CHECK_USED(twelve, "12.0"); // Implicit noplusminus.
+    CHECK_USED(twelve << noplusminus, "12.0"); // Explicit NO plusminus.
+    CHECK_USED(plusminus << twelve, "12.0 +/-0.25"); // Explicit plusminus. 
+
+    uncun twoPoint54(2.54, 0.f); // Real and exact.
+    BOOST_CHECK( (twoPoint54.types() & VALUE_EXACT)); // Check IS flagged as exact.
+    BOOST_CHECK(!(twoPoint54.types() & VALUE_INTEGER)); // Check NOT flagged as integer.
+    CHECK_USED(noplusminus << twoPoint54, "2.54"); // Check no added +/- .
+    CHECK_USED(plusminus << twoPoint54, "2.54 +/-0"); // Check do get added +/- 
+
+    uncun onepoint2(1.2);
+    CHECK_USED(onepoint2, "1.2");  // Exact.
+    onepoint2.std_dev(1.f);
+    CHECK_USED(onepoint2, "1.2");
+    onepoint2.std_dev(0.1f);
+    CHECK_USED(onepoint2, "1.20"); 
+    onepoint2.std_dev(0.01f);
+    CHECK_USED(onepoint2, "1.200"); 
+    onepoint2.std_dev(0.001f);
+    CHECK_USED(onepoint2, "1.2000");
+    onepoint2.std_dev(0.005f);
+    CHECK_USED(onepoint2, "1.200");
+} //  BOOST_AUTO_TEST_CASE(unc_test_12345)
+  
+BOOST_AUTO_TEST_CASE(unc_test_input)
+{
+  // zero integer rational uncKnown noPlus noMinus at end of read.
+  uncun r1;
+  //outUncTypes(r1.types(), cout);
+  istringstream isr1("0"); // Read from integer.
+  isr1 >> r1;
+  BOOST_CHECK_EQUAL(r1.value(), 0.);
+  BOOST_CHECK_CLOSE_FRACTION(r1.value(), 0., std::numeric_limits<double>::epsilon());
+  BOOST_CHECK_EQUAL(r1.std_dev(), 0.f);
+  BOOST_CHECK_EQUAL(r1.deg_free(), 0);
+  BOOST_CHECK_EQUAL(r1.types(), 
+    (VALUE_ZERO | VALUE_INTEGER | VALUE_RATIONAL | UNC_KNOWN | VALUE_EXACT | UNC_NOPLUS | UNC_NOMINUS));
+
+  // Read from real zero 0. with implicit +/- 0.5 == std deviation 0.5.
+  CHECK_IN("0.", 0., 0.5f, 0,  (VALUE_ZERO | UNC_KNOWN | UNC_QUAN_DECIMAL)  );
+  // Read from real unit 1. with implicit +/- 0.5 == std deviation 0.5.
+  CHECK_IN("1.", 1., 0.5f, 0,  (UNC_KNOWN | UNC_QUAN_DECIMAL));
+  // Read from real . with implicit +/- 0.5 == std deviation 0.5.
+  CHECK_IN("12.", 12., 0.5f, 0,  (UNC_KNOWN | UNC_QUAN_DECIMAL));
+  // Read from real with implicit +/- 0.5 == std deviation 0.5.
+  CHECK_IN("123.", 123., 0.5f, 0,  (UNC_KNOWN | UNC_QUAN_DECIMAL));
+  // Read from real with implicit +/- 0.05 == std deviation 0.05.
+  CHECK_IN("0.1", 0.1, 0.05f, 0,  (UNC_KNOWN | UNC_QUAN_DECIMAL));
+  // Read from real with implicit +/- 0.05 == std deviation 0.05.
+  CHECK_IN("0.12", 0.12, 0.005f, 0,  (UNC_KNOWN | UNC_QUAN_DECIMAL));
+  // Read from real with implicit +/- 0.05 == std deviation 0.05.
+  CHECK_IN("0.01", 0.01, 0.005f, 0,  (UNC_KNOWN | UNC_QUAN_DECIMAL));
+  // Read from real with implicit +/- 0.05 == std deviation 0.005.
+  CHECK_IN("0.001", 0.001, 0.0005f, 0,  (UNC_KNOWN | UNC_QUAN_DECIMAL));
+  // Read from real with implicit +/- 0.05 == std deviation 0.005.
+
+  // Read from real with explicit +/-.
+  CHECK_IN("12. +/-0.1", 12., 0.1f, 0, (UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT));
+  // Read from real with -/+ instead of +/-.
+  CHECK_IN("12. +/-0.1", 12., 0.1f, 0, (UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT));
+  // Read real zero, but +/1.
+  CHECK_IN("0. +/-0.1", 0., 0.1f, 0, (VALUE_ZERO | UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT));
+  // Read real zero, but -/+.
+  CHECK_IN("0. -/+0.1", 0., 0.1f, 0, (VALUE_ZERO | UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT));
+
+  // Read from real zero, plus only.
+  CHECK_IN("0. +0.01", 0.,  0.01f, 0, (VALUE_ZERO | UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT | UNC_NOMINUS));
+  // Read from real, minus only.
+  CHECK_IN("0. -0.2", 0., 0.2f, 0, (VALUE_ZERO | UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT | UNC_NOPLUS));
+
+  CHECK_IN("12. +|-0.1 (19)", 12., 0.1f, 19, (UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT | DEG_FREE_KNOWN | DEG_FREE_EXACT));
+  CHECK_IN("12. +\\-0.1 (19)", 12., 0.1f, 19, (UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT | DEG_FREE_KNOWN | DEG_FREE_EXACT));
+  CHECK_IN("12. +/+0.1 (19)", 12., 0.1f, 19, (UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT | DEG_FREE_KNOWN | DEG_FREE_EXACT | UNC_NOMINUS ));
+  CHECK_IN("12. -/-0.1 (19)", 12., 0.1f, 19, (UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT | DEG_FREE_KNOWN | DEG_FREE_EXACT | UNC_NOPLUS));
+  // Extra layout chars.
+  CHECK_IN("12.   +/-0.1", 12., 0.1f, 0, (UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT)); 
+  CHECK_IN("12.+/-  0.1", 12., 0.1f, 0, (UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT));
+
+  CHECK_IN("12.  +/-  0.1", 12., 0.1f, 0, (UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT));
+
+  // Integer (and hence rational too)
+  CHECK_IN("12 +/-0.1", 12., 0.1f, 0, (VALUE_INTEGER | VALUE_RATIONAL | UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT ));
+  // Rational - not implemented yet.
+  //CHECK_IN("2/3", 2/3, 0.1f, 0, (VALUE_RATIONAL | UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT ));
+  //CHECK_IN("2/3 +/-0.1", 2/3, 0.1f, 0, (VALUE_RATIONAL | UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT ));
+  
+  {
+    uncun r1;
+    istringstream isr1("2/3"); // Read from string.
+    isr1 >> r1;
+    cout << r1.value() << ' ' << r1.std_dev() << ' ' << r1.degFree() << r1.types() << ", " ;
+    outUncTypes(r1.types(), cout);
+    cout << endl;
+  }
+
+    {
+    uncun r1;
+    istringstream isr1("2/3+/-0.02f"); // Read from string.
+    isr1 >> r1;
+    cout << r1.value() << ' ' << r1.std_dev() << ' ' << r1.degFree() << r1.types() << ", " ;
+    outUncTypes(r1.types(), cout);
+    cout << endl;
+  }
+
+
+  // Exponent value and uncertainty.
+  CHECK_IN("12.e1 +/-0.1", 12., 0.1f, 0, (UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT));
+  CHECK_IN("12. +/-0.1e-1", 12., 0.01f, 0, (UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT));
+  CHECK_IN("12.e1 +/-0.1e-1", 12., 0.01f, 0, (UNC_KNOWN | UNC_QUAN_DECIMAL | UNC_EXPLICIT));
+
+  /*
+
+  */
+  // #define	CHECK_OUT_IN(manips, result, value, sd, df, types)
+} //  BOOST_AUTO_TEST_CASE(unc_test_input)
+
+BOOST_AUTO_TEST_CASE(unc_test_unity2)
+{
+  uncun one(1.); // Exact one from double.
+  // Check get and set functions.
+  BOOST_CHECK_EQUAL(one.value(), 1.); // value
+  BOOST_CHECK_EQUAL(one.std_dev(), 0.f); // std_dev
+  BOOST_CHECK_EQUAL(one.deg_free(), 1); // deg_free
+  BOOST_CHECK(!(one.types() & VALUE_ZERO));  // Check not zero.
+  BOOST_CHECK(!(one.types() & VALUE_INTEGER)); // Check NOT recognised as integer.
+  // Because constructed from double should not be integer.
+  CHECK_USED(one, "1."); // Sd = 0 so is exact, but not integer.
+  CHECK_USED(showpos << one, "+1."); // Show + sign.
+  CHECK_USED(plusminus << one, "1. +/-0"); // Do show +/-0 (and .) for NOT integer value.
+
+  one.setUncTypes(VALUE_INTEGER); // Set the integer flag.
+  BOOST_CHECK(one.types() & VALUE_INTEGER); // Check IS recognised as integer.
+  CHECK_USED(one, "1"); // Implicit so no . wanted. 
+  CHECK_USED(noshowpoint << one, "1"); // Explicit no . wanted. 
+  //CHECK_USED(showpoint << one, "1."); //  Explicitly want "1." showpoint is ignored for integers.
+  CHECK_USED(plusminus << one, "1"); // Don't show +/-0 for _integer_ value, despite plusminus.
+  uncun realOne(1.); // is implicitly Exact.
+// Construct from doubles: 1., unc 0.0, df 0 uncTypes (0x6420) uncKnown explicit df_exact df_known 
+//	Constructed from doubles: m_value 1., m_unc 0.0, m_df 0,  uncTypes (0x64e0) uncKnown noPlus noMinus explicit df_exact df_known 
+  BOOST_CHECK(!(realOne.types() & VALUE_INTEGER)); // Check NOT recognised as integer.
+  CHECK_USED(plusminus << realOne, "1. +/-0"); // explicit plusminus, but NOT integer, so show +/-
+  realOne.std_dev(0.1f); // Change to inexact
+  BOOST_CHECK_EQUAL(realOne.std_dev(), 0.1f); // sd = 0.1.
+  BOOST_CHECK(!(realOne.types() & VALUE_EXACT)); // Check NOT now recognised as exact because sd no longer zero.
+  CHECK_USED(plusminus << realOne, "1.00 +/-0.10"); 
+  // Output sd 0.20, stdDevsigDigits 2
+  realOne.std_dev(0.2f);
+  CHECK_USED(plusminus << realOne, "1.0 +/-0.20");
+  realOne.std_dev(0.3f);
+  CHECK_USED(plusminus << realOne, "1.0 +/-0.30");
+  realOne.std_dev(0.01f);
+  CHECK_USED(plusminus << realOne, "1.000 +/-0.010");
+  realOne.std_dev(0.0101f);
+  CHECK_USED(plusminus << realOne, "1.000 +/-0.010");
+
+  realOne.std_dev(0.05f);
+  CHECK_USED(plusminus << realOne, "1.00 +/-0.050");
+  realOne.std_dev(0.001f);
+  CHECK_USED(plusminus << realOne, "1.0000 +/-0.0010");
+  realOne.std_dev(0.075f);
+  CHECK_USED(plusminus << realOne, "1.00 +/-0.075"); // Note rounding because df = 1
+  BOOST_CHECK_EQUAL(realOne.deg_free(), 1); // deg_free
+  realOne.deg_free(11); // Increase degfree.
+  BOOST_CHECK_EQUAL(realOne.deg_free(), 11); // Check has increased.
+  CHECK_USED(plusminus << realOne, "1.00 +/-0.075"); // Note NO rounding because df = 10
+  realOne.deg_free(101); // and more
+  BOOST_CHECK_EQUAL(realOne.deg_free(), 101); // 
+  CHECK_USED(plusminus << realOne, "1.00 +/-0.075"); // Note NO rounding because df = 100
+  realOne.deg_free(1001);
+  BOOST_CHECK_EQUAL(realOne.deg_free(), 1001); // 
+  CHECK_USED(plusminus << realOne, "1.00 +/-0.075"); // Note NO rounding because df = 1000
+} //  BOOST_AUTO_TEST_CASE(unc_test_unity2)
+
+BOOST_AUTO_TEST_CASE(unc_test_123)
+{
+  uncun onetwothree(1.23); // Exact from double, 
+  BOOST_CHECK_EQUAL(onetwothree.value(), 1.23);
+  BOOST_CHECK_EQUAL(onetwothree.std_dev(), 0.f);
+  BOOST_CHECK_EQUAL(onetwothree.deg_free(), 1);
+  BOOST_CHECK(!(onetwothree.types() & VALUE_ZERO));
+  BOOST_CHECK(!(onetwothree.types() & VALUE_INTEGER));
+  CHECK_USED(onetwothree, "1.23");
+  CHECK_USED(showpos << onetwothree, "+1.23"); // Check showpos works.
+  //CHECK_USED(setw(10) << showpos << onetwothree, "+1.23     "); // TODO fails.
+
+  uncun minusone(-1.); // Exact minus one from double.
+  CHECK_USED(minusone, "-1."); 
+  uncun minusonetwothree(-1.23); // Exact negative from double, 
+  CHECK_USED(minusonetwothree, "-1.23"); 
+
+  uncun one2345(1.2345, 0.01f, 2); // Inexact from double, sd 0.01, df 2 values.
+  BOOST_CHECK_EQUAL(one2345.value(), 1.2345); // Check contructor.
+  BOOST_CHECK_EQUAL(one2345.std_dev(), 0.01f);
+  BOOST_CHECK_EQUAL(one2345.deg_free(), 2); // Now 2 means 2 values.
+  BOOST_CHECK(!(one2345.types() & VALUE_ZERO));
+  BOOST_CHECK(!(one2345.types() & VALUE_INTEGER));
+  CHECK_USED(one2345, "1.235"); // Round-up 4 sigDigits because sd 0.01
+  // Check that > 10 values means that more significant digits are used.
+  one2345.deg_free(10); // 0 is one value, so 10 means 11 values.
+  one2345.std_dev(0.01234f); // Check rounding of std deviation.
+  BOOST_CHECK_EQUAL(one2345.std_dev(), 0.01234f);
+  BOOST_CHECK_EQUAL(one2345.deg_free(), 10); // 0 is one value, so 10 means 11 values.
+  CHECK_USED(plusminus << one2345, "1.235 +/-0.012");  // Not +/-0.0123 despite sd < 0.02
+  one2345.deg_free(10); // 1 value.
+} //   BOOST_AUTO_TEST_CASE(unc_test_123)
+
+BOOST_AUTO_TEST_CASE(unc_test_nines)
+{
+  uncun nine95B(_nextafter(9.95, numeric_limits<double>::min()), 2.f); // Inexact from double, sd 0.01, df 2 = 3 values.
+  uncun nine95A(_nextafter(9.95, numeric_limits<double>::max()), 2.f); // Inexact from double, sd 0.01, df 2 = 3 values.
+  uncun nine95(9.95, 2.f); // Inexact from double, sd 0.01, df 2 = 3 values.
+  uncun nine94(9.94, 2.f); // Inexact from double, sd 0.01, df 2 = 3 values.
+  uncun nine96(9.96, 2.f); // Inexact from double, sd 0.01, df 2 = 3 values.
+}
+
+BOOST_AUTO_TEST_CASE(unc_test_rounding)
+{
+  // Uncertain values.
+   uncun one2345(1.2345, 0.01f, 2); // Inexact from double, sd 0.01, df 2 = 3 values.
+    one2345.std_dev(0.0049f);
+    CHECK_USED(plusminus << one2345, "1.235 +/-0.0049"); // 3 significant value, but only 1 sd digits.
+    one2345.std_dev(0.005f);
+    CHECK_USED(plusminus << one2345, "1.235 +/-0.0050"); //
+    one2345.std_dev(0.009f);  
+    CHECK_USED(plusminus << one2345, "1.235 +/-0.0090"); // 
+    one2345.std_dev(0.01f);  
+    CHECK_USED(plusminus << one2345, "1.235 +/-0.010"); // 
+    one2345.std_dev(0.011f);  
+    CHECK_USED(plusminus << one2345, "1.235 +/-0.011"); // 
+    one2345.std_dev(0.02f);  
+    CHECK_USED(plusminus << one2345, "1.23 +/-0.020");  // Round up to 1.24, 2 significant value digits.
+    one2345.std_dev(0.05f);  
+    CHECK_USED(plusminus << one2345, "1.23 +/-0.050");  // 1 significant sd digit.
+    one2345.std_dev(0.06f);  
+    CHECK_USED(plusminus << one2345, "1.23 +/-0.060");  //
+    one2345.std_dev(0.07f);  
+    CHECK_USED(plusminus << one2345, "1.23 +/-0.070");  // 
+    one2345.std_dev(0.08f);  
+    CHECK_USED(plusminus << one2345, "1.23 +/-0.080");  // 
+    one2345.std_dev(0.09f);  
+    CHECK_USED(plusminus << one2345, "1.23 +/-0.090");  // 
+    one2345.std_dev(0.095f);  
+    CHECK_USED(plusminus << one2345, "1.23 +/-0.095");  // 
+
+    one2345.std_dev(0.01f);
+    // without noscientific << causes std dev shows in exp format:  1.235 +/-1.00e-002  
+    CHECK_USED(scientific << noplusminus << one2345, "1.235"); 
+    CHECK_USED(scientific << plusminus << one2345, "1.235 +/-0.010");  // OK note not +/-0.010  because < 0.02.
+    one2345.std_dev(0.019f);  
+    CHECK_USED(scientific << plusminus << one2345, "1.23 +/-0.019");  // Note still 2 significant digits.
+    one2345.std_dev(0.02f);
+    CHECK_USED(scientific << plusminus << one2345, "1.23 +/-0.020");  // Note step change to 1 significant digits at 1.999.
+    one2345.std_dev(0.09f);
+    CHECK_USED(scientific << plusminus << one2345, "1.23 +/-0.090");  // Note sd 1 significant digit.
+    one2345.std_dev(0.1f);
+    CHECK_USED(scientific << plusminus << one2345, "1.23 +/-0.10");  // OK note not +/-0.01  because < 0.02.
+    one2345.std_dev(0.19f);
+    CHECK_USED(scientific << plusminus << one2345, "1.2 +/-0.19");  // Note still 2 significant digits.
+    one2345.std_dev(0.2f);
+    CHECK_USED(scientific << plusminus << one2345, "1.2 +/-0.20");  // Note step change to 1 significant digits at 1.999.
+    one2345.std_dev(0.9f);
+    CHECK_USED(scientific << plusminus << one2345, "1.2 +/-0.90");  // Note 1 significant digit.
+    CHECK_USED(scientific << plusminus << addnoisyDigit << one2345, "1.23 +/-0.90");  // Note 1 more significant digits for value & sd.
+} //   BOOST_AUTO_TEST_CASE(unc_test_rounding)
+
+BOOST_AUTO_TEST_CASE(unc_test_big)
+{
+  uncun bigish(1e14, 2e12f); // Not bigger than maxdigits10 limit 1 and 15 zeros, small unc.
+  CHECK_USED(bigish, "100000000000000.");  //
+  uncun bigish2(1.23456789e14, 2e12f); // 
+  CHECK_USED(bigish2, "123000000000000.");  //  Show some non-zero digits.
+  uncun bigish3(1.23456789e14, 1e6f); // 
+  CHECK_USED(bigish3, "123456789000000.");  // Show many non-zero digits.
+
+  // Check on too big values.
+  uncun big(1e39, 2e36f); // Bigger than exponent limit.
+  //cout << big << endl;
+  CHECK_USED(big, "1e+039");  // Default exp format, precision 6 total decimal digits.
+
+  uncun bigSI(1e25, 2.f); // Bigger than SI exponent limit.
+  CHECK_USED(bigSI, "1e+025");  // // Default exp format, precision 6
+  // Some very big integers and exacts.
+  uncun million = uncun(1000000);  // Exact integer million 1000000
+  CHECK_USED(million, "1000000"); // integer.
+  uncun billion = uncun(1000000000);  // Exact integer billion 1000000000
+  CHECK_USED(billion, "1000000000"); // integer.
+
+  // Exact but not integer.
+  uncun i10e3 = uncun(1.e3, 0.0f);  // Exact real thousand 1000,
+  CHECK_USED(i10e3, "1000."); // 1000. exact, but not integer.
+
+  uncun i10e6 = uncun(1.e6, 0.f);  // Exact real million 1000000.
+  CHECK_USED(i10e6, "1000000."); // exact.
+
+  uncun i10e6u = uncun(1.e6, 0.000001f);  // Nearly exact real million 1000000.
+  CHECK_USED(i10e6u,  "1000000.0000000"); // 
+  uncun i10e61 = uncun(1000000.123, 0.f);  // Exact real million 1000000.123.
+  CHECK_USED(i10e61, "1000000.123"); // exact.
+  uncun i10e62 = uncun(1000000.123, 0.000001f);  // Nearly Exact real million 1000000
+  CHECK_USED(i10e62, "1000000.1230000"); // exact.
+  uncun i10e9 = uncun(1.0e9, 0.0f);  // Exact billion 1000000000.
+  CHECK_USED(i10e9, "1000000000.");
+
+  uncun i10e99 = uncun(987654321., 0.0f);  // Exact 9 billion 987654321.
+  CHECK_USED(i10e99, "987654321.");
+
+} // BOOST_AUTO_TEST_CASE(unc_test_big)
+
+BOOST_AUTO_TEST_CASE(unc_test_manips)
+{
+  // Examples of scientific and unc values including setw.
+  uncun one2345(1.2345, 0.01f, 2); // Inexact from double, sd 0.01, df 2 = 3 values.
+  one2345.std_dev(0.01f);
+  CHECK_USED(scientific << noplusminus << setw(20) << left << one2345,   "1.235               "); // 
+  CHECK_USED(scientific << plusminus << setw(20) << left << one2345,     "1.235 +/-0.010      "); // 
+  CHECK_USED(scientific << plusminus << setw(20) << right << one2345,    "      1.235 +/-0.010"); //
+  CHECK_USED(scientific << plusminus << setw(20) << noadjust << one2345, "      1.235 +/-0.010"); // == right adjust.
+  CHECK_USED(scientific << plusminus << setw(20) << showpos << one2345,  "     +1.235 +/-0.010"); // == right adjust.
+  CHECK_USED(scientific << plusminus << setw(20) << showpos 
+                                                << internal << one2345,  "     +1.235 +/-0.010"); // Expect same as right.
+
+  CHECK_USED(scientific << plusminus << setw(20) << noadjust << setfill('~') << one2345, "~~~~~~1.235 +/-0.010"); // expect same as right adjust.
+  CHECK_USED(scientific << plusminus << setw(20) << setfill('~') << left << one2345,     "1.235 +/-0.010~~~~~~"); // 
+  CHECK_USED(scientific << plusminus << setw(20) << setfill('~') << internal << one2345, "~~~~~~1.235 +/-0.010"); 
+  CHECK_USED(scientific << plusminus << setw(20) << setfill('~') << right << one2345,    "~~~~~~1.235 +/-0.010"); // Expect same as right.
+  
+  // Some bigger values.
+  uncun ten2345(10.2345, 0.01f, 2); // Inexact from double, sd 0.01, df 2 = 3 values.
+  CHECK_USED(scientific << noplusminus << setw(20) << left << ten2345,   "10.235              "); // 
+
+} // BOOST_AUTO_TEST_CASE(unc_test_manips)
+
+BOOST_AUTO_TEST_CASE(unc_test_setsigfigs)
+{ // Tests of fixing sigfigs.
+  uncun u0(0, 0);  // Exact Zero, using constructor from int zero.
+
+  fout << "setSigDigits(4) " << setSigDigits(4) << endl; // Check can set setsigdigits,
+  BOOST_CHECK_EQUAL(fout.iword(setSigDigitsIndex), 4); // and read back correctly.
+
+  fout << "setUncSigDigits(1) " << setUncSigDigits(1) << endl; // Check can set setuncsigdigits,
+  BOOST_CHECK_EQUAL(fout.iword(setUncSigDigitsIndex), 1); // and read back correctly.
+
+  CHECK(setSigDigits(4) << u0, "0"); // Not yet setsigdigits, so has no effect.
+  // setsigdigits should force to 4 digits set by setSigDigits(4).
+  CHECK(setSigDigits(4) << setsigdigits << u0, "0.0000"); // Fails!
+
+  uncun one(1., 0.001f); // 
+  CHECK(setSigDigits(3) << setsigdigits << one, "1.00"); //  getting 1.
+  CHECK_USED(setSigDigits(-1) << setsigdigits << u0, "0.00000000000000000"); // Invalid sigDigits (show max_digits10).
+  CHECK_USED(setSigDigits(0) << setsigdigits << u0, "0.00000000000000000"); // Zero sigDigits (show max_digits10).
+  CHECK_USED(setSigDigits(1) << setsigdigits << u0, "0.0"); // Override normal is still exact, so no decimal point.
+  CHECK_USED(setSigDigits(2) << setsigdigits << u0, "0.00"); // Is still exact, so no decimal point.
+  CHECK_USED(setSigDigits(3) << setsigdigits << u0, "0.000"); // 
+  CHECK_USED(setSigDigits(4) << setsigdigits << u0, "0.0000"); //
+  CHECK_USED(setSigDigits(1) << setsigdigits << showpoint << u0, "0.0"); // Override normal is still exact, but showpoint demands a decimal point.
+  CHECK_USED(setSigDigits(1) << setsigdigits << showpos << u0, "+0.0"); //  Show plus sign.
+  CHECK_USED(setSigDigits(1) << setsigdigits << left << setw(6) << u0, "0.0   "); // Trailing spaces.
+
+
+  uncun u(12.345678, 0.09876F);
+  CHECK_USED(plusminus << u, "12.35 +/-0.099");
+  CHECK_USED(setSigDigits(6) << setsigdigits << plusminus << u, "12.3457 +/-0.099");
+  CHECK_USED(setSigDigits(6) << setsigdigits << plusminus << showpos << u, "+12.3457 +/-0.099");
+  CHECK_USED(setUncSigDigits(6) << setuncsigdigits << plusminus << u, "12.35 +/-0.0988");
+  // Uncertainty controls value but not uncertainty digits of precision.
+
+} 
+
+BOOST_AUTO_TEST_CASE(unc_test_setscale)
+{   // Tests of	unc setscale and autoscale functions.
+  // These may not be necessary because Boost.Units provides autoscaling via autoprefix.
+  //  uncun int10000(10000); // Should not be autoscaled nor set scaled.
+  //  CHECK_USED(int10000, "10000"); // NOT 10.000 k because is neither autoscaled nor set scaled.
+  //  CHECK_USED(autoscale << int10000, "10000"); // NOT 10.000 k because is integer.
+  //  CHECK_USED(scale	 << int10000, "10000"); // NOT 10.000 k because is integer.
+  //  uncun zero(0, 0.000001f); 
+  //  CHECK_USED(zero, "0"); 
+  //  CHECK_USED(autoscale << zero, "0"); // zero Should not be autoscaled 
+  //  CHECK_USED(setScale(6) << scale << zero, "0");  // nor set scaled.
+
+  //  uncun uScaled1(0.00123456);	// Input scaled	by unit	prefix or	symbol.
+  //  uncun uScaled2(2345.678);	// 
+  //  uncun uScaled3(1.23456);	//
+  //  CHECK_USED(autoscale <<	addsisymbol <<	uScaled3, "1.23456 "); // Is trailing space if no symbol right?
+  //  CHECK_USED(autoscale <<	addsisymbol <<	uScaled1, "1.23456 m");
+  //  CHECK_USED(autoscale <<	addsisymbol <<	uScaled2 , "2.345678 k");
+  //  CHECK_USED(autoscale <<	addsiprefix << 	uScaled1, "1.23456 milli");
+  //  CHECK_USED(autoscale <<	addsiprefix << 	uScaled2, "2.345678 kilo");
+  //  CHECK_USED(autoscale <<	addsiprefix <<	addsisymbol << 	uScaled2, "2.345678 kilo");
+  //  // Check get prefix if specify both.
+  //  CHECK_USED(noautoscale << scale	<< setScale(3)	<<	addsisymbol <<	 uScaled2, "2.345678 k");
+  //  CHECK_USED(scale <<	addsisymbol <<	 uScaled2 , "2345.678 "); // Can't test re-use of previous set scale(3).
+
+  //  CHECK_USED(scale	 << setScale(6)	<<	addsisymbol <<	 uScaled2 , "0.002345678 M");
+  //  CHECK_USED(scale	 << setScale(4)	<<	addsisymbol <<	 uScaled2 , "0.2345678 ");
+  //  CHECK_USED(scale	 << setScale(2)	<<	addsisymbol <<	 uScaled2 , "23.45678 h");
+  //  CHECK_USED(scale	 << setScale(1)	<<	addsisymbol <<	 uScaled2 , "234.5678 da");
+  //  CHECK_USED(scale	 << setScale(0)	<<	addsisymbol <<	 uScaled2 , "2345.678 ");
+  //  CHECK_USED(scale	 << setScale(-1)	 <<	addsisymbol <<	 uScaled2 , "23456.78 d");
+  //  CHECK_USED(scale	 << setScale(-2) 	<<	addsisymbol <<	 uScaled2 , "234567.8 c");
+  //  CHECK_USED(scale	 << setScale(-3) 	<<	addsisymbol <<	 uScaled2 , "2345678 m");
+  //  CHECK_USED(scale	 << setScale(-4)	 <<	addsisymbol <<	 uScaled2 , "23456780 ");
+  //  CHECK_USED(scale	 << setScale(-6)	 <<	addsisymbol <<	 uScaled2 , "2345678000 u"); // Silly scaling!
+  //  CHECK_USED(scale	 << setScale(-9)	 <<	addsisymbol <<	 uScaled2 , "2345678000000 n"); // Silly scaling!
+  //  CHECK_USED(scale	 << setScale(-6)	 <<	addsisymbol <<	 uScaled1 , "1234.56 u"); // 
+  //  CHECK_USED(scale	 << setScale(-3)	 <<	addsisymbol <<	 uScaled1 , "1.23456 m"); // 
+
+  //  CHECK_USED(setSigDigits(2) << setsigdigits << uScaled2 << addsisymbol, "2345.678"); // exact so didn't use setsigdigits
+  //  uScaled2.std_dev(0.1f);
+  //  CHECK_USED(uScaled2 << addsisymbol, "2345.68");
+  //  CHECK_USED(setSigDigits(2) << setsigdigits << uScaled2 << addsisymbol, "2400.");
+} //   BOOST_AUTO_TEST_CASE(unc_test_setscale)
+
+BOOST_AUTO_TEST_CASE(unc_test_asym)
+{	// Some asymetric uncertainties.
+  uncun notMore(1.71, 0.2f, 0, UNC_NOPLUS);  // Only minus.
+  BOOST_CHECK((notMore.types() & UNC_NOPLUS));  // 
+  CHECK_USED(plusminus << notMore, "1.71 +0/-0.20");
+  uncun notLess(1.81, 0.2f, 0, UNC_NOMINUS);  // Only plus.
+  BOOST_CHECK((notLess.types() & UNC_NOMINUS));  // 
+  CHECK_USED(plusminus << notLess, "1.81 -0/+0.20");
+}
+
+BOOST_AUTO_TEST_CASE(unc_test_set_manips)
+{
+  fout << "\nTest one parameter manips to set unc width, scale, sigdigits & unc sigdigits.\n";
+  setUncDefaults(fout);	// Resets stream's format flags to default.
+  fout << resetiosflags(ios_base::basefield | ios_base::adjustfield | ios_base::floatfield
+  | ios_base::showpos | ios_base::showpoint | ios_base::uppercase | ios_base::showbase )
+  << endl;
+  setiosDefaults(fout); // &
+  setUncDefaults(fout);
+
+  BOOST_CHECK_EQUAL(fout.flags(), ios_base::skipws | ios_base::dec);
+  BOOST_CHECK_EQUAL(fout.iword(oldUncSigDigitsIndex), -1);
+  BOOST_CHECK_EQUAL(fout.iword(sigDigitsIndex), 3);  // default
+  BOOST_CHECK_EQUAL(fout.iword(scaleIndex), 0);
+  BOOST_CHECK_EQUAL(fout.iword(widthIndex), -1);
+  BOOST_CHECK_EQUAL(fout.iword(oldScaleIndex),-1);
+  BOOST_CHECK_EQUAL(fout.iword(setScaleIndex), 0);
+  BOOST_CHECK_EQUAL(fout.iword(scaleIndex), 0);
+
+  fout << "setSigDigits(4) " << setSigDigits(4) << endl;
+  BOOST_CHECK_EQUAL(fout.iword(setSigDigitsIndex), 4); 
+
+  fout << setSigDigits(2)	<< endl;
+  BOOST_CHECK_EQUAL(fout.iword(setSigDigitsIndex), 2);
+  BOOST_CHECK_EQUAL(fout.iword(oldSigDigitsIndex), 4); // Check save.
+
+  BOOST_CHECK_EQUAL(fout.iword(oldUncSigDigitsIndex),-1); // Default means not set yet.
+  fout << setUncSigDigits(5) << endl; // Bigger that makes sense.
+  BOOST_CHECK_EQUAL(fout.iword(setUncSigDigitsIndex), 3); // Reduces to max sensible.
+  fout << setUncSigDigits(2) << endl; // ISO default.
+  BOOST_CHECK_EQUAL(fout.iword(setUncSigDigitsIndex), 2); // Is default.
+  BOOST_CHECK_EQUAL(fout.iword(oldUncSigDigitsIndex), 3); // Previous set to 3.
+
+  fout << "setUncWidth(10) " << setUncWidth(20) << flush;
+  BOOST_CHECK_EQUAL(fout.iword(uncWidthIndex), 20);
+
+  fout << "setScale(-3) " << setScale(-3) << flush;
+  BOOST_CHECK_EQUAL(fout.iword(setScaleIndex), -3);
+
+  fout << "setsigdigits(5) " << setSigDigits(5) << flush;
+  BOOST_CHECK_EQUAL(fout.iword(setSigDigitsIndex), 5);
+
+  fout << "setuncsigdigits(1) " << setUncSigDigits(1) << flush;
+  BOOST_CHECK_EQUAL(fout.iword(setUncSigDigitsIndex), 1);
+
+
+} // BOOST_AUTO_TEST_CASE(unc_test_set_manips)
+
+BOOST_AUTO_TEST_CASE(unc_test_more_naninf)
+{ // 	"\nNative method of display of floating point infinity & Not a Number\n";
+  CHECK(numeric_limits<double>::infinity(), "1.#INF");
+  CHECK(-numeric_limits<double>::infinity(), "-1.#INF");
+  CHECK(numeric_limits<float>::quiet_NaN() , "1.#QNAN");
+  CHECK(-numeric_limits<float>::quiet_NaN() , "-1.#IND");
+
+  // Uncertain type Infinite value - known exactly.
+  uncun infinite(numeric_limits<double>::infinity(), 0.f);  // Exact plus infinity.
+  CHECK_USED(infinite, "inf");
+  CHECK_USED(plusminus << infinite, "inf +/-0");
+  CHECK_USED(std::showpos << infinite, "+inf");
+  CHECK_USED(std::showpos << plusminus << infinite, "+inf +/-0");
+
+  uncun infiniteUK(numeric_limits<double>::infinity(), 0.1f);  // unknown plus infinity.
+  CHECK_USED(plusminus << infiniteUK, "inf +/-0.10");
+  CHECK_USED(std::showpos << plusminus << infiniteUK, "+inf +/-0.10");
+
+  uncun exactNaN(numeric_limits<double>::quiet_NaN(), 0.f); // Exact NaN
+  CHECK_USED(exactNaN, "NaN");
+  CHECK_USED(plusminus << exactNaN, "NaN +/-0");
+
+  // NaN with known uncertainty.
+  uncun NaNknown(numeric_limits<double>::quiet_NaN(), 0.01f);
+  CHECK_USED(NaNknown, "NaN");
+  CHECK_USED(plusminus << NaNknown, "NaN +/-0.010");
+  uncun NaNknown2(numeric_limits<double>::quiet_NaN(), 0.1f);
+  CHECK_USED(plusminus << NaNknown2, "NaN +/-0.10");
+
+  uncun undefined_uncertain = uncun(numeric_limits<double>::quiet_NaN(), 0.1f);
+  CHECK_USED(plusminus << undefined_uncertain, "NaN +/-0.10");
+
+  uncun NaNUnknown(numeric_limits<double>::quiet_NaN(), numeric_limits<float>::quiet_NaN()); // NaN of NaN uncertainty.
+  CHECK_USED(plusminus << NaNUnknown, "NaN +/-?");
+
+  // Values with unknown uncertainty.
+  // Try to treat stdDev==NaN as a special case,
+  // but get different results for zero and other values.
+  // max_digits10 used for zero (for which a case could be made),
+  // default precision 6 for others.
+  // Unable to see why at present, but other cases may be flawed too.
+
+} // BOOST_AUTO_TEST_CASE(unc_test_naninf)
+
+BOOST_AUTO_TEST_CASE(unc_test_unc_Nan_inf)
+{
+  uncun zeroMaybe(0., numeric_limits<float>::quiet_NaN() );
+  CHECK_USED(zeroMaybe, "0.00000000000000000");  //  Show max_digits10 because uncertainty is NaN.
+
+  CHECK_USED(plusminus << zeroMaybe, "0.00000000000000000 +/-?");
+  
+  uncun postwoMaybe(+2., numeric_limits<float>::quiet_NaN());  // +1.234 with unknown uncertainty.
+  //cout << postwoMaybe << endl;
+  uncun posonetwoMaybe(+1.234, numeric_limits<float>::quiet_NaN());  // +1.234 with unknown uncertainty.
+  //cout << posonetwoMaybe << endl;
+  CHECK_USED(posonetwoMaybe, "1.2340000000000000"); 
+
+  uncun negtwoMaybe(-2.2, numeric_limits<float>::quiet_NaN());  // -2.2 with unknown uncertainty.
+  CHECK_USED(negtwoMaybe, "-2.2000000000000002"); 
+  CHECK_USED(plusminus << negtwoMaybe, "-2.2000000000000002 +/-?") 
+  // Fails here on release version.
+  uncun twoMaybe(+2.2, numeric_limits<float>::quiet_NaN());  // +2.2 with unknown uncertainty.
+  CHECK_USED(twoMaybe, "2.2000000000000002"); 
+  CHECK_USED(plusminus << twoMaybe, "2.2000000000000002 +/-?") 
+  uncun infUnknown(9.8, numeric_limits<float>::infinity() );  // Value with infinite uncertainty.
+  CHECK_USED(infUnknown, "9.8000000000000007"); 
+  CHECK_USED(plusminus << infUnknown, "9.8000000000000007 +/-inf");
+} // BOOST_AUTO_TEST_CASE(unc_test_unc_Nan_inf)
+
+BOOST_AUTO_TEST_CASE(unc_test_setsegdigits)
+{
+  uncun zeroMaybe(0., numeric_limits<float>::quiet_NaN() );
+  //CHECK_USED(setSigDigits(7) << setsigdigits << zeroMaybe, "0.0000000"); // TODO
+// setSigDigits must override all other options (and also set stddev sigfigs too).
+} // BOOST_AUTO_TEST_CASE(unc_test_setsegdigits)
+
+BOOST_AUTO_TEST_CASE(unc_test_coda)
+{
+  BOOST_MESSAGE("Uncertain Class tests log end. " << __FILE__ << ' ' <<  __TIMESTAMP__ );
+
+  dout << "\n""Unc Diagnostics log end. " << endl; // \x0F1 = +- on screen, but ~n in files!
+
+  cerr.rdbuf(dout.rdbuf()); // Switch diagnostic log back to cerr before close!
+  // cerr = fout; in effect.
+  dout.close(); // Diagnostics.
+  cerr << "\n\nClosed diagnostics file " << diagFilename << ' '<< __TIMESTAMP__ << endl;
+
+  fout << "\nClosed test output "<< __FILE__ << ' ' <<  __TIMESTAMP__ << endl;
+  fout.close(); // Test output.
+  //lout << logFilename << " end." << endl;
+
+  //unit_test_log.set_stream(cout); // Switch back to cout,
+  //lout.close();  // before close in case there is more log output,
+  // which is almost certain, else ends unhappily!
+
+  cout << "\nClosed fout "<< __FILE__ << ' ' <<  __TIMESTAMP__ << endl;
+//	fin.close();
+//	cout << "\nClosed fin "<< __FILE__ << ' ' <<  __TIMESTAMP__ << endl;
+  cerr << endl;  // Needed to avoid crash right at end.
+}  // BOOST_AUTO_TEST_CASE(unc_test_coda)
+
+
+/*
+
+// Display of all 8-bit characters, showing differences between cout and fout.
+//{for (int i = 1; i < 0xFF; ++i)
+  //{ // Output all 256 8-bit chars.
+  //	fout << char(i);
+  //	if ((i % 64) == 0)
+  //	{ // 64 chars per line, 4 lines.
+  //		fout << nl;
+  //	}
+  //}} // for i
+  //fout << endl;
+  //!"#$%&'()*+,-./0123456789:;<=>?@
+  //ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
+  //
 ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿À
+  //ÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ
+
+// No minus infinity in numeric_limits,
+// but <cfloat> int _fpclass (double) == _FPCLASS_NINF if negative infinity.
+// uncun minus_infinite(MINUS_INFINITY, 0.0f);  // exact minus infinity.
+// fout << " (MINUS_INFINITY, 0.) " << minus_infinite << endl;
+// infinite = uncun(MINUS_INFINITY, 0.1f);  // uncertain plus infinity.
+// fout << " (MINUS_INFINITY, 0.1) " << minus_infinite << endl;
+if (testMath)
+{  
+cerr << "Test math functions." << nl;		
+// New scope for some unc variables.
+uncun a(0), b(0), c(0), d(0),  e(0),  t(0);
+fout <<
+"\nLibrary functions ceil(), floor(), fabs(),  modf(), frexp(), and fmod()\n"
+"all exist primarily for their discontinuities.  All give bad results\n"
+"(and warnings from the test class) when used near a discontinuity.\n" 
+"Extreme care needed in using these functions with uncertain arguments!\n";
+{
+// double fmod (double x, double y) returns the floating-point remainder of x / y.
+uncun mod(0);
+uncun x(0);
+mod = fmod(x + 0.5, 1.0);  // Floating point modulus or remainder.
+fout << "fmod(" << (x + 0.5) << ", " << 1.0 << ") = " << mod << endl;
+mod = fmod(5.5, 0.9 + 0.1 * a);
+fout << "fmod(" << 5.5 << ", " << (0.9 + 0.1 * a) << ") = " << mod << endl;
+}
+{
+// unc modf(unc x, double* intPart) 
+// modf breaks floating-point value x into fractional & integer parts,
+// (each of which has the same sign as x).
+// Returns signed fractional portion of x.
+// Integer portion is stored as a double floating-point value at intPart.
+uncun x(0); // to split.
+uncun frac(0.88); // for return.
+
+double intPartdbl;  // for integer part as double.
+frac = modf(x, &intPartdbl); // integer part as double.
+fout << "modf(" << x << ", intPart) = " << intPartdbl << " & " << frac << endl;
+frac = modf(x + 0.5, &intPartdbl);
+fout << "modf(" << (x + 0.5) << ", intPart) = " << intPartdbl << " & "<< frac << endl;
+}
+// double frexp( double x, int *expptr );
+// breaks floating-point value (x) into a mantissa (m) and an exponent (n),
+// such that the absolute value of 1.0 > m >= 0.5 and x = m*2n.
+// Integer exponent n is stored at the location pointed to by expptr. 
+
+int intPart;  // for exponent part of double.
+t = frexp(c, &intPart);  // split c to mantissa & exponent.
+fout << "frexp(" << c << ", i) = " << t << endl;
+t = frexp(c + 0.5, &intPart);
+fout << "frexp(" << (c + 0.5) << ", i) = " << t << endl;
+t = ceil(c);  // integer (as double) >= double.
+fout << "ceil(" << c << ") = " << " " << t << endl;
+t = ceil(c + 0.5);
+fout << "ceil(" << (c + 0.5) << ") = " << t << endl;
+t = floor(c);  // integer (as double) <= double.
+fout << "floor(" << c << ") = " << t << endl;
+t = floor(c + 0.5);
+fout << "floor(" << (c + 0.5) << ") = " << t << endl;
+
+t = fabs(c);  // absolute value of a double.
+fout << "fabs(" << c << ") = " << t << endl;
+b = -1.2;
+t = fabs(b);
+fout << "fabs(" << b << ") = " << t << endl;
+t = fabs(b + 0.02);
+fout << "fabs(" << (b + 0.02) << ") = " << t << endl;
+// End scope of uncun a,b,c, ...
+} // test Meth
+
+fout << "\nUnits test Output from "
+<< __FILE__ << space << __DATE__ << " " << __TIME__ 
+<< "\n" << endl;
+
+uncun uGiven;  // Give on input.
+uncun uScaled; // Input scaled by unit prefix or symbol.
+uncun uSIvalue (0.);  // Copy or converted from non-SI.
+string test; // = "  123.45 +/- 0.1 mA (99) ! description";
+while(!fin.fail())
+{
+if (fin) getline(fin, test);
+if (test.size() == 0) break;  // to quit.
+if (test.size() > 0)
+{
+fout << "\nINPUT: " << test << endl;  // Echo input to file.
+cerr << "\nINPUT: " << test << endl;  // Echo input to console.
+istringstream is(test);
+is >> uGiven;
+if (is.fail() == true || is.eof() == true)
+{  // No units given.
+
+fout << uGiven << "(no unit)." << flush;
+continue;
+} 
+bool isSIsymbol = false; // true if is k, m, M, G ...
+bool isSIprefix = false;  // true if is kilo, mill, Mega ...
+bool isSImultiple = false;  // if SIsymbol or SIprefix
+bool isUnit = false;  // if a unit like length, mass ... defined.
+bool isSIunit = false;  // true if meter, but false if foot.
+string multipleUnit = "";  // "mm", "Mm", "m", "um" "centim", "inches"...
+string SIsymbol;  // Examples: k, m, M ...
+string SIprefix;  // Examples: "kilo", milli, Mega ...
+string SIunitName = ""; // SI unit for type of unit, meter for length.
+string addSIsymbol = "";  // Example: m for meter
+string unitName = "";   // base unit name, for example meter, inch, oz
+string givenName = "";  // name, abbreviation or alias.
+double confactor;  // multiply by this to convert non-SI to SI unit.
+const unit* u = &length; // unitps[unitno];  // &length, &mass, ¤t ...
+unsigned int SIindex = notOK;  // Index to SIsymbols, SIprefixes & powersOfTen
+// == SI maxPowerTen if unity scale factor.
+const char** uNames;
+const char* unitAbbreviation = "";
+unsigned int unitNamesIndex = notOK;
+unsigned int givenIndex = 0; // uNames[givenIndex] = given name string
+
+is >> ws; // Needed because whitespace made significant by:
+// is.unsetf(ios_base::skipws); or >> noskipws to make all chars significant.
+if (is.peek() == '!')
+{  // comment follows, so
+string comment;
+getline(is, comment);  // to end of line.
+// No units given.
+fout << uGiven << "(no unit)." << flush;
+continue;
+}
+
+is >> multipleUnit;  // 1 meter, 2.2 mm, 1 inch, 3.4 uin or u"
+cerr << "multipleUnit " << multipleUnit << endl;
+is >> ws;  // Ensure any trailing whitespace read.
+
+// TODO multiple units like mg/ml also written as mg ml-1???
+
+if (multipleUnit[0] == '?')
+{
+if (multipleUnit[1] == '?')
+{  // Show all units for all types, mass, length, current ...
+// fout << "\nshowAllUnits(u, fout); for all units.\n" << endl;
+for (int unitno = 0; unitno < unitsCount; unitno++)  // All units.
+{
+const unit* unit = unitps[unitno];
+showAllUnits(unit, fout);
+}
+continue;  // while more test input.
+}
+else
+{  // Just some examples - or select somehow length, mass etc.
+// showAllUnits(¤t, fout); // Show possible units for current.
+// showAllUnits(&mass, fout);  // Show possible units for mass.
+// showAllUnits(&length, fout); // Show all possible units for length.
+showAllUnits(u, fout); // Show all possible units for current unit of .
+continue;  // while more test input.
+} // ?? option all units.
+}  // ? option current unit.
+
+// Try to decipher the unit, & SI symbol or prefix multiple, if any.
+// unitNamesIndex is one of unitNames like meter, inch, feet ...
+unitNamesIndex = findUnit(multipleUnit, u, givenIndex, SIindex);
+
+isUnit = !(unitNamesIndex == notOK);
+if (isUnit)  // of specified unit type like mass, length ...
+{
+uNames = u->unitNames[unitNamesIndex];  // gram, ton, cwt, lb, oz ...
+givenName = uNames[givenIndex]; // Name actually given on input.
+unitName = uNames[0];  // Base unit name: meter, inch, feet ...
+// not abbreviation or alias.
+unitAbbreviation = uNames[1];  // Base unit abbreviation: m, in, ft ..
+SIunitName = u->SIunitNames[0]; // For example: meter, gram, second ...
+addSIsymbol = u->SIunitNames[1];  // m, g, s ...
+confactor = u->unitToSIfactors[unitNamesIndex]; // Conversion factor to SI unit.
+}
+else // isUnit == false
+{
+cerr << "Unit " << multipleUnit << " is NOT a unit of " << u->unitOf << '.' << endl;
+fout << "Unit " << multipleUnit << " is NOT a unit of " << u->unitOf << '.' << endl;
+const unit& ur = findAnyUnit(multipleUnit, unitNamesIndex, givenIndex, SIindex);
+if (&ur == &unknownUnit  || unitNamesIndex == notOK)
+{
+fout << "Unit " << multipleUnit << " is NOT a known unit!" << endl;
+continue;
+}
+
+fout << "But unit " << multipleUnit << " IS a unit of " << ur.unitOf << '.' << endl;
+isUnit = (unitNamesIndex != notOK);
+if (!isUnit)
+{
+continue;
+}
+const unit* uu = u;
+u = &ur;
+uNames = u->unitNames[unitNamesIndex];  // gram, ton, cwt, lb, oz ...
+givenName = uNames[givenIndex]; // Name actually given on input.
+unitName = uNames[0];  // Base unit name: meter, inch, feet ...
+// not abbreviation or alias.
+unitAbbreviation = uNames[1];  // Base unit abbreviation: m, in, ft ..
+SIunitName = u->SIunitNames[0]; // For example: meter, gram, second ...
+addSIsymbol = u->SIunitNames[1];  // m, g, s ...
+confactor = u->unitToSIfactors[unitNamesIndex]; // Conversion factor to SI unit.
+}  // is Unit
+
+isSIunit = (unitNamesIndex == 0);  // If meter not inch.
+isSImultiple = !(SIindex == notOK); // SI symbol or prefix found.
+
+uScaled = uGiven;  // Assume no conversion factor.
+if (isSImultiple)
+{  // Scale using SIindex.
+uScaled *= powersOfTen[SIindex + maxPowerTen - SImaxPowerTen];
+// Works for non-SU units like inch too!
+}  //isSImultiple
+else
+{
+SIindex = SImaxPowerTen;  // So SI symbol & prefix = ""
+}  // no SImultiple.
+SIsymbol = SIsymbols[SIindex]; 
+SIprefix = SIprefixes[SIindex];
+
+if (isSIunit)
+{  
+confactor = u->unitToSIfactors[unitNamesIndex];
+if (confactor != 1.)
+{  // Internal data error, expect SI unit confactor to be unity!
+cerr << "SI unit conversion factor not unity but " << confactor << "!" << endl;
+// Ignoring error.
+uSIvalue = uScaled;
+}
+}
+else
+{ // not SI unit, so convert to SI.
+confactor = u->unitToSIfactors[unitNamesIndex];
+if (confactor != 0.)
+{  // Normal case of valid non-zero conversion factor.
+uSIvalue = uScaled * confactor; // Convert to SI unit.
+}
+else
+{  // Special formula needed, for example degrees Celsius.
+if (unitName == "Celsius")
+{
+uSIvalue = uScaled + 273.15;  // To degrees Kelvin.
+}
+else if (unitName == "Fahrenheit")
+{
+uSIvalue = (uScaled + 459.67) / 1.8;  // NIST 811 p 49.
+} // C or F.
+// else other complex conversion identified by (unitName == "???").
+} // confactor.
+} // SI unit or not.
+
+if (isSIunit)
+{
+fout << "SI unit of " << u->unitOf << ' '
+<< flexform << plusminus << noautoscale  << noSIprefix
+<< uGiven << SIprefix << unitName // millimeter
+<< " or " << SIsymbol << unitAbbreviation ; // mm
+if (isSImultiple)
+{
+fout << ", SI " // "SI 1.23 meter or m"
+<< uScaled << ' ' << SIunitName << " or " << unitAbbreviation;
+}
+if (fabs(double((uScaled.value()) > 1000.0)) || fabs(double((uScaled.value()) < 1.0)))
+{  // Useful to autoscale.
+fout << "\nAutoscaled " << plusminus << autoscale  << addSIprefix
+<< uScaled << SIunitName
+<< " or " << noplusminus << noSIprefix << addSIsymbol << uScaled << addSIsymbol;
+}
+}
+else 
+{  // NOT SI unit, so show the value in appropriate SI unit.
+fout << "Non-SI unit " << flexform << plusminus << noautoscale
+<< uScaled
+<< noSIsymbol // To avoid trailing space.
+// << '_' // testing
+// But want space after "1.0 +/- ?"
+<< givenName  // non-SI like feet, fortnight etc.
+<< " in SI is " 
+<< plusminus << addSIsymbol << noSIprefix << uSIvalue
+<< addSIsymbol;// For symbol and abbreviation like mm.
+if (
+(fabs(double(uSIvalue.value() > 1000.0) ) )
+|| fabs(double(uSIvalue.value() < 1.0) ) )
+{  // Useful to autoscale.
+fout << "\nAutoscaled SI " 
+<< plusminus << autoscale
+<< addSIprefix << uSIvalue << SIunitName
+// For prefix & unit name like millimeter.
+<< " or " << noplusminus << noSIprefix << addSIsymbol << uSIvalue << addSIsymbol;
+}
+}  // if SIunit or not.
+
+is >> noskipws >> ws; // Needed if whitespace made significant by:
+// is.unsetf(ios_base::skipws); or noskipws >> to make all chars significant.
+is.unsetf(ios_base::skipws); // ==  >> noskipws 
+if (is.peek() == '!')
+{ // A comment follows, so read and echo it.
+string comment;
+// is >> comment; // still stops at ws.
+getline(is, comment);  // to end of line.
+//fout << " Comment: "<< comment << ", length " << comment.length()<< endl;
+}
+}
+}
+
+
+/*
+
+------ Rebuild All started: Project: unc_tests, Configuration: Debug Win32 ------
+Build started 24-Apr-2012 12:20:16.
+_PrepareForClean:
+  Deleting file "Debug\unc_tests.lastbuildstate".
+InitializeBuildStatus:
+  Touching "Debug\unc_tests.unsuccessfulbuild".
+ClCompile:
+  cvt.cpp
+  si_units.cpp
+  unc.cpp
+  unc_print.cpp
+  unc_read.cpp
+  xiostream.cpp
+  unc_tests.cpp
+  Generating Code...
+Manifest:
+  Deleting file "Debug\unc_tests.exe.embed.manifest".
+LinkEmbedManifest:
+  unc_tests.vcxproj -> J:\Cpp\quan\MSVC\Debug\unc_tests.exe
+CustomBuildStep:
+  Description: Autorun J:\Cpp\quan\MSVC\Debug\unc_tests.exe
+  Running 1 test case...
+  Platform: Win32
+  Compiler: Microsoft Visual C++ version 10.0
+  STL     : Dinkumware standard library version 520
+  Boost   : 1.49.0
+  ± Uncertain Class Test output to unc_test_output.txt ..\..\libs\quan\test\unc_tests.cpp Fri Mar  9 19:18:39 2012
+  Unc Diagnostics logged to unc_diag.txt
+../../libs/quan/test/unc_tests.cpp(653): error : in "unc_test": check oss.str() == "0.0000" failed [0 != 0.0000]
+  0.00
+  Value 1 flagged as exact, but uncertainty 1 is not zero!
+  Value 1 flagged as exact, but degfree 2 is not zero!
+  uncTypes (0x60e7) zero integer rational uncKnown noPlus noMinus df_exact df_known.0.000000000000000
+../../libs/quan/test/unc_tests.cpp(1231): error : in "unc_test": check oss.str() == "0.00000" failed [0.000000000000000 != 0.00000]
+  2.00000
+  1.23400
+  
+  Closed fout ..\..\libs\quan\test\unc_tests.cpp Fri Mar  9 19:18:39 2012
+C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(183,5): error MSB3073: The command ""J:\Cpp\quan\MSVC\Debug\unc_tests.exe" --result_code=yes --report_level=detailed --catch_system_errors=no  --build_info=yes
+C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(183,5): error MSB3073: :VCEnd" exited with code 201.
+
+Build FAILED.
+
+Time Elapsed 00:00:08.71
+========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
+
+*/
\ No newline at end of file