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

 
 

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

Submitter:  None
Submitted:  Tue 25 Jun 2019 08:32:10 PM UTC
   
 
Category:  Octave Function Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Unexpected Error or Warning
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 Fixed Release:  None
Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

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

This bug also exists in Octave 4.4.1 in GNU/Linux

Anonymous
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(...);
    end
end
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.

Workarounds:

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)

Anonymous

 

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

Attach Files:
   
   
Comment:
   

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)
  •  

    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.

     

    No changes have been made to this item

    Back to the top

    Powered by Savane 3.13-4448.
    Corresponding source code