octave-bug-tracker
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Octave-bug-tracker] [bug #48350] plot error calculating yticks on large


From: Dan Sebald
Subject: [Octave-bug-tracker] [bug #48350] plot error calculating yticks on large constant plus small delta
Date: Fri, 1 Jul 2016 08:49:24 +0000 (UTC)
User-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0

Follow-up Comment #3, bug #48350 (project octave):

I followed this one through the code.  This is the failing line:


    handles(i) = __go_line__ (p, data_args{:}, other_args{:});


(I put some debug lines in __line__.m and got a plot but there is no y-axis
tics or labels.)  __go_line__ is internal, in the file graphics.cc as
follows:


DEFUN (__go_line__, args, ,
       doc: /* -*- texinfo -*-
@deftypefn {} {} __go_line__ (@var{parent})
Undocumented internal function.
@end deftypefn */)
{
  GO_BODY (line);
}


And GO_BODY is


#define GO_BODY(TYPE) \
  gh_manager::auto_lock guard; \
 \
  if (args.length () == 0) \
    print_usage (); \
 \
  return octave_value (make_graphics_object (#TYPE, false, args)); \


which takes us to


static octave_value
make_graphics_object (const std::string& go_name,
                      bool integer_figure_handle,
                      const octave_value_list& args)
{


My best guess is that internally something is going wrong with the line
construction or plotting and the return value of __go_line__ is invalid such
that Octave thinks it is trying to index something (what should be a returned
handle) it doesn't know about.  E.g., there is no "ans = -2.1370" or something
like it even though my plot is occurring.

The construction of the line and its properties seems pretty straightforward. 
There is a go.initialize() though, and this function gets called (I placed the
fprintf() calls within):


Matrix
line::properties::compute_ylim (void) const
{
  Matrix m (1, 4);

  m(0) = ydata.min_val ();
fprintf(stderr, "min_val: %30lg\n", ydata.min_val ());
  m(1) = ydata.max_val ();
fprintf(stderr, "max_val: %30lg\n", ydata.max_val ());
  m(2) = ydata.min_pos ();
fprintf(stderr, "min_pos: %30lg\n", ydata.min_pos ());
  m(3) = ydata.max_neg ();
fprintf(stderr, "max_neg: %30lg\n", ydata.max_neg ());

  return m;
}


Here is what I'm seeing (snipping out the garbage):


>> h = plot ( (5e-10 .* [1:70]'))
min_val: 5.0000000000000003114079572889e-10
max_val: 3.50000000000000023866508541606e-08
min_pos: 5.0000000000000003114079572889e-10
max_neg: -inf
[snip]
>> h = plot (15 + (5e-10 .* [1:70]'))
min_val: 15.0000000005000000413701854995
max_val: 15.0000000349999993431993061677
min_pos: 15.0000000005000000413701854995
max_neg: -inf


That seems OK, nothing is being lost in the data (e.g., there is no double
conversion to float or int or anything).


Maybe it is this routine:


void
axes::properties::calc_ticks_and_lims (array_property& lims,
                                       array_property& ticks,
                                       array_property& mticks,
                                       bool limmode_is_auto, bool
is_logscale)
{


YES, I think that is where the problem lies.  I can say that this is not
correct:


fprintf(stderr, "tick_sep: %lg\n", tick_sep);
  int i1 = static_cast<int> (std::floor (lo / tick_sep));
  int i2 = static_cast<int> (std::ceil (hi / tick_sep));
fprintf(stderr, "i1=%d, i2=%d\n", i1, i2);


The result I see is:


>> h = plot (15 + (5e-10 .* [1:70]'))
[snip]
min_val: 15.0000000005000000413701854995
max_val: 15.0000000349999993431993061677
min_pos: 15.0000000005000000413701854995
max_neg: -inf
tick_sep: 5e-09
i1=-2147483648, i2=-2147483648


Because the tick_sep turns out to be so small, the division is putting that
double value outside the range of an int and the value is wrapping to negative
numbers.

I changed the type of i1 and i2 to "long long", but that didn't fix the
problem.  I suppose it is the double arithmetic that is saturating.  But I'm
not sure that is the way to fix this anyway.  Probably the right thing to do
is to subtract the mean value from the data somehow before doing the range
integerization.  (Takes quite a while to compile though, so I've had enough
for now.)


    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?48350>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]