bsxfun when inputs are scalar and vector

Hello,
I am having trouble using bsxfun when the function inputs are a scalar and a vector. I would like to speed up a function by using bsxfun instead of a for loop. I provide below a very simple function that illustrates the inputs and the operations I want to perform as well as the error i get:
function C = bsxfun_test(a, vec)
el1 = vec(1);
el2 = vec(2);
el3 = vec(3);
C = (exp(el1)*sqrt(el2) + el3)/a;
end
Works well for one:
>> bsxfun_test(2, [1 2 3])
ans =
3.4221
But has some trouble when I want to vectorize:
bsxfun(@bsxfun_test,[2 3 4],[1,2,3; 4,5,6; 7,8,9])
And the error message:
Error using bsxfun Specified function handle produces invalid output dimensions. The function handle must be a binary elementwise function.
The expected output is a vector of size 3x1 (or 1x3) as follows:
>> [bsxfun(@bsxfun_test,2,[1,2,3]);
bsxfun(@bsxfun_test,3,[4,5,6]);
bsxfun(@bsxfun_test,4,[7,8,9])]
ans =
3.4221
42.6951
777.6867
EDIT: 1) I am running version 2018b

3 Comments

Stephen23
Stephen23 on 26 Oct 2018
Edited: Stephen23 on 26 Oct 2018
@Diego Leal: what MATLAB version are you using?
What size do you expect the output to have? Please show the expected output matrix.
Hello Stephen,
I updated my question to reply to your comment,
@Diego Leal: bsxfun is not the correct tool for what you are trying to do. It will expand scalar dimensions, but it will not contract any dimensions: this means that for your example data:
bsxfun(@bsxfun_test,[2 3 4],[1,2,3; 4,5,6; 7,8,9])
it will return an array whose size is where all scalar dimensions are expanded to the size of the other array. In your case it would return a 3x3 matrix, if the function worked without error.
The real solution is to write vectorized code (e.g. see my answer):

Sign in to comment.

 Accepted Answer

Stephen23
Stephen23 on 26 Oct 2018
Edited: Stephen23 on 26 Oct 2018
bsxfun is totally the wrong tool to use. You just need to vectorize your code:
>> a = [2,3,4]
a =
2 3 4
>> b = [1,2,3; 4,5,6; 7,8,9]
b =
1 2 3
4 5 6
7 8 9
>> (exp(b(:,1)).*sqrt(b(:,2))+b(:,3))./a(:)
ans =
3.4221
42.6951
777.6867

2 Comments

Thank you Stephen. In the example I posted I tried to simplify as much as I could, but the real function I am using calls several different functions and vectorizing does not seem to easy. In your comment above you suggest I might still be able to get the same answer but as a 3x3 matrix instead of an array?
Stephen23
Stephen23 on 26 Oct 2018
Edited: Stephen23 on 26 Oct 2018
"In your comment above you suggest I might still be able to get the same answer but as a 3x3 matrix instead of an array"
A 3x3 matrix is a 3x3 array. They are the same thing.
I have no idea what you mean by "the same answer", given that your example output had only three elements: how can three elements be "the same answer" as nine elements?
"...vectorizing does not seem to easy"
Vectorizing code is not always easy, or even desirable, or even possible. Well written loops are perfectly efficient for solving many problems. Some tasks cannot be computed efficiently. It might be possible to improve efficiency of your code, but I have no idea because you have not uploaded your code: you have not said if you have profiled your code, or if you have preallocated the output arrays before the loop, etc..
bsxfun is not a "replacement" for any generic loop. You should read this:

Sign in to comment.

More Answers (0)

Products

Release

R2018b

Tags

Asked:

on 26 Oct 2018

Edited:

on 26 Oct 2018

Community Treasure Hunt

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

Start Hunting!