bsxfun when inputs are scalar and vector

1 Ansicht (letzte 30 Tage)
Diego Leal
Diego Leal am 26 Okt. 2018
Bearbeitet: Stephen23 am 26 Okt. 2018
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 Kommentare
Diego Leal
Diego Leal am 26 Okt. 2018
Hello Stephen,
I updated my question to reply to your comment,
Stephen23
Stephen23 am 26 Okt. 2018
Bearbeitet: Stephen23 am 26 Okt. 2018
@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):

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Stephen23
Stephen23 am 26 Okt. 2018
Bearbeitet: Stephen23 am 26 Okt. 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 Kommentare
Diego Leal
Diego Leal am 26 Okt. 2018
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 am 26 Okt. 2018
Bearbeitet: Stephen23 am 26 Okt. 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:

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Tags

Produkte


Version

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by