Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r51622 - in sandbox/SOC/2007/visualization: boost/svg_plot boost/svg_plot/detail libs/svg_plot/doc
From: pbristow_at_[hidden]
Date: 2009-03-05 11:27:20


Author: pbristow
Date: 2009-03-05 11:27:19 EST (Thu, 05 Mar 2009)
New Revision: 51622
URL: http://svn.boost.org/trac/boost/changeset/51622

Log:
Unc class added and working for 1D only. All examples compile still, but 2D uncertainty info not yet passed through.
Added:
   sandbox/SOC/2007/visualization/libs/svg_plot/doc/auto_1d_plot.qbk (contents, props changed)
Text files modified:
   sandbox/SOC/2007/visualization/boost/svg_plot/detail/axis_plot_frame.hpp | 82 ++++++++++++++++++++++++++-------------
   sandbox/SOC/2007/visualization/boost/svg_plot/detail/functors.hpp | 74 +++++++++++++++++++++++++++++++++--
   sandbox/SOC/2007/visualization/boost/svg_plot/svg_1d_plot.hpp | 63 ++++++++++++++++--------------
   sandbox/SOC/2007/visualization/boost/svg_plot/svg_boxplot.hpp | 4 +
   4 files changed, 161 insertions(+), 62 deletions(-)

Modified: sandbox/SOC/2007/visualization/boost/svg_plot/detail/axis_plot_frame.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/detail/axis_plot_frame.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/axis_plot_frame.hpp 2009-03-05 11:27:19 EST (Thu, 05 Mar 2009)
@@ -25,7 +25,10 @@
 // template <class T>bool isfinite (T);
 // template <class T>bool isinf (T);
 // template <class T> bool isnan (T);
+#include "uncertain.hpp"
+// using boost::svg::unc;
 
+#include <limits>
 #include <string>
 // using std::string;
 
@@ -1021,11 +1024,15 @@
             }
           } // void draw_plot_point
 
- void draw_plot_point_value(double x, double y, g_element& g_ptr, value_style& val_style, plot_point_style& point_style, double value)
- { //! Write the data point (X or Y) value as a string, for example "1.23e-2", near the data point marker.
+ void draw_plot_point_value(double x, double y, g_element& g_ptr, value_style& val_style, plot_point_style& point_style, unc uvalue)
+ { //! Write one data point (X or Y) value as a string, for example "1.23e-2", near the data point marker.
             //! Unecessary e, +, & leading exponent zeros may optionally be stripped, and the position and rotation controlled.
             //! Uncertainty estimate ('plus or minus') may be optionally be appended.
             //! Degrees of freedom estimate (number of replicates) may optionally be appended.
+ double value = uvalue.value(); // Most likely value.
+ double u = uvalue.uncertainty(); // Uncertainty or plusminus for value.
+ double df = uvalue.deg_free(); // Degrees of freedom estimate for value.
+
             std::stringstream label;
             label.precision(val_style.value_precision_);
             label.flags(val_style.value_ioflags_);
@@ -1119,27 +1126,34 @@
             text_element& t = g_ptr.text(x, y, stripped, val_style.values_text_style_, al, rot); // X or Y value "1.23"
             int f = static_cast<int>(val_style.values_text_style_.font_size() * 0.8); // Make uncertainty and df a bit smaller to distringuish from value.
 
- double u = 0.0123;// Uncertainty or plusminus value.
- double df = 23; // Degrees of freedom estimate value.
             std::string label_u; // Uncertainty or plusminus.
             std::string label_df; // Degrees of freedom estimate.
             std::string pm = "&#x00A0;&#x00B1;"; //! Unicode space plusminus glyph.
+ // Might also use ANSI symbol for plusminus 0xF1 == '\361' or char(241)
+ // but seems to vary with different codepages
+ // LOCALE_SYSTEM_DEFAULT LOCALE_IDEFAULTANSICODEPAGE == 1252
+ // LOCALE_SYSTEM_DEFAULT LOCALE_IDEFAULTCODEPAGE == 850 for country 44 (UK)
+ // And seems to vary from console to printable files.
             // Spaces seem to get lost, so use 00A0 as an explicit space glyph.
             // Layout seems to vary with font - Times New Roman leaves no space after.
             //text_element& t = g_ptr.text(x, y, label_v, val_style.values_text_style_, al, rot);
            // Optionally, show uncertainty as 95% confidence plus minus: 2.1 +-0.012 (23)
 
- if (val_style.plusminus_on_)
+ if ((val_style.plusminus_on_ == true) // Is wanted.
+ && (u > 0.) // Is a valid uncertainty estimate.
+ )
             { // Uncertainty estimate usually 95% confidence interval + or - 2 standard deviation.
               label_u = sv(u, val_style, true); // stripped.
               t.tspan(pm).fill_color(darkcyan);
               t.tspan(label_u).fill_color(purple).font_size(f);
               // TODO Colors should not be hard coded.
             }
- if (val_style.df_on_)
+ if (val_style.df_on_ == true // Is wanted.
+ && (df != (std::numeric_limits<unsigned short int>::max)()) // and deg_free is defined OK.
+ )
             { // Degrees of freedom or number of values-1 used for this estimate of value.
               std::stringstream label;
- label.precision(4);
+ label.precision(4); // Might need 5 to show 65535?
               //label.flags(sty.value_ioflags_); // Leave at default.
               label << "&#x00A0;(" << df << ")"; // "123"
               // Explicit space "&#x00A0;" seems necessary.
@@ -1149,13 +1163,13 @@
 
           } // void draw_plot_point_value(double x, double y, g_element& g_ptr, double value)
 
- std::string sv(double v, const value_style& sty, bool unc = false)
+ std::string sv(double v, const value_style& sty, bool precise = false)
           { //! Strip from double value any unecessary e, +, & leading exponent zeros, reducing "1.200000" to "1.2" or "3.4e1"...
             std::stringstream label;
             // Precision of uncertainty is usually less than precision of value,
             // label.precision((unc) ? ((sty.value_precision_ > 3) ? sty.value_precision_-2 : 1) : sty.value_precision_);
             // Possible but simpler to fix at precision=2
- label.precision((unc) ? 2 : sty.value_precision_);
+ label.precision((precise) ? 2 : sty.value_precision_);
             label.flags(sty.value_ioflags_);
             label << v; // "1.2" or "3.4e+001"...
             return (sty.strip_e0s_) ?
@@ -1165,11 +1179,18 @@
               label.str(); // Leave unstripped.
           } // std::string sv(double v, const value_style& sty)
 
- void draw_plot_point_values(double x, double y, g_element& x_g_ptr, g_element& y_g_ptr, const value_style& x_sty, const value_style& y_sty, double vx, double vy)
+ void draw_plot_point_values(double x, double y, g_element& x_g_ptr, g_element& y_g_ptr, const value_style& x_sty, const value_style& y_sty, unc uncx, unc uncy)
           { //! Write the \b pair of data point's X and Y values as a string,.
             //! If a separator, then both on the same line, for example "1.23, 3.45", or "[5.6, 7.8]
             //! X value_style is used to provide the prefix and separator, and Y value_style to provide the suffix.
             // draw_plot_point_values is only when both x and Y pairs are wanted.
+ double vx = uncx.value();
+ double vy = uncy.value();
+ double ux = uncx.uncertainty();
+ double uy = uncy.uncertainty();
+ double dfx = uncx.deg_free();
+ double dfy = uncy.deg_free();
+
             using std::string;
             using std::stringstream;
             std::string label_xv = sv(vx, x_sty); //! Also strip unnecessary e, + and leading exponent zeros, if required.
@@ -1253,20 +1274,14 @@
             // value and uncertainty, and degrees of freedom estimate.
             // So the coding complexity is judged with it (even if it may not always work right yet ;-)
 
- // Unclear how to get this uncertainty information into this function,
- // so these are purely imaginary for now.
- // Might template so can use an uncertain type instead of double?
- double ux = 0.0123;
- double uy = 0.00321;
- double dfx = 23;
- double dfy = 6;
-
             // Tasteless colors and font changes are purely proof of concept.
 
- int fx = static_cast<int>(y_sty.values_text_style_.font_size() * 0.8); // Make uncertainty and df a bit smaller to distringuish from value.
- // X value (and optional uncertainty & df).
+ int fx = static_cast<int>(y_sty.values_text_style_.font_size() * 0.8);
+ // Make uncertainty and df a bit smaller to distinguish from value by default (but make configurable).
+ // X value (and optional uncertainty & df).
             text_element& t = x_g_ptr.text(x, y, label_xv, x_sty.values_text_style_, al, rot);
- // Optionally, show uncertainty as 95% confidence plus minus: 2.1 +-0.012 (23)
+ // Optionally, show uncertainty as 95% confidence plus minus: 2.1 +-0.012
+ // and also optionally show degrees of freedom (23).
 
             string pm = "&#x00A0;&#x00B1;"; //! Unicode space plusminus glyph.
             // Spaces seem to get lost, so use 00A0 as an explicit space glyph.
@@ -1277,8 +1292,12 @@
               t.tspan(pm).fill_color(darkcyan);
               t.tspan(label_xu).fill_color(darkcyan).font_weight("bold").font_size(fx);
             }
- if (x_sty.df_on_)
- { // Degrees of freedom or number of values-1 used for this estimate of value.
+ if (
+ (x_sty.df_on_ == true) // Is wanted.
+ &&
+ (dfx != (std::numeric_limits<unsigned short int>::max)()) // and deg_free is defined OK.
+ )
+ { // Degrees of freedom (usually number of observations-1) used for this estimate of value.
               stringstream label;
               label.precision(4);
               //label.flags(sty.value_ioflags_); // Leave at default.
@@ -1294,14 +1313,19 @@
             { // On same line so no change in y.
               t.tspan(x_sty.separator_).fill_color(brown).font_size(fx); // Separator like comma and leading space ", ".
               t.tspan(label_yv, y_sty.values_text_style_); // Color?
- if (y_sty.plusminus_on_)
+ if (
+ (y_sty.plusminus_on_) // Is wanted.
+ && (uy > 0.) // Is valid uncertainty estimate.
+ )
               { // Uncertainty estimate usually 95% confidence interval + or - 2 standard deviation.
                  // Precision of uncertainty is usually less than value,
                 label_yu = "&#x00A0;" + sv(uy, y_sty, true);
                 t.tspan(pm).font_family("arial").font_size(fy).fill_color(green);
                 t.tspan(label_yu).fill_color(green).font_size(fy);
               }
- if (y_sty.df_on_)
+ if ((y_sty.df_on_ == true)
+ && (dfy != (std::numeric_limits<unsigned short int>::max)())
+ )
               { // degrees of freedom or number of values -1 used for this estimate.
                 std::stringstream label;
                 label.precision(4);
@@ -1322,14 +1346,18 @@
               double dy = y_sty.values_text_style_.font_size() * 2.2; // "newline"
               text_element& ty = y_g_ptr.text(x, y + dy, label_yv, y_sty.values_text_style_, al, rot);
 
- if (y_sty.plusminus_on_)
+ if ((y_sty.plusminus_on_ == true) // Is wanted.
+ && (uy > 0.) // Is valid uncertainty estimate.
+ )
               { // Uncertainty estimate usually 95% confidence interval + or - 2 standard deviation.
                  // Precision of uncertainty is usually less than value,
                 label_yu = "&#x00A0;" + sv(uy, y_sty, true);
                 ty.tspan(pm).font_family("arial").font_size(fy).fill_color(green);
                 ty.tspan(label_yu).fill_color(green).font_size(fy);
               }
- if (y_sty.df_on_)
+ if ((y_sty.df_on_ == true) // Is wanted.
+ && (dfy != (std::numeric_limits<unsigned short int>::max)()) // and deg_free is defined OK.
+ )
               { // degrees of freedom or number of values -1 used for this estimate.
                 std::stringstream label;
                 label.precision(4);

Modified: sandbox/SOC/2007/visualization/boost/svg_plot/detail/functors.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/detail/functors.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/functors.hpp 2009-03-05 11:27:19 EST (Thu, 05 Mar 2009)
@@ -1,12 +1,17 @@
 /*! \file functors.hpp
   \brief Functors to convert data to doubles.
- \details SVG plot assumes all data are convertible to double before being plotted.
- The functors are used to convert both 1D and 2D (pairs of data values) to be converted.
+ \details SVG plot assumes all data are convertible to double or uncertain value type unc before being plotted.
+ The functors are used to convert both 1D and 2D (pairs of data values) to be converted.
+ Note that uncertain value class unc only holds double precision and long double data
+ will therefore lose information. This seems reasonable design decision as any real data
+ to be plotted is unlikely to have more than double precision (about 16 decimal digits).
 
- \author Jacob Voytko
+ \author Jacob Voytko and Paul A. Bristow
+ \date Mar 2009
 */
 
 // Copyright Jacob Voytko 2007
+// Copyright Paul A. Bristow 2009
 
 // Use, modification and distribution are subject to the
 // Boost Software License, Version 1.0.
@@ -16,10 +21,20 @@
 #ifndef BOOST_SVG_DETAIL_FUNCTORS_HPP
 #define BOOST_SVG_DETAIL_FUNCTORS_HPP
 
+#if defined (_MSC_VER)
+# pragma warning (push)
+# pragma warning (disable : 4244)
+#endif
+
+#include "..\uncertain.hpp"
+//using boost::svg::unc;
+
 namespace boost {
 namespace svg {
-namespace detail {
+namespace detail
+{
 
+ // TODO change name from boost_default_convert to double_default_convert.
 class boost_default_convert
 { /*! \class boost::svg::detail::boost_default_convert
       \brief This functor allows any 1D data convertible to doubles to be plotted.
@@ -36,7 +51,7 @@
 
 class boost_default_2d_convert
 { /*! \class boost::svg::detail::boost_default_2d_convert
- \brief This functor allows any data convertible to type std::pair<double, double> to be plotted.
+ \brief This functor allows any 2 D data convertible to type std::pair<double, double> to be plotted.
 */
 public:
     typedef std::pair<double, double> result_type;
@@ -60,8 +75,57 @@
     }
 }; // class boost_default_2d_convert
 
+class unc_default_2d_convert
+{ /*! \class boost::svg::detail::unc_default_2d_convert
+ \brief This functor allows any 2D data convertible to type std::pair<unc, unc> to be plotted.
+*/
+public:
+ typedef std::pair<unc, unc> result_type;
+ unc i;
+ void start(unc i)
+ {
+ i = i;
+ }
+
+ template <class T, class U>
+ std::pair<unc, unc> operator()(const std::pair<T, U>& a) const
+ {
+ return std::pair<unc, unc>((unc)(a.first), (unc)(a.second));
+ }
+
+ template <class T>
+ std::pair<unc, unc> operator()(T a)
+ {
+ return std::pair<unc, unc>(i++, (unc)a);
+ }
+}; // class boost_default_2d_convert
+
+class unc_default_convert
+{ /*! \class boost::svg::detail::unc_convert
+ \brief This functor allows any 1D data convertible to unc (uncertain doubles) to be plotted.
+ \details Defaults provided by the unc class constructor ensure that
+ uncertainty, degrees of freedom information, and type are set too.
+*/
+public:
+
+ typedef unc result_type;
+
+ template <class T>
+ unc operator()(T val) const
+ {
+ return (unc)val;
+ // warning C4244: 'argument' : conversion from 'long double' to 'double', possible loss of data.
+ // because unc only holds double precision.
+ }
+}; // class default_convert
+
+
 } // namespace detail
 } // namespace svg
 } // namespace boost
 
+#if defined (BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
 #endif // BOOST_SVG_DETAIL_FUNCTORS_HPP

Modified: sandbox/SOC/2007/visualization/boost/svg_plot/svg_1d_plot.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/svg_1d_plot.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_1d_plot.hpp 2009-03-05 11:27:19 EST (Thu, 05 Mar 2009)
@@ -4,11 +4,12 @@
   \details Provides svg_1d_plot data and function to create plots, and svg_1d_plot_series to allow data values to be added.
   Very many functions allow fine control of the appearance and layout of plots and data markers.
   Items common to 1D and 2D use axis_plot_frame.
+ \date Mar 2009
   \author Jacob Voytko & Paul A. Bristow
  */
 
 // Copyright Jacob Voytko 2007
-// Copyright Paul A. Bristow 2008
+// Copyright Paul A. Bristow 2008, 2009
 
 // Use, modification and distribution are subject to the
 // Boost Software License, Version 1.0.
@@ -25,13 +26,17 @@
 #endif
 
 #include <boost/iterator/transform_iterator.hpp>
-// for using boost::make_transform_iterator;
+// using boost::make_transform_iterator;
 
 #include "svg.hpp"
 #include "svg_style.hpp"
 #include "detail/axis_plot_frame.hpp" // Code shared with 2D.
-#include "detail/functors.hpp"
+#include <boost/svg_plot/detail/functors.hpp>
+using boost::svg::detail::unc_default_convert;
 #include "detail/numeric_limits_handling.hpp"
+#include <boost/svg_plot/uncertain.hpp>
+// using boost::svg::unc;
+
 using boost::svg::detail::limit_NaN;
 
 #include <boost/svg_plot/detail/auto_axes.hpp> // provides:
@@ -76,8 +81,9 @@
 */
 
 public:
- std::vector<double> series_; //!< Normal 'OK to plot' data values.
+ std::vector<unc> series_; //!< Normal 'OK to plot' data values.
   std::vector<double> series_limits_; //!< 'limit' values: too big, too small or NaN.
+ // TODO should these be unc too?
 
   std::string title_; //!< title of data series (to show on legend).
   plot_point_style point_style_; //!< circle, square...
@@ -127,10 +133,10 @@
 {
   for(T i = begin; i != end; ++i)
   { // No defaults for begin and end?
- double temp = *i;
- if(detail::is_limit(temp))
+ unc temp = *i;
+ if(detail::is_limit(temp.value()))
     {
- series_limits_.push_back(temp); // 'limit' values: too big, too small or NaN.
+ series_limits_.push_back(temp.value()); // 'limit' values: too big, too small or NaN.
     }
     else
     {
@@ -140,7 +146,6 @@
 } // svg_plot_series constructor.
 
 // Definitions of svg_plot_series Member Functions.
-
 svg_1d_plot_series& svg_1d_plot_series::fill_color(const svg_color& col_)
 { //! Set fill color for plot point marker(s) (chainable).
   point_style_.fill_color_ = col_;
@@ -682,20 +687,20 @@
 
       for(unsigned int j = 0; j < serieses_[i].series_.size(); ++j)
       { // Draw jth point for ith series.
- double x = serieses_[i].series_[j];
- // TODO symbols are offset downwards
- // because the origin of the point is the top left of the glyph.
- // Need to offset by the height and width of the font size.
- double vx = x; // Note the true x value.
+ unc ux = serieses_[i].series_[j];
+ double x = ux.value();
+ // TODO symbols are offset downwards because
+ // the origin of the point is the top left of the glyph.
+ // Need to offset by the height and width of the font size?
         transform_x(x);
         if((x >= plot_left_) && (x <= plot_right_)) // Check point is inside plot_window.
         // May need a margin here to avoid points just over the window not being shown.
         {
           draw_plot_point(x, y, g_ptr, serieses_[i].point_style_); // Marker.
           if (x_values_on_)
- { // Show the value of the data point too.
+ { // Show the value (& perhaps uncertainty) of the data point too.
             g_element& g_ptr_v = image.g(detail::PLOT_X_POINT_VALUES).g();
- draw_plot_point_value(x, y, g_ptr_v, x_values_style_, serieses_[i].point_style_, vx);
+ draw_plot_point_value(x, y, g_ptr_v, x_values_style_, serieses_[i].point_style_, ux);
             // TODO separate X and Y colors?
           }
           else
@@ -795,9 +800,8 @@
   }
 
   svg_1d_plot& svg_1d_plot::write(std::ostream& s_out)
- { //! Write SVG image to the specified std::ostream.
- /*!
- This function also is used by the write to file function.
+ { /*! Write SVG image to the specified std::ostream.
+ This function also is used by the write to file function.
     */
     update_image();
     /*!
@@ -810,7 +814,7 @@
     */
     image.write(s_out);
     return (svg_1d_plot&)*this;
- }
+ } // write
 
   template <class T>
   svg_1d_plot_series& svg_1d_plot::plot(const T& container, const std::string& title /*= "" */)
@@ -819,8 +823,8 @@
     */
     serieses_.push_back(
       svg_1d_plot_series(
- boost::make_transform_iterator(container.begin(), detail::boost_default_convert()),
- boost::make_transform_iterator(container.end(), detail::boost_default_convert()),
+ boost::make_transform_iterator(container.begin(), detail::unc_default_convert()),
+ boost::make_transform_iterator(container.end(), detail::unc_default_convert()),
       title)
     );
    /*
@@ -832,15 +836,16 @@
 my_1d_plot.plot(my_data, "All my container"); // Plot all data.
      \endcode
    */
- return serieses_[serieses_.size() - 1]; // Reference to data series just added.
- }
+ return serieses_[serieses_.size() - 1];
+ //! \return Reference to data series just added.
+ } // plot(const T& container, const std::string& title)
 
   template <class T>
   svg_1d_plot_series& svg_1d_plot::plot(const T& begin, const T& end, const std::string& title)
   { //! Add a data series to the plot (by default, converting to doubles), with optional title.
     /*!
     Note that this version permits a partial range, begin to end, of the container to be used.
- Returns a reference to data series just added.
+ \return a reference to data series just added.
     */
     serieses_.push_back(
       svg_1d_plot_series(
@@ -858,13 +863,13 @@
   svg_1d_plot_series& svg_1d_plot::plot(const T& begin, const T& end, const std::string& title /* = ""*/, U functor /* = boost_default_convert */)
   { /*! Add a data series to the plot, with optional title. (Version with custom functor, rather than to double).
       Note that this version permits a partial range, begin to end, of the container to be used.
- Returns a reference to data series just added.
+ \return a reference to data series just added.
     */
     serieses_.push_back(
       svg_1d_plot_series(
- boost::make_transform_iterator(container.begin(), functor),
- boost::make_transform_iterator(container.end(), functor),
- title)
+ boost::make_transform_iterator(container.begin(), functor),
+ boost::make_transform_iterator(container.end(), functor),
+ title)
     );
     return serieses_[serieses_.size() - 1]; // Reference to data series just added.
   } // plot
@@ -874,7 +879,7 @@
   { //! Add a data series to the plot, with optional title.
   /*!
     This version of plot includes a functor, allowing other than just convert data values to double(the default).
- Returns a reference to data series just added.
+ \return a reference to data series just added.
   */
     serieses_.push_back(
       svg_1d_plot_series(

Modified: sandbox/SOC/2007/visualization/boost/svg_plot/svg_boxplot.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/svg_boxplot.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_boxplot.hpp 2009-03-05 11:27:19 EST (Thu, 05 Mar 2009)
@@ -17,10 +17,11 @@
   The American Statistician, Vol. 53, No. 4 (Nov., 1999), pp. 382-387
 
   \author Jacob Voytko & Paul A. Bristow
+ \date Mar 2009
  */
 
 // Copyright Jacob Voytko 2007
-// Copyright Paul A. Bristow 2008
+// Copyright Paul A. Bristow 2008, 2009
 
 // Use, modification and distribution are subject to the
 // Boost Software License, Version 1.0.
@@ -46,6 +47,7 @@
 #include "detail/axis_plot_frame.hpp"
 #include "detail/auto_axes.hpp" //
 #include "quantile.hpp"
+#include "uncertain.hpp"
 
 #include <vector>
 #include <string>

Added: sandbox/SOC/2007/visualization/libs/svg_plot/doc/auto_1d_plot.qbk
==============================================================================


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk