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);
Related
I'm working on my own Matlab code for the bisection method, and have defined an anonymous function I am trying to find the root for. It produces a simple graph and I know it could easily find the root if it would run properly.
When my code gets up to evaluating the function at a given x value, it returns:
Error using feval
Function to evaluate must be represented as a string scalar, character vector, or
function_handle object.
Error in bisection (line 3)
fa = feval(f, a);
My full code is:
function m=bisection(f,a,b,imax,tol)
fa = feval(f, a);
fb = feval(f, b);
i=0;
if fa*fb>0
disp('No root here: pick a new interval')
return
end
while abs(b-a) >= tol
i = i + 1;
m=(a+b)/2;
fm = feval(f, m);
if fa*fb<0
b = m;
else
a = m;
end
abs(fm);
end
% Show the last approximation considering the tolerance
w = feval(f, m);
fprintf('\n x = %f produces f(x) = %f \n %i iterations\n', m, fm, i-1);
fprintf(' Approximation with tolerance = %f \n', tol);
end
With my function being:
function [T] = freezing(x)
alpha = 0.138*10^-6;
Ti = 20;
Ts = -15;
t = 60*60*24*60;
tol = 10^-13;
%x = linspace(0,3);
T = #(x) (Ti-Ts)*erf(x./(2*sqrt(alpha*t)))+Ts;
dT = #(x) (Ti-Ts)*(1/sqrt(pi*alpha*t))*exp(-x.^2./(4*alpha*t));
T = T(x);
end
I'm really not sure what the issue is here – in my command window, I can easily input x values and get output. Any suggestions are much appreciated!
feval needs f to be a function handle. When you call bisection, I suspect you're passing the result of freezing to bisection instead of the function handle to freezing
You need to do bisection(#freezing, ...) instead of bisection(freezing(...), ...)
The #freezing creates a function handle that is passed to bisection. Doing the latter passes the result of freezing to bisection.
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);
I am trying to feed a function handle into the function I created below. I'm not exactly sure how to do this.
For example, how do I get:
conjugate_gradient(#(y) ABC(y), column_vector, initial_guess)
to not error?
If I use matlab's pcg function in the same way it will work:
pcg(#(y) ABC(y),b,tol).
I tried reading the pcg function, and they do take about this in the function description, however I'm still super inexperienced with MATLAB and had shall we say some difficulty understanding what they did.Thank You!
function [x] = conjugate_gradient(matrix, column_vector, initial_guess)
y = [];
col_size = length(column_vector);
temp = size(matrix);
mat_row_len = temp(2);
% algorithm:
r_cur = column_vector - matrix * initial_guess;
p = r_cur;
k = 0;
x_approx = initial_guess;
for i=1:mat_row_len
alpha = ( r_cur.' * r_cur ) / (p.' *(matrix* p));
x_approx = x_approx + alpha * p;
r_next = r_cur - alpha*(matrix * p);
fprintf(num2str(r_next'*r_next), num2str(i))
y = [y; i, r_next'*r_next];
%exit condition
if sqrt(r_next'*r_next) < 1e-2
y
break;
end
beta = (r_next.'* r_next )/(r_cur.' * (r_cur) );
p = r_next + beta * p;
k = k+1;
r_cur = r_next;
end
y
[x] = x_approx;
end
When you do
f = #(y) ABC(y)
You create a function handle. (Note that in this case it's the same as f=#ABC). This handle is a variable, and this can be passed to a function, but is otherwise the same as the function. Thus:
f(1)
is the same as calling
ABC(1)
You pass this handle to a function as the first argument, which you have called matrix. This seems misleading, as the variable matrix will now be a function handle, not a matrix. Inside your function you can do matrix(y) and evaluate the function for y.
However, reading your function, it seems that you treat the matrix input as an actual matrix. This is why you get errors. You cannot multiply it by a vector and expect a result!
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).
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.