octave-maintainers
[Top][All Lists]
Advanced

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

Re: A problem with range objects and floating point numbers


From: Daniel J Sebald
Subject: Re: A problem with range objects and floating point numbers
Date: Mon, 29 Sep 2014 10:56:19 -0500
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.24) Gecko/20111108 Fedora/3.1.16-1.fc14 Thunderbird/3.1.16

On 09/29/2014 10:30 AM, s.jo wrote:

On 09/28/2014 10:20 PM, s.jo wrote:
Daniel Sebald wrote


[snip]

Here I want to find the largest digits for the perfect decimation,
say '%.12f'. Roughly speaking, the number of decimation digits is
not much related to step size.
You can try and see range_test4 with any number less than 12, and
more than 13, such as '%.11f' and '%.13f'
With less than 12, there is no errors and no non-zero digit from
10^-12 up-to 0.1. Why?

It's because the printf() routine is rounding to the nearest 12th fractional digit and drops the resolution. I see what you are looking for now, but I was just thinking of test4 as the benchmark, i.e., produce:

test4 = [-1000 -999.9 -999.8 ...

The odd thing is that by going to lower resolution/precision it can make your sine-crossing test pass. Norm would be better overall test, but your test is sort of the "feel good" preferred behavior because humans accustom to the decimal number system and whole numbers will tend to choose ranges similar to your example.


This is the difference between round-off and decimation.
It depends on from which base system number to which base system
we convert it.
In our example, we decimate base-2 numbers (into base-10 number).
For example, if we take the decimal (or base-10) range [... -0.2 -0.1 0 0.1
0.2 ....],
we may have base-2 representation equivalent to [... -0.199999 -0.1 0
0.111111 0.2 ...].
The floating-point numbers with errors from decimal number may look like
repeating decimals. http://en.wikipedia.org/wiki/Repeating_decimal
Thus, the difference between them can be bounded by a small number such
as+/-0.00...001 or +/-10^12 or so.
The exact number of decimation digits depends on step-size and epsilons
(floating-point space). Epsilon is also a function of numbers.
So I claim that we can choose '12'  as a decimation digit number of
the base-2 double precision floating-point numbers for decimal numbers.
I believe that Matlab's colon operator employs such 'blind decimation' by
choosing a specific decimal digit.
How? It is not difficult. If we scale the step-size by a large number of
multiple of 10, say 10^12, and take it back to the original scale,
we have the similar effect as '%.12f'. decimation.
Again, The range (A:s:B) can be decimated by
(A*10^12:s*10^12:B*10^12)/10^12,
whatever step-size s is. The scale factor 10^12 will be a design parameter.
Such multiplication and division with a large number causes a truncation
around a specific decimal position.

All true, and eps() is important, but I think the base-10 vs. base-2 representation is a red herring. It's just simply the fact we are dealing with fractional numbers (which are not going to be accurate in many cases regardless of the number system), and we have to deal with that in the best way possible that mitigates the effects of limited resolution.


Dan expanded test cases up-to 6:
In my note pc (Octave 3.8.2/cygwin/intel-i5-M450), I have ...

+ N = 1000;
+ range_test1 = (-N:0.1:N);
+ range_test2 = [-N:0.1:N];
+ range_test3 = linspace (-N, N, 20 * N + 1);
+ range_test4 = (str2num (sprintf ('%.12f ', -N:0.1:N)));
+ range_test5 = (-N / 0.1:1:N / 0.1) * 0.1;
+ range_test6 = [-N / 0.1:1:N / 0.1] * 0.1;

+ sum (abs (sin (range_test1 * pi))<  eps (range_test1 * pi))
ans =3D       1055
+ sum (abs (sin (range_test2 * pi))<  eps (range_test2 * pi))
ans =3D       1168
+ sum (abs (sin (range_test3 * pi))<  eps (range_test3 * pi))
ans =3D       2001
+ sum (abs (sin (range_test4 * pi))<  eps (range_test4 * pi))
ans =3D       2001
+ sum (abs (sin (range_test5 * pi))<  eps (range_test5 * pi))
ans =3D       1055
+ sum (abs (sin (range_test6 * pi))<  eps (range_test6 * pi))
ans =3D       2001

test5 is just like test1 (expected), and test6 passes.  That's good!


I happened to think my system is based on a mobile processor. It may cause
test 2 to fail.

OK, at least it is giving the algorithm a good test.


[snip]
People always try to compare Octave and Matlab to get more confidence.

I don't think that replicating Matlab's numerical behavior exactly is that important. It's more about minimizing the arithmetic effects. And the best benchmark, as I see it, is

test4 = [-1000 -999.9 -999.8 ...

If the underlying C code mapping decimal numbers to binary float (IEEE float) isn't as accurate as possible, then all this analysis is meaningless.

Dan



reply via email to

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