I have defined a function in matlab:
function1 = #(x,y,z)[x*y*z,y^2,x+z]
Then in the program I want to writ, I want to evaluate the values of this function for (1,2,3).
Outside the program I can use feval(function1,1,2,3) and this returns
6 4 4.
Now inside my program, I want the input to be like this: output = program(fun, vec), where vec is a vector like [1,2,3].
If I now call: feval(fun,vec) I get the following error message:
Error using #(x,y,z)[x*y*z,y^2,x+z]
Not enough input arguments.
Can someone tell me how I can evaluate the values of my function when the input is a vector instead of three seperate numbers?
Many thanks!
You need a comma-separated list. Define your vector vec as follows:
vec = {1 2 3}
or use
vec = [1 2 3]
vec = num2cell{vec}
and then call feval:
feval(fun,vec{:})
It is actually obsolete to evaluate functions with feval, the following is equivalent:
function1(1,2,3)
function1(vec{:})
As you want to pass the vector vec to your program you need to modify your program to either accepted a various number of inputs with varargin:
program(fun, vec{:))
or you change the evaluation of vec inside your function to vec{:}
You are creating anonymous functions, and they can be used with the following syntax:
myfun= #(x,y,z)([x*y*z,y^2,x+z])
res=myfun(1,2,3);
vect=[1 2 3]
res2=myfun(vect(1),vect(2),vect(3));
In general I would try to avoid using feval.
Related
In Matlab, I have a variable length cell of values:
C={A1,...,An}
How should I pass and distribute these values into a function able to receive a variable number of arguments?
f(A1,...,An)
Ultimately if not possible, how should I modify the beginning of this function for making this work?
You need to convert the cell array into a comma-separated list via curly-brace indexing, that is, use C{:}.
Example with the reshape function:
>> C = {ones(3,4), 2, 2, 3};
>> y = reshape(C{:});
>> size(y) % check
ans =
2 2 3
This is exactly what 'varargin' does for you. Read in multiple variables, e.g. f(a,b,c), and store them in a cell-array.
Then you could go for one of these 'quick and dirty' processing methods:
function asdf(varargin)
yourarguments=[varargin{:}]; % if all numerical
yourargumentscontain=contains(varargin,'asdf'); %if strings contained
all_processed_args=cellfun(#(x) whateveryouwant_function(x), varargin); %for older versions of matlab
end
For more here's documentation: https://ch.mathworks.com/help/matlab/matlab_prog/parse-function-inputs.html
I want to write an inline function which will accept two arguments in which one argument is a vector.
>>nCk = #(n,k)(nchoosek(n,k));
>>nCk(3,1:2)
Error using nchoosek (line 29)
The second input has to be a non-negative integer.
How can I make the second argument accepts a vector.
As mentioned, nchoosek only allows integer inputs for the second argument. If you do want to make an inline function, you can fold the loop into a call to arrayfun, however:
nCk = #(n,kVec)arrayfun(#(k)nchoosek(n,k),kVec);
And use like this:
nCk(5,0:5)
ans =
1 5 10 10 5 1
While its probably not what you want, I think this is one situation where I would use a for loop, as nchoosek only accepts an integer for its k value:
nCk = #(n,k)(nchoosek(n,k));
n = 3;
for k = 1:2
disp(nCk(n,k));
end
Though if you do it this way, then the inline statement is likely redundant, so it could be reduced to:
n = 3;
for k = 1:2
disp(nchoosek(n,k));
end
From here ,you can see that you can have as vector the first argument and not the second.
So ,you can use:
nCk = #(k,n)(nchoosek(k,n));
If that helps you of course
In my matlab script, I have a function handler
F=#(x1,x2)6+2*x1^1+3*x2^2;
This gives me an anonymous function as F that takes 2 arguments and returns the value. I also have an array of values
x = [1 2];
With the above, how can I do
F(x)
In other words, something like F(1, 2) but I want to use x, I don't want to hard code values, and it also needs to work for any dimension size, I don't want to hard code it for 2-dimension like in the above example. Basically what I'm looking for is a way to turn an array into arguments.
Can this be done in matlab?
Thanks
To turn an array into its arguments: first turn the array into a cell array (with num2cell), and then turn the cell array into a comma-separated list (with {:}):
xcell = num2cell(x);
F(xcell{:})
Does this work?
F=#(x)6+2*x(1)^1+3*x(2)^2;
xx = [1 2];
F(xx)
ans =
20
I have a defined mathematical function: f =Inline('x1^2+x2^2+2*x1*x2','x1','x2')
and I have an array that represents the number value of x1 and x2. (e.g. the array is A=[1 2])
I want to automate the process of getting the f(x1,x2), but I couldn't figure out the right way that Matlab can take in the array and assign values to x1 and x2.
What can I do to pass in the array values to the mathematical model and get the function value?
You should be using anonymous functions instead of inline since inline will be removed in a future release of MATLAB.
Example (from the docs):
sqr = #(x) x.^2;
a = sqr(5)
a =
25
In your case:
f = #(x) x(1)^2+x(2)^2+2*x(1)*x(2);
Now it expects x to be a two (or more) value array.
A = [1 2];
f(A) =
9
Note:
I don't have MATLAB on my home computer so I haven't actually tested this but it should get you going in the right direction. Have a look over the docs and you'll be fine.
I need help figuring out how to code the following problem. Any help would be greatly appreciated!
Create a function that will take a vector/array input for x (1 by n) and a scalar input for a, and produce the output defined by the following equation:
y(x,a)=((xsin(ax-2))/(sqrt(1+(ax)^2)
-π ≤ x ≤ π
a={.5 1 1.5 2}
The equation must be vectorized in terms of x and the output from the function is the array y which has the same dimension as the array x.
Write a script that calls this function to compute y(x,a) for the range of x defined above and each value of the parameter a. Results should be stored in a solution matrix using a different row of the solution matrix for each value of a.
So far for my function I have:
function [y] = part1(a,x)
y=((x*sin(a*x-2))/(sqrt(1+(a*x).^2)));
end
I'm not sure how to output this into the solution matrix
For my script I have:
%%
clear,clc
a={0.5 1 1.5 2};
x=-pi:0.1:pi;
for
part1(x,a)
end
I'm getting the following errors when I run this now:
Undefined function 'mtimes' for input arguments of type 'cell'.
Error in part1 (line 4)
y=((x*sin(a*x-2))/(sqrt(1+(a*x).^2)));
Error in labtest2 (line 8)
y(i,:)=part1(x,a(i));
EDIT
I've made some changes and am still getting some errors that I cannot resolve.
Here is my full code for function followed by full code for script:
Function
function [y] = part1(x,a)
nx=numel(x);
na=numel(a);
y=((x.*sin(a.*x-2))./(sqrt(1+(a.*x).^2)));
size(y)=[nx na]
end
Script
%%
clear,clc
a={0.5 1 1.5 2};
x=-pi:0.1:pi;
for i = 1:length(a)
y(i,:)=part1(x,a(i));
end
Errors
Undefined function 'times' for input arguments of type 'cell'.
Error in part1 (line 6)
y=((x.*sin(a.*x-2))./(sqrt(1+(a.*x).^2)));
Error in labtest2 (line 8)
y(i,:)=part1(x,a(i));
The reason you're getting Undefined function 'times' for input arguments of type 'cell' is because your variable a is a cell array. You need to change your assignment of a from
a={0.5 1 1.5 2};
to
a=[0.5 1 1.5 2];
which will make it just a normal array. Alternatively, you need to reference it with cell array notation: a{i} instead of a(i).
You're almost there. Note that you've written
function [y] = part1(a,x)
but you call it in your script as
part1(x,a)
so you should probably correct that.
A few things jump out at me:
You never assign the output of part1(x,a) to anything. You're told that
Results should be stored in a solution matrix using a different row of the solution matrix for each value of a.
What I take this to mean is that the 1st row corresponds to part1() evaluated for the 1st element of a. Since we're operating on x which is a vector, that row will have multiple columns. Your output is indeed a matrix. In your case, length(-pi:0.1:pi) == 63, therefore size(y) == [4 63], where y is your output matrix.
Your for loop is backwards. You're told to accept scalar a and vector x. Therefore, your script should be something like:
a = 0.5:0.5:2;
x = -pi:0.1:pi;
for i = 1:length(a)
y(i,:) = part1(x, a(i));
end
Note the use of length and the : operator. I want to iterate between 1 to length(a) (in this case, length(a) == 4) so that I can use the current a(i) value as an index into my output matrix, y. The : operator in y(i,:) signifies "The ith row and all columns of y will take the value output by part1(x,a(i))."
Your function needs to be changed up for element-by-element operations. Notice that, for instance, x*sin(a*x-2) works for scalar x but not vectors. This is because x is a vector and sin(a*x-2) is also a vector (since the sin call will operate element-by-element and a is a scalar). Trying to multiply two vectors together will result in errors since MATLAB will try to perform a matrix multiplication. Resolve this by replacing * with .*. This way it is unambiguous that you are going to multiply these two vectors element-by-element. You'll also need to change / to ./.
On another note, thank you for attempting to do your homework before asking SO for help. We've been getting a huge influx of questions from students that have made no attempt to do their own work before dumping it on us, so it's refreshing that we regulars of the MATLAB tag get to actual help out instead of telling people to do their own work.
Finally got the whole thing worked out.
Function
function [y] = part1(x,a)
y=((x.*sin(a.*x - 2))./(sqrt(1 + (a.*x).^2)));
end
Script
%%
clear all;
clc;
close all;
x=[-pi:.1:pi];
a=[.5:.5:2];
for i=1:length(a)
y(i,:)=part1(x,a(i));
plot(x,y)
end
Sol=[y]