With an anonymous function, you can return any number of outputs. What I need is to be able to use functors (anonymous functions as arguments of other functions), while not knowing how many outputs I will get.
This is to avoid code duplication by injecting functions calls inside a while loop which is reused in many functions.
Example:
function y = foo( x )
y = x;
end
function [y1, y2] = goo( x1, x2 )
y1 = x1;
y2 = x2;
end
function [ varargout ] = yolo( functor, varargin )
varargout = functor(varargin{:});
end
I want to be able to call:
y = yolo(#foo, 2)
[y1, y2] = yolo(#goo, 3, 4);
Is there any way to achieve this ?
Thanks
It is not possible to get the number of outputs of an anonymous function (a function handle to an inline function) because the output is always varargout and therefore nargout is always going to return -1
myfunc = #(x, y) x + y;
nargout(myfunc)
% -1
However, it looks like you don't have anonymous functions, but rather just function handles to normal functions that are defined in an .m file and have an explicit number of output arguments. In this case, you can combine nargout with {:} indexing to fill varargout with all of the output arguments.
function y = foo(x)
y = x;
end
function [y1, y2] = goo(x1, x2)
y1 = x1;
y2 = x2;
end
function varargout = yolo(functor, varargin)
[varargout{1:nargout(functor)}] = functor(varargin{:});
end
y = yolo(#foo, 2)
[y1, y2] = yolo(#goo, 3, 4)
Related
I have to code the Secant Method: a variant of the Newton-Raphson method.
I have done the following:
function [SecantMethod] = SecantMethod(x0, x1);
%this is a variation on the Newton-Raphson MEthod, uses two inital guesses
%so that we do not have to explicitly work of the derivative of f(x).
x0 = 2;
x1 = 1;
%the two guesses
f0 = f(x0);
f1 = f(x1);
%two coressponding values of the function evaluated at x0 and x1
x = x1 - (f1*((x1 - x0)/(f1 - f0)));
%actual Secant Method (finds x axis intercept between two guesses
end
When I run the code in Matlab, an error appears "Undefined function or variable 'f'."
I dont have any particular function that I want to solve I just have to code it so I am not sure how to do so.
You can have a function take a function as an argument as follows:
function [SecantMethod] = SecantMethod(f,x0, x1);
disp(f(x0));
end
Then in your code:
%make anonymous function:
f=#(x)(x.^2);
%or:
f=#sin;
%and simply:
SecantMethod(f,1,2)
% or just:
SecantMethod(#myfucntion,1,2)
Working with trying to make an Olver's method, my code is working however I want to try and combine the 3 functions into multi output function with use of diff() but i'm struggling to manipulate the inputs without jeopardizing outputs.
% Defining the function in the equation f(x)=0
function y = f(x)
y = x-exp(1/x);
end
% Defining the derivative of the function in the equation f(x)=0
function y = fd(x)
y = 1+exp(1/x)/(x^2);
end
% Defining the second derivative of the function in the equation f(x)=0
function y = fdd(x)
y = exp(1/x)*(2*x+1)/(x^4);
end
It is not very clear but having all these as a single function (with the use of Symbolic Toolbox) can be done as follows:
function [y1, y2, y3] = getDerivatives(a)
syms f(x)
f(x) = x-exp(1/x);
fd = diff(f,x);
fdd = diff(f,x,2);
y1 = double(f(a));
y2 = double(fd(a));
y3 = double(fdd(a));
end
and you can run it as follows:
[y1, y2, y3] = getDerivatives(1)
y1 =
-1.7183
y2 =
3.7183
y3 =
-8.1548
I want to create an anonymous function which takes the first output variable of an existing vector function in file in Matlab. For example, the existing vector function in a separate M-file is
function [y1,y2] = myfun(x1)
y1 = x1;
y2 = x1^2;
end
Is it possible to create an anonymous scalar function from myfun() which takes the value of y1? Thank you for any suggestions.
P.S. I am doing this because actually my original function is more like
function [y1,y2] = myfun(x1,x2)
y1 = x1+x2;
y2 = x1^2+x2^2;
end
and I want to create a scalar function y1 with only one parameter x1 (pass a known value of x2 to the anonymous function).
I think I know what you're looking for, but it's a little unclear. If you're starting with a function like this:
function [y1,y2] = myfun(x1,x2)
y1 = x1+x2;
y2 = x1^2+x2^2;
end
You can make a wrapper anonymous function with a fixed value of x2 (fixed at whatever the variable is when the anonymous function is created) like this:
newFcn = #(x1) myfun(x1, x2);
Now, you can use this to get whichever of the two outputs from myfun you want. For example:
y1 = newFcn(x1); % Gets the first output
[~, y2] = newFcn(x1); % Gets the second output
[y1, y2] = newFcn(x1); % Gets both
Based on #David 's method I adjusted my code and it works well.
function y = myfun(x1,x2)
y1 = x1+x2;
y2 = x1^2+x2^2;
y = [y1 y2];
end
and the anonymous functions output1 and output2 return y1 and y2 respectively.
paren=#(y,varargin) y(varargin{:});
output1 = #(x1) paren(myfun(x1,x2), 1);
output2 = #(x1) paren(myfun(x1,x2), 2);
I am trying to implement the Taylor method for ODEs in MatLab:
My code (so far) looks like this...
function [x,y] = TaylorEDO(f, a, b, n, y0)
% syms t
% x = sym('x(t)'); % x(t)
% f = (t^2)*x+x*(1-x);
h = (b - a)/n;
fprime = diff(f);
f2prime = diff(fprime);
y(0) = y0,
for i=1:n
T((i-1)*h, y(i-1), n) = double(f((i-1)*h, y(i-1)))+(h/2)*fprime((i-1)*h, y(i-1))
y(i+1) = w(i) + h*T(t(i), y(i), n);
I was trying to use symbolic variables, but I donĀ“t know if/when I have to use double.
I also tried this other code, which is from a Matlab function, but I do not understand how f should enter the code and how this df is calculated.
http://www.mathworks.com/matlabcentral/fileexchange/2181-numerical-methods-using-matlab-2e/content/edition2/matlab/chap_9/taylor.m
As error using the function from this link, I got:
>> taylor('f',0,2,0,20)
Error using feval
Undefined function 'df' for input arguments of type 'double'.
Error in TaylorEDO (line 28)
D = feval('df',tj,yj)
The f I used here was
syms t
x = sym('x(t)'); % x(t)
f = (t^2)*x+x*(1-x);
This is a numerical method, so it needs numerical functions. However, some of them are computed from the derivatives of the function f. For that, you need symbolic differentiation.
Relevant Matlab commands are symfun (create a symbolic function) and matlabFunction (convert a symbolic function to numerical).
The code you have so far doesn't seem salvageable. You need to start somewhere closer to basics, e.g., "Matlab indices begin at 1". So I'll fill the gap (computation of df) in the code you linked to. The comments should explain what is going on.
function [T,Y] = taylor(f,a,b,ya,m)
syms t y
dfs(1) = symfun(f, [t y]); % make sure that the function has 2 arguments, even if the user passes in something like 2*y
for k=1:3
dfs(k+1) = diff(dfs(k),t)+f*diff(dfs(k),y); % the idea of Taylor method: calculate the higher derivatives of solution from the ODE
end
df = matlabFunction(symfun(dfs,[t y])); % convert to numerical function; again, make sure it has two variables
h = (b - a)/m; % the rest is unchanged except one line
T = zeros(1,m+1);
Y = zeros(1,m+1);
T(1) = a;
Y(1) = ya;
for j=1:m
tj = T(j);
yj = Y(j);
D = df(tj,yj); % syntax change here; feval is unnecessary with the above approach to df
Y(j+1) = yj + h*(D(1)+h*(D(2)/2+h*(D(3)/6+h*D(4)/24)));
T(j+1) = a + h*j;
end
end
Example of usage:
syms t y
[T, Y] = taylor(t*y, 0, 1, 2, 100);
plot(T,Y)
Let's say I have a function
f = #(x,y) g(x,y)
g is not explicit. It should be calculated numerically after inputting x and y values.
How can I calculate and save all values of this function at points
[x,y] = meshgrid(0:0.1:1,0:pi/10:2*pi);
I call f[x,y], but it doesn't work.
You have two ways to do it. Your function g should work with matrices, or you should give the values one by one
function eval_on_mesh()
f1 = #(x,y) g1(x,y);
f2 = #(x,y) g2(x,y);
[x,y] = meshgrid(0:0.1:1,0:pi/10:2*pi);
%# If your function work with matrices, you can do it like here
figure, surf(f1(x,y));
%# If your function doesnt, you should give the values one by one
sol = zeros(size(x));
for i=1:size(x,1)
for j=1:size(x,2)
sol(i,j) = f2(x(i,j),y(i,j));
end
end
figure, surf(sol);
end
function res = g1(x, y)
res = x.^2 + y.^2;
end
function res = g2(x, y)
res = x^2 + y^2;
end