Use of varargin in octave - matlab

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.

Related

Nesting multiple functions in Matlab

I have two nested functions in Matlab. The outer one uses fminunc and I would like your help how to correctly pass through it some arguments. Here my code
clear
rng default
%Some useful parameters
number_starting=10^3;
r=10^5;
J=2;
epsilon_sim=-evrnd(0,1,r,J+1); %rx(J+1)
options = optimoptions(#fminunc, 'MaxFunctionEvaluations', 10^4 ,'MaxIterations', 10^4, 'StepTolerance', 10^(-8), 'Display', 'off');
u_starting=normrnd(0,1,number_starting,J); %rxJ
This is the outer function which uses fminunc
function conv_conjugate=G_star(P, number_starting, options, u_starting,epsilon_sim)
fval=NaN(number_starting,1);
exitflag=NaN(number_starting,1);
for t=1:number_starting
try
coeff=u_starting(t,:).'; %starting values, column vector
[~,fval_temp,exitflag_temp]=fminunc(#obj,coeff, options);
fval(t)=fval_temp;
exitflag(t)=exitflag_temp;
catch
end
end
fval(exitflag>0,:);
conv_conjugate=-min(fval);
end
This is the inner function
function inner=obj(coeff)
comp1=sum(P.*(coeff.'));
comp2=mean(max(epsilon_sim+[coeff.' 0],[],2));
inner=-(comp1-comp2);
end
Here I try, for example, to evaluate the outer function at a given P and it clearly gives me a mistake because some arguments are not correctly passed through obj. Could you advise?
P_0=[0.7387,0.1562];
G_star(P_0, number_starting, options, u_starting,epsilon_sim);
There are two different ways that you can implement this.
1: The simple way
We create an anonymous function that encapsulates function values. Your inner function becomes:
function inner=obj(coeff,P,epsilon_sim)
comp1 = sum(P.*(coeff.'));
comp2 = mean(max(epsilon_sim+[coeff.' 0],[],2));
inner = -(comp1-comp2);
end
such that all values it uses are passed into it as arguments, then we create an anonymous function with one argument that calls obj with all its arguments:
#(x)obj(x,P,epsilon_sim)
This is used as follows:
[~,fval_temp,exitflag_temp] = fminunc(#(x)obj(x,P,epsilon_sim),coeff, options);
2: The more obscure way
I say more obscure because this method makes it harder to see what is happening with variables.
Here we create a nested function, which shares variables with the function it is nested in. A nested function is defined inside another function, and will only be visible to that function:
function conv_conjugate = G_star(P,number_starting,options,u_starting,epsilon_sim)
fval = NaN(number_starting,1);
exitflag = NaN(number_starting,1);
for t = 1:number_starting
coeff = u_starting(t,:).'; %starting values, column vector
[~,fval_temp,exitflag_temp] = fminunc(#obj,coeff, options);
fval(t) = fval_temp;
exitflag(t) = exitflag_temp;
end
fval(exitflag>0,:);
conv_conjugate = -min(fval);
% Nested function:
function inner=obj(coeff)
comp1 = sum(P.*(coeff.'));
comp2 = mean(max(epsilon_sim+[coeff.' 0],[],2));
inner = -(comp1-comp2);
end
end % Note this "end" terminates the enclosing function, and is mandatory.
In the nested function, P and epsilon_sim are shared with the enclosing function.

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);

Passing varargin to nested class method in 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

How to wrap a function using varargin and varargout?

mini-example:
function varargout = wrapper(varargin)
varargout = someFunction(varargin);
That's how I'd do it first. But for example if someFunction = ndgrid this yields a not defined for cell arrays error, so the next try was using someFunction(varargin{:}) instead. That's a successful call, but calling [a,b] = wrapper([1,2], [3,4]) does not yield the same result as a direct call to ndgrid, so what am I doing wrong?
Actually, Mikhail's answer is not quite right. In the case that someFunction is a function that returns a value even if none is requested, which is how a function indicates that the value should be assigned to ans, Mikhail's wrapper will fail. For example, if someFunction were replaced with sin and you compared running wrapper versus running sin directly, you'd see:
>> wrapper(0)
>> sin(0)
ans =
0
The right way to do this is
function varargout = wrapper( varargin )
[varargout{1:nargout}] = someFunction( varargin{:} );
The reason this works is due to a little known edge case in MATLAB indexing rules that has existed precisely for this case since at least R2006a (probably longer). It is something of a wart in MATLAB indexing but was deemed necessary to handle this sort of thing.
The rule is:
When performing subscripted assignment, if
subscripted-assigning to an uninitialized variable, AND
the uninitialized variable is curly-brace indexed, AND
the index in the curly braces is empty, AND
the left-hand side appears inside square braces, AND
the right-hand side resolves to a value / returns an output
Then the uninitialized variable is assigned a scalar cell containing the value returned by the right-hand side.
For example:
>> clear uninit % just to make sure uninit is uninitialized
>> [uninit{[]}] = sin(0)
uninit =
[0]
function varargout = wrapper( varargin )
if ~nargout
someFunction( varargin{:} );
else
[varargout{1:nargout}] = someFunction( varargin{:} );
end
If the number of output arguments is the same as the number of input arguments, you can use
function varargout = wrapper(varargin)
[varargout{1:nargin}] = someFunction(varargin{:});
This works fine with ndgrid.

define anonymous function as 2 of 4 outputs of m file function

I have an m-file function with 4 outputs. I would like to define an anonymous function that has the same inputs, but only produces 2 of the four outputs. Is this possible?
AFAIK, you can't do this with just an inline anonymous function, because that Matlab syntax doesn't provide a way of capturing and indexing in to multiple outputs of a function in a single expression. But you can write a couple reusable helper functions that do so, and then define anonymous functions using them.
Let's say your four argout function is named "f4".
function varargout = f4(x)
%F4 Dummy function that returns 4 argouts holding identifying indexes
varargout = num2cell(1:4);
Here's a reusable helper function that remaps outputs of a function call.
function varargout = callandmap(fcn, ix, varargin)
%CALLANDMAP Call a function and rearrange its output arguments
tmp = cell(1,max(ix)); % Capture up to the last argout used
[tmp{:}] = fcn(varargin{:}); % Call the original function
varargout = tmp(ix); % Remap the outputs
Now you can make anonymous, argout-remapping functions like this. Here, g holds an anonymous function that takes the same inputs as your original function, but just returns 2 of its original 4 outputs.
>> g = #(varargin) callandmap(#f4, [2 4], varargin{:})
g =
#(varargin)callandmap(#f4,[2,4],varargin{:})
>> [a,b] = g('dummy') % gets argouts 2 and 4 from original f4() function
a =
2
b =
4
>>
Using varargin allows you to omit trailing arguments when the resulting function handle is called. If you know all argins will always be provided, you can use named argins for readability if you want.
You can get even fancier and do this with a closure.
function fcn = mapargout(fcnIn, ixArgout)
%MAPARGOUT Create wrapper function that selects or reorders argouts
%
% fcn = argoutselector(fcnIn, ixArgout)
%
% Wraps a given function handle in a function that rearranges its argouts.
% This uses closures so it may have performance impacts.
%
% FcnIn is a function handle to wrap.
%
% IxArgout is a list of indexes in to the original functions argout list
% that should be used as the outputs of the new function.
%
% Returns a function handle to a new function.
fcn = #extractor;
function varargout = extractor(varargin)
n = max(ixArgout);
tmp = cell(1,n);
% Call the wrapped function, capturing all the original argouts
[tmp{:}] = fcnIn(varargin{:});
% And then select the ones you want
varargout = tmp(ixArgout);
end
end
This results in simpler code for creating the anonymous function. And you could compose it with other function wrapper calls.
>> g = mapargout(#f4, [2 4])
g =
#mapargout/extractor
>> [a,b] = g('dummy')
a =
2
b =
4
>>
But closures can be tricky to work with in Matlab and may have performance implications. The callandmap approach is probably preferable unless you need the extra power.
If the two outputs are #1 and #2, everything is fine, and you don't have to worry about the other two outputs.
If the two outputs are any two others, you have two options
(1) Create a wrapper function with two outputs (note that in newer versions of Matlab you can replace the unused outputs dummy by ~.
function [out1,out2] = wrapperFunction(in1,in2,in3)
[dummy,out1,dummy,out2] = mainFunction(in1,in2,in3);
(2) Add another input variable that allows you to switch your function's behavior
function varargout = mainFunction(in1,in2,in3,outputSwitch)
%# make output switch optional
if nargin < 4 || isempty(outputSwitch)
outputSwitch = 0;
end
%# calculation here that creates out1-4
if outputSwitch
%# the special case where we only want outputs 2 and 4
varargout = {out2,out4};
else
%# return all four outputs
varargout = {out1,out2,out3,out4}
end
Then you can create the anonymous function as usual.