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);
Related
Consider the function f(y1,y2,y3,y4,z1)=(-(z1^3)/(y3^2))(3(y2-y1+y3^(-1)-z1/10)^2+(1/5)(y2-y1+y3^(-1)-(z1)/10))-y4 with 5 variables. When I put f(1,1,1,1,1) I find the answer but when I write f(v) in which v=(1,1,1,1,1) matlab does not work. How can I do that (by the second way)?
You could write a wrapper function, that will take a vector as input argument and 'unpacks' this vector before calling your function.
f(y1,y2,y3,y4,z1) = (-(z1^3)/ ...; % your function
fv(v) = f(v(1),v(2),v(3),v(4),v(5));
Or alternatively, make f refer to elements in the input vector by using the appropriate indices:
f(v) = (-(v(5)^3)/(v(3)^2)); ... % etc.
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.
I begin with a symbolic function of one variable, calculate the symbolic derivatives of orders 1 through N, and then convert those symbolic functions into function handles and store the function handles in a cell array. I then evaluate each function handle at the same input value using a loop. The problem I have is that it is possible for one of the derivatives to be a constant (with higher order derivatives being zero, of course). As I was trying to give each function handle an input, I face the "Too many input arguments" error. I would like to be able to check, in advance, whether the function handle is a constant so I can avoid the error, but I can't figure out how to do that.
In case a small working example is helpful, I provide the following
symVar = sym('symVar');
startFunc = symVar^4 + symVar^3 + symVar^2;
derivesCell = cell(5);
for J=1:5
derivesCell(J) = {matlabFunction(diff(startFunc,symVar,J))};
end
cumSum = 0;
evalPoint = 2;
for J=1:5
cumSum = cumSum + derivesCell{J}(evalPoint);
end
Execution produces "Error using symengine>#()2.4e1
Too many input arguments."
tl;dr: You can do this with nargin:
>> nargin(derivesCell{5})
ans =
0
>> nargin(derivesCell{3})
ans =
1
Explanation:
Most people are familiar with the use of nargin as a "special variable" inside the function, but it can be used outside the context of a function definition, as a function that takes a function_handle argument, returning the number of input arguments that function handle takes. From the documentation:
NARGIN(FUN) returns the number of declared inputs for the
M-file function FUN. The number of arguments is negative if the
function has a variable number of input arguments. FUN can be
a function handle that maps to a specific function, or a string
containing the name of that function.
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
I did this
function f=objfun(w)
a=0.5
w0=[0.1;0.2;0.3];
f=(a^2)/2 + w(1)+ w(2)+ w(3);
[w,fval]=fmincon('objfun',w0,[],[],[],[],[],[],'constraint')
But I got this error message.
Error using objfun (line 3)
Not enough input arguments.
What problem is it talking about?
I learned fmincon from
http://www.math.colostate.edu/~gerhard/classes/331/lab/fmincon.html
and it tells me that codes like this
function f=objfun(x)
f=x(1)^4-x(1)^2+x(2)^2-2*x(1)+x(2);
will be the first lines to do constrained optimization.
What has gone wrong?
I believe you need to pass a function handle to fmincon. From the docs http://www.mathworks.com/help/optim/ug/fmincon.html
x = fmincon(#myfun,x0,A,b)
where myfun is a MATLABĀ® function such as
function f = myfun(x)
f = ... % Compute function value at x
Try passing a function handle to fmincon. I assume that constraints is your non linear constraint function, it should be a function handle as well. I also assume that you are not calling fmincon from inside your objective function. If so then I think you will have some thing like this:
objfun.m
function f = objfun(w)
a=0.5;
f=(a^2)/2 + w(1)+ w(2)+ w(3);
return
end
main.m
w0=[0.1;0.2;0.3];
[w,fval]=fmincon(#objfun,w0,[],[],[],[],[],[],#constraint)