bugGNU Octave - Bugs: bug #46004, ezplot fails to recognise...

 
 

bug #46004: ezplot fails to recognise functions with 2 arguments passed as handles

Submitter:  Tasos Papastylianou <tpapastylianou>
Submitted:  Sun 20 Sep 2015 12:07:16 AM UTC
   
 
Category:  Plotting Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  Fixed Assigned to:  None
Originator Name:  Tasos Papastylianou <tpapastylianou> Open/Closed:  * Closed
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Tue 22 Sep 2015 11:19:08 AM UTC, comment #6: 

This turned out to be quite an involved fix.  I simplified 1/3rd of the input processing for _ezplot_ and also fixed this issue on the stable branch in this changeset (http://hg.savannah.gnu.org/hgweb/octave/rev/c0566df8cde3).  It will be a part of the next minor bug fix release (4.0.1).

Rik <rik5>
Group administrator
Mon 21 Sep 2015 11:37:41 PM UTC, comment #5: 

(sorry, just pointing out the bulk of my previous comment has been eaten up at savannah.gnu.org ... though it appears in full on email. Not sure why this happens)

Tasos Papastylianou <tpapastylianou>
Mon 21 Sep 2015 11:32:51 PM UTC, comment #4: 

Hi Rik. Thanks for the explanation about nargin; I wasn't aware of this substitution.
I can confirm that


if builtin ("nargin", fun) == 2; args{2} = "y"; end


in __ezplot.m__ (placed under line 135) works as expected and fixes the bug.

The correct output should be from +verbatim+ ezplot (@(a,b) a - b, [ 0, 10, 0, 10]) -verbatim-

Since @f is a handle to a function expecting two inputs, the output should have been identical.

I apologise, I used an example where the bug was a bit subtle, in that it produces the wrong graph, only because that was the scenario where I came across it. In reality it doesn't have to be subtle at all. Consider the following:

  • in function f.m:



function Out = f(a,b)
  Out = a-b;
end


(note there's no nargin check to provide a default value for b this time. If b isn't provided, this function will simply result in an error.)

  • then at the terminal:



>> ezplot(@f, [0,10,0,10])
error: 'b' undefined near line 2 column 11
error: called from
    f at line 2 column 7
    __ezplot__ at line 399 column 13
    ezplot at line 76 column 19


Line 399 of __ezplot__.m is:


Z = feval (fun, X);


In other words, __ezplot__ has branched down to a point in a nested if block where it tries to evaluate fun using only one argument, hence it fails. The reason it inappropriately reaches that part at all is because of the bug at line 135, which makes the assumption that any handle derived from a simple function will always only have one argument, and implicitly results in setting the second argument to "". This assumption is false, hence the fix to check for a second argument and act accordingly.

Tasos Papastylianou <tpapastylianou>
Mon 21 Sep 2015 08:49:15 PM UTC, comment #3: 

Which plot is considered the correct one?


ezplot(@f,[0,10,0,10]);


or


ezplot (@(a,b) a - b, [0, 10, 2, 10])


The reason


nargin (fun) == 2


doesn't work is that nargin has been declared as a variable which shadows the function declaration.  You can always use builtin() to recover the original function.


builtin ("nargin", fun) == 2



Rik <rik5>
Group administrator
Sun 20 Sep 2015 01:55:55 PM UTC, comment #2: 

Thanks, Mike! You're right about the caller workspace. This will allow handles to subfunctions to also work.
As for handles to nested functions, octave complains that these are not implemented yet, but in theory when they do, the fix should work for those too.

Also, somewhat less ugly-looking fix. Under line 135 of _ezplot_.m insert:

if evalin('caller','nargin(varargin{1})') == 2; args{2} = "y"; end

(in theory, if nargin(fun) == 2 should have worked too since fun was instantiated from varargin{1}, but this produces an error ... don't know why, but let's not waste time figuring out why)

To test:

  • in file Bar.m


function Bar(Domain)
  % Function Bar
  ezplot(@Foo,Domain);
endfunction

function Out = Foo(a,b)
  % Subfunction Foo
  if nargin < 2; b = 5; end
  Out = a-b;
endfunction


  • at the console


Bar([0,10,0,10]);


Note: For some reason when fixing _ezplot_.m you need to restart octave for the fix to take effect.
      Not sure why, presumably private functions are preloaded in memory or sth?
      Just pointing this out in case someone tries the fix and runs without restarting and thinks the fix doesn't work.

Tasos Papastylianou <tpapastylianou>
Sun 20 Sep 2015 01:10:27 AM UTC, comment #1: 

Confirmed here, thanks for finding this. The equivalent works for me with an anonymous function, a literal string "a-b", a string "f" that evaluates your user function f, or a handle to an anonymous or call to inline(). But not with the case of a handle to a two-argument user function. Have not tried the proposed fix yet. Should the evalin be "caller" instead of "base"? That might cover the case of a function that calls ezplot on a nested function?

Mike Miller <mtmiller>
Group Member
Sun 20 Sep 2015 12:07:16 AM UTC, original submission:  

To replicate:

Create a function f.m

%% in file f.m
function Out = f(a,b)
  if nargin < 2; b = 5; end
  Out = a-b;
end


Then at the terminal, compare:

ezplot(@f,[0,10,0,10]);


with:

ezplot(@(a,b) a-b, [0,10,0,10]);


The results should be the same, but they're not. Octave treats the function as a single argument function.
(The two commands give the same output in Matlab as expected)

The error lies in line 135 of private function _ezplot_.m, which is called by ezplot.m
This assumes erroneously that if the function handle passed in is not an anonymous function, then it must necessarily come from a function with a single argument; clearly this neglects functions with two arguments which are also valid input for ezplot.

Suggested fix:
Add the following line below line 135:

if evalin('base',['nargin(''' func2str(fun) ''')']) == 2; args{2} = "y"; end


Many thanks,
T.

Tasos Papastylianou <tpapastylianou>

 

(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 rik5 (Posted a comment)
  • -email is unavailable- added by mtmiller (Posted a comment)
  • -email is unavailable- added by tpapastylianou (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 4 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2015-09-22 rik5 StatusConfirmed Fixed
        Open/ClosedOpen Closed
    2015-09-20 mtmiller StatusNone Confirmed
        Release4.0.0 dev

    Back to the top

    Powered by Savane 3.13-d3ae.
    Corresponding source code