will_cheuk
will_cheuk

Reputation: 379

Defining a multivariable function for vector inputs

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

Answers (3)

Sabarinathan Vadivelu
Sabarinathan Vadivelu

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

EBH
EBH

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

Zeta.Investigator
Zeta.Investigator

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

Related Questions