bugGNU Octave - Bugs: bug #66617, structfun assumes output arguments...

 
 

bug #66617: structfun assumes output arguments for invoked command

Submitter:  Liang Tang <lt1234>
Submitted:  Sun 29 Dec 2024 05:46:37 PM UTC
   
 
Category:  Octave Function Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Unexpected Error or Warning
Status:  Confirmed Assigned to:  None
Originator Name:  lt1234 Open/Closed:  * Open
Release:  * 9.2.0 Operating System:  * Microsoft Windows
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Sat 18 Jan 2025 10:06:24 AM UTC, comment #19: 

I agree that your proposed change is clearer.

I think cellfun can only return an empty matrix when you assign the result to a variable, e.g:

x=cellfun(@f,{})

sets x to [], while a sentence like

cellfun(@f,{})

does not set "ans" to anything. But it's probably better to stay safe.

Making structfun a built-in function would require more work, so maybe for the moment we could take your solution and add BIST tests from file #56743.

Fernando <tutissanalio>
Thu 16 Jan 2025 11:16:11 PM UTC, comment #18: 

Directly manipulating and looking at the value of "ans" seems strange to me.  Maybe structfun should also be a built-in function so that it can do a better job of handling this corner case?  But if not, maybe the attached change would be better.  Won't the check for "ans = []" be the wrong thing to do if cellfun happens to return the empty matrix?



(file #56776)

John W. Eaton <jwe>
Group administrator
Thu 16 Jan 2025 10:11:34 PM UTC, comment #17: 

The issue from the original post is not fixed, but there is a patch for it in comment #11 (file #56743).

Fernando <tutissanalio>
Thu 16 Jan 2025 06:45:43 PM UTC, comment #16: 

It looks like this is also fixed now that bug #66642 is fixed.
I'm seeing the following for the reproducer in comment #13 now:

octave:1> function [a,b]=f(x);a=x;end
octave:2> s = struct ("a", 1, "b", 4);
octave:3> [a,b]=structfun(@f,s)
error: cellfun: function returned fewer than nargout values
error: called from
    structfun at line 108 column


Is there anything else that needs to be done for this report?

Markus Mützel <mmuetzel>
Group administrator
Mon 06 Jan 2025 12:35:04 PM UTC, comment #15: 

I also get the same with Matlab 2024a. I think it's an error message, even if the word "error" is not actually displayed. You cant catch it with try-catch.

I filed bug #66642 for it.

Fernando <tutissanalio>
Sun 05 Jan 2025 02:05:28 PM UTC, comment #14: 

In Matlab r2024b I also get:

>> [a,b]=structfun(@f,s)
Output argument "b" (and possibly others) not assigned a value in the execution with "f" function.

but neither 'a' nor 'b' are assigned a value.
Matlab doesn't clearly indicate an error, it sounds more like a warning.

Philip Nienhuis <philipnienhuis>
Group Member
Sun 05 Jan 2025 01:09:32 PM UTC, comment #13: 

While testing for this issue, I noticed a case that should produce an error but does not (in current default branch).



octave:> ver octave
----------------------------------------------------------------------
GNU Octave Version: 10.0.0 (hg id: 462e19654ec9)
GNU Octave License: GNU General Public License
Operating System: Linux 6.8.0-51-generic #52-Ubuntu SMP PREEMPT_DYNAMIC Thu Dec  5 13:09:44 UTC 2024 x86_64
----------------------------------------------------------------------
octave:> function [a,b]=f(x);a=x;end
octave:> s = struct ("a", 1, "b", 4);
octave:> [a,b]=structfun(@f,s)
a =
   1
   4
b =
   0
   0


I expected an error, because variable b should not have been given any value. In Matlab, you get an error:

Output argument "b" (and possibly others) not assigned a value in the execution with "ff_ab" function.

It looks like the problem is in cellfun:

octave:13> [a,b]=cellfun(@f,{1,4})
a =
   1   4
b =
   0   0


I can file a bug report for that.

Fernando <tutissanalio>
Sun 05 Jan 2025 12:56:50 PM UTC, comment #12: 

I read the earlier diff files you attached.  Your m file should work for the original issue I submitted.  Thanks.

Liang Tang <lt1234>
Sun 05 Jan 2025 12:37:19 PM UTC, comment #11: 

Thanks for the info, @lt1234. The problem with your solution is that the number of outputs of a function is not always known a priori. E.g. this function:

function varargout=ff2(x)
varargout={x,2*x};
end

returns two outputs, but nargout(@ff2) returns -1, which means Octave does not know a priori the number of outputs.

Because of that, your solution throws an error in this case:

s = struct ("a", 1, "b", 4);
[a, b] = structfun (@ff2, s);
error: element number 2 undefined in return list


I updated the patch with some tests which have to do with that case. This is attached here.

@lt1234, can you confirm if the patch fixes the issue in your case? (for convinience, I also attach the file, structfun.m, resulting from applying the patch).

(file #56743, file #56744)

Fernando <tutissanalio>
Sat 04 Jan 2025 02:01:36 PM UTC, comment #10: 

FYI only.  I attach my work around structfun.m file that I used to bypass the issue. The changes started from line 107 to the eof. See comment #3 for the general info.  Thanks.

(file #56741)

Liang Tang <lt1234>
Fri 03 Jan 2025 07:55:02 AM UTC, comment #9: 

There's another case where Matlab result differs slightly from Octave, and the patch I submitted also eliminates the discrepancy.

In Octave (without the patch), the following two calls to structfun return the same:


octave:> x=struct;
octave:> structfun(@(z)z,x)
ans = [](0x1)
octave:> y=structfun(@(z)z,x)
y = [](0x1)


while in Matlab (or Octave with the patch), the first call returns nothing:


>> x=struct;
>> structfun(@(z)z,x)
>> y=structfun(@(z)z,x)
y = [](0x1)


I updated the patch with a couple of tests for that case.

(file #56737)

Fernando <tutissanalio>
Thu 02 Jan 2025 10:59:39 PM UTC, comment #8: 

the same with a couple of tests.

(file #56736)

Fernando <tutissanalio>
Thu 02 Jan 2025 04:08:18 PM UTC, comment #7: 

Correction for the fix, taking into account non-uniform output.

(file #56733)

Fernando <tutissanalio>
Wed 01 Jan 2025 10:52:43 PM UTC, comment #6: 

Attached is a possible way to fix it.


(file #56732)

Fernando <tutissanalio>
Tue 31 Dec 2024 01:06:47 PM UTC, comment #5: 

Same issue.  The command window returns:

Error using foobar
Too many output arguments.

Liang Tang <lt1234>
Tue 31 Dec 2024 02:21:18 AM UTC, comment #4: 

What happens in Matlab if you define a function like


function foobar (x)
  disp (nargout)
end


and then execute the following code


varargout = {[]};
[varargout{:}] = cellfun (@foobar, {1})


?

John W. Eaton <jwe>
Group administrator
Mon 30 Dec 2024 04:56:30 PM UTC, comment #3: 

I think the nargout in structfun is associated with structfun.  It should be redirected according to nargout=nargout(fcn);, plus other fixes.  Thanks.

Liang Tang <lt1234>
Mon 30 Dec 2024 04:54:48 PM UTC, comment #2: 

With octave 10 on either MacOS or Linux (fedora 41):

>> FIG.main=figure;
structfun(@delete, FIG)
error: delete: function called with too many outputs
error: called from
    delete
    structfun at line 108 column 4
>> ver
----------------------------------------------------------------------
GNU Octave Version: 10.0.0 (hg id: 564e33ab34fe)


Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Mon 30 Dec 2024 04:43:00 PM UTC, comment #1: 

I can reproduce it with Octave-10.0.0. But I don't get the traceback pointing to l.108 of structfun.m (a regression?)

>> FIG.main=figure;
>> structfun(@delete, FIG)
error: delete: function called with too many outputs
>>

The cause of this bug looks to be that 'structfun.m' unconditionally expects the invoked function to return an output in L.108, while 'delete.m' supplies none.

Philip Nienhuis <philipnienhuis>
Group Member
Sun 29 Dec 2024 05:46:37 PM UTC, original submission:  

Hi, Octave gave an error message for the commands below.  No issue with matlab, i.e., the figure is closed.  Thanks. 

FIG.main=figure;
structfun(@delete, FIG)

error: delete: function called with too many outputs
error: called from
    delete
    structfun at line 108 column 18

which structfun
'structfun' is a function from the file C:\Octave\Octave-9.2.0\mingw64\share\octave\9.2.0\m\general\structfun.m

Liang Tang <lt1234>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #56776:  structfun-diff.txt added by jwe (1KiB - text/plain)
file #56743:  structfun5.diff added by tutissanalio (2KiB - text/x-patch)
file #56744:  structfun.m added by tutissanalio (6KiB - text/x-objcsrc)
file #56741:  structfun.m added by lt1234 (5KiB - application/octet-stream)
file #56737:  structfun4.diff added by tutissanalio (1KiB - text/x-patch)
file #56736:  structfun3.diff added by tutissanalio (1KiB - text/x-patch)
file #56733:  structfun2.diff added by tutissanalio (930B - text/x-patch)
file #56732:  structfun.diff added by tutissanalio (728B - text/x-patch)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by tutissanalio (Updated the item)
  • -email is unavailable- added by dasergatskov (Posted a comment)
  • -email is unavailable- added by jwe (Updated the item)
  • -email is unavailable- added by lt1234 (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
    2025-01-16 jwe Attached File- Added structfun-diff.txt, #56776
    2025-01-05 tutissanalio Attached File- Added structfun5.diff, #56743
        Attached File- Added structfun.m, #56744
    2025-01-04 lt1234 Attached File- Added structfun.m, #56741
    2025-01-03 tutissanalio Attached File- Added structfun4.diff, #56737
    2025-01-02 tutissanalio Attached File- Added structfun3.diff, #56736
    2025-01-02 tutissanalio Attached File- Added structfun2.diff, #56733
    2025-01-01 tutissanalio Attached File- Added structfun.diff, #56732
    2024-12-30 philipnienhuis Summarystructfun assumes output arguments for delete command structfun assumes output arguments for invoked command
    2024-12-30 philipnienhuis StatusNone Confirmed
    2024-12-29 jwe Item GroupMatlab Compatibility Unexpected Error or Warning

    Back to the top

    Powered by Savane 3.14-708e.
    Corresponding source code