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

Stephen23
Stephen23 2016년 5월 20일
편집: Stephen23 2016년 5월 20일
The error you are getting has nothing to do with anonymous functions, so why put this in your title? This misleads people about what the real topic is.
Nor does it have anything to with "because the variable is just not there": in both of your examples you call your function with one input variable (a scalar and a vector respectively). Perhaps you are confused about the difference between variables and the array elements, in which case you should do the introductory tutorials:
Actually your vector x is one variable, it does not matter how many elements it has (one or one million). These are the standard MATLAB terms: when we learn and use the correct terms it makes communicating on this forum much easier.
Davide Calzolari
Davide Calzolari 2016년 5월 20일
I have put anonymous functions because I generate this function with matlabFunction(), and I cannot find a way to assure that the output size is kept when utilizing anonymous functions. Taking in consideration that the result is a position, velocity or acceleration vector and the input variable the time, the result has to remain a vector. I m sorry the example I have made is far too general.
Stephen23
Stephen23 2016년 5월 20일
편집: Stephen23 2016년 5월 20일
Aha, so you are using matlabFunction. Is there any particular reason why you do this? Is it not possible to write the anonymous function by hand? Why do you need to use matlabFunction ?
If I understand correctly you are trying to get matlabFunction to generate an anonymous function that uses code vectorization? According to the documentation there is certainly an option for specifying that an input is a vector (see the 'Vars' option), but this seems to only permit a known size of this vector.
Davide Calzolari
Davide Calzolari 2016년 5월 20일
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 2016년 5월 20일
편집: Davide Calzolari 2016년 5월 20일
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.

댓글을 달려면 로그인하십시오.

 채택된 답변

Kelly Kearney
Kelly Kearney 2016년 5월 20일

3 개 추천

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

Davide Calzolari
Davide Calzolari 2016년 5월 20일
편집: Davide Calzolari 2016년 5월 20일
the input would remain always a column array.
And, well if there is no solution, I will go for a for-loop and pack results..
Matt J
Matt J 2016년 5월 20일
You have already said that my Answer (the second option mentioned) gave the output that you want. In what way is the problem still unsolved?
Davide Calzolari
Davide Calzolari 2016년 5월 20일
I cannot write the zeros() in the function.. I have written that I m using matlabFunction to obtain the anonymous function, plus I dont know this function in advance so that i can define it.
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 2016년 5월 24일
Thank you for your solution! This is the best approach so far.

댓글을 달려면 로그인하십시오.

추가 답변 (3개)

Matt J
Matt J 2016년 5월 20일

2 개 추천

Not sure what you want the output to be. Two possibilities are
f=@(x)[x(:);0]
and
f=@(x) [x;zeros(size(x))]

댓글 수: 4

Davide Calzolari
Davide Calzolari 2016년 5월 20일
the second one. The function returns nominally a vector. if I give multiple inputs it should give back multiple columns.
This is because the result is a position, velocity or acceleration vector.
Stephen23
Stephen23 2016년 5월 20일
편집: Stephen23 2016년 5월 20일
@Davide Calzolari: "I give multiple inputs" is impossible, because the function your showed us only has one input argument: x. Count it: one input, x. The (one) variable x might have many elements, but this has nothing to do with the number of input variables your function has (one). You might like to repeat the MATLAB introductory course to learn these very important basic concepts about MATLAB:
And Matt J's answer does give multiple columns, with a row-vector input:
>> f=@(x) [x;zeros(size(x))];
>> f(1:4)
ans =
1 2 3 4
0 0 0 0
Four columns. Count them.
Davide Calzolari
Davide Calzolari 2016년 5월 20일
편집: Davide Calzolari 2016년 5월 20일
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 2023년 8월 31일
Thank you very much, the second one is good.

댓글을 달려면 로그인하십시오.

Matt J
Matt J 2016년 5월 20일
편집: Matt J 2016년 5월 20일

0 개 추천

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.

카테고리

도움말 센터File Exchange에서 Programming에 대해 자세히 알아보기

질문:

2016년 5월 20일

댓글:

Yue
2023년 8월 31일

Community Treasure Hunt

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

Start Hunting!

Translated by