Apply function to each column in matrix

Dear MATLAB community,
In my current code I need to apply (very quickly) a user specified function to each row of a matrix. The function typically looks like this (but can take any other form including nonlinear):
v = @(b) b(1)*x1 + b(2)*x2 + b(3)*x3
(with x's being vectors)
now I have a matrix B of dimension [3 x DRAWS] and need to apply the function to each of the columns. Is there anything similar to the apply() function in R?
In an more advanced version B has the dimension [3 x DRAWS x PEOPLE] where I need to do the same again for both dimensions.
My issue now is the following: I could, of course, apply a simple for loop. However, this is too slow, because DRAWS can be quite large (up to 5000) and PEOPLE can be quite large too (often >1000). Additionally, the entire thing enters another function (log-likelihood) that is optimised using fmincon.
Does anyone have an idea on how to do this efficiently?
Best wishes and thanks a lot in advance!
Sebastian

Answers (1)

‘... a matrix B of dimension [3 x DRAWS] and need to apply the function to each of the columns.’
I don’t understand. If ‘DRAWS’ is other than 3, I don’t see how you could use it across columns.
You can apply them across the rows easily enough by adding an extra dimension to the subscript references:
DRAWS = 10;
M = randi(9, 3, DRAWS);
x1 = 2;
x2 = 3;
x3 = 5;
v = @(b) b(1,:)*x1 + b(2,:)*x2 + b(3,:)*x3;
Out = v(M);

6 Comments

Sebastian
Sebastian on 18 Mar 2016
Edited: Sebastian on 18 Mar 2016
Thanks but, the problem is that the x's are vectors...
It would have helped to have mentioned that earlier.
I know of no way to generalise that to any length vectors ‘x1’... (that I assume are equal length), especially with a nonlinear function. You will likely end up with a for loop, looping through the elements of the matrix (columns) at each iteration. What you want would defeat bsxfun and arrayfun.
Thanks Star Strider, I was afraid you will say this... Seems like R has an advantage here over MATLAB with its apply() function...
My pleasure.
I experimented with it with bsxfun and arrayfun, but they aren’t set up for the sort of calculation you want to do. You could also end up with a multi-dimensional matrix as output.
One option could be something like this:
DRAWS = 10;
M = randi(9, 3, DRAWS);
x1 = randi(9, 5, 1);
x2 = randi(9, 5, 1);
x3 = randi(9, 5, 1);
v = @(b) b(1,:)'*x1' + b(2,:)'*x2' + b(3,:)'*x3';
Out = v(M);
but I don’t know if it would generalise to non-linear functions, since I don’t know what ‘non-linear’ means here.
Sebastian
Sebastian on 18 Mar 2016
Edited: Sebastian on 18 Mar 2016
Ah that could work!!! I will try to implement it in my code! Thanks! PS: Also works for the nonlinear functions I tried!

Sign in to comment.

Asked:

on 18 Mar 2016

Commented:

on 18 Mar 2016

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!