Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r51956 - sandbox/SOC/2007/visualization/boost/svg_plot/detail
From: pbristow_at_[hidden]
Date: 2009-03-24 10:11:45


Author: pbristow
Date: 2009-03-24 10:11:44 EDT (Tue, 24 Mar 2009)
New Revision: 51956
URL: http://svn.boost.org/trac/boost/changeset/51956

Log:
Corrected error finding Y min and max in autoscale.
Text files modified:
   sandbox/SOC/2007/visualization/boost/svg_plot/detail/auto_axes.hpp | 66 ++++++++++++++++++++++++++-------------
   1 files changed, 44 insertions(+), 22 deletions(-)

Modified: sandbox/SOC/2007/visualization/boost/svg_plot/detail/auto_axes.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/detail/auto_axes.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/auto_axes.hpp 2009-03-24 10:11:44 EDT (Tue, 24 Mar 2009)
@@ -70,7 +70,7 @@
 namespace svg
 {
 
-// Defines:
+// Declarations:
 
 // Show and show_all to display size and contents of STL containers.
 // range and range_all to find the min and max of STL containers.
@@ -101,6 +101,8 @@
    int min_ticks, // Minimum number of major ticks.
    int steps); // Round up and down to 2, 4, 6, 8, 10, or 5, 10 or 2, 5, 10 systems.
 
+// Definitions.
+
 template <typename iter>
 int mnmx(iter begin, iter end, double* min, double* max)
 { //! \brief Inspect values to find min and max.
@@ -268,7 +270,7 @@
     int good = mnmx(container.begin(), container.end(), &x_min, &x_max);
     if (good < 2)
     {
- throw std::runtime_error("Autoscale could not find useful min & max to scale axis!");
+ throw std::runtime_error("Autoscale could not find useful min & max values to scale the X axis!");
     }
     // cout << "x_min " << x_min << ", x_max " << x_max << endl; //
   }
@@ -306,20 +308,45 @@
   double y_max = std::numeric_limits<double>::quiet_NaN();
   double y_min = std::numeric_limits<double>::quiet_NaN();
 
- if (!check_limits) // TODO my_plot.autoscale_check_limits(false); This path bombs - I fear it will never work?
+ if (!check_limits) // TODO my_plot.autoscale_check_limits(false);
   { // BUT only if it can be assumed that no values are 'at limits',
     // infinity, NaN, max_value, min_value, denorm_min.
     // minmax_element is efficient for maps because it can use knowledge of all maps being sorted,
+ // And also sadly it doesn't work right - Y minimum is wrong!
+ // TODO
     std::pair<T::const_iterator, T::const_iterator> result = boost::minmax_element(container.begin(), container.end());
- //originally std::pair<const double, double> px = *result.first; // x min & max
-
- std::pair<const double, double> px = values_of(*result.first); // x min & max
- //originally std::pair<const double, double> py = *result.second; // y min & max
+ std::pair<const double, double> px = values_of(*result.first); // x min & y_min
     std::pair<const double, double> py = values_of(*result.second); // y min & max
     x_min = px.first;
- x_max = px.second;
- y_min = py.first;
- y_max = py.second;
+ x_max = py.first;
+ // x are OK, but Y are only those corresponding to those X, not min and max.,
+ // so still need to iterate through the Y to find y min and y max.
+ //y_min = px.second;
+ //y_max = py.second;
+ T::const_iterator pos = container.begin();
+ if (pos == container.end())
+ {
+ throw std::runtime_error("Autoscale could not find any values to scale axes!");
+ }
+ double y = value_of(pos->second);
+ double yu = unc_of(pos->second) * autoscale_plusminus;
+ y_max = y + yu;
+ y_min = y - yu;
+ while(pos != container.end())
+ {
+ y = value_of(pos->second);
+ yu = unc_of(pos->second) * autoscale_plusminus;
+ if (y + yu > y_max)
+ {
+ y_max = y + yu;
+ }
+ if (y - yu < y_min)
+ {
+ y_min = y - yu;
+ }
+ pos++;
+ }
+ cout << "No limits checks: x_min = " << x_min << ", x_max = " << x_max << ", y_min = " << y_min << ", y_max = " << y_max << endl;
   }
   else
   { // Otherwise it is necessary to inspect all values individually.
@@ -353,7 +380,7 @@
       double yu = unc_of(pos->second) * autoscale_plusminus;
       y_max = y + yu;
       y_min = y - yu;
- cout << "Initial min & max " << x << "+-" << xu << " = " << x_min << " to " << x_max << ", " << y << "+-" << yu << "=" <<y_min << " to " << y_max << endl;
+ //cout << "Initial min & max " << x << "+-" << xu << " = " << x_min << " to " << x_max << ", " << y << "+-" << yu << "=" <<y_min << " to " << y_max << endl;
       pos++;
       goods++;
       while(pos != container.end())
@@ -362,7 +389,6 @@
         { // Either x and/or y are finite.
           x = value_of(pos->first);
           xu = unc_of(pos->first) * autoscale_plusminus;
-
           if (x + xu > x_max)
           {
             x_max = x + xu;
@@ -381,8 +407,7 @@
           {
             y_min = y - yu;
           }
- cout << "min & max " << x << "+-" << xu << " = " << x_min << " to " << x_max << ", " << y << "+-" << yu << "=" <<y_min << " to " << y_max << endl;
-
+ //cout << "min & max " << x << "+-" << xu << " = " << x_min << " to " << x_max << ", " << y << "+-" << yu << "=" <<y_min << " to " << y_max << endl;
           goods++;
           // cout << goods << " goods, " << x << ' ' << y << endl;
        } // if finite
@@ -395,10 +420,7 @@
         }
         ++pos;
       } // while
-
- cout << "x_min " << x_min << ", x_max " << x_max << endl; // x_min 1, x_max 7.3
- cout << "y_min " << y_min << ", y_max " << y_max << endl; // y_min 3.2, y_max 9.1
- cout << "limits " << limits << endl;
+ cout << "Checked: x_min " << x_min << ", x_max " << x_max << ", y_min " << y_min << ", y_max " << y_max << ", " << goods << " 'good' values, " << limits << " values at limits."<< endl;
     }
   }
   scale_axis(x_min, x_max,
@@ -411,12 +433,12 @@
 } // template <class T> int scale_axis T an STL container: array, vector ...
 
 
-// Above versions use version below that does the real scaling work.
+// Above versions all use the scale_axis version below that does the real scaling work.
 
 void scale_axis(double min_value, double max_value, // Scale axis from Input range min & max.
                double* axis_min_value, double* axis_max_value, double* axis_tick_increment, int* auto_ticks, // All 4 updated.
- // NO check_limits parameter.
- bool origin = false, // do not include the origin unless the range min_value <= 0 <= max_value.
+ // NO check_limits parameter in this version.
+ bool origin = false, // Do not include the origin unless the range min_value <= 0 <= max_value.
                double tight = 0., // tightest - fraction of 'overrun' allowed before another tick used.
                // for visual effect up to about 0.001 might suit a 1000 pixel wide image,
                // allowing values just 1 pixel over the tick to be shown.
@@ -479,7 +501,7 @@
 
   if (min_value > max_value)
   { // max and min are transposed!
- throw(std::domain_error("min > max!"));
+ throw std::domain_error("min > max!");
   }
   else if (is_small(range)
     // range <= 1000. * std::numeric_limits<double>::min()) // Absolute range > ~1e-308 * 1000 ~= 1e-305


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