octave-maintainers
[Top][All Lists]
Advanced

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

Re: common warning id for double->object conversion


From: Oliver Heimlich
Subject: Re: common warning id for double->object conversion
Date: Thu, 23 Jun 2016 03:07:39 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.1.0

On 22.06.2016 20:07, Colin Macdonald wrote:
> [moving to maintainers list]
> 
> Summary: if you do `sym(1/3)` instead of `sym(1)/3`, we give a warning.

How do you decide whether to give a warning? If the parameter is no
integer? There are some fractions which have no rounding errors, e. g.
0.5, 0.25, 0.125, … and sums thereof.

On 22.06.2016 23:34, Colin Macdonald wrote:
> On 22/06/16 11:26, Reik Reid wrote:
>> If vpa() behaved the same way as sym(), would leaving out the quotes be
>> safe for all cases of constant numerical expressions? Is that a
>> desirable behavior?
>
> There is a relatively small set of values were its safe to leave off the
> quotes, for both sym and vpa.  That set is "small" integers, inf, nan,
> and pi.  The latter just for convenience (might have been a bad idea).

It's a difficult topic:

1. Even small integers might be the result of lost digits, e. g.
1.0000000000000001.

2. Experts might argue that inf is not infinity, but overflow of a big
value, e. g. 1e309.

3. nans are complicated already, e. g. 1e-324 / 1e-324.

4. yeah, pi might be problematic as well if the user expects to use the
approximate floating point value returned by pi () instead of π.

> On 22/06/16 08:48, Oliver Heimlich wrote:
>> There is the exactly same issue in the interval package. If you want
>> to implement this feature in the construtors (maybe with a regexp
>> to identify fractions and decimal numbers) we should use the same
>> warning id.
> 
> Good idea.  Do you think its appropriate to use the "Octave" namespace?
> 
> Maybe something lke:
> 
> 2. warning("Octave:possible-precision-loss", <custom message>)
> 3. warning("Octave:lossy-object-from-double", ...)
> 
> For `sym` objects its currently:
> 
> warning('OctSymPy:sym:rationalapprox', ...
>   'Using rat() heuristics for double-precision input (is this what you
> wanted?)');
> 
> (but I'm happy to change it).
> 
> Colin

We could stick to the official naming from IEEE 754, which is the
“inexact” exception. I propose one of the following:
    warning("Octave:inexact-argument", …)
    warning("numeric:inexact-argument", …)
    warning("double:inexact-argument", …)

I am still not sure how do decide whether to trigger the warning.
Basically, we want to trigger the warning if some expression for the
input argument has triggered the “inexact” floating point exception.

However, we have no access to this information. What we have:
a. the floating point value of the input argument,
b. the expression for the input argument as a string (“argn” variable)

The argn variable might hide that the inexactness has happened before
calling the function. However, in this case I would not want to have a
warning. For example,
x = 0.1
sym (x)

Also the argn variable might be a complicated expression which produces
inexactness, e. g. 1 / (2 + 8). We don't want to handle these cases.
However, we want to handle basic matrix expressions like [1 2; 3 0.1]

Points 1 – 4 from above show that it is not possible to conclude from
the parameter's value alone, whether inexactness has occurred. If in
addition, we use the parameter's expression (argn), we can detect simple
cases at least. So what do we have to do to eliminate false positives?

1. Check if the parameter has a scalar value of type double (binary64).
2. Check if the parameter expression is either a decimal number of the
form [+-]d[.]d[[eE][+-]d] or a fraction of the form [+-]d / d. Matrix
expressions with square brackets, comma, and semicolon must be
considered as well.
3. Check whether the value is the result of inexact conversion.

The last point is complicated/costly. It gets even more complicated when
you want to cover non-scalar arguments as well, e. g. sym ([0.1, 0.2]).

So, maybe above goals are too ambitious. We could lower the quality of
step 3 and only check whether the parameter's value is not an integer
and uses more than N mantissa bits on the fractional part of the value
(N = 26 should be reasonable -- half the double precision). Then it is
possible to decide this problem in many common cases and create an
internal function.

__check_inexact_arg__ (x, argn(1, :))
__check_inexact_arg__ (y, argn(2, :))

function __check_inexact_arg__ (val, expression)
if (isa (val, 'double') && warning ("query", "numeric:inexact-argument"))
  if (rem (val, pow2 (-26)) != 0)
    if (regexp (expression, …))
      warning ("numeric:inexact-argument", …)
    endif
  endif
endif
endfunction

This is quite cheap to check and limits false positives to cases where
the user has entered more than 8 decimal digits and the number happens
to be exact. We don't detect some cases with lengthy numbers, e. g.
1.0000000000000001.

Oliver



reply via email to

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