bugGNU Octave - Bugs: bug #33104, mat2str returns ugly result...

 
 

bug #33104: mat2str returns ugly result (different to Matlab)

Submitted by:  Patrick Häcker <magicmuscleman>
Submitted on:  Sun 17 Apr 2011 10:55:27 AM UTC  
 
Category: InterpreterSeverity: 3 - Normal
Priority: 5 - NormalItem Group: Incorrect Result
Status: FixedAssigned to: Ben Abbott <bpabbott>
Originator Name: Open/Closed: Closed
Release: devOperating System: GNU/Linux

Add a New Comment(Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

(Jump to the original submission Jump to the original submission)

Sun 17 Apr 2011 08:44:40 PM UTC, comment #10:

Ben Abbot wrote:

> My thought was that the number of digits displayed should not exceed
> the numeric precision. In general, we can only be confident in the
> first 15 digits, correct?


As I said, it really is a matter of preference, but as far as defaults
go, since the 16th digit has a good chance of being accurate, as 2^52
is approximately 4.5e15, my own preference is to give as much accuracy
as possible. The 17th digit of course can't be accurate except by
fluke, but the 16th digit has about a 45% chance of being accurate. My
own preference is that by default that extra digit be given and that
the user should understand the caveats that the 16th digit could be
wrong about half the time.

Hiding that digit so that users don't complain about 0.7 not being
exactly representable in IEEE 754 arithmetic seems a little
patronising to me. I'd rather explain a million times how hardware
floats work than to alleviate user complaints about them.

Then again, looking at other Octave functions, I see that format long
and save apparently prefers to round to 15 digits, or rather, prefers
to count the leading zero as part of the digits it displays. Perhaps
with consistency for those functions, this patch is correct, and I'll
stop being contrarian.

Jordi Gutiérrez Hermoso <jordigh>
Project Administrator
Sun 17 Apr 2011 07:27:30 PM UTC, comment #9:

Sorry for being unprecise: I see, that the numerical representation is not exact (thanks for the good example!). But what I meant was the representation as a string (char array, to be precise). And with the patch mat2str(0.69) results in the string '0.69'.

So it's simply not possible, that the "loss of precision adds up" in this example, because the string is exact (although the intermediate representation has been wrong - I don't know which mind-reading genius programmed the responsible sprintf function ...).

Is there a (more or less common) number where the output of mat2str is wrong with the applied patch?

Anyway, I don't think that anyone gets major numerical problems due to tons of mat2str/eval combinations compared to e.g. a svd. And if he does, he should seriously think about his programming style.

Patrick Häcker <magicmuscleman>
Sun 17 Apr 2011 06:08:41 PM UTC, comment #8:

Patrick Häcker wrote:

> I cannot follow the example with 0.69. With 15 digits the applied
> patch is exact (result: '0.69'). Do I miss anything?


It's not exact. It only looks exact. With 0.69, the exact value
represented in memory is
0.689999999999999946709294817992486059665679931640625 =
1553741871442821/2^51, which is closer to 0.6899999999999999 than to
0.69, so by always rounding to 15 decimal digits you're losing a
little precision that you could have saved. Always rounding to 15
digits hides a few details that a lot of people don't understand about
hardware floats at the expense of losing a little precision now and
then. This is fine except when that loss of precision adds up as it
can during a long computation.

As long as you don't use the results of mat2str as anything more than
a human convenience and you don't care about loss of precision,
unilaterally rounding or truncating the result to 15 digits can be
acceptable.

Jordi Gutiérrez Hermoso <jordigh>
Project Administrator
Sun 17 Apr 2011 05:52:34 PM UTC, comment #7:

Conclusion of this comment: Please apply the patch.

I cannot follow the example with 0.69. With 15 digits the applied patch is exact (result: '0.69'). Do I miss anything?

When creating the patch I, too, had the feeling, that the problem cannot be completely solved, as the precision is finite.

Some thoughts:

- We want to have mat2str(eval('a')) = 'a' for any representation of a number of "a" or at least for common numbers.
=> We should definitely use less output digits than digits available for internal representation. The precision depends on the number's size, so we probably cannot find one fixed precision which always works.

- We should have some reserves for numerical noise, so that something like mat2str(eval('sqrt(a)^2')) = 'a' does work, too.

- The people programming Matlab had the same problem and hopefully thought about the problem, too. They came up with these 15 digits, so hopefully this is not the worst compromise. Furthermore, we want to be as compatible as possible.

- It should be possible to use eps() to determine the sensible precision of the result. Still, I don't see a possibility to get the number of correct digits regarding the numerical noise added by computations.

- My patch works in all my tests. It's probably possible to find situations, where this solution is failing and to come up with a better solution there, but probably at the cost of losing Matlab compatibility.

Patrick Häcker <magicmuscleman>
Sun 17 Apr 2011 05:51:43 PM UTC, comment #6:

Since this patch only changes to default value of N
in mat2str(x,N) I do not see it has having important
precision problems. Anyone who prefers to see more
digits can say mat2str(x,17) or whatever.

Using the matlab default of 15 will, at least, save
the trouble of answering bug reports about differences
between Octave and matlab.

Michael Godfrey <godfrey>
Project Member
Sun 17 Apr 2011 04:45:36 PM UTC, comment #5:

My thought was that the number of digits displayed should not exceed the numeric precision. In general, we can only be confident in the first 15 digits, correct?

Ben Abbott <bpabbott>
Project MemberIn charge of this item.
Sun 17 Apr 2011 04:24:48 PM UTC, comment #4:

I'm not sure this was actually a bug at all. Choosing to display 15 or 16 digits is a matter of preference, and the actual precision of a double is in fact closer to 16 decimal digits. This particular example the binary representation happens to be closer to 0.7 than to 0.699999999999999, but it's easy to come up with examples when the number displayed with sixteen digits is closer to the actual representation than the one displayed with 15, e.g. 0.69

Jordi Gutiérrez Hermoso <jordigh>
Project Administrator
Sun 17 Apr 2011 04:06:34 PM UTC, comment #3:

I've pushed the change to the default branch.

http://hg.savannah.gnu.org/hgweb/octave/rev/708186085e0d

Patrick, thanks for the report and the patch.

Ben Abbott <bpabbott>
Project MemberIn charge of this item.
Sun 17 Apr 2011 04:00:42 PM UTC, comment #2:

Geezzz ... just as I was going to attached a changeset I noticed Patrick's patch and hit hit the wrong botton :-(

I'll convert Patrick's patch to a mercurial changeset, push it and update here when done.

Ben Abbott <bpabbott>
Project MemberIn charge of this item.
Sun 17 Apr 2011 03:58:41 PM UTC, comment #1:

Looks like a trivial fix. The format specification by Octave uses 17 digits which exceeds that of a double (i.e. EPS = 2.220446049250313e-16)

The attached patch changes the format to 15 digits (same as Matlab).

Ben Abbott <bpabbott>
Project MemberIn charge of this item.
Sun 17 Apr 2011 10:55:27 AM UTC, original submission:

Matlab:
mat2str(0.7)
ans = 0.7

Octave:
mat2str(0.7)
ans = 0.69999999999999996

This behaviour is related with internal floating point representation, and the used precision:

Octave:
mat2str(0.5)
ans = 0.5

According to Matlab's documentation (http://www.mathworks.com/help/techdoc/ref/mat2str.html), the precision's default is 15 digits.

The attached patch sets the default accordingly and adds a test case to show the problem in the unpatched version and its solution in the patched version.

Patrick Häcker <magicmuscleman>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach File(s):
   
   
Comment:
   

Attached Files
file #23263:  patch added by magicmuscleman (272B - text/plain)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by godfrey (Posted a comment)
  • -unavailable- added by jordigh (Posted a comment)
  • -unavailable- added by bpabbott (Posted a comment)
  • -unavailable- added by magicmuscleman (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only project members can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follow 6 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Sun 17 Apr 2011 04:06:34 PM UTCbpabbottStatusPatch Submitted=>Fixed
      Open/ClosedOpen=>Closed
    Sun 17 Apr 2011 03:58:41 PM UTCbpabbottCategoryNone=>Interpreter
      StatusNone=>Patch Submitted
      Assigned toNone=>bpabbott
    Sun 17 Apr 2011 10:55:27 AM UTCmagicmusclemanAttached File-=>Added patch, #23263

    Back to the top


    Powered by Savane 3.1-cleanup1