Mercurial > hg > octave-lyh
changeset 13756:6dfebfa334cb
allow negative data log plots with OpenGL+FLTK graphics (bug #34232)
* mx-inlines.cc (mx_inline_any_positive): New function.
* lo-mappers.h (xpositive_sign (double), xpositive_sign (float)):
New functions.
* fNDArray.h, fNDArray.cc (FloatNDArray::any_element_is_positive):
New function.
* fMatrix.h, fMatrix.cc (FloatMatrix::any_element_is_positive):
New function.
* dNDArray.h, dNDArray.cc (NDArray::any_element_is_positive):
New function.
* dMatrix.h, dMatrix.cc (Matrix::any_element_is_positive):
New function.
* graphics.h.in (log_scaler::do_neg_scale): New function.
(log_scaler::scale (const Matrix&) const,
log_scaler::scale (const NDArray&) const): Call do_neg_scale if no
array elements are positive.
* graphics.cc (axes::properties::get_axis_limits): Omit zero from
positive values for log plots. Correctly widen range for all negative
log plots.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 26 Oct 2011 14:19:54 -0400 |
parents | 8cd08124cb59 |
children | 1e81e2e30af3 |
files | liboctave/dMatrix.cc liboctave/dMatrix.h liboctave/dNDArray.cc liboctave/dNDArray.h liboctave/fMatrix.cc liboctave/fMatrix.h liboctave/fNDArray.cc liboctave/fNDArray.h liboctave/lo-mappers.h liboctave/mx-inlines.cc src/graphics.cc src/graphics.h.in |
diffstat | 12 files changed, 68 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/dMatrix.cc +++ b/liboctave/dMatrix.cc @@ -2655,6 +2655,13 @@ } bool +Matrix::any_element_is_positive (bool neg_zero) const +{ + return (neg_zero ? test_all (xpositive_sign) + : do_mx_check<double> (*this, mx_inline_any_positive)); +} + +bool Matrix::any_element_is_nan (void) const { return do_mx_check<double> (*this, mx_inline_any_nan);
--- a/liboctave/dMatrix.h +++ b/liboctave/dMatrix.h @@ -296,6 +296,7 @@ // other operations bool any_element_is_negative (bool = false) const; + bool any_element_is_positive (bool = false) const; bool any_element_is_nan (void) const; bool any_element_is_inf_or_nan (void) const; bool any_element_not_one_or_zero (void) const;
--- a/liboctave/dNDArray.cc +++ b/liboctave/dNDArray.cc @@ -554,6 +554,13 @@ } bool +NDArray::any_element_is_positive (bool neg_zero) const +{ + return (neg_zero ? test_all (xpositive_sign) + : do_mx_check<double> (*this, mx_inline_any_positive)); +} + +bool NDArray::any_element_is_nan (void) const { return do_mx_check<double> (*this, mx_inline_any_nan);
--- a/liboctave/dNDArray.h +++ b/liboctave/dNDArray.h @@ -75,6 +75,7 @@ boolNDArray operator ! (void) const; bool any_element_is_negative (bool = false) const; + bool any_element_is_positive (bool = false) const; bool any_element_is_nan (void) const; bool any_element_is_inf_or_nan (void) const; bool any_element_not_one_or_zero (void) const;
--- a/liboctave/fMatrix.cc +++ b/liboctave/fMatrix.cc @@ -2655,6 +2655,13 @@ } bool +FloatMatrix::any_element_is_positive (bool neg_zero) const +{ + return (neg_zero ? test_all (xpositive_sign) + : do_mx_check<float> (*this, mx_inline_any_positive)); +} + +bool FloatMatrix::any_element_is_nan (void) const { return do_mx_check<float> (*this, mx_inline_any_nan);
--- a/liboctave/fMatrix.h +++ b/liboctave/fMatrix.h @@ -296,6 +296,7 @@ // other operations bool any_element_is_negative (bool = false) const; + bool any_element_is_positive (bool = false) const; bool any_element_is_nan (void) const; bool any_element_is_inf_or_nan (void) const; bool any_element_not_one_or_zero (void) const;
--- a/liboctave/fNDArray.cc +++ b/liboctave/fNDArray.cc @@ -514,6 +514,13 @@ } bool +FloatNDArray::any_element_is_positive (bool neg_zero) const +{ + return (neg_zero ? test_all (xpositive_sign) + : do_mx_check<float> (*this, mx_inline_any_positive)); +} + +bool FloatNDArray::any_element_is_nan (void) const { return do_mx_check<float> (*this, mx_inline_any_nan);
--- a/liboctave/fNDArray.h +++ b/liboctave/fNDArray.h @@ -72,6 +72,7 @@ boolNDArray operator ! (void) const; bool any_element_is_negative (bool = false) const; + bool any_element_is_positive (bool = false) const; bool any_element_is_nan (void) const; bool any_element_is_inf_or_nan (void) const; bool any_element_not_one_or_zero (void) const;
--- a/liboctave/lo-mappers.h +++ b/liboctave/lo-mappers.h @@ -218,6 +218,10 @@ extern OCTAVE_API bool xnegative_sign (double x); extern OCTAVE_API bool xnegative_sign (float x); +// Test for positive sign. +inline bool xpositive_sign (double x) { return ! xnegative_sign (x); } +inline bool xpositive_sign (float x) { return ! xnegative_sign (x); } + // Some old rounding functions. extern OCTAVE_API octave_idx_type NINTbig (double x);
--- a/liboctave/mx-inlines.cc +++ b/liboctave/mx-inlines.cc @@ -215,6 +215,19 @@ return false; } +template <class T> +inline bool +mx_inline_any_positive (size_t n, const T* x) throw () +{ + for (size_t i = 0; i < n; i++) + { + if (x[i] > 0) + return true; + } + + return false; +} + template<class T> inline bool mx_inline_all_real (size_t n, const std::complex<T>* x) throw ()
--- a/src/graphics.cc +++ b/src/graphics.cc @@ -5568,7 +5568,7 @@ retval(1) = pow (10., retval(1)); return retval; } - if ((min_val <= 0 && max_val >= 0)) + if ((min_val <= 0 && max_val > 0)) { warning ("axis: omitting nonpositive data in log plot"); min_val = min_pos; @@ -5588,8 +5588,8 @@ else { // Log plots with all negative data - min_val = -pow (10, gnulib::floor (log10 (-min_val))); - max_val = -pow (10, std::ceil (log10 (-max_val))); + min_val = -pow (10, std::ceil (log10 (-min_val))); + max_val = -pow (10, gnulib::floor (log10 (-max_val))); } } else
--- a/src/graphics.h.in +++ b/src/graphics.h.in @@ -221,7 +221,11 @@ { Matrix retval (m.rows (), m.cols ()); - do_scale (m.data (), retval.fortran_vec (), m.numel ()); + if (m.any_element_is_positive ()) + do_scale (m.data (), retval.fortran_vec (), m.numel ()); + else + do_neg_scale (m.data (), retval.fortran_vec (), m.numel ()); + return retval; } @@ -229,7 +233,11 @@ { NDArray retval (m.dims ()); - do_scale (m.data (), retval.fortran_vec (), m.numel ()); + if (m.any_element_is_positive ()) + do_scale (m.data (), retval.fortran_vec (), m.numel ()); + else + do_neg_scale (m.data (), retval.fortran_vec (), m.numel ()); + return retval; } @@ -248,6 +256,12 @@ for (int i = 0; i < n; i++) dest[i] = log10(src[i]); } + + void do_neg_scale (const double *src, double *dest, int n) const + { + for (int i = 0; i < n; i++) + dest[i] = -log10(-src[i]); + } }; class scaler