Passing varargin to nested class method in MATLAB - matlab

I would like to parse variable inputs for several class methods in the same way, so I wrote a method to do just that and intend to call it from the other methods as needed. However, when I call methodB from methodA, varargin{:} isn't being passed as its cell contents but as another cell array – similar to if I hadn't included the {:}.
Does anyone have an idea why the contents aren't passing?
methods
function varargout = methodA(obj,varargin)
[obj,t.start,t.stop,prn,elevLim,t.interval] = methodB(varargin{:});
end
function varargout = methodB(varargin)
% parse inputs here...
%output parsed inputs to calling function
varargout = {obj,t.start,t.stop,prn,elevLim,t.interval};
end
end

When you try to use your code as stated in the question, you will get error messages which would have been valuable to mention. In case you write methodB(varargin) this message is:
Undefined function 'methodB' for input arguments of type 'double'.
And when writing methodB(varargin{:}) it is:
Undefined function 'methodB' for input arguments of type 'cell'.
The main problem here is that you have not explicitly defined the first argument of methodB to be an object variable. This is needed since methodB is a so-called ordinary method because it is not defined as static. There are some other problems in the code as well. For example methodA never assigns something to varargout and methodB should return obj which is not defined neither.
Solution with ordinary method
methodB needs to have an explicitly defined object variable, so the first line of the definitition should be: function varargout = methodB(obj,varargin). However, if we don't need obj in the method itself, we can replace it with ~, so it dosen't get assigned to a variable.
In order to call the method you need to use the proper syntax to call it, either methodB(obj,varargin{:}) or obj.methodB(varargin{:}).
Here is working code to verify it:
classdef nestedvarargin
properties
end
methods
function varargout = methodA(obj,varargin)
[t.start,t.stop,prn,elevLim,t.interval] = methodB(obj,varargin{:}); % call ordinary method (syntax 1)
% [t.start,t.stop,prn,elevLim,t.interval] = obj.methodB(varargin{:}); % call ordinary method (syntax 2)
varargout = {t.start,t.stop,prn,elevLim,t.interval};
end
function varargout = methodB(~,varargin)
% extract desired values from varargin (for example leave 3rd argument out)
varargout = {varargin{1},varargin{2},varargin{4},varargin{5},varargin{6}};
end
end
end
Solution with static method
The other way is to define methodB to be static and call it as baseclass.methodB(varargin{:}). In this case, no explicitly defined object variable is needed.
The code looks like this:
classdef nestedvarargin
properties
end
methods
function varargout = methodA(obj,varargin)
[t.start,t.stop,prn,elevLim,t.interval] = nestedvarargin.methodB(varargin{:}); % call static method
varargout = {t.start,t.stop,prn,elevLim,t.interval};
end
end
methods(Static)
function varargout = methodB(varargin)
% extract desired values from varargin (for example leave 3rd argument out)
varargout = {varargin{1},varargin{2},varargin{4},varargin{5},varargin{6}};
end
end
end
Testing
In order to verify the functionality, you can use the following two lines. As defined in methodB, the third argument should be omitted as well as the arguments after the sixth (5 in the case below).
testobj = nestedvarargin;
[a,b,c,d,e] = testobj.methodA(1,2,[],3,4,5,[])
The output is be as expected:
a =
1
b =
2
c =
3
d =
4
e =
5

Related

Axes output not assigned

I'm working on an assignment in which we create a function that creates a blank figure. I think I have most of the function correct, but I also know that parts of it aren't. It is a very simple function, but I'm not sure exactly how to use the outputs. Below are the function and the code calling that function.
function [ax, f] = create_axes(fignum)
figure(fignum)
clf(fignum, 'reset')
ax = axes('Parent',fignum)
axis(ax,'equal')
box(ax,'on')
end
Code to call the above function:
fignum = 317;
[ax,f] = create_axes(fignum)

function handles in Octave

I have a question regarding function(handles) in Octave.
So, I want to call a function, which accepts two variables and returns two(the implementation is faulty; but not relevant in this case).
According to the documentation this should be quite straightforward:
function [ret-list] = name (arg-list)
body
endfunction
I'm trying the following:
function two_d_comp = twodcomp
twodcomp.twoDperp=#perp;
^
end
function twoDperp[vmag, vangle]=perp(x,y)
W = hypot(y,x);
vmag = y/W;
vangle = x/y;
end;
I saved the function in a file called twodcomp.m.
When I call the function as follows:
[X, Y] = twodcomp.twoDperp(1,2)
Octave spits out the following:
error: #perp: no function and no method found
error: called from
twodcomp at line 2 column 20
I managed to remove the error by removing the output arguments vmag and vangle, as follows:
function twoDperp=perp(x,y)
But this is obviously not really what I want.
Do you guys happen to have some pointers as to what I'm doing wrong?
Cheers
Your initial function twodcomp: you cannot have the output variable (before the =) be named the same as your function name (after the =).
Then if you want to assign an anonymous function (MATLAB docs, Octave docs) using the # notation, you can still pass the desired inputs.
So rewrite it like:
% Include empty parentheses after a function name to make it clear which is the output
function output = twodcomp()
% Not sure why you're assigning this function to a struct, but
% still give yourself the ability to pass arguments.
% I'm assuming you want to use the output variable,
% and not reuse the main function name (again)
output.twoDperp = #(x,y) perp(x,y);
end
With your second function, you just need to remove the twoDperp before your output arguments. In your question you state the expected syntax from the docs, but then didn't follow it...
function [vmag, vangle] = perp(x,y)
W = hypot(y,x);
vmag = y/W;
vangle = x/y;
end
Now these can be used like so:
% Deliberately using different variable names to make it clear where things
% overlap from the function output. twodcomp output is some struct.
myStruct = twodcomp();
% The output struct has the field "twoDperp" which is a function with 2 outputs
[m, a] = myStruct.twoDperp(1,2);

I pass an anonymous function f = #(x) x.^2 to a MatLab class, but then it disappears?

I have a class Solver:
classdef Solver
properties
myFunc
end
methods
function setMyFunc(this, myFunc)
this.myFunc = myFunc;
end
end
end
I create an instance of this class and then pass it an anonymous function like so:
f = #(x) x.^2;
solver = Solver();
solver.setMyFunc(f);
If I debug the code and print the 'this' variable inside the setMyFunc method I get the following:
Solver with properties:
myFunc: #(z) x.^2
However when the code exits back to my main file and I print the solver variable this time I get:
Solver with properties:
myFunc: []
And so clearly it has lost the reference to the function I passed it. What is happening here, how can I pass an anonymous function to a class?
Matlab strictly uses the pass-by-value convention. The only exception is when you derive from the handle class. If you do not want to derive from the handle class you need to do
methods
function this = setMyFunc(this, myFunc)
this.myFunc = myFunc;
end
end
and use it with
solver = solver.setMyFunc(f);
Since this is a bit awkward, so I would use the following (standard way)
methods
function this = set.myFunc(this, myFunc)
this.myFunc = myFunc;
end
end
Using this property set method you can actually write
solver.myFunc = XXX;
to involke the set function. Note, that in both cases you need this also as output argument.
using classdef Solver < handle worked for me:
classdef Solver < handle
properties
myFunc;
end
methods
function setMyFunc(this,myFunc)
this.myFunc = myFunc;
end
end
end

Use of varargin in octave

I am trying to use varargin in octave but seems that it is getting some problem. Here is my code:
into2.m
function [result] = into2(x)
result = x*2;
endfunction
into3.m
function [result] = into3(x)
result = x*3;
endfunction
calc.m
function [result1] = calc(varargin, x)
fn1 = varargin{1};
fn2 = varargin{2};
result1 = fn1(x) + fn2(x);
endfunction
test1.m (main function)
function [] = test1()
result= calc(#into2,#into3,2);
disp(result);
endfunction
test1() is main function calling calc() and passing two function handles and one scalar. I expect that varargin should have #into2,#into3 and x should have 2. However, varargin has #into2 and x has #into3. I tried changing order but two functions passed do not go into one argument; each argument has only one function. I believe that varargin should have a cell, but seems not working. I am using Octave 4.2. (Putting MATLAB into tag because the two should be similar.)
The issue is that varargin must appear as the last input argument to a function. If it is not the last, then it is simply treated as an input parameter named varargin instead. From the documentation:
If the special parameter name varargin appears at the end of a function parameter list it indicates that the function takes a variable number of input arguments
So in effect, your calc function is functionally no different from:
function result = calc(y, x)
What you'll want to do instead, is place varargin last in the list of input arguments and modify the logic within calc.
function result = calc(x, varargin)
fn1 = varargin{1};
fn2 = varargin{2};
result = fn1(x) + fn2(x);
end
As a side note, it's not clear why exactly you need to use varargin in this scenario since you don't actually have a variable number of inputs.

call a function return from another function

I've function1 that returns a value which is editText.
from another function2, I would like to get the function1 to after type a text
I tried
function function2(arg)
editTextarea = #()function2(arg)
editTextarea....
is this correct ?
I am confused by your question? Are you saying that you have a main function function1 that contains a sub-function function2 and that you would like to be able to call the sub-function directly?
If so then refer to this Mathworks support article
The first method to call a subfunction from outside a main function is
to create a function handle to the subfunction inside the main
function (where the subfunction is in scope) and return it as an extra
output argument. You can then use FEVAL to evaluate the function
handle, passing it any arguments the subfunction accepts. The reason
this works is that a function handle records the scope of the function
or subfunction in which it was created. A simple example of how to do
this is:
function y=myfun(varargin)
if nargin==0 % There are no input arguments, I assume you are asking for the function handle
y=#mysubfun; % This only works in MATLAB 6.0 (R12) and above else % There is an input argument, I assume you want to evaluate the main function
y=2*varargin{1}
end
function t=mysubfun(z)
t=3*z;
Now, if you type:
H=myfun;
y1=myfun(1);
y2=feval(H,1);
[y1 y2]
You receive the result:
ans =
2 3