bugGNU Octave - Bugs: bug #56548, Inconsistent behavior between...


bug #56548: Inconsistent behavior between horzcat/vertcat/cat and bracket syntax

Submitted by:  None
Submitted on:  Tue 25 Jun 2019 08:32:10 PM UTC  
Category:  Octave Function Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Unexpected Error
Status:  None Assigned to:  None
Originator Name:  Geoffrey K Adams Originator Email:  -email is unavailable-
Open/Closed:  Open Release:  4.2.2
Operating System:  GNU/Linux

Add a New Comment (Rich Markup)

You are not logged in

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


Wed 26 Jun 2019 01:34:38 AM UTC, comment #1: 

This bug also exists in Octave 4.4.1 in GNU/Linux

Tue 25 Jun 2019 08:32:10 PM UTC, original submission:  

When concatenating an empty matrix with a struct, the functions horzcat and vertcat generate an error, while the bracket concatenation syntax behaves as expected. Curiously, cat is inconsistent depending on the order of the arguments.

The expected (Matlab-consistent, and also convenient from a programming standpoint) behavior is that empty numeric matrices are dropped entirely, treated effectively as though they were the same type as the struct. This behavior is seen with bracket concatenation:

>>> [[], struct]
ans =
  scalar structure containing the fields:

>>> [[]; struct]
ans =
  scalar structure containing the fields:

>>> [struct, []]
ans =
  scalar structure containing the fields:

However, when using horzcat or vertcat, the same concatenation unexpectedly produces an error:

>>> horzcat([], struct)
error: concatenation operator not implemented for 'scalar' by 'scalar struct' operations

>>> vertcat([], struct)
error: concatenation operator not implemented for 'scalar' by 'scalar struct' operations

>>> horzcat(struct, [])
error: concatenation operator not implemented for 'scalar struct' by 'matrix' operations

Perhaps more concerning, the cat function does not produce an error but instead gives inconsistent results depending on whether the struct or the empty matrix is the first input:

>>> cat(3, struct, [])
ans =
  scalar structure containing the fields:
>>> cat(3, [], struct)
ans = 0

It seems cat is choosing the type of its output based on the type of the first input (after the dimension specifier).

Note that the above examples are somewhat trivial, but I sometimes use a programming pattern like the following:

items = cell(n,1)
for i=1:n
    % calculate a condition
    if condition
        items{i} = struct(...);
items = vertcat(items{:});

so that it may not be clear which elements are actually assigned, but I can rely on the interpreter's error handling to catch if any of the items which were assigned don't have matching fields.


horzcat(args{:}) and vertcat(args{:}) can be replaced by [args{:}] and [args{:}]', respectively. I sometimes prefer to use horzcat and vertcat because the transpose operator is easy to miss when reading code and the function forms make it very explicit which type of concatenation is being performed. However, cat(D, args{:}) is less straightforward to workaround. and would require explicitly testing with isempty (or something similar) to remove unassigned elements.

(c.f. bug #36817)



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

Attach Files:

No files currently attached


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by None (Submitted the item)

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

    Only project members can vote.




    No changes have been made to this item

    Back to the top

    Powered by Savane 3.5