matlab - arrayfun(..) call, "Not enough input arguments." - matlab

In the following boiled down example illustrating the error, the function f_what(..) should return the values of input argument y at indices in the array ts:
function Y = f_what(y, ts)
function get_out = get(t)
get_out = y(t);
end
Y = arrayfun(get, ts);
end
Calling it:
>> f_what(1:10, 1:5)
Error using f_what/get (line 4)
Not enough input arguments.
Error in f_what (line 7)
Y = arrayfun(get, ts);
Also, for some reason, the following, where get(..) should be the same as the one above, works:
function Y = f_what(y, ts)
get = #(t) y(t);
Y = arrayfun(get, ts);
end
Calling it:
>> f_what(1:10, 1:5)
ans =
1 2 3 4 5
"Not enough input arguments" ... arrayfun(..) should call its first argument with, in this case, one argument. And get(..) has one input argument. I don't get why it's not enough.
Edit: even more boiled down:
function Y = f_what
function get_out = get_(t)
get_out = t;
end
Y = arrayfun(get_, 1:5);
end
Still the same error.
Edit 2: It works if I supply #get to the first argument of arrayfun(..), instead of get. But I still don't get why it doesn't work without the #.

Looking at the arrayfun documentation
func
Handle to a function that accepts n input arguments and returns m output arguments.
A handle in matlab is denoted using #, so you need to pass #get as first parameter. Otherwise matlab tries to evaluate function get instead of obtaining its handle, which results in "not enough parameters" error.
In the example that works you defined get to be a handle to an anonymous function, that's why it worked.

Related

Calculating the numeric derivative

So i'm a little confounded by how to structure my problem.
So the assignment states as following:
Type a m-file numerical_derivative.m that performs numerical derivation. Use
it to calculate f'(-3) when f(x) = 3x^2 /(ln(1-x))
In the m-file you to use h = 10^-6 and have the following mainfunction:
function y = numericalderivative (f, x)
% Calculates the numerical value in the case of f in punk x.
% --- Input ---
% f: function handle f(x)
% x: the point where the derivative is calculated
% --- output ---
% y: the numerical derivative of f on the point x
If I want to save it as a file and run the program in matlab, does't it make it redundant to use handles then?
I won't give you the answer to your homework, but perhaps a simpler example would help.
Consider the following problem
Write a function named fdiff which takes the following two arguments:
A function f represented by a function handle which takes one argument,
and a point x which can be assumed to be in the domain of the f.
Write fdiff so that it returns the value f(x) - f(x-1)
Solution (would be in the file named fdiff.m)
function result = fdiff(f, x)
result = f(x) - f(x-1);
end
Example Use Cases
>> my_function1 = #(x) 3*x^2 /(log(1-x));
>> fdiff(my_function1, -3)
ans =
-10.3477
>> my_function2 = #(x) x^2;
>> fdiff(my_function2, 5)
ans =
9
What you've created with fdiff is a function which takes another function as an input. As you can see it doesn't just work for 3*x^2 /(log(1-x)) but any function you want to define.
The purpose of your assignment is to create something very similar, except instead of computing f(x) - f(x-1), you are asked write a function which approximates f'(x). Your use-case will be nearly identical to the first example except instead of fdiff your function will be named numericalderivative.
Note
In case it's not clear, the second example defines the my_function2 as x^2. The value returned by fdiff(my_function2, 5) is therefore 5^2 - 4^2 = 9.
When you make this as a function file and run this in MATLAB without any input arguments i.e., 'f' and 'x', it will give you the error: 'not enough input arguments'. In order to run the file you have to type something like numericalderivative (3x^2 /(ln(1-x)), 5), which gives the value of the numerical derivative at x = 5.
Functions and, in MATLAB function files are a simple implementation of the DRY programming method. You're being asked to create a function that takes a handle and an x file, then return the derivative of that function handle and that x value. The point of the function file is to be able to re-use your function with either multiple function handles or multiple x values. This is useful as it simply involves passing a function handle and a numeric value to a function.
In your case your script file or command window code would look something like:
func = #(x) (3*x^2)/log(1-x);
x = -3;
num_deriv = numericalderivative(func,x);
You should write the code to make the function numericalderivative work.

ODE solver producing runtime error - not enough input arguments [duplicate]

I have a use case as follows:
Inside F.m I have a function F that takes as its argument a 2 x 1 matrix x. F needs to matrix multiply the matrix kmat by x. kmat is a variable that is generated by a script.
So, what I did was set kmat to be global in the script:
global kmat;
kmat = rand(2);
In F.m:
function result = F(x)
global kmat;
result = kmat*x;
end
Then finally, in the script I have (x_0 has already been defined as an appropriate 2 x 1 matrix, and tstart and tend are positive integers):
xs = ode45(F, [tstart, tend], x_0);
However, this is causing the error:
Error using F (line 3)
Not enough input arguments.
Error in script (line 12)
xs = ode45(F, [tstart, tend], x_0);
What is going on here, and what can I do to fix it? Alternatively, what is the right way to pass kmat to F?
Firstly, the proper way to handle kmat is to make it an input argument to F.m
function result = F(x,kmat)
result = kmat*x;
end
Secondly, the input function to ode45 must be a function with inputs t and x (possibly vectors, t is the dependent variable and x is the dependent). Since your F function doesn't have t as an input argument, and you have an extra parameter kmat, you have to make a small anonymous function when you call ode45
ode45(#(t,x) F(x,kmat),[tstart tend],x_0)
If your derivative function was function result=derivative(t,x), then you simply do ode45(#derivative,[tstart tend],x_0) as Erik said.
I believe F in ode45(F,...) should be a function handle, i.e. #F. Also, you can have a look at this page of the MATLAB documentation for different methods to pass extra parameters to functions.

MATLAB function handles and parameters

When I type help gmres in MATLAB I get the following example:
n = 21; A = gallery('wilk',n); b = sum(A,2);
tol = 1e-12; maxit = 15;
x1 = gmres(#(x)afun(x,n),b,10,tol,maxit,#(x)mfun(x,n));
where the two functions are:
function y = afun(x,n)
y = [0; x(1:n-1)] + [((n-1)/2:-1:0)'; (1:(n-1)/2)'].*x+[x(2:n); 0];
end
and
function y = mfun(r,n)
y = r ./ [((n-1)/2:-1:1)'; 1; (1:(n-1)/2)'];
end
I tested it and it works great. My question is in both those functions what is the value for x since we never give it one?
Also shouldn't the call to gmres be written like this: (y in the #handle)
x1 = gmres(#(y)afun(x,n),b,10,tol,maxit,#(y)mfun(x,n));
Function handles are one way to parametrize functions in MATLAB. From the documentation page, we find the following example:
b = 2;
c = 3.5;
cubicpoly = #(x) x^3 + b*x + c;
x = fzero(cubicpoly,0)
which results in:
x =
-1.0945
So what's happening here? fzero is a so-called function function, that takes function handles as inputs, and performs operations on them -- in this case, finds the root of the given function. Practically, this means that fzero decides which values for the input argument x to cubicpoly to try in order to find the root. This means the user just provides a function - no need to give the inputs - and fzero will query the function with different values for x to eventually find the root.
The function you ask about, gmres, operates in a similar manner. What this means is that you merely need to provide a function that takes an appropriate number of input arguments, and gmres will take care of calling it with appropriate inputs to produce its output.
Finally, let's consider your suggestion of calling gmres as follows:
x1 = gmres(#(y)afun(x,n),b,10,tol,maxit,#(y)mfun(x,n));
This might work, or then again it might not -- it depends whether you have a variable called x in the workspace of the function eventually calling either afun or mfun. Notice that now the function handles take one input, y, but its value is nowhere used in the expression of the function defined. This means it will not have any effect on the output.
Consider the following example to illustrate what happens:
f = #(y)2*x+1; % define a function handle
f(1) % error! Undefined function or variable 'x'!
% the following this works, and g will now use x from the workspace
x = 42;
g = #(y)2*x+1; % define a function handle that knows about x
g(1)
g(2)
g(3) % ...but the result will be independent of y as it's not used.

How to store a function-wrapped solve call?

Bear with me please, I'm completely new to matlab. I am attempting to store the call to eigenvalue in another function, but it's giving me the error: Too many output arguments.
function eigenvalue(M)
syms l;
eq = det(M - l*[1 0; 0 1]);
solve(eq == 0)
end
I've tried storing it in many different ways, but nothing seems to work:
>> a = eigenvalue(M)
Error using eigenvalue
Too many output arguments.
>> [a, b] = eigen(M)
Error using eigenvalue
Too many output arguments.
The weird thing is that if I solve a normal polynomial equation I can do sol=solve(x^2==4) just fine and access sol(0)and sol(1)without any problems. I guess that I haven't picked up on a simple matlab concept and thanks to anyone who's willing to help!
Your problem is that you don't have any output arguments in your function.
function eigenvalue(M)
In MATLAB, you should* use the following syntax:
function output = func_name(input_1,input_2,...)
You have 2 alternatives:
You can skip the first line and save it as script, as this:
syms l;
eq = det(M - l*[1 0; 0 1]);
solve(eq == 0)
Or, you can save it as a function, but with output variable(s), like this:
function output = eigenvalue(M)
syms l;
eq = det(M - l*[1 0; 0 1]);
output = solve(eq == 0)
end
*You should use the syntax I described, but you can use the syntax you used as well. However, if you do, the function won't give you anything back except possibly printing the result to screen. You will not get to use any variables created inside the function.
If you want a function to provide an output argument then you have to declare it in the function definition. E.g.
function a = eigenvalue(M)
You then need to make sure you assign a value to each output variable in the function body.

Matlab function argument issue

hey I have a function defined as,
drift = #(x1,x2,u)[x2,(a*sin(x1) - b*x2 + u)]*.05;
then I attempt to call it while in a triple for loop (iterating over
x1= 1:length(n1),
x2 = 1:length(n2)
x3 = 1:length(nu)
)
next = [n1(x1), n2(x2)] + drift([n1(x1), n2(x2), nu(k)]);
and I get Error using myMDP>#(x1,x2,u)[x2,(a*sin(x1)-b*x2+u)]*.05 (line 148)
Not enough input arguments.
that error. Why?
f([1,2,3]) %function call with a single parameter, which is a 3 element vector
f(1,2,3) %function call with three parameters
f([1,2,3],[1,2,3],[1,2,3]) %function call with three parameters, each a 3 element vector.