bugGNU Octave - Bugs: bug #36221, using ~ as optional output for...

 
 

bug #36221: using ~ as optional output for unique causes error in ismember

Submitter:  None
Submitted:  Tue 17 Apr 2012 07:52:37 AM UTC
   
 
Category:  None Severity:  3 - Normal
Priority:  5 - Normal Item Group:  None
Status:  Fixed Assigned to:  jwe
Originator Name:  Yoerik de Voogd Originator Email:  -email is unavailable-
Open/Closed:  * Closed Release:  * 3.6.1
Operating System:  * Any Fixed Release:  None
Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Thu 19 Apr 2012 08:25:36 PM UTC, comment #13: 

I checked in the following change to fix this problem:

http://hg.savannah.gnu.org/hgweb/octave/rev/000cd393f3c1

This fix will appear in the upcoming 3.6.2 release.

John W. Eaton <jwe>
Group administrator
Thu 19 Apr 2012 01:27:00 PM UTC, comment #12: 

Ben, I see the problem now.  It must be related to varargout processing because I don't see it if I use a function like


function [a, b, c] = f ()
  if (isargout (1)) a = 1; endif
  if (isargout (2)) b = 2; endif
  if (isargout (3)) c = 3; endif
endfunction


Sorry about the confusion.

I'll check it out.

John W. Eaton <jwe>
Group administrator
Thu 19 Apr 2012 11:21:59 AM UTC, comment #11: 

I'm seeing the error below


error: element number 3 undefined in return list


When "~" is used for the last output and it has not been set.

For example, using the newdeal.m function below


function varargout = newdeal (varargin)
  for n = nargin:-1:1
    if (isargout (n))
      varargout(n) = varargin(n);
    else
      # varargout(n) = {[]};
    endif
  endfor
endfunction


The "~" works as expected, except for the last output.


[a, b, c] = newdeal (1, 2, 3)
a =  1
b =  2
c =  3
[~, b, c] = newdeal (1, 2, 3)
b =  2
c =  3
[a, ~, c] = newdeal (1, 2, 3)
a =  1
c =  3
[a, b, ~] = newdeal (1, 2, 3)
a =  1
b =  2
error: element number 3 undefined in return list


Ben Abbott <bpabbott>
Group Member
Thu 19 Apr 2012 01:04:42 AM UTC, comment #10: 

If the output is not used, I see no reason to require it to be set.

John W. Eaton <jwe>
Group administrator
Thu 19 Apr 2012 12:11:25 AM UTC, comment #9: 

Did you intend for the changeset to require the nth output be set? As below, for example?


  if (isargout (n))
    % compute n-th output
  else
    nth_output = [];
  end



Ben Abbott <bpabbott>
Group Member
Wed 18 Apr 2012 07:15:37 PM UTC, comment #8: 

Oh, wait.  Now I remember, Matlab has the special "~" that allows outputs to be ignored, but it doesn't seem to provide a way for a function to check to see whether the outputs are ignored.  At least it doesn't seem to have an isargout function.

John W. Eaton <jwe>
Group administrator
Wed 18 Apr 2012 07:07:48 PM UTC, comment #7: 

The originally reported problem is fixed by the changeset I committed, so I don't think there is anything in unique.m that needs to be changed.

I also don't think that we should require that unused outputs must be set to something.  Does matlab really require that?  So you have to write things like


  if isargout (n)
    % compute n-th output
  else
    % no need to compute the n-th output, but we still
    % have to set it, because even though matlab is
    % ignoring this output, it needs a dummy value.
    % Seriously?
    nth_output = [];
  end


Anyway, what is left to fix?


John W. Eaton <jwe>
Group administrator
Wed 18 Apr 2012 06:54:10 PM UTC, comment #6: 

John,

I think you are correct that "~" is sticky, and should be fixed.

Regarding omitting setting the value for output's corresponding to "~", I also agree that would be useful. Reading the help string, my impression was that the function still needed to set the value, but that the result would be ignored when returned.

I don't think we need to copy the behavior of Matlab in this instance, but Matlab does throw an error if the output corresponding to "~" is not set.

How would you like to proceed? Should the parser be fixed, or shall unique.m be modified to use nargout instead ?

Ben Abbott <bpabbott>
Group Member
Wed 18 Apr 2012 06:48:23 PM UTC, comment #5: 

This bug is fixed with the changeset:

http://hg.savannah.gnu.org/hgweb/octave/rev/6131fead3135

See also bug #36260

John W. Eaton <jwe>
Group administrator
Wed 18 Apr 2012 05:21:52 PM UTC, comment #4: 

With your function


function varargout = newdeal (varargin)
  for n = 1:nargin
    if (isargout (n))
      varargout(n) = varargin(n);
    endif
  endfor
  printf ("nargin = %d, nargout = %d, isargout(%d) = %d\n",
          nargin (), nargout (), nargout (), isargout (nargout ()))
endfunction


I see the following:


octave:2>  [a1, b1, c1] = newdeal (1, 2, 3);
nargin = 3, nargout = 3, isargout(3) = 1
octave:3>  [a2, b2,  ~] = newdeal (1, 2, 3);
nargin = 3, nargout = 3, isargout(3) = 0
error: element number 3 undefined in return list
octave:3> [a3, b3, c3] = newdeal (1, 2, 3);
nargin = 3, nargout = 3, isargout(3) = 0
error: element number 3 undefined in return list


I think that in the third call to newdeal, isargout(3) should be true and the call should succeed.  It seems like isargout is somehow sticky and I don't think it should be.  Or am I misunderstanding something here?

Also, if isargout(N) is true, I think we should be able to completely omit setting a value for that output.  The point of isargout is to be able to avoid calculation, but I think it would annoying if we still had to set values (even if just []) for unused output values.

John W. Eaton <jwe>
Group administrator
Wed 18 Apr 2012 04:23:57 PM UTC, comment #3: 

I wrote a simple function that isolates the problem.


function varargout = newdeal (varargin)
  for n = 1:nargin
    if (isargout (n))
      varargout(n) = varargin(n);
    endif
  endfor
  printf ("nargin = %d, nargout = %d, isargout(%d) = %d\n",
          nargin (), nargout (), nargout (), isargout (nargout ()))
endfunction

%!shared a1, a2, a3, b1, b2, b3, c1, c3
%! [a1, b1, c1] = newdeal (1, 2, 3);
%! [a2, b2,  ~] = newdeal (1, 2, 3);
%! [a3, b3, c3] = newdeal (1, 2, 3);
%!assert (a1, a2)
%!assert (a1, a3)
%!assert (b1, b2)
%!assert (b1, b3)
%!assert (c1, c3)


Running "test newdeal" ends with


test newdeal
nargin = 3, nargout = 3, isargout(3) = 1
nargin = 3, nargout = 3, isargout(3) = 0
  ***** shared a1, a2, a3, b1, b2, b3, c1, c3
 [a1, b1, c1] = newdeal (1, 2, 3);
 [a2, b2,  ~] = newdeal (1, 2, 3);
 [a3, b3, c3] = newdeal (1, 2, 3);
!!!!! test failed
element number 3 undefined in return list
shared variables
  scalar structure containing the fields:

    a1 = [](0x0)
    a2 = [](0x0)
    a3 = [](0x0)
    b1 = [](0x0)
    b2 = [](0x0)
    b3 = [](0x0)
    c1 = [](0x0)
    c3 = [](0x0)


The parser expects the third argument to be set when the "~" is present. I think this is intended. Thus, unique.m should be rewritten to use "(nargout () <= n)" in place of "isargout (n)". For example, modifying the simple example, the version below passes all tests.


function varargout = newdeal (varargin)
  nout = nargout ();
  isargout = @(n) nout >= n;
  for n = 1:nargin
    if (isargout (n))
      varargout(n) = varargin(n);
    endif
  endfor
  printf ("nargin = %d, nargout = %d, isargout(%d) = %d\n",
          nargin (), nargout (), nargout (), isargout (nargout ()))
endfunction

%!shared a1, a2, a3, b1, b2, b3, c1, c3
%! [a1, b1, c1] = newdeal (1, 2, 3);
%! [a2, b2,  ~] = newdeal (1, 2, 3);
%! [a3, b3, c3] = newdeal (1, 2, 3);
%!assert (a1, a2)
%!assert (a1, a3)
%!assert (b1, b2)
%!assert (b1, b3)
%!assert (c1, c3)


Ben Abbott <bpabbott>
Group Member
Wed 18 Apr 2012 02:59:28 PM UTC, comment #2: 

this bug is not limited to unique, see #36240

meanwhile you can just avoid trailing ~
(beware that once unique has been called with a trailing ~,
clear unique is mandatory for it to work again)

output from 56 to 60 : same as yours
output from 61 to 64 : works


octave:56> A = [1 2];
octave:57> s = [1 2; 3 4; 5 6];
octave:58> [xx, ii, jj] = unique ([A; s], "rows", "last")
xx =

   1   2
   3   4
   5   6

ii =

   2
   3
   4

jj =

   1
   1
   2
   3

octave:59> [a, b, ~] = unique ([1, 2, 3, 2, 1, 6, 4]);
octave:60> [xx, ii, jj] = unique ([A; s], "rows", "last")
xx =

   1   2
   3   4
   5   6

ii =

   2
   3
   4

jj = [](0x0)
octave:61> clear unique
octave:62> [xx, ii, jj] = unique ([A; s], "rows", "last")
xx =

   1   2
   3   4
   5   6

ii =

   2
   3
   4

jj =

   1
   1
   2
   3

octave:63> [a, b] = unique ([1, 2, 3, 2, 1, 6, 4]);
octave:64> [xx, ii, jj] = unique ([A; s], "rows", "last")
xx =

   1   2
   3   4
   5   6

ii =

   2
   3
   4

jj =

   1
   1
   2
   3


John Hunt <huntj>
Wed 18 Apr 2012 01:32:19 AM UTC, comment #1: 

I tracked the problem a bit. The script below results in an empty "jj" when unique is called the last time.


A = [1 2];
s = [1 2; 3 4; 5 6];
[xx, ii, jj] = unique ([A; s], "rows", "last")
[a, b, ~] = unique ([1, 2, 3, 2, 1, 6, 4]);
[xx, ii, jj] = unique ([A; s], "rows", "last")


Ben Abbott <bpabbott>
Group Member
Tue 17 Apr 2012 07:52:37 AM UTC, original submission:  

When using ~ as the optional 3rd output argument in the unique function the ismember function using the optional 'rows' argument causes the error:


error: ismember: A(I): index out of bounds; value 1 out of bound 0
error: called from:
error:   C:\Octave\Octave3.6.1_gcc4.6.2\Octave3.6.1_gcc4.6.2\share\octave\3.6.1\m\set\ismember.m at line 124, column 10
error:   H:\code\bugTesting.m at line 6, column 6


The error can be reproduced using the code


clear all;
ism1 = ismember([1 2],[1 2;3 4;5 6],'rows')
[a,b,~] = unique({'1','2','3','2','1','6','4'});
ism2 = ismember([1 2],[1 2;3 4;5 6],'rows')


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 jwe (Posted a comment)
  • -email is unavailable- added by huntj (Posted a comment)
  • -email is unavailable- added by bpabbott (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 11 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2012-04-19 jwe StatusIn Progress Fixed
        Open/ClosedOpen Closed
    2012-04-19 bpabbott Assigned tobpabbott jwe
    2012-04-18 bpabbott StatusFixed In Progress
        Open/ClosedClosed Open
    2012-04-18 jwe StatusIn Progress Fixed
        Open/ClosedOpen Closed
    2012-04-18 bpabbott StatusConfirmed In Progress
        Assigned toNone bpabbott
        Operating SystemMicrosoft Windows Any
    2012-04-18 bpabbott StatusNone Confirmed

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code