How to handle multiple inputs while writing a matlab function - matlab

How to handle multiple inputs while writing a matlab function ? For example if n is the number of parameters to be passed in the run time then how do my function prototype will look ? Any help will be good. Thanks.

An example of function with various number of parameters is:
function my_function(varargin)
% This is an example
min_arg = 1;
max_arg = 6;
% Check numbers of arguments
error(nargchk(min_arg,max_arg,nargin))
% Check number of arguments and provide missing values
if nargin==1
w = 80;
end
% Your code ...
end
The same is for the output.

If the number of arguments can be changed Matlab offers a very good and simple solution for that:
http://www.mathworks.com/help/matlab/ref/varargin.html

While for small functions with few arguments, the solution by #GiacomoAlessandroni works nicely, I would suggest something different for more complex functions: Using InputParser.
It features required and optional parameters, as well as name-value pairs. The handling of default values is easy, without if clauses. There is also a very flexible type-checking available.
Instead of creating an example myself, I post the example from the MATLAB help page linked above. The code is pretty much self-explanatory.
function a = findArea(width,varargin)
p = inputParser;
defaultHeight = 1;
defaultUnits = 'inches';
defaultShape = 'rectangle';
expectedShapes = {'square','rectangle','parallelogram'};
addRequired(p,'width',#isnumeric);
addOptional(p,'height',defaultHeight,#isnumeric);
addParameter(p,'units',defaultUnits);
addParameter(p,'shape',defaultShape,...
#(x) any(validatestring(x,expectedShapes)));
parse(p,width,varargin{:});
a = p.Results.width .* p.Results.height;
end

Related

Summation of N function handles in MATLAB

I have N functions in MATLAB and I can define them using strcat, num2str and eval in a for loop. So without defining by hand I am able to define N functions. Let N=4 and let them be given as follows:
f1=#(x) a1*x+1;
f2=#(x) a2*x+1;
f3=#(x) a3*x+1;
f4=#(x) a4*x+1;
Now I add these four functions and I can do this by hand as follows:
f=#(x)(f1(x)+f2(x)+f3(x)+f4(x));
Here I can do it by hand because I know that N=4. However, in general I never know how many functions I will have. For all cases I cannot write a new function.
Is there any way to do this automatically? I mean if I give N=6 I am expecting to see MATLAB giving me this:
f=#(x)(f1(x)+f2(x)+f3(x)+f4(x)+f5(x)+f6(x));
Whenever I give N=2 then I must have the function f, defined as follows:
f=#(x)(f1(x)+f2(x));
How can we do this?
First of all, you should read this answer that gives a series of reasons to avoid the use of eval. There are very few occasions where eval is necessary, in all other cases it just complicates things. In this case, you use to dynamically generate variable names, which is considered a very bad practice. As detailed in the linked answer and in further writings linked in that answer, dynamic variable names make the code harder to read, harder to maintain, and slower to execute in MATLAB.
So, instead of defining functions f1, f2, f3, ... fN, what you do is define functions f{1}, f{2}, f{3}, ... f{N}. That is, f is a cell array where each element is an anonymous function (or any other function handle).
For example, instead of
f1=#(x) a1*x+1;
f2=#(x) a2*x+1;
f3=#(x) a3*x+1;
f4=#(x) a4*x+1;
you do
N = 4;
a = [4.5, 3.4, 7.1, 2.1];
f = cell(N,1);
for ii=1:N
f{ii} = #(x) a(ii) * x + 1;
end
With these changes, we can easily answer the question. We can now write a function that outputs the sum of the functions in f:
function y = sum_of_functions(f,x)
y = 0;
for ii=1:numel(f)
y = y + f{ii}(x);
end
end
You can put this in a file called sum_of_functions.m, or you can put it at the end of your function file or script file, it doesn't matter. Now, in your code, when you want to evaluate y = f1(x) + f2(x) + f3(x)..., what you write is y = sum_of_functions(f,x).

Create function with given number of input arguments

Here's the situation:
I need to create a function that takes a function handle fun which is of CONSTANT input-length (that is nargin(fun)>=0), does some transformation on the inputs and then calls fun.
Pseudo-Code:
function g = transformFun(fun)
n = nargin(fun);
g = #(v_1, ..., v_n) ...
% ^ NOT REAL MATLAB - THE MAIN PROBLEM
fun(someCalculationsWithSameSizeOfOutput(v_1,...v_n){:});
% CAN BE ACHIEVED WITH TEMPORARY CELL IN HELPER FUNCTION ^
end
Now the problem: the output function's handle (g = transformFun(concreteFun)) is then passed to other code that relies on the fact that the function is of constant length (assumes nargin(g)>=0), thus a variable-input-length function is unacceptable (the "easy" solution).
This transformation is called with many functions with every possible number of arguments (n is unbounded), so covering a finite number of possibilities is also not possible.
Is there a (simple?) way to achieve that?
[I've searched the internet for a few hours and could only come up with a nasty hack involving the deprecated inline function, which I couldn't make work; maybe I have the wrong terminology].
So typically you could use varargin to handle this sort of thing, but since you need nargin(g) to return the actual number of inputs it's a little trickier.
You could use str2func to create the anonymous function as a string and then convert it to a function handle.
% Create a list or arguments: x1, x2, x3, x4, ...
args = sprintf('x%d,', 1:nargin(func));
args(end) = '';
% Place these arguments into a string which indicates the function call
str = sprintf('#(%s)fun(someCalculationsWithSameSizeOfOutput(%s))', args, args);
% Now create an anonymous function from this string
g = str2func(str);
Based on the attrocity above, it may be worth considering an alternative way of dealing with your function handles.

MATLAB: varargin (cell) not compatible with fminsearch (double)?

I have functions I've built using variable arguments but now I want to optimize these functions. However, in the current form, varargin doesn't seem to work well with FMINSEARCH? What can I do? Is there something wrong?
I am trying to do the following:
y = #(varargin)-fn_backtest_v0002(varargin{:});
start = {3,0,0.5,10,0.05,0,1,1};
max = fminsearch(y,start);
But I get this error:
Error using fminsearch (line 96)
FMINSEARCH only accepts inputs of data type double.
From the simple examples of FMINSEARCH, a vector should be used, however I have varargin in my functions which require arguments to be of cell type.
Any help appreciated.
You should write a wrapper function that accepts vector as parameter and passes them in the format that fn_backtest_v0002 expects to get. For example:
function out = fn_backtest_v0002(varargin)
.... %Your code here
end
And the wrapper function:
function out = fn_backtest_v0002_wrapper(vec)
out = -fn_backtest_v0002(num2cell(vec));
end
Then, you can use the wrapper function with fminsearch :
start = [3,0,0.5,10,0.05,0,1,1];
max = fminsearch(y,#fn_backtest_v0002_wrapper);
Another alternative is to re-write fn_backtest_v0002 to have vector input arguments (Which makes much more sense than varargin in your case.
Thanks to Andrey for idea of wrapper function. (I am a programming newbie).
This is exactly how I did it.
Create wrapper function:
function [ out ] = fn_backtest_v0002_wrapper( vec )
cell = num2cell(vec);
out = fn_backtest_v0002(cell{:});
end
Then I can run the following commands successfully:
y = #(vec)-fn_backtest_v0002_wrapper(vec);
start = [3,0,0.5,10,0.05,0,1,1];
max = fminsearch(y,start);

How to store a function-wrapped solve call?

Bear with me please, I'm completely new to matlab. I am attempting to store the call to eigenvalue in another function, but it's giving me the error: Too many output arguments.
function eigenvalue(M)
syms l;
eq = det(M - l*[1 0; 0 1]);
solve(eq == 0)
end
I've tried storing it in many different ways, but nothing seems to work:
>> a = eigenvalue(M)
Error using eigenvalue
Too many output arguments.
>> [a, b] = eigen(M)
Error using eigenvalue
Too many output arguments.
The weird thing is that if I solve a normal polynomial equation I can do sol=solve(x^2==4) just fine and access sol(0)and sol(1)without any problems. I guess that I haven't picked up on a simple matlab concept and thanks to anyone who's willing to help!
Your problem is that you don't have any output arguments in your function.
function eigenvalue(M)
In MATLAB, you should* use the following syntax:
function output = func_name(input_1,input_2,...)
You have 2 alternatives:
You can skip the first line and save it as script, as this:
syms l;
eq = det(M - l*[1 0; 0 1]);
solve(eq == 0)
Or, you can save it as a function, but with output variable(s), like this:
function output = eigenvalue(M)
syms l;
eq = det(M - l*[1 0; 0 1]);
output = solve(eq == 0)
end
*You should use the syntax I described, but you can use the syntax you used as well. However, if you do, the function won't give you anything back except possibly printing the result to screen. You will not get to use any variables created inside the function.
If you want a function to provide an output argument then you have to declare it in the function definition. E.g.
function a = eigenvalue(M)
You then need to make sure you assign a value to each output variable in the function body.

Parameter passing to function handle

I have a function and I want to each time change its input and integrate over a certain interval. For example, I first write an m file:
function y = myfun(x)
y = 1 ./ (x.^3 - 2*x - 5);
Now I want to integrate functions like myfun(x-2) or myfun(2*x). Does anyone know how I should pass them? Integral(myfun(x-2),a,b) creates an error.
Thanks
I suggest calling integral on a handle for your function as below:
h1 = #(x)myfun(x);
h2 = #(x)myfun(x-2);
h3 = #(x)myfun(x.^2);
integral(h1,a,b);
integral(h2,a,b);
integral(h3,a,b);
This should trick the integral function into thinking that you are just defining myfun as a function of x while allowing you to pass whatever expression you want to it. You could also pass additional parameters this way, such as:
h = #(x)myfun(x, params);
integral(h,a,b);
Where params could be a list of parameters that you use in your definition of myfun.
I hope that helps.
EDIT: I tested this on a server that I have access to which does have the integral function and it seemed to work. Hopefully this answers your question.