bugGNU Octave - Bugs: bug #29942, concatenating with an empty scalar...

 
 

bug #29942: concatenating with an empty scalar gives an error

Submitted by:  Ben Abbott <bpabbott>
Submitted on:  Sat 22 May 2010 06:51:27 PM UTC  
 
Category: NoneSeverity: 3 - Normal
Priority: 5 - NormalItem Group: Incorrect Result
Status: FixedAssigned to: Jaroslav Hajek <highegg>
Originator Name: Ben AbbottOpen/Closed: Closed
Release: devOperating System: Mac OS

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)

Mon 21 Jun 2010 01:50:44 PM UTC, comment #26:

This patch brings horzcat/vertcat in line with [], like in Matlab:
http://hg.savannah.gnu.org/hgweb/octave/rev/f7f26094021b

Closing, thx for cooperation.

Jaroslav Hajek <highegg>In charge of this item.
Fri 18 Jun 2010 04:13:08 PM UTC, comment #25:

Matlab gives the same result.

>> x = zeros(1,0); y = zeros(0,1);
>> [x;y;x]

ans =
Empty matrix: 1-by-0

>> [[x;y];x]

ans =
Empty matrix: 1-by-0

Ben Abbott <bpabbott>
Project Member
Fri 18 Jun 2010 12:52:53 PM UTC, comment #24:

Ugh. That was hard, but this patch brings [] pretty close:
http://hg.savannah.gnu.org/hgweb/octave/rev/53253f796351

octave:1> load t.mat
octave:2> t1{1} = test_cat (@(x,y) [x,y]);
octave:3> t1{2} = test_cat (@(x,y) [x;y]);
octave:4> t1{3} = test_cat (@(x,y) [x;y;x]);
octave:5> t1{4} = test_cat (@(x,y) [x,y,x]);
octave:6> t1{5} = test_cat (@(x,y) horzcat (x, y));
octave:7> t1{6} = test_cat (@(x,y) vertcat (x, y));
octave:8> t1{7} = test_cat (@(x,y) cat (1, x, y));
octave:9> t1{8} = test_cat (@(x,y) cat (2, x, y));
octave:10> t1{9} = test_cat (@(x,y) cat (3, x, y));
octave:11>
octave:11> t1 = cat (3, t1{:});
octave:12> m = cellfun (@isequal, t, t1);
octave:13> squeeze(all(all(m,1),2))
ans =

1
1
0
0
0
0
1
1
1

Regarding the mismatches of 3, 4, they are:

octave:15> [i,j] = find(!m(:,:,3))
i = 3
j = 2
octave:16> [i,j] = find(!m(:,:,4))
i = 2
j = 3

Hmmm. This corresponds to this case:

octave:17> x = zeros(1,0); y = zeros(0,1);
octave:18> [x;y;x]
ans = [](1x0)
octave:19> [[x;y];x]
ans = [](1x0)

can you verify that these two expressions give a different result in Matlab?

This suggests that strictly incremental accumulation of the dimension vector is not enough to mimick Matlab. Duh.

I hope everyone agrees that these corner cases are anal enough to be beyond Octave's scope of Matlab compatibility.

The rest two mismatches (5 and 6) correspond to vertcat/horzcat, which now simply call cat(). I'll address those in a separate changeset.

Jaroslav Hajek <highegg>In charge of this item.
Fri 18 Jun 2010 11:30:10 AM UTC, comment #23:

I agree.

Ben Abbott <bpabbott>
Project Member
Fri 18 Jun 2010 09:53:09 AM UTC, comment #22:

So, here's the hopefully complete rule for cat/horzcat/vertcat:
two arrays can be concatenated along dimension dim if

1. their dimensions except dim-th are exactly equal, in which case the dim-th dimensions are summed

OR

2. one of them is a 0x0 array, in which case the other one is used

OR (only applies to horzcat/vertcat)

3. they are both 2D and one of them is a 1x0 or 0x1 array, in which case the other one is used

EXCEPT

4. if one is 1x0 and the other is 0x1, the result is 0x0.

Can we agree on this?

Jaroslav Hajek <highegg>In charge of this item.
Tue 08 Jun 2010 06:26:57 AM UTC, comment #21:

Hmmm. The new results seem completely equal to the old ones. This is unexpected, because you've shown earlier that at least two cases do indeed produce a warning. Are you sure you used the latter test_cat version (the one which uses lastwarn) to produce it?

Jaroslav Hajek <highegg>In charge of this item.
Mon 07 Jun 2010 01:26:18 PM UTC, comment #20:

ok, time for some coffee!

The Matlab version is attached.

(file #20703)

Ben Abbott <bpabbott>
Project Member
Mon 07 Jun 2010 12:38:55 PM UTC, comment #19:

Huh, did you create this with Octave? I need the results from Matlab, preferably the same version you used before.

Jaroslav Hajek <highegg>In charge of this item.
Mon 07 Jun 2010 12:16:02 PM UTC, comment #18:

Sorry, I'm a bit slow in the morning ;-)

I've uploaded t.mat.

(file #20702)

Ben Abbott <bpabbott>
Project Member
Mon 07 Jun 2010 12:11:17 PM UTC, comment #17:

Er, sorry. By "redo the same test" I meant again doing

t{1} = test_cat (@(x,y) [x,y]);
t{2} = test_cat (@(x,y) [x;y]);
t{3} = test_cat (@(x,y) [x;y;x]);
t{4} = test_cat (@(x,y) [x,y,x]);
t{5} = test_cat (@(x,y) horzcat (x, y));
t{6} = test_cat (@(x,y) vertcat (x, y));
t{7} = test_cat (@(x,y) cat (1, x, y));
t{8} = test_cat (@(x,y) cat (2, x, y));
t{9} = test_cat (@(x,y) cat (3, x, y));

t = cat (3, t{:});

save t.mat t

and once again sending me the t.mat file.

Jaroslav Hajek <highegg>In charge of this item.
Mon 07 Jun 2010 11:25:14 AM UTC, comment #16:

Results below.

octave:2> test_cat
ans =

{
[1,1] = [](0x0)
[2,1] = [](0x0)
[3,1] = [](0x0)
[4,1] = [](0x0)
[5,1] = [](0x0)
[6,1] = [](0x0)
[7,1] = [](0x0)
[8,1] = [](0x0)
[9,1] = [](0x0)
[10,1] = [](0x0)
[11,1] = [](0x0)
[12,1] = [](0x0)
[1,2] = [](0x0)
[2,2] = [](0x0)
[3,2] = [](0x0)
[4,2] = [](0x0)
[5,2] = [](0x0)
[6,2] = [](0x0)
[7,2] = [](0x0)
[8,2] = [](0x0)
[9,2] = [](0x0)
[10,2] = [](0x0)
[11,2] = [](0x0)
[12,2] = [](0x0)
[1,3] = [](0x0)
[2,3] = [](0x0)
[3,3] = [](0x0)
[4,3] = [](0x0)
[5,3] = [](0x0)
[6,3] = [](0x0)
[7,3] = [](0x0)
[8,3] = [](0x0)
[9,3] = [](0x0)
[10,3] = [](0x0)
[11,3] = [](0x0)
[12,3] = [](0x0)
[1,4] = [](0x0)
[2,4] = [](0x0)
[3,4] = [](0x0)
[4,4] = [](0x0)
[5,4] = [](0x0)
[6,4] = [](0x0)
[7,4] = [](0x0)
[8,4] = [](0x0)
[9,4] = [](0x0)
[10,4] = [](0x0)
[11,4] = [](0x0)
[12,4] = [](0x0)
[1,5] = [](0x0)
[2,5] = [](0x0)
[3,5] = [](0x0)
[4,5] = [](0x0)
[5,5] = [](0x0)
[6,5] = [](0x0)
[7,5] = [](0x0)
[8,5] = [](0x0)
[9,5] = [](0x0)
[10,5] = [](0x0)
[11,5] = [](0x0)
[12,5] = [](0x0)
[1,6] = [](0x0)
[2,6] = [](0x0)
[3,6] = [](0x0)
[4,6] = [](0x0)
[5,6] = [](0x0)
[6,6] = [](0x0)
[7,6] = [](0x0)
[8,6] = [](0x0)
[9,6] = [](0x0)
[10,6] = [](0x0)
[11,6] = [](0x0)
[12,6] = [](0x0)
[1,7] = [](0x0)
[2,7] = [](0x0)
[3,7] = [](0x0)
[4,7] = [](0x0)
[5,7] = [](0x0)
[6,7] = [](0x0)
[7,7] = [](0x0)
[8,7] = [](0x0)
[9,7] = [](0x0)
[10,7] = [](0x0)
[11,7] = [](0x0)
[12,7] = [](0x0)
[1,8] = [](0x0)
[2,8] = [](0x0)
[3,8] = [](0x0)
[4,8] = [](0x0)
[5,8] = [](0x0)
[6,8] = [](0x0)
[7,8] = [](0x0)
[8,8] = [](0x0)
[9,8] = [](0x0)
[10,8] = [](0x0)
[11,8] = [](0x0)
[12,8] = [](0x0)
[1,9] = [](0x0)
[2,9] = [](0x0)
[3,9] = [](0x0)
[4,9] = [](0x0)
[5,9] = [](0x0)
[6,9] = [](0x0)
[7,9] = [](0x0)
[8,9] = [](0x0)
[9,9] = [](0x0)
[10,9] = [](0x0)
[11,9] = [](0x0)
[12,9] = [](0x0)
[1,10] = [](0x0)
[2,10] = [](0x0)
[3,10] = [](0x0)
[4,10] = [](0x0)
[5,10] = [](0x0)
[6,10] = [](0x0)
[7,10] = [](0x0)
[8,10] = [](0x0)
[9,10] = [](0x0)
[10,10] = [](0x0)
[11,10] = [](0x0)
[12,10] = [](0x0)
[1,11] = [](0x0)
[2,11] = [](0x0)
[3,11] = [](0x0)
[4,11] = [](0x0)
[5,11] = [](0x0)
[6,11] = [](0x0)
[7,11] = [](0x0)
[8,11] = [](0x0)
[9,11] = [](0x0)
[10,11] = [](0x0)
[11,11] = [](0x0)
[12,11] = [](0x0)
[1,12] = [](0x0)
[2,12] = [](0x0)
[3,12] = [](0x0)
[4,12] = [](0x0)
[5,12] = [](0x0)
[6,12] = [](0x0)
[7,12] = [](0x0)
[8,12] = [](0x0)
[9,12] = [](0x0)
[10,12] = [](0x0)
[11,12] = [](0x0)
[12,12] = [](0x0)
}

Ben Abbott <bpabbott>
Project Member
Mon 07 Jun 2010 05:56:55 AM UTC, comment #15:

Thanks. This shows that cat() really behaves differently from horzcat/vertcat, who are exact equivalents of [,] and [;]. I more or less expected this. It means this will require some more significant modifications from us (now we have horzcat/vertcat simply calling cat(1, ) or cat(2, )).
For cat(), the rule is simple: first try an exact match, and, if it fails, and if one of operands is 0x0, use the other one, otherwise fail.
Note that this means that cat(3,[],[]) is 0x0x2 (i.e. exact match is preferred).
I'm still wondering what to do with things like
[zeros(1,0), zeros(0,1)] which produce a 0x0 array. I consider it unwise to replicate those cases that produce an obsolescence warning. Unfortunately, the test function I sent to you doesn't catch warnings. I've attached a new one; can you please redo the same test with it, and again send the results to me?

(file #20701)

Jaroslav Hajek <highegg>In charge of this item.
Fri 28 May 2010 02:34:21 PM UTC, comment #14:

I've uploaded the t.mat

(file #20645)

Ben Abbott <bpabbott>
Project Member
Fri 28 May 2010 01:22:34 PM UTC, comment #13:

Ugh. I admit I got a bit lost in this, so if you would be so kind, here's a more systematic request. Please download the attached function test_cat.m and do in Matlab:

t{1} = test_cat (@(x,y) [x,y]);
t{2} = test_cat (@(x,y) [x;y]);
t{3} = test_cat (@(x,y) [x;y;x]);
t{4} = test_cat (@(x,y) [x,y,x]);
t{5} = test_cat (@(x,y) horzcat (x, y));
t{6} = test_cat (@(x,y) vertcat (x, y));
t{7} = test_cat (@(x,y) cat (1, x, y));
t{8} = test_cat (@(x,y) cat (2, x, y));
t{9} = test_cat (@(x,y) cat (3, x, y));

t = cat (3, t{:});

save t.mat t

and send it to me?

(file #20644)

Jaroslav Hajek <highegg>In charge of this item.
Fri 28 May 2010 11:19:58 AM UTC, comment #12:

The results are below.

>> a = zeros (0, 2);

b = zeros (2, 0);
c = zeros (1, 0);

[a; a]
[a, a]
[b, b]
[b; b]
[a; c]
[a, c]
[b, c]
[c, b]

ans =

Empty matrix: 0-by-2

ans =

Empty matrix: 0-by-4

ans =

Empty matrix: 2-by-0

ans =

Empty matrix: 4-by-0

ans =

Empty matrix: 0-by-2

ans =

Empty matrix: 0-by-2

ans =

Empty matrix: 2-by-0

ans =

Empty matrix: 2-by-0

>>

Ben Abbott <bpabbott>
Project Member
Fri 28 May 2010 06:31:00 AM UTC, comment #11:

Can you please further test what happens if all empty arrays are concatenated?

a = zeros (0, 2);
b = zeros (2, 0);
c = zeros (1, 0);

[a; a]
[a, a]
[b, b]
[b; b]
[a; c]
[a, c]
[b, c]
[c, b]

Jaroslav Hajek <highegg>In charge of this item.
Mon 24 May 2010 02:48:40 PM UTC, comment #10:

No. Horizcat/vertcat for Matlab and Octave behave the same. Meaning empty 2D arrays are not ignored.

Ben Abbott <bpabbott>
Project Member
Mon 24 May 2010 01:44:03 PM UTC, comment #9:

So, the conclusion is that we shall make [] skip empty 2D matrices? What about horzcat/vertcat, do they skip those too?

Jaroslav Hajek <highegg>In charge of this item.
Mon 24 May 2010 12:26:11 PM UTC, comment #8:

Replacing zeros(0,1) with zeros(0,2), or zeros(1,0) with zeros(2,0), produce the same results (i.e. no errors or warnings).

Ben Abbott <bpabbott>
Project Member
Mon 24 May 2010 12:09:40 PM UTC, comment #7:

Could you please repeat the first ten examples with 2 as the nonzero dimension? Maybe it's just empty vectors that are skipped, not all empty 2D matrices.

Other than that, I think we need not repeat those cases that raise a warning.

Jaroslav Hajek <highegg>In charge of this item.
Mon 24 May 2010 12:00:02 PM UTC, comment #6:

Ok, I understand. It appears that Matlab ignores empty 2D arrays. The first 10 examples below behave in that manner.

a0 = [zeros(0); 1]
a1 = [zeros(1,0); 1]
a2 = [zeros(0,1); 1]
a3 = [zeros(1,0), 1]
a4 = [zeros(0,1), 1]

a5 = [zeros(0,0); [1 1]]
a6 = [zeros(0,0), [1 1]]
a7 = [zeros(1,0); [1 1]]
a8 = [zeros(0,1); [1 1]]
a9 = [zeros(1,0), [1; 1]]
a10 = [zeros(0,1), [1; 1]]

However, the 11th example below fails for any([k,m,n] > 0).

a11 = [zeros(0,0,0); ones(k,m,n)]

??? Error using ==> vertcat
CAT arguments dimensions are not consistent.

Switching to horizontal concatenation ...

>> [zeros(0,0,0), zeros(1,0,0)]

Warning: Concatenation involves an empty array with an incorrect number of rows.
This may not be allowed in a future release.

ans =

[]

>> [zeros(0,0,0), zeros(1,1,0)]

Warning: Concatenation involves an empty array with an incorrect number of rows.
This may not be allowed in a future release.

ans =

[]

>> [zeros(0,0,0), zeros(1,1,1)]

??? Error using ==> horzcat
CAT arguments dimensions are not consistent

Is that sufficient, or are there some additional cases which should be examined?

Ben Abbott <bpabbott>
Project Member
Mon 24 May 2010 07:18:25 AM UTC, comment #5:

Ben, I think I haven't made myself clear. I'm OK with making the behavior Matlab-compatible. But you only pointed out a single example of the incompatibility, and I really doubt that the rule is "skip 1x0 arrays in []" (in addition to the 0x0 arrays). Most likely it's "skip all empty arrays" or "skip all empty 2D arrays" or "skip 0x0 arrays and empty vectors". So, someone needs to do a somewhat detailed investigation what exactly is allowed to mismatch, before we change anything. Simply implement 1x0 as a special case based on your report is, IMHO, a nonsense.
I may do the investigation later, but it would be better if you did as you apparently can access a newer version of Matlab than I do.

Jaroslav Hajek <highegg>In charge of this item.
Sun 23 May 2010 03:24:39 PM UTC, comment #4:

The Matlab code I found this in was written in 2002, and I'm running 2009b. So this behavior appears to have been around a while.

Perhaps your recollection is with regards to cat()?

>> cat (1, zeros(1,0), 1)

??? Error using ==> cat
CAT arguments dimensions are not consistent.

>> cat (2, zeros(1,0), 1)


ans =

1

>> cat (2, zeros(0,1), 1)

??? Error using ==> cat
CAT arguments dimensions are not consistent.

>> cat (1, zeros(0,1), 1)


ans =

1

For cat(), Matlab and Octave behave the same way.

Mathwork's description for how "[...]" works is

"Vectors and matrices can be used inside [ ] brackets. [A B;C] is allowed if the number of rows of A equals the number of rows of B and the number of columns of A plus the number of columns of B equals the number of columns of C. This rule generalizes in a hopefully obvious way to allow fairly complicated constructions."
-- http://www.mathworks.com/access/helpdesk/help/techdoc/ref/specialcharacters.html

The way Matlab functions isn't consistent, but I hesitate to conclude this is due to a bug, a feature, or intent.

The original context was I discovered this in was ...

a = []
do ...
b = ...
a = [a(n:end);b]
end

I don't expect the typical user would realize that "a" and "a(n:end)" will have different shapes when "a" is empty. So Mathworks may have chosen this approach as a path of least resistance.

In either event, I agree that the way Octave behaves is consistent and technically proper. So, I have no problem leaving it as it is. However, I'm not sure if this is a Matlab bug or incompatibility on the part of Octave.

Ben Abbott <bpabbott>
Project Member
Sun 23 May 2010 06:29:19 AM UTC, comment #3:

Maybe it's just a bug in Matlab? What version is it?
I don't think Matlab simply skips all empty arrays (I vaguely recall I tested it before), so I would like to know the general rule before changing anything.

Jaroslav Hajek <highegg>In charge of this item.
Sat 22 May 2010 08:41:25 PM UTC, comment #2:

Matlab allows [zeros(1,0); 1], and treats [](1:end} the same as Octave does.

Using Matlab ...

a =

[]

>> a(1:end)


ans =

Empty matrix: 1-by-0

>> [zeros(1,0); 1]


ans =

1

Ben Abbott <bpabbott>
Project Member
Sat 22 May 2010 07:16:02 PM UTC, comment #1:

You mean that this doesn't work as expected in Matlab? In other words, that Matlab allows [zeros(1,0); 1], despite the column dimension mismatch? Or is it the [](1:end) expression that is buggy? Please clarify.

Jaroslav Hajek <highegg>In charge of this item.
Sat 22 May 2010 06:51:27 PM UTC, original submission:

I know this lousy programing, but it does work as expected in Matlab, and came about while I was helping someone translate some Matlab code to run under Octave.

a=[];
[a(1:end);1]
error: number of columns must match (1 != 0)

Ben Abbott <bpabbott>
Project Member

 

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

Attach File(s):
   
   
Comment:
   

Attached Files
file #20705:  t.mat added by bpabbott (49KiB - application/x-matlab-workspace - 2nd t.mat)
file #20701:  test_cat.m added by highegg (385B - text/x-matlab)
file #20645:  t.mat added by bpabbott (49KiB - application/x-matlab-workspace - test results)
file #20644:  test_cat.m added by highegg (289B - application/mathematica)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by highegg (Posted a comment)
  • -unavailable- added by bpabbott (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 12 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Mon 21 Jun 2010 01:50:43 PM UTChigheggOpen/ClosedOpen=>Closed
    Mon 21 Jun 2010 01:50:42 PM UTChigheggStatusIn Progress=>Fixed
    Tue 08 Jun 2010 11:33:33 AM UTCbpabbottAttached File-=>Added t.mat, #20705
    Tue 08 Jun 2010 11:32:44 AM UTCbpabbottAttached File#20703=>Removed
    Mon 07 Jun 2010 01:26:37 PM UTCbpabbottAttached File#20702=>Removed
    Mon 07 Jun 2010 01:26:18 PM UTCbpabbottAttached File-=>Added t.mat, #20703
    Mon 07 Jun 2010 12:16:02 PM UTCbpabbottAttached File-=>Added t.mat, #20702
    Mon 07 Jun 2010 05:56:55 AM UTChigheggAttached File-=>Added test_cat.m, #20701
    Fri 28 May 2010 02:34:21 PM UTCbpabbottAttached File-=>Added t.mat, #20645
    Fri 28 May 2010 01:22:34 PM UTChigheggAttached File-=>Added test_cat.m, #20644
    Wed 26 May 2010 07:13:29 AM UTChigheggStatusNone=>In Progress
      Assigned toNone=>highegg

    Back to the top


    Powered by Savane 3.1-cleanup1