I tried to test with my really simple code as below, but the error is "Too many output arguments."
function func1(x,y)
plot(x, y), xlabel('x'), ylabel('Sin(x)'), title('Sin(x) Graph'),
grid on, axis equal
end
function func2(x,y)
plot(x, y), xlabel('x'), ylabel('Cos(x)'), title('Cos(x) Graph'),
grid on, axis equal
end
the main is
x = 0:0.01:10;
y1 = sin(x);
y2 = cos(x);
funcs = {#func1, #func2} ; % let fun1, fun2 be two functions
arguments = {x y1;x y2} ; % write the inputs of each function
solutions = cell(1,2); % initialize the solution
% use of parfor
parfor ii = 1:2
solutions{ii}=funcs{ii}(arguments{ii,:});
end
Please help!!!
The way you call the function
solutions{ii}=funcs{ii}(arguments{ii,:});
Expects an output, which you're assigning to solutions{ii}.
This wouldn't work within a normal loop, or even without a loop, the fact that you're trying to write a parfor is immaterial here...
Your functions are defined as
function func1(x,y)
% ...
function func2(x,y)
% ...
Neither of these have output arguments, so it's unclear what you expect to be assigning to solutions{ii} - this exactly matches the error message you're seeing "too many output arguments".
If you expect an output from your function, then declare one
function z = func1(x,y)
z = x + y;
% other stuff
end
Otherwise, don't request an output within the loop
parfor ii = 1:2
funcs{ii}(arguments{ii,:});
end
Related
I have written the following Matlab function:
function EulerMethod(t_min,t_max,h,f,Y,yzero)
tlist = t_min:h:t_max;
N = (t_max - t_min)/h;
ylist = transpose(zeros(N+1,1));
ylist(1) = yzero;
for i=1:N
term = f(tlist(i),ylist(i))*h;
ylist(i+1) = ylist(i) + term;
end
yrange = Y(tlist);
% modified to generate a new figure window each time.
figure;
plot(tlist,yrange,'red','LineWidth', 2);
hold;
plot(tlist,ylist,'blue','LineWidth', 2);
plot(tlist, abs(yrange - ylist),'magenta','LineWidth', 2)
% modified to wrap the title.
title({'Graphs of the True Solution, Euler Solution,', 'and the Absolute Value of the Global Error (GE)'})
xlabel('t')
ylabel('Y(t)')
legend({'True Solution','Euler Solution', 'Absolute Value of the GE'},'Location','southwest')
end
I now try and call this function in another script. The variables f and Y in the function are symbolic functions; so, in the other file, I first declare these functions before calling this function. Here's the code:
clc
syms f(t,y)
syms Y(t)
f(t,y) = -y + 2.0*cos(t); %This the derivative of the function whose solution we're trying to computed
Y(t) = sin(t) + cos(t); %This is the true solution;
% Calling function
EulerMethod(0.0, 6.0, 0.2, f, Y, 1.0);
I, however, get errors when I run the second script. Can anyone help me figure out what's going wrong? I suspect this may be because of the way I have both input and used the symbolic functions f and Y but I am not sure.
Matlab introduced for the ~ character in the list of output arguments of some routine in order to indicate we're not interested in this output value. For instance:
% Only interested for max position, not max value
[~, idx] = max(rand(1, 10));
For speed optimization reasons, is it possible from inside some routine to detect that some of the output arguments are not used ? For instance:
function [y, z] = myroutine(x)
%[
if (argout(1).NotUsed)
% Do not compute y output it is useless
y = [];
else
% Ok take time to compute y
y = timeConsummingComputations(x);
end
...
%]
It may not be the best one but an easy solution is to add another input argument
function [y, z] = myroutine(x, doYouWantY)
%[
if doYouWantY == 0
% Do not compute y output it is useless
y = [];
else
% Ok take time to compute y
y = timeConsummingComputations(x);
end
...
%]
nargout method, edited for 2nd output. Not very stable solution though, since whenever you call the function with one output argument, you need to be aware that the output is the second argument only.
function [y, z] = myroutine(x)
%[
if nargout==1
% Do not compute y output it is useless
y = [];
else
% Ok take time to compute y
y = timeConsummingComputations(x);
end
%]
I want to Calculating the value of a function for different inputs in matlab and insert output in a matrix for example: x(1,1)=1 y(1,1)=1 x(1,2)=2 y(1,2)=4 and etc.
this is my m file in matlab:
clc,clear all,close all
x0=0;
xn=10;
n=10;
h=(xn-x0)/n;
k=1;
for k=1:n
x=[1:10];
x=x0+h;
y=x^2
x0=x;
end
My problem is that every time the for loop runs The output value is stored in the y and I can't use the output value for example: x=2 in somewhere else.
A few thoughts:
x=[1:10] does not do anything as you overwrite it in the next line
If you remove x = [1:10] you can achieve what you want to achieve by using indexing, i.e. x(k) = x0 + h and y(k) = x(k)^2 and x0 = x(k)
There is a simpler way though using vectorization though!
x = 1:10
y = x.^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)
I have two Matlab functions f=fun1(x) and f=fun2(x,y) which are very alike and I would like to integrate them into a single function f=fun(x,y).
For the first function I have
function f=fun1(x)
N=1000; % Some large number.
for j=1:N
f=x^2;
end
and for the second function
function f=fun2(x,y)
N=1000; % Some large number.
for j=1:N
f=x^2;
f=f+y;
end
. So actually fun1 is sort of a subfunction of fun2. I would like to construct a function f=fun(x,y,method_number) like
function f=fun(x,y,method_number)
N=1000; % Some large number.
for j=1:N
f=x^2; % If method_number==1 run only this command....
f=f+y; % If method_number==2 run also this command.
end
This is just a short simplified example of the problem I want to solve. My real problem is that I have three long functions f=fun1(x,y,z), f=fun2(x,y) and f=fun3(x) with several resemblances and of which fun3 is a subfunction of fun2 and fun2 is a subfunction of fun1 in the same meaning as here above. I do not believe using switch-case or if-else everywhere is an option since N can be very large, which would be inefficient. Furthermore, it would completely destroy the layout of the code.
In your case it seem each of your function have a different number of input argument. If it is the case, the matlab function nargin can detect that and you do not have to specify an additional method parameter.
For example:
function f = fun(x,y,z)
switch nargin
case 1
f = x.^2; %// run only if ONE argument was specified
case 2
f = fun(x) + y; %// run only if TWO arguments were specified
case 3
f = fun(x,y) ./ z ; %// run only if THREE arguments were specified
otherwise
disp('Houston, we have a problem !!') ; %// run if NO or more than 3 arguments were specified
end
You can call f with one argument, two or three without trouble, Matlab will only execute the function corresponding to the proper number of argument.
The function, when passed with 3 arguments, can call on itself to calculate the part with 2 argument (which can call on itself to calculate the part from the first argument).
Case two: If the recursion really cannot be taken out of the loop, the classic if ... then will work:
function f = fun(x,y,z)
if nargin == 3
threeArgs = true ;
twoArgs = true ;
elseif nargin == 2
threeArgs = false ;
twoArgs = true ;
elseif nargin == 1
threeArgs = false ;
twoArgs = false ;
end
for it=1:1e6
f = x.^2; %// If method_number==1 run only this command....
%// ... other computations
if twoArgs
f = f + y ; %// If method_number==2 run also this command.
%// ... other computations
if threeArgs
f = f ./z ; %// If method_number==3 run also this command.
%// ... other computations
end
%// ... other computations only relevant to f(x,y)
end
%// ... other computations only relevant to f(x)
end
This would totally exclude recursion and would insure the minimum number of computation.
Now I realise this looks a bit clumsy code and you asked for a solution without if ... then and switch. Depending on your calculation, there is a method which can avoid any if or switch but may not be practical for all cases.
The idea is to assign an invariant operator to y or z in case they are not called.
Example:
function f = fun(x,y,z)
if nargin < 3 ; z = 1 ; end
if nargin < 2 ; y = 0 ; end
for it=1:1e6
f = x.^2;
%// ... other computations just based on X
f = f + y ; %// This always run, but if "y" wasn't specified, it does not modify the result (f+0=f)
%// ... other computations
f = f ./z ; %// This always run, but if "z" wasn't specified, it does not modify the result (f./1=f)
%// ... other computations
end
This avoid any flow branch in the code but i would only keep this method for simple cases, because the computations are always done regardless of the case (although may be some JIT compiler are smart enough to not bother doing 'no effect' operations).
You can avoid checking for the number of input arguments nargin N-times by duplicating code. You will check once, which computation should be done and repeat it N times. In this example, the for-loop is the duplicated code. To some extent, this might be okay.
function f = fun(x, y, z)
N = 1000;
switch nargin
%// Do something if only x is given
case 1
for j = 1:N
f = x.^2;
end
%// Do something else if only x and y are given
case 2
for j = 1:N
f = x.^2 + y;
end
%// Do something else if x, y and z are given
case 3
for j = 1:N
f = x.^2 + y - z;
end
otherwise
error('Use fun.m with 1, 2 or 3 arguments only!');
end
end
This is a variation of Hoki`s answer. In fact, I started from it adding the for-loop and removing the recursive function calls by adding duplicated code.