bugGNU Octave - Bugs: bug #61295, cross() dimensions inconsistent...

 
 

bug #61295: cross() dimensions inconsistent with Matlab when using mismatched input vector dimensions

Submitter:  None
Submitted:  Tue 05 Oct 2021 11:06:16 PM UTC
   
 
Category:  Octave Function Severity:  3 - Normal
Priority:  3 - Low Item Group:  Matlab Compatibility
Status:  Ready For Test Assigned to:  None
Originator Name:  DavidS Originator Email:  -email is unavailable-
Open/Closed:  * Open Release:  * dev
Operating System:  * Any Fixed Release:  None
Planned Release:  10.1.0 (current default)
* Mandatory Fields

Add a New Comment Rich Markup
   

Tue 02 Apr 2024 02:28:31 AM UTC, comment #5: 

pushed a switch to row vector output from mixed vector inputs along with BISTs and a NEWS item to default as
https://hg.savannah.gnu.org/hgweb/octave/rev/1db14e08bee4

didn't break any calling functions. passes make check. marking as ready for test.

Nicholas Jankowski <nrjank>
Group Member
Tue 02 Apr 2024 01:57:49 AM UTC, comment #4: 

agreed.  testing out a patch to default now to see if it affects any calling functions.

Nicholas Jankowski <nrjank>
Group Member
Mon 01 Apr 2024 10:30:16 PM UTC, comment #3: 

My vote would be for solution #2: Matlab-compatible row vector output.  I would certainly put a note in the NEWS file for 10.1.

When it comes to something like matrix-by-vector multiplication, the orientation is quite important.  But, when it comes to vector-by-vector operations it is important to distinguish whether the vector is really a just a 1-D list data structure.  I think many programmers, in these cases, just lose track of whether it is a row or column vector because it isn't very important.  In the case of cross() with two vectors, I think it is enough for Octave to recognize that they are vectors and hence it's not terribly important whether they came is as row or column vectors.  And with that view, we might as well adopt whatever output convention Matlab has since the choice is arbitrary.

Rik <rik5>
Group administrator
Mon 01 Apr 2024 08:50:36 PM UTC, comment #2: 

testing in matlab 2023b

no dim input:

>> x = 1:3; y = 2:4;
>> cross (x,y) % row, row
ans =
    -1     2    -1
>> cross (x',y') % col, col
ans =
    -1
     2
    -1
>> cross (x',y) % col, row
ans =
    -1     2    -1
>> cross (x,y') % row, col
ans =
    -1     2    -1

>> x = 1:3; y = 2:4;
>> cross (x,y) % row, row

ans =

    -1     2    -1

so output is a row except for 'col,col", which outputs a column. with dim input and mismatched vectors, e.g., cross(x,y',1), you get a size mismatch error for any combination, as one of the dims don't have size 3:

>> cross (x',y,1) % col, row
Error using cross
A and B must be of length 3 in the dimension in which the cross product is taken.


current octave behavior (using current stable):

>> x = 1:3;y=2:4;
>> cross (x,y) % row, row
ans =

  -1   2  -1

>> cross (x',y') % col, col
ans =

  -1
   2
  -1

>> cross (x,y') % row, col
warning: cross: taking cross product of row by column
warning: called from
    cross at line 78 column 7

ans =

  -1
   2
  -1

>> cross (x',y) % col, row
warning: cross: taking cross product of column by row
warning: called from
    cross at line 75 column 7

ans =

  -1
   2
  -1

so we do the opposite, defaulting to a col. Octave also catches the mismatch with dim specified and issues an error.

i also assume the fact that we have a compatibility hack to specifically address this indicates they made a col->row switch at some point. Our hack to match now causes an incompatibility.  could be an inadvertent effect of some other change they made for underlying functions working on vectors. seemed to be a lot of them in the ~2018 timeframe.

So, options here:
(1) leave it alone, advise that inputs should pass size_equal(x,y) for predictable/compatible behavior, and document the potential incompatibility.
(2) switch the undocumented compatibility hack to be compatible, making them row vectors. it's simple enough to change what is transposed. this could break some octave backward compatibility but improve cross-compatibility.
(3) absent any documentation we remove the hack, just throw a size mismatch error, and stop trying to copy undocumented behavior.  this would break both cross and backward compatibility. advise that inputs must pass size_equal

(i may still peek through release notes/bugfix reports to see if i can pinpoint a change. that would at least be some documentation to go on)

Nicholas Jankowski <nrjank>
Group Member
Thu 07 Oct 2021 05:08:19 PM UTC, comment #1: 

It would probably be better to change the calling code to use all row vectors or all column vectors rather than rely on quirks in the implementation of the cross function.  The Matlab documentation for cross() is available at https://www.mathworks.com/help/matlab/ref/cross.html.  They do not specify what should happen in the case of mixed orientation vectors and thus the behavior could change from version to version.

In fact, this seems to have been the case.  The code for cross() in Octave is just an m-file cross.m.  Looking at the code I see there is a special case for mixed orientation along with a lot of commentary.


  if (ndims (x) < 3 && ndims (y) < 3 && nargin < 3)
    ## COMPATIBILITY -- opposite behavior for cross(row,col)
    ## Swap x and y in the assignments below to get the matlab behavior.
    ## Better yet, fix the calling code so that it uses conformant vectors.
    if (columns (x) == 1 && rows (y) == 1)
      warning ("cross: taking cross product of column by row");
      y = y.';
    elseif (rows (x) == 1 && columns (y) == 1)
      warning ("cross: taking cross product of row by column");
      x = x.';
    endif
  endif


Matlab doesn't display a lot of consistency.  I would say overall that they have a preference for column vectors, except when they don't.  All of the set functions, for example, prefer column vectors for mixed orientations.


intersect ([1:5], [3:10]')
ans =

   3
   4
   5


But, then you can try something like plot() where the data is specifically a column vector on entry and is transformed into a row vector


h = plot ([1:10]', [1:10]');
get (h, 'xdata')
ans =

    1    2    3    4    5    6    7    8    9   10

get (h, 'ydata')
ans =

    1    2    3    4    5    6    7    8    9   10


You can make your own code conformant by transforming to column vectors using


x = x(:);  % ensure column vector


or to row vectors using


x = x(:).';  % ensure row vector


I've marked the bug as Confirmed, but it will be more expedient to bullet-proof your own code.

Rik <rik5>
Group administrator
Tue 05 Oct 2021 11:06:16 PM UTC, original submission:  

When calling cross() with a column vector and a row vector or a row vector and a column vector Octave will return a column vector (and a warning) while Matlab will return a row vector.

In octave for example:

> cross([1,2,3]',[0,0,1])
warning: cross: taking cross product of column by row
warning: called from
    cross at line 62 column 7

ans =

   2
  -1
   0

 In Matlab:

>> cross([1 2 3]',[0 0 1])

ans =

     2    -1     0


In general, Matlab will only return a column vector if both vectors are column vectors and Octave will only return a row vector if both vectors are row vectors. This can break script compatibility.


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 nrjank (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -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.

     

    Follow 6 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2024-04-02 nrjank StatusConfirmed Ready For Test
        Planned ReleaseNone 10.1.0 (current default)
    2021-10-07 rik5 Priority5 - Normal 3 - Low
        StatusNone Confirmed
        Release6.3.0 dev
        Operating SystemMac OS Any

    Back to the top

    Powered by Savane 3.13-4448.
    Corresponding source code