Matlab: Create function with another function as argument - matlab

I need to create a function f with another function, g, as argument (g is defined in a .m file, not inline). In the body of f, I need to use feval to evaluate g on multiple values; something like:
function y = f(a,b,c,g)
z=feval(g,a,b,c);
y=...
end
What is the syntax ? I tried to use handles, but I got error messages.

You can do it this way:
Define f in an m-file:
function y = f(a,b,c,g)
y = feval(g,a,b,c);
end
Define g in an m-file:
function r = g(a,b,c)
r = a+b*c;
end
Call f with a handle to g:
>> f(1,2,3,#g)
ans =
7

If you do not want to change the body of add, then you could do that:
function s = add_two(a)
s = a + 2;
end
function s = add_three(a)
s = a + 3;
end
function s = add(a, fhandle1, fhandle2)
s = feval(fhandle1, a);
s = s + feval(fhandle2, s);
end
a = 10;
fhandle1 = #add_two; // function handler
fhandle2 = #add_three;
a = add(a, fhandle1, fhandle2);
a

Related

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)

Anonymous function defined by a loop in matlab

I use anonymous functions in my code. For example:
G = #(x) [norm(A*x-b);A'*(A*x-b)];
norm(Ax-b) is the objective function and A'*(Ax-b) the gradient.
Then,
Algo( G,varagin );
etc
What I would like to do is to define f with a loop:
n = 9;
k = 2;
t = 1 - x.^k;
f = 0;
for i=1:n
f = f + x(i,1)*prod(t(1:i-1));
end
grad_f = zeros(n,1);
for i0=1:n
s = t;
s(i0) = [];
for i=i0+1:n
grad_f(i0) = grad_f(i0) + x(i)*prod(s(1:i0-1));
end
grad_f(i0) = -k*x(i0)^(k-1)*grad_f(i0);
grad_f(i0) = grad_f(i0) + prod(t(1:i0-1));
end
Then I would like to do something like:
" G = #(x) [f,grad_f] "
Thanks a lot for your help!
Found the answer:
create F(x) and GRAD_F(x) as functions in matlab computing f and grad_f respectively.
Then:
G = #(x) [F(x);GRAD_F(x)];
Algo(G,varargin);

Replicating Simpson's rule, error with eval

I'm trying to replicate the Simpson's rule by writing a function for it. However, I'm still not clear how I could possibly use eval to transform a string to a actual function in MatLab.
The function is:
function result = simpson(fun, x0, xn, n)
f = eval(fun);
h = (xn-x0)/2;
xstart = f(x0) + f(xn);
x1 = 0;
x2 = 0;
for i = 1:n-1
x = x0 + h*i;
if (mod(i,2) == 0)
x2 = x2 + f(x);
else
x1 = x1 + f(x);
end
end
result = h*(xstart + 2*x2 + 4*x1)/3;
The error reported is
Error using eval
Undefined function or variable 'x'
How could I pass x to a string form of a function?
The clean way to do that: Use a function handle, avoid eval.
Function handles are documented here: http://www.mathworks.de/de/help/matlab/ref/function_handle.html
Define them like this:
sqr = #(x) x.^2;
and then call your function:
simpson(sqr, 1, 2, 3);
within your function, you should e able to call fun(3) and get 9 as a result.
If you have to use eval, I could see two solutions:
The Sneaky way: simpson('#(x) x.^2') (eval creates a proper function handle)
The dirty way:
function result = simpson(fun)
x = 4;
f = eval(fun);
result = f;
return;
end
Call it like this: simpson('x.^2')
The problem here is the way eval is being used. The documentation indicates that in your example the output f would not be a function handle (as is expected by the way the code uses it), but rather the output of the fun function.
So, in order to make the eval function work you need to provide it with it's input.
For example:
fun = 'x.^2';
x = 4;
f = eval(fun);
Results in f == 16
In short, any time you wish to call fun you would have to set x to the appropriate value, call eval and store the result.
For example, in your code:
f = eval(fun);
h = (xn-x0)/2;
xstart = f(x0) + f(xn);
Would become:
h = (xn-x0)/2;
x = x0;
fx0 = eval(fun);
x = xn;
fxn = eval(fun);
xstart = fx0 + fxn;
I would suggest function handles as a safer and easier way of implementing this, but as mentioned in the comments this is not allowed in your case.

How do you pass in a value to a subfunction in Matlab I am getting output errors?

Below is my code in Matlab I am having trouble with the line sum = (h/2) * (f(a) + f(b)) + h; Matlab says I have to many outputs when I try to call the f(x) function. Is my problem with the f(x) function
function Trapezoid_Uniform(a,b,n)
h = (b - a)/n;
sum = (h/2) * (f(a) + f(b)) + h;
for i = 1:n-1
x = a + i*h;
sum = sum + f(x);
end
sum = sum*h;
disp(sum);
end
function f(z)
f = exp(z);
end
You need to specify the returned variable in your function. For e.g., In C++ there's an explicit return statement - how does MATLAB know what needs to be returned? You specify it in the signature, i.e. in this case f_of_z.
function f_of_z = f(z)
f_of_z = exp(z);
end
Yes, your problem is in the subfunction: It should return an output (maybe your main function should do that as well);
Instead of
function f(z)
f=exp(z);
end
you should write
function out = f(z)
out = exp(z)
end
I don't have matlab here to test, anyway the code for f should be
function y = f(z)
y = exp(z);
end

How to call a function in a for loop in MATLAB?

I would like to call (execute) an m-file (function) in a loop like this:
global m, r
m = 2;
for n = 2:10;
for r1 = 0:n-m;
r2 = n-m-r1;
r = [r1,r2];
[Call the function here?????????]
end
end
This is the function:
function main
x0 = [-0.5403,0.5471];
fsolve(#fcn,x0)
function z = fcn(X)
rand('twister',5409);
global m, r
a = rand(m,1);
for i = 1:m
sm(i) = 0.0;
for l = m-i+1:m
sm(i) = sm(i)+r(l);
end
s = 1.0/(i+sm(i));
g(i) = (a(i))^s;
end
prod = 1.0;
for k = 1:m
prod = prod * g(m+1-k);
u(k) = 1.0-prod;
x(k) = (sqrt(3)/pi)*log(u(k)/(1-u(k)));
end
sum = 0;
sum1 = 0;
sum2 = 0;
for j = 1:m
sum = sum+(r(j)+2)*(1/(1+exp((-pi/sqrt(3))*((x(j)-X(1))/X(2)))));
sum1 = sum1+(r(j)+2)*((x(j)-X(1))/X(2))*(1/(1+exp((-pi/sqrt(3))*((x(j)-X(1))/X(2)))));
sum2 = sum2+(x(j)-X(1))/X(2);
end
z(1) = pi/(X(2)*sqrt(3))*(-m+sum);
z(2) =(-1/X(2))*(m+(pi/sqrt(3))*(sum2-sum1));
Thank you very much for your help.
The functions main and fcn should be saved in a file called "main.m". You have to make sure this file is either in your current working directory or somewhere on the MATLAB path (as mentioned in a comment by Amro) so that MATLAB can get to it. Since main requires no input arguments and has no output arguments, you could then just call it in any one of the following ways:
main
main;
main()
main();
If you have a function Main.m
Main.m
function out = main(in)
% blah blah blah
You would call the function
in = 2;
out = main(in)
Does this make sense?
Personnally I would create your function without a main() part.
create a file called
fcn.m
with your function fcn in it, make sure it's in your working directory or in your matlab path and then call it inside your loop.
addpath(genpath('/the/path/to/your/function/');
global m, r
m = 2;
for n = 2:10;
for r1 = 0:n-m;
r2 = n-m-r1;
r = [r1,r2];
z=fcn(r)
end
end