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.
|
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
|
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.
|
Fri 18 Jun 2010 11:30:10 AM UTC, comment #23:
I agree.
|
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?
|
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?
|
Mon 07 Jun 2010 01:26:18 PM UTC, comment #20:
ok, time for some coffee!
The Matlab version is attached.
(file #20703)
|
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.
|
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)
|
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.
|
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)
}
|
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)
|
Fri 28 May 2010 02:34:21 PM UTC, comment #14:
I've uploaded the t.mat
(file #20645)
|
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)
|
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
>>
|
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]
|
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.
|
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?
|
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).
|
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.
|
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?
|
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.
|
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.
|
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.
|
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
|
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.
|
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)
|