Reputation: 379
I am a bit new in using Matlab, and I have a question about defining a multivariable function for vector input.
If the function is a single function, say f(t)
, I know how to make it for vector input. The general way is to use arrayfun
after defining a f(t)
. How about for multivariable function, say f(x,y)
? What I want to do is to get two inputs, say [1 2 3]
for x
and [4 5 6 7]
for y
(dimension may be different, but both of them are either column vector or row vector) so that I can calculate to give
[f(1,4),f(1,5),f(1,6),f(1,7);
f(2,4),f(2,5),f(2,6),f(2,7);
f(3,4),f(3,5),f(3,6),f(3,7)]
The difficulty is that the vector input for x
and y
may not be in the same dimension.
I understand it may be difficult to illustrate if I do not have an example of f(x,y)
. For my use of f(x,y)
, it may be very complicated to display f(x,y)
. For simplicity, treat f(x,y)
to be x^2+y
, and once defined, you cannot change it to x.^2+y
for vector inputs.
Upvotes: 2
Views: 583
Reputation: 57
>> x = [1 2 3];
>> y = [4 5 6 7];
>> outValue = foo(x, y);
>> outValue
outValue =
5 6 7 8
8 9 10 11
13 14 15 16
Make this function:
function out = foo(x, y)
for i = 1 : length(x)
for j = 1 : length(y)
out(i, j) = x(i)^2 + y(j);
end
end
Upvotes: 0
Reputation: 10440
Here is a set of suggestions using ndgrid
:
testfun = @(x,y) x^2+y; % non-vectorized form
x = 1:3;
y = 4:7;
[X,Y] = ndgrid(x,y);
% if the function can be vectorized (fastest!):
testfun_vec = @(x,y) x.^2+y; % vectorized form
A = testfun_vec(X,Y);
% or without ndgrid (also super fast):
B = bsxfun(testfun_vec,x.',y); % use the transpose to take all combinations
% if not, or if it's not bivariate operation (slowest):
C = arrayfun(testfun,X(:),Y(:));
C = reshape(C,length(x),length(y));
% and if you want a loop:
D = zeros(length(x),length(y));
for k = 1:length(X(:))
D(k) = testfun(X(k),Y(k));
end
Which will output for all cases (A
,B
,C
and D
):
5 6 7 8
8 9 10 11
13 14 15 16
As mentioned already, if you can vectorize your function - this is the best solution, and if it has only two inputs bsxfun
is also a good solution. Otherwise if you have small data and want to keep your code compact use arrayfun
, if you are dealing with large arrays use an un-nested for loop.
Upvotes: 2
Reputation: 973
Here is the code using for loops and inline functions:
x = [1 2 3];
y = [4 5 6 7];
f = @(x,y) x^2 +y;
A = zeros(length(x), length(y));
for m = 1:length(x)
for n = 1:length(y)
A(m, n) = f(x(m), y(n));
end
end
disp(A);
Result:
A =
5 6 7 8
8 9 10 11
13 14 15 16
Upvotes: 0