bugGNU Octave - Bugs: bug #46770, num2str in Matlab overwrites...

 
 

bug #46770: num2str in Matlab overwrites user-supplied input FORMAT

Submitter:  Luis Mendo <lmendo>
Submitted:  Mon 28 Dec 2015 04:57:44 PM UTC
   
 
Category:  Octave Function Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Matlab Compatibility
Status:  Wont Fix Assigned to:  None
Originator Name:  Luis Mendo Open/Closed:  * Closed
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Wed 10 Feb 2016 08:28:05 PM UTC, comment #19: 

For my part, it can be closed, yes

Luis Mendo <lmendo>
Thu 28 Jan 2016 06:48:57 AM UTC, comment #18: 

Can this be closed, since the remaining issue is "won't fix"?

Lachlan Andrew <lachlan>
Wed 13 Jan 2016 09:53:11 PM UTC, comment #17: 

I made num2str and int2str Matlab compatible for all cases where a FORMAT argument is not used.  See http://hg.savannah.gnu.org/hgweb/octave/rev/b0afe1993268.  I won't override a programmer's intention by changing a user-specified FORMAT, so that incompatibility will remain by choice.  And as the documentation says, sprintf is always available for having more control over the output.

Rik <rik5>
Group administrator
Wed 13 Jan 2016 06:47:55 PM UTC, comment #16: 

Hi, I just run the script on R2015b. Find the diary attached.

(file #36016)

Max Görner <maxg>
Wed 13 Jan 2016 05:12:19 PM UTC, comment #15: 

Thanks for running the examples.  I have a few more tests to run.  One of the most obvious is to see whether int2str behaves like num2str when concatenating ND-arrays.  The others are corner cases for num2str.


diary on
x = cat (3, magic (3), -magic (3))
y = int2str (x)

x = [0 0 0]
num2str (x)
x = [2 NaN 1e5]
num2str (x)
x = [pi NaN 1e5]
num2str (x)
x = [Inf NaN -Inf]
num2str (x)
x = [2 1e23 4]
num2str (x)
x = [2.1 1e23 pi]
num2str (x)
diary off



Rik <rik5>
Group administrator
Wed 06 Jan 2016 09:37:14 AM UTC, comment #14: 

Hi, I just run the script on R2015b. I had to change the call to 'e' to 'exp(1)', since 'e' is not known by Matlab. Find the diary attached.

(file #35933)

Max Görner <maxg>
Sun 03 Jan 2016 07:25:03 PM UTC, comment #13: 

@Luis: Thanks for the earlier round of testing.  I'm uploading a file called tst_n2s.m to this bug report.  If you can download it, run it under Matlab, and then upload the resulting diary file I would appreciate it.  The script pokes at various corner cases, such as using Inf, to see how Matlab responds.

(file #35907)

Rik <rik5>
Group administrator
Sat 02 Jan 2016 12:08:21 AM UTC, comment #12: 

Luis, to upload a file, you can go to the bottom of this page and look for "Attached files".  There should be four buttons labelled "Browse...", each followed by "No file selected".  Click "Browse..." and select the file to upload.  Then, when you click "submit changes" to post your comment, the file will be uploaded too.

Lachlan Andrew <lachlan>
Tue 29 Dec 2015 12:08:17 PM UTC, comment #11: 

Thanks for your response. And sorry for my lack of knowledge about Savannah usage. I was using the markup wrong. I still don't know how to upload, so I'm pasting here the contents of the diary file:


x = [1.1, 2.22, -3.3; 4.44, 5.55, 6.6];

num2str (x)
ans =
 1.1        2.22        -3.3
4.44        5.55         6.6

num2str (x, 16)
ans =
 1.1                   2.22                   -3.3
4.44                   5.55                    6.6

num2str (x, '%.16g')
ans =
 1.12.22-3.3
4.445.55 6.6

x(1,2) = 1e7;
num2str (x)
ans =
 1.1           10000000               -3.3
4.44               5.55                6.6

num2str (x, '%.16f ')
ans =
1.1000000000000001 10000000.0000000000000000       -3.2999999999999998
4.4400000000000004        5.5499999999999998        6.5999999999999996

diary off


Luis Mendo <lmendo>
Tue 29 Dec 2015 12:59:37 AM UTC, comment #10: 

@Luis: Can you run the following code samples and upload the results so that we can get a better idea of what Matlab is trying to do?


diary on

x = [1.1, 2.22, -3.3; 4.44, 5.55, 6.6];

num2str (x)

num2str (x, 16)

num2str (x, '%.16g')

x(1,2) = 1e7;
num2str (x)

num2str (x, '%.16f ')

diary off


And then upload the diary file.


Rik <rik5>
Group administrator
Tue 29 Dec 2015 12:49:08 AM UTC, comment #9: 

@Luis: I didn't mean to suggest that Matlab always uses a fixed width of 4.  For the particular input given it used a width of 4.  This is somewhat problematic.  It is fine, when no format is given, for a program to create something reasonable as a default.  However, it is not good practice to override the programmer's choice when it has been given.  It appears that Matlab may be modifying the specified input format and giving it a field width even though none was specified in the format given.

I fixed the difference between row/column concatenation for N-dimensional arrays in this changeset (http://hg.savannah.gnu.org/hgweb/octave/rev/b51078f07886).

Incidentally, you can enter code between verbatim tags to avoid having it processed by the bug tracker and potentially modified.

There is a hyperlink (Rich Markup) which describes how to do it.

Rik <rik5>
Group administrator
Mon 28 Dec 2015 06:28:15 PM UTC, comment #8: 

Running this in Matlab

x = cat(3, magic(3), -magic(3));
fmt = '%.16g %.16g %.16g \n';
y = sprintf (fmt, x)

produces

y =
8 3 4
1 5 9
6 7 2
-8 -3 -4
-1 -5 -9
-6 -7 -2

ans =
     1    51

Luis Mendo <lmendo>
Mon 28 Dec 2015 06:26:25 PM UTC, comment #7: 

Thanks for fixing my message, Rik.

I don't think Matlab simply useds 4 for width:

x = [334341.1, 2.22, -3.3; 4.44, 5.55, 6.6];
fmt = '%4.16g ';
y = num2str(x, fmt)

gives in Matlab

334341.1     2.22     -3.3
    4.44     5.55      6.6

and in Octave

334341.1 2.22 -3.3
4.44 5.55  6.6

Luis Mendo <lmendo>
Mon 28 Dec 2015 06:14:19 PM UTC, comment #6: 

To the original reporter, can you run the following code in Matlab and report back the results to help debug what Matlab is doing?


x = cat(3, magic(3), -magic(3));
fmt = '%.16g %.16g %.16g \n';
y = sprintf (fmt, x)
size (y)



Rik <rik5>
Group administrator
Mon 28 Dec 2015 06:09:54 PM UTC, comment #5: 

Second incompatibility regards how to apply the format string to N-d arrays.  Copying from Stack Overflow report again.

Another difference is how multidimensional arrays are treated. For example,


x = cat(3, magic(3), -magic(3));
fmt = '%.16g ';
y = num2str(x, fmt)


produces in Matlab


y =
8  1  6 -8 -1 -6
3  5  7 -3 -5 -7
4  9  2 -4 -9 -2


and in Octave


y =

8 1 6
3 5 7
4 9 2
-8 -1 -6
-3 -5 -7
-4 -9 -2


That is, Matlab attaches the 3D slices along the second dimension, and Octave along the first.

Rik <rik5>
Group administrator
Mon 28 Dec 2015 06:02:10 PM UTC, comment #4: 

There is another subtle difference.  Matlab is using a field width of 4.  You can see that in the last column where there are two spaces between "5.55" and "6.6".

A quick workaround in Octave is to use the specific format string that Matlab must be using.


x = [1.1, 2.22, -3.3; 4.44, 5.55, 6.6];
fmt = '%4.16g ';
y = num2str(x, fmt)

y =

 1.1 2.22 -3.3
4.44 5.55  6.6


The underlying C libraries can't determine left/right justification if there is no field width, because Octave also right justifies by default.  You can see that by explicitly asking for left justification.


fmt = '%-4.16g ';
y = num2str(x, fmt)

y =

1.1  2.22 -3.3
4.44 5.55 6.6



Rik <rik5>
Group administrator
Mon 28 Dec 2015 05:55:13 PM UTC, comment #3: 

Copying over from stackoverflow.

The following code


x = [1.1, 2.22, -3.3; 4.44, 5.55, 6.6];
fmt = '%.16g ';
y = num2str(x, fmt)


produces different results in Matlab (R20105b)


y =
 1.1 2.22 -3.3
4.44 5.55  6.6


and in Octave (4.0.0)


y =
1.1 2.22 -3.3
4.44 5.55 6.6


The difference is the alignment: in Matlab the columns are right-aligned, whereas in Octave they are not aligned.

Rik <rik5>
Group administrator
Mon 28 Dec 2015 05:04:24 PM UTC, comment #2: 

I can't get the message right. It's all essentially here: http://stackoverflow.com/q/34483961/2586922

Luis Mendo <lmendo>
Mon 28 Dec 2015 05:02:43 PM UTC, comment #1: 

Sorry, the message was cut. I'll try again:

I've noticed two differences in `num2str` between Octave in Matlab:

(1) 2D arrays are not displayed aligned by Octave, whereas Matlab right-aligns columns. For example, consider the following code:


x = [1.1, 2.22, -3.3; 4, 5.5, 6];
fmt = '%.16g ';
y = num2str(x, fmt)
+verbatim+

Octave output (columns are not aligned):

+verbatim+
1.1 2.22 -3.3
4 5.5 6
+varbatim+

Matlab output (columns are right-aligned):

+verbatim+
1.1 2.22 -3.3
  4  5.5    6
+verbatim+

More details here, where I originally asked: http://stackoverflow.com/q/34483961/2586922. I found a workaround when format string contains a single formatting operator, but not in the general case.

(2) The behaviour for arrays with more than two-dimensions also differs.

+verbatim+
x = [1:3; 4:6]; x = cat(3, x, x);
num2str(x, '%i ')
+verbatim+

Octave output:

+verbatim+
1 2 3
4 5 6
1 2 3
4 5 6
+verbatim+

Matlab output:

+verbatim+
1 2 3 1 2 3
4 5 6 4 5 6
+verbatim+

It seems like Matlab collapses all dimensions beyond the first and then applies the formatting. Not sure if this is documented behaviour, though.

Luis Mendo <lmendo>
Mon 28 Dec 2015 04:57:44 PM UTC, original submission:  

I've noticed two differences in `num2str` between Octave in Matlab:

(1) 2D arrays are not displayed aligned by Octave, whereas Matlab right-aligns columns. For example, consider the following code:


x = [1.1, 2.22, -3.3; 4, 5.5, 6];
fmt = '%.16g ';
y = num2str(x, fmt)
+verbatim+

Octave output (columns are not aligned):

+verbatim+
1.1 2.22 -3.3
4 5.5 6
+varbatim+

Matlab output (columns are right-aligned):

+verbatim+
1.1 2.22 -3.3
  4  5.5    6
+verbatim+

More details here, where I originally asked: http://stackoverflow.com/q/34483961/2586922. I found a workaround when the format string contains a single formatting operator, but not in the general case.

(2) The behaviour for arrays with more than two dimensions also differs.

+verbatim+
x = [1:3; 4:6]; x = cat(3, x, x);
num2str(x, '%i ')
+verbatim+

Octave output:

+verbatim+
1 2 3
4 5 6
1 2 3
4 5 6
+verbatim+

Matlab output:

+verbatim+
1 2 3 1 2 3
4 5 6 4 5 6
+verbatim+

It seems like Matlab collapses all dimensions beyond the first and then applies the formatting. Not sure if this is documented behaviour, though.

Luis Mendo <lmendo>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #36016:  diary added by maxg (921B - application/octet-stream)
file #35933:  diary added by maxg (4KiB - application/octet-stream)
file #35907:  tst_n2s.m added by rik5 (614B - d2l/unknowntype)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by maxg (Updated the item)
  • -email is unavailable- added by lachlan (Posted a comment)
  • -email is unavailable- added by rik5 (Updated the item)
  • -email is unavailable- added by lmendo (Submitted the item)
  • -email is unavailable- added by lmendo
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 12 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2016-01-28 rik5 Open/ClosedOpen Closed
    2016-01-13 rik5 StatusIn Progress Wont Fix
        Summarynum2str produces different results in Octave and in Matlab num2str in Matlab overwrites user-supplied input FORMAT
    2016-01-13 maxg Attached File- Added diary, #36016
    2016-01-13 rik5 StatusConfirmed In Progress
        Release4.0.0 dev
    2016-01-06 maxg Attached File- Added diary, #35933
    2016-01-03 rik5 Attached File- Added tst_n2s.m, #35907
    2015-12-28 rik5 StatusNone Confirmed
        Operating SystemMicrosoft Windows Any
        Summary`num2str` produces different results in Octave and in Matlab num2str produces different results in Octave and in Matlab
    2015-12-28 lmendo Carbon-Copy- Added lmendo

    Back to the top

    Powered by Savane 3.13-02a9.
    Corresponding source code