How to write a different handle objective function in MATLAB? - matlab

I have a function with multiple outputs, let's assume them as different objective function f1 and function f2. How could I write the two handling functions for the two objectives?
function [f1,f2] = myfunc(x)
f1=x^2;
f2=sqrt(x);
end
I gave a try
[obj1,obj2] = #(x)myfunc(x)

Make f1 and f2 function handles in myfunc() as follows:
function [f1, f2] = myfunc()
f1 = #(x) x^2;
f2 = #(x) sqrt(x);
end
Then you can call them from your main script/command window as:
[obj1,obj2] = myfunc();
x = 2; % just to test the output
obj1(x);
obj2(x);

Related

Forwarding varargout in matlab non-verbosely

I have a matlab function like:
function [f, fdx] = twice(x)
f = x * 2;
if nargout > 1
fdx = 2;
end
end
I want to call this function from another function, keeping the optional second-argument semantics. However, this is messy:
function [g, gdx] = twiceplusinverse(x)
% this starts to get messy if the arguments to double are long
if nargout > 1
[f, fdx] = twice(x);
else
f = double(x)
end
g = f + 1/x;
if narargout > 1
gdx = fdx + -1/x^2;
end
end
How can I avoid duplicating every function call that has multiple return values? What's a way to write the following that doesn't violate DRY?
if nargout > 1
[f, fda, fdb, fdc] = longfunction(some_func_producing_a(), b, another_func_for_c());
else
f = longfunction(somefunc_like_above(), b, another_func_for_c());
end
You can use varargout as the output of your function and then use a comma-separated list to assign the outputs of the other function. Since you use 1:nargout as the indices in the comma-separated list, the number of output arguments requested from your function will be passed onto the other function automatically.
function varargout = myfunc(x)
[varargout{1:nargout}] = other_func(x);
end

Matlab coder fzero function

I am trying to convert a MATLAB code to C code using "MATLAB Coder", but anonymous functions are not allowed.
How can I convert for example an fzero function as
myfun = #(x,c) cos(c*x); % parameterized function
c = 2; % parameter
fun = #(x) myfun(x,c); % function of x alone
x = fzero(fun,0.1)
into a normal function, for instance, to convert the whole code to C.
You have "anonymous" functions, not "undefined" functions, just to clear up the terminology.
To convert the following to a named function:
myfun = #(x,c) cos(c*x); % parameterized function
write this:
function result = myfun(x,c)
result = cos(c*x);
end
For the second function, write this:
function result = myfun2(x)
c = 2;
result = cos(c*x);
end
Finally, call fzero like this:
x = fzero(#myfun2, 0.1);

calling function with multi-variable functions

I have the following function which finds the zero of a function using Newton-Raphson:
function [ x,i ] = nr_function( x0,f,fp )
N = 15;
eps = 1e-5;
x=x0;
for i=0:N
if( abs(f(x))<eps )
return;
end
x=x-f(x)/fp(x);
end
I can call the function like this:
f = #(x) x.^3-1
fp = #(x) 3*x.^2
nr_function(3, f,fp)
However, say I instead define my function like this, i.e. taking 2 variables:
f = #(x, q) q*x.^3-1
fp = #(x, q) q*3*x.^2
Then how would I be able to call nr_function with f and fp? I tried nr_function(3, f,fp), but that doesn't work
If q is defined when you call nr_function, you can use an anonymous function in the call. When you do this, then the argument you pass is a new function-handle with variable x and constant q.
f = #(x, q) q*x.^3-1
fp = #(x, q) q*3*x.^2
q = 1;
nr_function(3, #(x)f(x,q), #(x)fp(x,q))
Note: It's not necessary that you use the variable x in the anonymous function. The only importance is to have a single argument in the end. So we can use for example y as the intermediate variable like this:
nr_function(3, #(y)f(y,q), #(y)fp(y,q))
If we expand it to multiple lines, it would look like this:
f = #(x, q) q*x.^3-1
fp = #(x, q) q*3*x.^2
q = 1;
f2 = #(y) f(y,q)
fp2 = #(y) fp(y,q)
nr_function(3, f2, fp2)

Call function inside another function

I have a function
function toto(a,b)
[out,~] = evalc(a)
% here I would like to call another function
myFunc(x,y,file);
end
How could I pass this function as args to toto function as sometimes I want to call toto(a,b) and some other times toto(a,b,#()myFunc(x,y) ?
(Answer before question edit: assumes fixed number of inputs to toto)
If you want to call an arbitrary function from within function toto: first define a handle to that function:
f = #myFunc;
and then pass that handle as input argument to toto, so that you can use it within toto:
function toto(a,b,f)
[out,~] = evalc(a)
f(x,y,file); %// call function whose handle is f
end
Define your function with an input to pass a function handle:
function toto(a,b,fun)
...
% You must know how many inputs and outputs to expect
% but nargin and nargout do work for function handles
% so you can handle different cases if needed.
[y1,y2,...] = fun(x1,x2,...);
...
Call the function and pass in a handle to the function:
toto(a,b,#FunName)
Or:
FunHandle = #FunName;
toto(a,b,FunHandle)
You can pass in additional parameters by using an anonymous function:
Param = 'FileName';
AnonFunHandle = #(x1,x2)FunName(x1,x2,Param);
toto(a,b,AnonFunHandle)
If you want to be able to use both the toto(a,b) and toto(a,b,f) or similar function calls, you need to use varargin and nargin (and their output counterparts). Here is a very basic example; it ignores any more than two outputs or any more than three inputs, and does not do any input checking etc.
function [vargout] = toto(a,b,varargin)
if nargin >2
func = vargin{1};
fout = func(a,b);
else
fout = [] % if no third argument is given returns empty
end
if nargout > 0
varargout{1} = a+b;
end
if nargout > 1
varargout{2} = fout;
end
end
So for example you can call this as x = toto(2,3) (returns x = 5), [x y] = toto(2,3) (returns x = 5, y = []), [x y] = toto(2,3,#(x,y)(x*y)) (returns x = 5, y = 6).

nlfilter: Choosing nested subfunctions?

The syntax for nlfilter in MATLAB is:
B = nlfilter(A, [m n], fun)
I am considering creating a M-File with several subfunctions to be called using test function here; i.e., I wanted a choice such that each time I can choose what subfunction gets called under fun.
% Main Function
function test
B = nlfilter(A, [m n], fun)
% Subfunction 1
function sub1
.......
% Subfunction 2
function sub2
.......
% Subfunction 3
function sub3
.......
Will it be possible to generalize fun in such a way that I can call either sub1 or sub2 or sub3 from test.
EDIT
My function:
function funct(subfn)
clc;
I = rand(11,11);
ld = input('Enter the lag = ') % prompt for lag distance
fh = {#dirvar,#diagvar};
feval(fh{subfn});
A = nlfilter(I, [7 7], subfn);
% Subfunction
function [h] = dirvar(I)
c = (size(I)+1)/2
EW = I(c(1),c(2):end)
h = length(EW) - ld
end
% Subfunction
function [h] = diagvar(I)
c = (size(I)+1)/2
NE = diag(I(c(1):-1:1,c(2):end))
h = length(NE) - ld
end
end
When I run funct(1) now this is the output with error:
Enter the lag = 1
ld =
1
??? Input argument "I" is undefined.
Error in ==> funct>dirvar at 12
c = (size(I)+1)/2
Error in ==> funct at 6
feval(fh{subfn});
I am puzzled as to what is the problem now?
If you know the name of the subfunction, you can use str2func:
Change the test function to accept a string which holds the subfunction name:
function test (subfunNm)
And call nlfilter like this:
B = nlfilter(A, [m n], str2func (subfunNm));
Now you can call test:
test ('sub1')
etc.
EDIT
In the case of nested functions, you can hold a cell array of the function handles, and pass in an index (instead of a string):
function test(fnInd)
fh = {#f1,#f2,#f3};
feval(fh{fnInd});
function f1
disp('f1')
end
function f2
disp('f2')
end
function f3
disp('f3')
end
end
And call it using test (1) etc.
Take a look at str2func and/or function handles.
I'd personally stay away from strings to pass functions, but you might just need to use that.