Vectorization of anonymous functions

21 visualizaciones (últimos 30 días)
Davide Calzolari
Davide Calzolari el 20 de Mayo de 2016
Comentada: Yue el 31 de Ag. de 2023
Hi everybody,
I am trying to get vectorized outputs from anonymous functions. With a single input, the function returns a vector. I am getting in trouble when all or some part of the output is not function of the input therefore constant. In this case Matlab does not manage to generate a vectorized version of the results because the variable is just not there. I m generating the function with matlabFunction(). A small example of the problem (I don't know how the output relates to the input in advance):
>> f=@(x)[x;0]
f =
@(x)[x;0]
>> f(1)
ans =
1 % everything is fine
0
>> f(1:10)
Error using vertcat
Dimensions of matrices being concatenated are not consistent.
Error in @(x)[x;0]
The output that I would expect would be:
1 2 3 4 5 6 7 8 9 10
0 0 0 0 0 0 0 0 0 0
I wish to add that I cannot use logic statements when later I need to call this function.
Thank you for your time.
Best, Davide
EDIT: This function would solve the problem, but it loses the efficiency I hoped to achieve with vectorization.
function [ out ] = f_vectinput( f,u )
%F_VECTINPUT
dim=size(u,2);
out=zeros(size(f(u(1)),1),dim);
%for column input and column results
for i=1:dim
out(:,i)=f(u(i));
end
end
  5 comentarios
Davide Calzolari
Davide Calzolari el 20 de Mayo de 2016
Yeah I also write it regularly by hand, but this time the function comes in symbolic form from earlier manipulations. And I normally use matlabFunction to convert symbolic to function that I can use.
Davide Calzolari
Davide Calzolari el 20 de Mayo de 2016
Editada: Davide Calzolari el 20 de Mayo de 2016
My problem is the output dimension! I know it sounds weird.. but say a ball is at position [0;0] and is immobile. My function f(time) should give always [0;0] back, and if I ask where the ball is from at 0:10 seconds it should give me back an array where each column represents the position at t.
Also my codes works fine in general, except for these cases where part or all of the output is constant.

Iniciar sesión para comentar.

Respuesta aceptada

Kelly Kearney
Kelly Kearney el 20 de Mayo de 2016
I don't think there's any way to force matlabFunction to properly parse the contents of its functions and adapt to vector input appropriately. For example, how would you want it to deal with an input like (1:10)'? Just add a single 0 to the end (as it does now), or transpose the vector and add a 0 to every element? If I don't know what you want, an automatic parser certainly wouldn't.
In this case, I think arrayfun is your best bet.
f = @(x) [x;0]
tmp = arrayfun(f, 1:10, 'uni', 0);
tmp = cat(2, tmp{:})
tmp =
1 2 3 4 5 6 7 8 9 10
0 0 0 0 0 0 0 0 0 0
  5 comentarios
Kelly Kearney
Kelly Kearney el 23 de Mayo de 2016
You're asking this function to read your mind... if the input is a scalar or a column vector, append a 0, but if it's a row vector, apply the function element by element. (And if the input is a ND matrix? Or...?)
In order to get this behavior, you need to explicitly program f to handle each potential input type. Or, since it seems that you have no control over f itself, write a wrapper function around it:
function y = fwrap(f, x)
if size(x,2) == 1
y = f(x);
else
y = arrayfun(f, x, 'uni', 0);
y = cat(2, y{:})
end
Davide Calzolari
Davide Calzolari el 24 de Mayo de 2016
Thank you for your solution! This is the best approach so far.

Iniciar sesión para comentar.

Más respuestas (3)

Matt J
Matt J el 20 de Mayo de 2016
Not sure what you want the output to be. Two possibilities are
f=@(x)[x(:);0]
and
f=@(x) [x;zeros(size(x))]
  4 comentarios
Davide Calzolari
Davide Calzolari el 20 de Mayo de 2016
Editada: Davide Calzolari el 20 de Mayo de 2016
it is getting funny here..I m using matlab regularly since 3 years, I m really okay with the foundamentals.. I gave multiple inputs was badly written: I meant that I want a vectorized output, by using an input array. Example: I give an array 0:10. If the input is the time t, each column is the position at t. Also what you write is what i would have already done knowing f in advance, but i don't.
Yue
Yue el 31 de Ag. de 2023
Thank you very much, the second one is good.

Iniciar sesión para comentar.


Matt J
Matt J el 20 de Mayo de 2016
Editada: Matt J el 20 de Mayo de 2016
This function would solve the problem, but it loses the efficiency I hoped to achieve with vectorization.
The efficiency you seek needs to be built directly into f. If you are given f already, there is no general way to further vectorize out(:,i)=f(u(i)) externally. You can eliminate the for-loop in favor of more condensed syntax, e.g.,
out= cell2mat( arrayfun(@(i) f(u(i)), 1:10, 'uni',0) );
but there is no execution efficiency that this brings.

Walter Roberson
Walter Roberson el 23 de Mayo de 2016

Categorías

Más información sobre Programming en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by